LMMS
Loading...
Searching...
No Matches
juce_MultiChoicePropertyComponent.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26
27namespace juce
28{
29
30//==============================================================================
32{
33public:
34 static int compareElements (var first, var second)
35 {
36 if (first.toString() > second.toString())
37 return 1;
38 else if (first.toString() < second.toString())
39 return -1;
40
41 return 0;
42 }
43};
44
45static void updateButtonTickColour (ToggleButton* button, bool usingDefault)
46{
47 button->setColour (ToggleButton::tickColourId, button->getLookAndFeel().findColour (ToggleButton::tickColourId)
48 .withAlpha (usingDefault ? 0.4f : 1.0f));
49}
50
51//==============================================================================
53 private Value::Listener
54{
55public:
56 MultiChoiceRemapperSource (const Value& source, var v, int c)
57 : sourceValue (source),
60 {
61 sourceValue.addListener (this);
62 }
63
64 var getValue() const override
65 {
66 if (auto* arr = sourceValue.getValue().getArray())
67 if (arr->contains (varToControl))
68 return true;
69
70 return false;
71 }
72
73 void setValue (const var& newValue) override
74 {
75 if (auto* arr = sourceValue.getValue().getArray())
76 {
77 auto temp = *arr;
78
79 if (static_cast<bool> (newValue))
80 {
81 if (temp.addIfNotAlreadyThere (varToControl) && (maxChoices != -1) && (temp.size() > maxChoices))
82 temp.remove (temp.size() - 2);
83 }
84 else
85 {
86 temp.remove (arr->indexOf (varToControl));
87 }
88
90 temp.sort (c);
91
92 sourceValue = temp;
93 }
94 }
95
96private:
99
101
102 //==============================================================================
103 void valueChanged (Value&) override { sendChangeMessage (true); }
104
105 //==============================================================================
107};
108
109//==============================================================================
111 private Value::Listener
112{
113public:
115 var v, int c, ToggleButton* b)
116 : value (val),
117 varToControl (v),
118 sourceValue (value.getPropertyAsValue()),
119 maxChoices (c),
121 {
122 sourceValue.addListener (this);
123 }
124
125 var getValue() const override
126 {
127 auto v = value.get();
128
129 if (auto* arr = v.getArray())
130 {
131 if (arr->contains (varToControl))
132 {
133 updateButtonTickColour (buttonToControl, value.isUsingDefault());
134 return true;
135 }
136 }
137
138 return false;
139 }
140
141 void setValue (const var& newValue) override
142 {
143 auto v = value.get();
144
145 OptionalScopedPointer<Array<var>> arrayToControl;
146
147 if (value.isUsingDefault())
148 arrayToControl.set (new Array<var>(), true); // use an empty array so the default values are overwritten
149 else
150 arrayToControl.set (v.getArray(), false);
151
152 if (arrayToControl != nullptr)
153 {
154 auto temp = *arrayToControl;
155
156 bool newState = newValue;
157
158 if (value.isUsingDefault())
159 {
160 if (auto* defaultArray = v.getArray())
161 {
162 if (defaultArray->contains (varToControl))
163 newState = true; // force the state as the user is setting it explicitly
164 }
165 }
166
167 if (newState)
168 {
169 if (temp.addIfNotAlreadyThere (varToControl) && (maxChoices != -1) && (temp.size() > maxChoices))
170 temp.remove (temp.size() - 2);
171 }
172 else
173 {
174 temp.remove (temp.indexOf (varToControl));
175 }
176
178 temp.sort (c);
179
180 value = temp;
181
182 if (temp.size() == 0)
183 value.resetToDefault();
184 }
185 }
186
187private:
188 //==============================================================================
189 void valueChanged (Value&) override { sendChangeMessage (true); }
190
191 //==============================================================================
195
197
199
200 //==============================================================================
202};
203
204//==============================================================================
206{
207 return numButtons * buttonHeight + 1;
208}
209
211 const StringArray& choices,
212 const Array<var>& correspondingValues)
213 : PropertyComponent (propertyName, jmin (getTotalButtonsHeight (choices.size()), collapsedHeight))
214{
215 // The array of corresponding values must contain one value for each of the items in
216 // the choices array!
217 jassertquiet (choices.size() == correspondingValues.size());
218
219 for (auto choice : choices)
220 addAndMakeVisible (choiceButtons.add (new ToggleButton (choice)));
221
223 {
224 expandable = true;
226 }
227
228 if (isExpandable())
229 {
230 {
231 Path expandShape;
232 expandShape.addTriangle ({ 0, 0 }, { 5, 10 }, { 10, 0});
233 expandButton.setShape (expandShape, true, true, false);
234 }
235
236 expandButton.onClick = [this] { setExpanded (! expanded); };
238
240 }
241}
242
244 const String& propertyName,
245 const StringArray& choices,
246 const Array<var>& correspondingValues,
247 int maxChoices)
248 : MultiChoicePropertyComponent (propertyName, choices, correspondingValues)
249{
250 // The value to control must be an array!
251 jassert (valueToControl.getValue().isArray());
252
253 for (int i = 0; i < choiceButtons.size(); ++i)
254 choiceButtons[i]->getToggleStateValue().referTo (Value (new MultiChoiceRemapperSource (valueToControl,
255 correspondingValues[i],
256 maxChoices)));
257}
258
260 const String& propertyName,
261 const StringArray& choices,
262 const Array<var>& correspondingValues,
263 int maxChoices)
264 : MultiChoicePropertyComponent (propertyName, choices, correspondingValues)
265{
266 value = valueToControl;
267
268 // The value to control must be an array!
269 jassert (value.get().isArray());
270
271 for (int i = 0; i < choiceButtons.size(); ++i)
272 choiceButtons[i]->getToggleStateValue().referTo (Value (new MultiChoiceRemapperSourceWithDefault (value,
273 correspondingValues[i],
274 maxChoices,
275 choiceButtons[i])));
276
277 value.onDefaultChange = [this] { repaint(); };
278}
279
281{
283 g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (*this));
284
285 if (isExpandable() && ! isExpanded())
286 {
287 g.setColour (findColour (TextEditor::backgroundColourId).contrasting().withAlpha (0.4f));
288 g.drawFittedText ("+ " + String (numHidden) + " more", getLookAndFeel().getPropertyComponentContentPosition (*this)
289 .removeFromBottom (expandAreaHeight).withTrimmedLeft (10),
291 }
292
294}
295
297{
298 auto bounds = getLookAndFeel().getPropertyComponentContentPosition (*this);
299
300 if (isExpandable())
301 {
302 bounds.removeFromBottom (5);
303
304 auto buttonSlice = bounds.removeFromBottom (10);
305 expandButton.setSize (10, 10);
306 expandButton.setCentrePosition (buttonSlice.getCentre());
307 }
308
309 numHidden = 0;
310
311 for (auto* b : choiceButtons)
312 {
313 if (bounds.getHeight() >= buttonHeight)
314 {
315 b->setVisible (true);
316 b->setBounds (bounds.removeFromTop (buttonHeight).reduced (5, 2));
317 }
318 else
319 {
320 b->setVisible (false);
321 ++numHidden;
322 }
323 }
324}
325
326void MultiChoicePropertyComponent::setExpanded (bool shouldBeExpanded) noexcept
327{
328 if (! isExpandable() || (isExpanded() == shouldBeExpanded))
329 return;
330
331 expanded = shouldBeExpanded;
333
334 if (auto* propertyPanel = findParentComponentOfClass<PropertyPanel>())
335 propertyPanel->resized();
336
337 if (onHeightChange != nullptr)
339
341 (float) expandButton.getBounds().getCentreX(),
342 (float) expandButton.getBounds().getCentreY()));
343
344 resized();
345}
346
347//==============================================================================
349{
350 auto iconColour = findColour (TextEditor::backgroundColourId).contrasting();
351 expandButton.setColours (iconColour, iconColour.darker(), iconColour.darker());
352
353 const auto usingDefault = value.isUsingDefault();
354
355 for (auto* button : choiceButtons)
356 updateButtonTickColour (button, usingDefault);
357}
358
359} // namespace juce
static AffineTransform rotation(float angleInRadians) noexcept
Definition juce_AffineTransform.cpp:106
Definition juce_Array.h:56
int size() const noexcept
Definition juce_Array.h:215
void addAndMakeVisible(Component *child, int zOrder=-1)
Definition juce_Component.cpp:1554
void repaint()
Definition juce_Component.cpp:1917
TargetClass * findParentComponentOfClass() const
Definition juce_Component.h:813
Colour findColour(int colourID, bool inheritFromParent=false) const
Definition juce_Component.cpp:2219
LookAndFeel & getLookAndFeel() const noexcept
Definition juce_Component.cpp:2173
Definition juce_GraphicsContext.h:45
@ centredLeft
Definition juce_Justification.h:143
Definition juce_MultiChoicePropertyComponent.cpp:54
var varToControl
Definition juce_MultiChoicePropertyComponent.cpp:98
void valueChanged(Value &) override
Definition juce_MultiChoicePropertyComponent.cpp:103
int maxChoices
Definition juce_MultiChoicePropertyComponent.cpp:100
Value sourceValue
Definition juce_MultiChoicePropertyComponent.cpp:97
void setValue(const var &newValue) override
Definition juce_MultiChoicePropertyComponent.cpp:73
MultiChoiceRemapperSource(const Value &source, var v, int c)
Definition juce_MultiChoicePropertyComponent.cpp:56
var getValue() const override
Definition juce_MultiChoicePropertyComponent.cpp:64
Definition juce_MultiChoicePropertyComponent.cpp:112
ValueTreePropertyWithDefault value
Definition juce_MultiChoicePropertyComponent.cpp:192
void valueChanged(Value &) override
Definition juce_MultiChoicePropertyComponent.cpp:189
void setValue(const var &newValue) override
Definition juce_MultiChoicePropertyComponent.cpp:141
Value sourceValue
Definition juce_MultiChoicePropertyComponent.cpp:194
ToggleButton * buttonToControl
Definition juce_MultiChoicePropertyComponent.cpp:198
int maxChoices
Definition juce_MultiChoicePropertyComponent.cpp:196
var varToControl
Definition juce_MultiChoicePropertyComponent.cpp:193
MultiChoiceRemapperSourceWithDefault(const ValueTreePropertyWithDefault &val, var v, int c, ToggleButton *b)
Definition juce_MultiChoicePropertyComponent.cpp:114
var getValue() const override
Definition juce_MultiChoicePropertyComponent.cpp:125
static constexpr int buttonHeight
Definition juce_MultiChoicePropertyComponent.h:127
int numHidden
Definition juce_MultiChoicePropertyComponent.h:130
void resized() override
Definition juce_MultiChoicePropertyComponent.cpp:296
int maxHeight
Definition juce_MultiChoicePropertyComponent.h:130
bool expanded
Definition juce_MultiChoicePropertyComponent.h:131
bool expandable
Definition juce_MultiChoicePropertyComponent.h:131
void paint(Graphics &g) override
Definition juce_MultiChoicePropertyComponent.cpp:280
ValueTreePropertyWithDefault value
Definition juce_MultiChoicePropertyComponent.h:133
static int getTotalButtonsHeight(int)
Definition juce_MultiChoicePropertyComponent.cpp:205
ShapeButton expandButton
Definition juce_MultiChoicePropertyComponent.h:135
bool isExpandable() const noexcept
Definition juce_MultiChoicePropertyComponent.h:89
static constexpr int expandAreaHeight
Definition juce_MultiChoicePropertyComponent.h:128
bool isExpanded() const noexcept
Definition juce_MultiChoicePropertyComponent.h:86
MultiChoicePropertyComponent(const String &, const StringArray &, const Array< var > &)
Definition juce_MultiChoicePropertyComponent.cpp:210
void setExpanded(bool expanded) noexcept
Definition juce_MultiChoicePropertyComponent.cpp:326
void lookAndFeelChanged() override
Definition juce_MultiChoicePropertyComponent.cpp:348
OwnedArray< ToggleButton > choiceButtons
Definition juce_MultiChoicePropertyComponent.h:134
std::function< void()> onHeightChange
Definition juce_MultiChoicePropertyComponent.h:106
static constexpr int collapsedHeight
Definition juce_MultiChoicePropertyComponent.h:126
Definition juce_OptionalScopedPointer.h:38
void set(ObjectType *newObject, bool takeOwnership)
Definition juce_OptionalScopedPointer.h:147
Definition juce_Path.h:65
void addTriangle(float x1, float y1, float x2, float y2, float x3, float y3)
Definition juce_Path.cpp:417
PropertyComponent(const String &propertyName, int preferredHeight=25)
Definition juce_PropertyComponent.cpp:29
int preferredHeight
Definition juce_PropertyComponent.h:139
void paint(Graphics &) override
Definition juce_PropertyComponent.cpp:37
Definition juce_StringArray.h:35
int size() const noexcept
Definition juce_StringArray.h:136
Definition juce_MultiChoicePropertyComponent.cpp:32
static int compareElements(var first, var second)
Definition juce_MultiChoicePropertyComponent.cpp:34
Definition juce_String.h:53
@ backgroundColourId
Definition juce_TextEditor.h:209
Definition juce_ToggleButton.h:41
@ tickColourId
Definition juce_ToggleButton.h:75
Definition juce_Value.h:139
Definition juce_Value.h:180
void sendChangeMessage(bool dispatchSynchronously)
Definition juce_Value.cpp:43
friend class Value
Definition juce_Value.h:203
Definition juce_Value.h:51
var getValue() const
Definition juce_Value.cpp:151
Definition juce_ValueTreePropertyWithDefault.h:39
Definition juce_Variant.h:42
bool isArray() const noexcept
Definition juce_Variant.cpp:561
unsigned v[N_MAX]
Definition inflate.c:1584
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
int val
Definition jpeglib.h:956
#define jassert(expression)
#define jassertquiet(expression)
#define JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className)
Definition carla_juce.cpp:31
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
static void updateButtonTickColour(ToggleButton *button, bool usingDefault)
Definition juce_MultiChoicePropertyComponent.cpp:45
@ button
Definition juce_AccessibilityRole.h:38
static constexpr FloatType twoPi
Definition juce_MathsFunctions.h:385
static constexpr FloatType pi
Definition juce_MathsFunctions.h:382
return c
Definition crypt.c:175
b
Definition crypt.c:628
ulg size
Definition extract.c:2350