Krotos Modules 3
Loading...
Searching...
No Matches
ModulationAssigner.cpp
Go to the documentation of this file.
2
3namespace krotos
4{
5 ModulationAssigner::ModulationAssigner(KwidgetAudioProcessor& processor, const StringArray& kwidgetWhitelist)
6 : m_processor(processor), m_modulationParentTree(processor.parameterManager.getModulationTree()),
7 m_kwidgetTree(processor.parameterManager.getKwidgetsTree()), TabbedComponent(TabbedButtonBar::TabsAtTop)
8 {
9 addToWhitelist(kwidgetWhitelist);
10
12 m_dropArea = std::make_unique<ModulationAssignerDropArea>();
13 m_dropArea->setNumComponentsPerRow(m_rowSize, m_rowSize);
14 m_dropArea->drawSingleRowAsColumn(false);
15
18
19 setTabBarDepth(0);
20 setOutline(0);
21
22 addTab("Assign", findColour(TabbedComponent::backgroundColourId), m_dropArea.get(), true);
23
25 }
26
28
30 {
31 // Update assign tab after a setColour call
32 if (getNumTabs() > 0)
33 {
34 setTabBackgroundColour(0, findColour(TabbedComponent::backgroundColourId));
35 }
36 }
37
38 DropComponent* ModulationAssigner::addDropComponent(const String& labelText, const String& targetModSourceKwidgetID,
39 int targetModulatorIdx)
40 {
41 auto* dropComponent = m_dropArea->addDropComponent(new DropComponent(labelText, targetModSourceKwidgetID));
42 auto* modTable =
43 addTable(labelText + " Modulation", ModSourceIndexPair(targetModSourceKwidgetID, targetModulatorIdx));
44 int tabIndex = getTabNames().indexOf(modTable->getId());
45
46 dropComponent->onDropped = [this, targetModSourceKwidgetID, targetModulatorIdx, modTable](var desc) {
47 assignModulation(desc, targetModSourceKwidgetID, targetModulatorIdx, modTable);
48 };
49
50 // Set up Button onClick to switch to Mod List
51 dropComponent->onClick = [this, tabIndex] { setCurrentTabIndex(tabIndex); };
52
53 return dropComponent;
54 }
55
57 {
58#if !ENABLE_QUICKFX_ASSIGNMENT
59 // Do not add specific MasterFX types
61 {
62 return;
63 }
64#endif
65
66 auto type = kwidget->getKwidgetType();
67
68#if ENABLE_SANDBOX
70 {
71 auto numModulators = kwidget->getNumModulators();
72
73 if (numModulators > 0)
74 {
75 Array<Value> labelValues = Array<Value>();
76 auto customParams = kwidget->getState().getChildWithName(XmlType::Tag::customParams);
77
78 for (auto param : customParams)
79 {
80 if (param.getProperty(XmlType::Property::id).toString().contains("editableLabel"))
81 labelValues.add(param.getPropertyAsValue(XmlType::Property::value, nullptr));
82 }
83
84 addMultiDropComponent(kwidget->getKwidgetLabel(), kwidget->getKwidgetID(), numModulators, labelValues);
85 }
86 }
87#endif
88
89 if (m_whitelist.isEmpty() || m_whitelist.contains(type))
90 {
91 auto numModulators = kwidget->getNumModulators();
92
93#if !ENABLE_VELOCITY_ASSIGNMENT
94 // Do not add Table for final modulator i.e. Velocity
95 if (type.contains(KwidgetFactory::KwidgetType::XyPad))
96 {
97 numModulators -= 1;
98 }
99#endif
100 if (numModulators > 0)
101 {
102 Array<Value> labelValues = Array<Value>();
103 auto customParams = kwidget->getState().getChildWithName(XmlType::Tag::customParams);
104
105 for (auto param : customParams)
106 {
107 if (param.getProperty(XmlType::Property::id).toString().contains("editableLabel"))
108 labelValues.add(param.getPropertyAsValue(XmlType::Property::value, nullptr));
109 }
110
111 addMultiDropComponent(kwidget->getKwidgetLabel(), kwidget->getKwidgetID(), numModulators, labelValues);
112 }
113 }
114 }
115
117
119 const String& targetModSourceKwidgetID,
120 int numModulators, Array<Value> labelValues)
121 {
122 auto* dc = m_dropArea->addMultiDropComponent(
123 new MultiDropComponent(labelText, targetModSourceKwidgetID, numModulators));
124
125 for (int i = 0; i < numModulators; ++i)
126 {
127 auto label = labelText + " " + String(i + 1) + " Modulation";
128
129 auto* modTable = addTable(label, ModSourceIndexPair(targetModSourceKwidgetID, i));
130 int tabIndex = getTabNames().indexOf(modTable->getId());
131 auto* dropComponent = dc->getDropComponent(i);
132 dropComponent->onDropped = [this, targetModSourceKwidgetID, i, modTable](var desc) {
133 assignModulation(desc, targetModSourceKwidgetID, i, modTable);
134 };
135 dropComponent->onClick = [this, tabIndex] { setCurrentTabIndex(tabIndex); };
136
137 // If provided, set up the label Values
138 if (!labelValues.isEmpty())
139 {
140 // Not enough label values for the number of modulators.
141 jassert(i < labelValues.size());
142
143 auto value = labelValues[i];
144
145 if (i < labelValues.size())
146 dropComponent->setLabelValue(value);
147 }
148 }
149
150 return dc;
151 }
152
153 void ModulationAssigner::removeDropComponent(const String& kwidgetID) { m_dropArea->removeComponent(kwidgetID); }
154
156 {
158 {
159 g.setColour(findColour(LassoComponent<TabbedComponent>::lassoOutlineColourId));
160 g.drawRoundedRectangle(getLocalBounds().reduced(m_padding - 1).toFloat(), m_cornerSize, (float)m_padding);
161 }
162 }
163
165 {
166 TabbedComponent::resized();
167 if (m_dropArea != nullptr)
168 {
169 m_dropArea->resized();
170 }
171 }
172
174 {
175 for (auto* t : m_modulationTables)
176 {
177 if (t->getId() == id)
178 return t;
179 }
180
181 return nullptr;
182 }
183
185 {
186 auto id = String(modSourceIdx.first) + String(modSourceIdx.second);
187 auto colour = findColour(ResizableWindow::backgroundColourId);
188 auto* table = m_modulationTables.add(new ModulationAssignerTable(*this, label, id));
189
190 m_tableMap.insert(std::pair<ModSourceIndexPair, ModulationAssignerTable*>(modSourceIdx, table));
191
192 addTab(table->getId(), colour, table, true);
193
194 return table;
195 }
196
198 {
199 auto table = m_tableMap[modSourceIdx];
200 auto tabID = getTabNames().indexOf(table->getId());
201 if (table != nullptr)
202 {
203 m_tableMap.erase(modSourceIdx);
204 m_modulationTables.removeObject(table, true);
205 removeTab(tabID);
206 }
207 else
208 {
209 m_tableMap.erase(modSourceIdx);
210 }
211 }
212
214 {
215 // We need the "Modulations" tree!
216 jassert(tree.hasType(XmlType::Tag::modulations));
217
219 m_modulationParentTree.addListener(this);
220 }
221
223 {
224 // We need the "Kwidgets" tree!
225 jassert(tree.hasType(XmlType::Tag::kwidgets));
226
227 m_kwidgetTree = tree;
228 m_kwidgetTree.addListener(this);
229 }
230
232 {
233 // First, initialise drop components by looking for modulator kwidgets
234 auto& kwidgets = m_processor.getKwidgets();
235 for (auto& k : kwidgets)
236 {
237 kwidgetAdded(k);
238 }
239
240 // Then initialise tables with data from the modulation ValueTree.
241 // Used if the ValueTree already has data in it before the Table has been created.
242 // This is really inefficient and could potentially be really slow if there's
243 // lots of modulation entries in the ValueTree.
244 if (m_modulationParentTree.isValid())
245 {
246 for (int i = 0; i < m_modulationParentTree.getNumChildren(); i++)
247 {
249 }
250 }
251 else
252 jassertfalse;
253 }
254
255 void ModulationAssigner::valueTreePropertyChanged(ValueTree& treeWhosePropertyHasChanged,
256 const Identifier& property)
257 {
258 (void)treeWhosePropertyHasChanged;
259 (void)property;
260 }
261
262 void ModulationAssigner::valueTreeChildAdded(ValueTree& /*parentTree*/, ValueTree& childWhichHasBeenAdded)
263 {
264 if (childWhichHasBeenAdded.hasType(XmlType::Tag::modulation))
265 {
266 addAssignment(childWhichHasBeenAdded);
267 }
268 }
269
270 void ModulationAssigner::valueTreeChildRemoved(ValueTree& /*parentTree*/, ValueTree& childWhichHasBeenRemoved,
271 int /*indexFromWhichChildWasRemoved*/)
272 {
273 if (childWhichHasBeenRemoved.hasType(XmlType::Tag::modulation))
274 {
275 auto source = childWhichHasBeenRemoved.getProperty(XmlType::Property::source);
276 auto index = childWhichHasBeenRemoved.getProperty(XmlType::Property::modulatorIndex);
277
278 auto pair = ModSourceIndexPair(source, index);
279
280 if (m_tableMap[pair])
281 {
282 m_tableMap[pair]->deleteRow(childWhichHasBeenRemoved, false);
283 }
284
285 if (auto* dropComponent = m_dropArea->findDropComponent(source, index))
286 {
287 dropComponent->setArmed(false);
288 }
289 }
290 }
291
292 void ModulationAssigner::addAssignment(ValueTree newAssignment)
293 {
294 auto source = newAssignment.getProperty(XmlType::Property::source);
295 auto index = newAssignment.getProperty(XmlType::Property::modulatorIndex);
296
297 auto pair = ModSourceIndexPair(source, index);
298
299 if (m_tableMap[pair])
300 {
301 m_tableMap[pair]->addRow(newAssignment);
302 }
303
304 if (auto* dropComponent = m_dropArea->findDropComponent(source, index))
305 {
306 dropComponent->setArmed(true);
307 }
308 }
309
311 {
312 m_indicatorActive = isActive;
313 repaint();
314 }
315
316} // namespace krotos
A component for dropping draggable juce objects onto.
Definition DropComponent.h:11
Definition KwidgetAudioProcessor.h:12
const Array< Kwidget * > & getKwidgets()
Definition KwidgetAudioProcessor.cpp:1059
void removeKListener(KListener *l)
Definition KwidgetAudioProcessor.cpp:495
void addKListener(KListener *l)
Definition KwidgetAudioProcessor.cpp:493
Definition Kwidget.h:8
const ValueTree & getState()
Definition Kwidget.cpp:242
const String & getKwidgetType() const
Definition Kwidget.cpp:365
int getNumModulators() const
Definition Kwidget.cpp:357
const String & getKwidgetID() const
Definition Kwidget.cpp:367
virtual const String & getKwidgetLabel()
Definition Kwidget.cpp:378
ValueTree m_kwidgetTree
Definition ModulationAssigner.h:119
StringArray m_whitelist
Definition ModulationAssigner.h:122
void attachKwidgetsTreeListener(const ValueTree &tree)
Definition ModulationAssigner.cpp:222
void removeTable(ModSourceIndexPair modSourceIdx)
Definition ModulationAssigner.cpp:197
void valueTreeChildRemoved(ValueTree &parentTree, ValueTree &childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved) override
Definition ModulationAssigner.cpp:270
std::pair< String, int > ModSourceIndexPair
Definition ModulationAssigner.h:151
void colourChanged() override
Definition ModulationAssigner.cpp:29
~ModulationAssigner()
Definition ModulationAssigner.cpp:27
KwidgetAudioProcessor & m_processor
Definition ModulationAssigner.h:180
ValueTree m_modulationParentTree
Definition ModulationAssigner.h:119
std::unique_ptr< ModulationAssignerDropArea > m_dropArea
Definition ModulationAssigner.h:144
const int m_padding
Definition ModulationAssigner.h:174
void removeDropComponent(const String &kwidgetID)
Definition ModulationAssigner.cpp:153
void addAssignment(ValueTree assignment)
Definition ModulationAssigner.cpp:292
ModulationAssigner(KwidgetAudioProcessor &processor, const StringArray &kwidgetWhitelist=StringArray())
Definition ModulationAssigner.cpp:5
DropComponent * addDropComponent(const String &labelText, const String &targetModSourceKwidgetID, int targetModulatorIdx=-1)
Definition ModulationAssigner.cpp:38
ModulationAssignerTable * getTable(String id)
Definition ModulationAssigner.cpp:173
void setIndicatorActive(bool isActive)
Sets whether to draw a border around the component to highlight it as a target destination for a drag...
Definition ModulationAssigner.cpp:310
ModulationAssignerTable * addTable(String label, ModSourceIndexPair modSourceIdx)
Definition ModulationAssigner.cpp:184
OwnedArray< ModulationAssignerTable > m_modulationTables
Definition ModulationAssigner.h:147
bool m_indicatorActive
Definition ModulationAssigner.h:178
void kwidgetAdded(Kwidget *k) override
Definition ModulationAssigner.cpp:56
void kwidgetRemoved(Kwidget *k) override
Definition ModulationAssigner.cpp:116
void resized() override
Definition ModulationAssigner.cpp:164
void valueTreePropertyChanged(ValueTree &treeWhosePropertyHasChanged, const Identifier &property) override
Definition ModulationAssigner.cpp:255
std::map< ModSourceIndexPair, ModulationAssignerTable * > m_tableMap
Definition ModulationAssigner.h:159
const float m_cornerSize
Definition ModulationAssigner.h:175
void initialiseData()
Definition ModulationAssigner.cpp:231
void paintOverChildren(Graphics &g) override
Definition ModulationAssigner.cpp:155
const int m_rowSize
Definition ModulationAssigner.h:174
void attachModTreeListener(const ValueTree &tree)
Definition ModulationAssigner.cpp:213
MultiDropComponent * addMultiDropComponent(const String &labelText, const String &targetModSourceKwidgetID, int numModulators, Array< Value > labelValues=Array< Value >())
Add a multi drop component. This will create a parent with drop components for the given number of mo...
Definition ModulationAssigner.cpp:118
void addToWhitelist(StringRef KType)
Add a kwidget type to the whitelist.
Definition ModulationAssigner.h:105
void valueTreeChildAdded(ValueTree &parentTree, ValueTree &childWhichHasBeenAdded) override
Definition ModulationAssigner.cpp:262
std::function< void(var desc, String targetModSourceKwidgetID, int targetModulatorIdx, ModulationAssignerTable *table)> assignModulation
Definition ModulationAssigner.h:41
Definition ModulationAssignerTable.h:9
A simple container for a holding multiple drop components used for assigning modulation to a kwidget ...
Definition MultiDropComponent.h:16
Definition AirAbsorptionFilter.cpp:2
static const String MasterFX
Definition KwidgetFactory.h:40
static const String SandBox
Definition KwidgetFactory.h:39
static const String XyPad
Definition KwidgetFactory.h:21
static const Identifier modulatorIndex
Definition XmlType.h:48
static const Identifier id
Definition XmlType.h:41
static const Identifier value
Definition XmlType.h:42
static const Identifier source
Definition XmlType.h:45
static const Identifier kwidgets
Definition XmlType.h:22
static const Identifier modulation
Definition XmlType.h:27
static const Identifier customParams
Definition XmlType.h:20
static const Identifier modulations
Definition XmlType.h:26