Krotos Modules 3
Loading...
Searching...
No Matches
SampleBrowser.cpp
Go to the documentation of this file.
1namespace krotos
2{
3 const String SampleBrowser::ComponentIds::VerticalViewportScrollbar("SamplerBrowserVertical");
4
5 SampleBrowser::SampleBrowser(int width, int height, int itemHeight, OwnedArray<Sample> samplesToShow)
6 : PopupMenu::CustomComponent(false), m_idealWidth(width), m_idealHeight(height), m_itemHeight(itemHeight),
7 m_samples(std::move(samplesToShow))
8 {
9 for (int i = 0; i < m_samples.size(); ++i)
10 {
11 // Create sample item component
12 auto* sampleItem = m_sampleItems.add(std::make_unique<SampleItem>(m_samples[i]->name));
13 // Set up mute / solo buttons
14 int sampleIndex = m_samples[i]->index;
15
16 // Attach buttons to sample mute / solo Value references
17 sampleItem->muteButton.getToggleStateValue().referTo(m_samples[i]->muted);
18 sampleItem->soloButton.getToggleStateValue().referTo(m_samples[i]->solo);
19
20 // Initialise mute active state
21 sampleItem->sampleSelectButton.setEnabled(!static_cast<bool>(m_samples[i]->muted.getValue()));
22
23 // Solo handling, mute others
24 sampleItem->soloButton.onClick = [this, sampleItem, sampleIndex]() {
25 bool isSolo = sampleItem->soloButton.getToggleState();
26
27 for (int i = 0; i < m_sampleItems.size(); i++)
28 {
29 m_sampleItems[i]->muteButton.setToggleState(isSolo && (i != sampleIndex), dontSendNotification);
30
31 m_sampleItems[i]->sampleSelectButton.setEnabled(!m_sampleItems[i]->muteButton.getToggleState());
32
33 // Unsolo other samples if activated
34 if (i != sampleIndex && isSolo)
35 {
36 m_sampleItems[i]->soloButton.setToggleState(false, dontSendNotification);
37 }
38 }
39
40 if (onSampleSolo)
41 {
42 onSampleSolo(sampleIndex, isSolo);
43 }
44
45 // Retain cue on solo deactivated
46 if (isSolo)
47 {
48 setCuedSample(sampleIndex, true);
49 }
50 };
51
52 // Prevent all samples from being muted (limitation with sample engine)
53 sampleItem->muteButton.onClick = [this, sampleItem, sampleIndex]() {
54 if (allMuteButtonsOn())
55 {
56 sampleItem->muteButton.setToggleState(false, dontSendNotification);
57 }
58 sampleItem->sampleSelectButton.setEnabled(!sampleItem->muteButton.getToggleState());
59
60 if (onSampleMuted)
61 {
62 onSampleMuted(sampleIndex, sampleItem->muteButton.getToggleState());
63 }
64 };
65
66 // Sample select button
67 sampleItem->sampleSelectButton.onClick = [this, sampleIndex] {
69 {
70 onSampleSelected(sampleIndex);
71 }
72 };
73
74 sampleItem->deleteButton.onClick = [this, sampleIndex] {
76 {
77 onSampleDeleted(sampleIndex);
78 }
79
80 m_samples.remove(sampleIndex);
81 m_sampleItems.remove(sampleIndex);
82 };
83
84 // Initialise component
85 sampleItem->setLookAndFeel(&m_textButtonLAF);
86 m_itemsParent.addAndMakeVisible(sampleItem);
87 }
88
89 addAndMakeVisible(m_scrollableArea);
90 m_scrollableArea.setScrollBarThickness(7);
91 m_scrollableArea.getVerticalScrollBar().setComponentID(ComponentIds::VerticalViewportScrollbar);
92 m_scrollableArea.setViewedComponent(&m_itemsParent);
93 }
94
96 {
97 for (auto& item : m_sampleItems)
98 {
99 item->setLookAndFeel(nullptr);
100 }
101 }
102
104 {
105 for (auto& sample : m_sampleItems)
106 {
107 if (!sample->muteButton.getToggleState())
108 {
109 return false;
110 }
111 }
112 return true;
113 }
114
115 void SampleBrowser::getIdealSize(int& width, int& height)
116 {
117 width = m_idealWidth;
118 height = m_idealHeight;
119 }
120
122 {
124
125 m_itemsParent.setBounds(0, 0, m_idealWidth - m_scrollableArea.getScrollBarThickness(),
126 m_itemHeight * m_samples.size());
127
128 int i = 0;
129 for (auto btn : m_sampleItems)
130 {
131 btn->setBounds(0, i * m_itemHeight, m_idealWidth - m_scrollableArea.getScrollBarThickness(), m_itemHeight);
132 i++;
133 }
134 }
135
136 void SampleBrowser::setCuedSample(int sampleIndex, bool isCued)
137 {
138 const int itemCount = std::distance(m_sampleItems.begin(), m_sampleItems.end());
139
140 if (sampleIndex >= 0 && sampleIndex < itemCount)
141 {
142 for (auto& item : m_sampleItems)
143 {
144 item->setCued(false);
145 }
146 m_sampleItems[sampleIndex]->setCued(isCued);
147 }
148 }
149
150 // ===============================================================
151 SampleBrowser::Sample::Sample(const String& otherName, const String& otherPath, int otherIndex,
152 const Value& otherMuted, const Value& otherSolo)
153 : name(otherName), path(otherPath), index(otherIndex)
154 {
155 muted.referTo(otherMuted);
156 solo.referTo(otherSolo);
157 }
158
159 SampleBrowser::Sample::Sample(const Sample& other) : name(other.name), path(other.path), index(other.index)
160 {
161 muted.referTo(other.muted);
162 solo.referTo(other.solo);
163 }
164
166 {
167 name = other.name;
168 path = other.path;
169 index = other.index;
170 muted.referTo(other.muted);
171 solo.referTo(other.solo);
172 return *this;
173 }
174
175 void SampleBrowser::ButtonLAF::drawButtonText(Graphics& g, TextButton& button, bool shouldDrawButtonAsHighlighted,
176 bool shouldDrawButtonAsDown)
177 {
178 Font font(button.getHeight());
179 g.setFont(font);
180
181 auto isHighlighted = button.getProperties()[SampleItem::CuedId];
182 auto defaultOpacity = button.getComponentID().contains("Icon") ? 0.1f : isHighlighted ? 1.0f : 0.5f;
183 auto opacity = button.isEnabled()
184 ? (button.isMouseButtonDown() ? 1.0f : (button.isMouseOver() ? 0.7f : defaultOpacity))
185 : 0.1f;
186
187 g.setColour(
188 button.findColour(button.getToggleState() ? TextButton::textColourOnId : TextButton::textColourOffId)
189 .withMultipliedAlpha(opacity));
190
191 auto justification =
192 button.getComponentID() == "SampleSelectButton" ? Justification::centredLeft : Justification::centred;
193
194 g.drawFittedText(utils::ellipsizeStringToWidth(font, button.getButtonText(), button.getWidth()), 0, 0,
195 button.getWidth(), button.getHeight(), justification, 1, 1.0f);
196 }
197
199 {
200 for (SampleItem* sample : m_sampleItems)
201 {
202 sample->muteButton.setVisible(isVisible);
203 sample->soloButton.setVisible(isVisible);
204 sample->deleteButton.setVisible(isVisible);
205 }
206 }
207
208} // namespace krotos
void drawButtonText(Graphics &, TextButton &, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
Definition SampleBrowser.cpp:175
void resized() override
Definition SampleBrowser.cpp:121
OwnedArray< SampleItem > m_sampleItems
Definition SampleBrowser.h:110
Viewport m_scrollableArea
Definition SampleBrowser.h:108
std::function< void(int sampleIndex)> onSampleDeleted
Definition SampleBrowser.h:93
std::function< void(int sampleIndex)> onSampleSelected
Assign this callback to do something when a sample has been selected in the browser....
Definition SampleBrowser.h:91
Component m_itemsParent
Definition SampleBrowser.h:109
OwnedArray< Sample > m_samples
Definition SampleBrowser.h:111
int m_itemHeight
Definition SampleBrowser.h:113
~SampleBrowser()
Definition SampleBrowser.cpp:95
SampleBrowser(int width, int height, int itemHeight, OwnedArray< Sample > samplesToShow)
Creates a sample browser showing a list of given samples. It uses a viewport to allow scrolling throu...
Definition SampleBrowser.cpp:5
int m_idealHeight
Definition SampleBrowser.h:106
void getIdealSize(int &width, int &height) override
Returns the ideal size of the browser that has been set.
Definition SampleBrowser.cpp:115
std::function< void(int sampleIndex, bool muteState)> onSampleMuted
Assign this callback to do something when a sample has been muted in the browser.
Definition SampleBrowser.h:78
int m_idealWidth
Definition SampleBrowser.h:105
ButtonLAF m_textButtonLAF
Definition SampleBrowser.h:124
void setCuedSample(int sampleIndex, bool isCued)
Set the sample at the given index to display as cued.
Definition SampleBrowser.cpp:136
bool allMuteButtonsOn()
Definition SampleBrowser.cpp:103
void setSampleFunctionButtonsVisibility(bool isVisible)
Change the visibility of the functions buttons on the individual sample list items i....
Definition SampleBrowser.cpp:198
std::function< void(int sampleIndex, bool soloState)> onSampleSolo
Assign this callback to do something when a sample has been soloed in the browser.
Definition SampleBrowser.h:84
An individual sample item component shown in the SampleBrowser. A parent component for the various bu...
Definition SampleItem.h:8
static const Identifier CuedId
Identifier used for the boolean LAF property to draw this item as cued or not.
Definition SampleItem.h:45
String ellipsizeStringToWidth(const Font &font, const String &input, const int maxWidth)
Cuts the center out of a String to make it fit a given pixel width.
Definition helpers.cpp:93
Definition AirAbsorptionFilter.cpp:2
static const String VerticalViewportScrollbar
Definition SampleBrowser.h:57
Wrapper object for sample data used by the browser. The Value objects are shared reference objects wh...
Definition SampleBrowser.h:18
int index
Definition SampleBrowser.h:21
Value muted
Definition SampleBrowser.h:22
Sample & operator=(const Sample &other)
Definition SampleBrowser.cpp:165
String path
Definition SampleBrowser.h:20
String name
Definition SampleBrowser.h:19
Value solo
Definition SampleBrowser.h:23
Sample(const String &otherName, const String &otherPath, int otherIndex, const Value &otherMuted, const Value &otherSolo)
Create a sample data object to be used in the browser. Values are reference shared allowing attachmen...
Definition SampleBrowser.cpp:151