Krotos Modules 3
Loading...
Searching...
No Matches
Kwidget.cpp
Go to the documentation of this file.
1namespace krotos
2{
3 const String Kwidget::Constants::ChildDelimiter = ":";
4 const String Kwidget::Constants::Parent = "parent";
5 const String Kwidget::Constants::Bounds = "bounds";
6 const String Kwidget::Constants::Renderstyle = "renderstyle";
7
8 Kwidget::Kwidget(const String& kwidgetType, const String& kwidgetID)
9 : m_kwidgetType(kwidgetType), m_kwidgetID(kwidgetID), m_kwidgetTree(XmlType::Tag::kwidget),
10 m_paramTree(XmlType::Tag::params), m_customParamTree(XmlType::Tag::customParams),
11 m_childTree(XmlType::Tag::kwidgets)
12 {
13 m_kwidgetTree.setProperty(XmlType::Property::type, kwidgetType, nullptr);
14 m_kwidgetTree.setProperty(XmlType::Property::id, kwidgetID, nullptr);
15 m_kwidgetTree.setProperty(XmlType::Property::version, "1.0", nullptr);
16 m_kwidgetTree.appendChild(m_paramTree, nullptr);
17 m_kwidgetTree.appendChild(m_customParamTree, nullptr);
18 m_kwidgetTree.appendChild(m_childTree, nullptr);
19
23
24 setAccessible(true);
25 }
26
28 {
29 auto paramInfo = createParameters();
30 for (auto& p : paramInfo)
32
36 }
37
39 {
40 jassert(isPositiveAndBelow(idx, getNumVoices()));
41 return m_processors.getUnchecked(idx);
42 }
43
44 std::unique_ptr<KwidgetProcessor> Kwidget::createVoice()
45 {
46 if (m_initialVoice != nullptr)
47 {
48 return std::move(m_initialVoice);
49 }
50 else
51 {
52 auto p = createProcessor();
53 m_processors.add(p.get());
54 return p;
55 }
56 }
57
58 std::unique_ptr<KwidgetGUI> Kwidget::createControls()
59 {
60 std::unique_ptr<KwidgetGUI> gui = createGUI();
61 addChildGuis(gui);
62 return gui;
63 }
64
65 int Kwidget::getNumVoices() const { return m_processors.size(); }
66
67 void Kwidget::noteOn(int voiceIdx, int midiNoteNumber, float velocity)
68 {
69 auto v = getVoice(voiceIdx);
70
71 v->updateAttachments();
72 v->noteOn(midiNoteNumber, velocity, voiceIdx);
73 m_activeVoice = v;
74 }
75
76 void Kwidget::noteOff(int voiceIdx, float velocity) { getVoice(voiceIdx)->noteOff(velocity); }
77
78 void Kwidget::noteCleared(int voiceIdx) { getVoice(voiceIdx)->noteCleared(); }
79
80 bool Kwidget::isActive(int voiceIdx) { return getVoice(voiceIdx)->isActive(); }
81
82 void Kwidget::addModulator(const String& paramID, Kwidget* modulator, int modulatorIdx, float depth,
83 KAttachment::Polarity polarity)
84 {
85 if (modulator->getNumVoices() == getNumVoices())
86 {
87 for (int i = 0; i < getNumVoices(); i++)
88 {
89 auto modulatorPtr = modulator->getVoice(i)->getModulator(modulatorIdx);
90 getVoice(i)->getAttachment(paramID)->addModulator(modulatorPtr, depth, polarity);
91 }
92 }
93 else if (modulator->getNumVoices() == 1)
94 {
95 auto modulatorPtr = modulator->getVoice(0)->getModulator(modulatorIdx);
96
97 for (auto p : m_processors)
98 p->getAttachment(paramID)->addModulator(modulatorPtr, depth, polarity);
99 }
100 else
101 {
102 // Modulator Kwidget must have the same number of voices as this Kwidget, or be monophonic.
103 jassertfalse;
104 return;
105 }
106 }
107
108 void Kwidget::removeModulator(const String& paramID, Kwidget* modulator, int modulatorIdx)
109 {
110 if (modulator->getNumVoices() == getNumVoices())
111 {
112 for (int i = 0; i < getNumVoices(); i++)
113 {
114 auto modulatorPtr = modulator->getVoice(i)->getModulator(modulatorIdx);
115 getVoice(i)->getAttachment(paramID)->removeModulator(modulatorPtr);
116 }
117 }
118 else
119 {
120 auto modulatorPtr = modulator->getVoice(0)->getModulator(modulatorIdx);
121
122 for (auto p : m_processors)
123 p->getAttachment(paramID)->removeModulator(modulatorPtr);
124 }
125 }
126
127 void Kwidget::setModulatorDepth(const String& paramID, Kwidget* modulator, int modulatorIdx, float depth)
128 {
129 if (modulator->getNumVoices() == getNumVoices())
130 {
131 for (int i = 0; i < getNumVoices(); i++)
132 {
133 auto modulatorPtr = modulator->getVoice(i)->getModulator(modulatorIdx);
134 getVoice(i)->getAttachment(paramID)->setModulatorDepth(modulatorPtr, depth);
135 }
136 }
137 else
138 {
139 auto modulatorPtr = modulator->getVoice(0)->getModulator(modulatorIdx);
140
141 for (auto p : m_processors)
142 p->getAttachment(paramID)->setModulatorDepth(modulatorPtr, depth);
143 }
144 }
145
146 void Kwidget::setModulatorPolarity(const String& paramID, Kwidget* modulator, int modulatorIdx,
147 KAttachment::Polarity polarity)
148 {
149 if (modulator->getNumVoices() == getNumVoices())
150 {
151 for (int i = 0; i < getNumVoices(); i++)
152 {
153 auto modulatorPtr = modulator->getVoice(i)->getModulator(modulatorIdx);
154 getVoice(i)->getAttachment(paramID)->setModulatorPolarity(modulatorPtr, polarity);
155 }
156 }
157 else
158 {
159 auto modulatorPtr = modulator->getVoice(0)->getModulator(modulatorIdx);
160
161 for (auto p : m_processors)
162 p->getAttachment(paramID)->setModulatorPolarity(modulatorPtr, polarity);
163 }
164 }
165
166 const std::vector<std::shared_ptr<KParameter>>& Kwidget::getParameters() const { return m_parameters; }
167
168 KParameter* Kwidget::getParameter(const String& parameterID) const noexcept
169 {
170 if (m_parameterIDs.find(parameterID) == m_parameterIDs.end())
171 {
172 jassertfalse; // parameter not found
173 return nullptr;
174 }
175 return m_parameters[m_parameterIDs.at(parameterID)].get();
176 }
177
178 std::shared_ptr<KParameter> Kwidget::getParameterToAttach(const String& parameterID) const noexcept
179 {
180 if (m_parameterIDs.find(parameterID) == m_parameterIDs.end())
181 {
182 jassertfalse; // parameter not found
183 return nullptr;
184 }
185 return m_parameters[m_parameterIDs.at(parameterID)];
186 }
187
189 {
190 if (m_customParameterIDs.count(parameterID) == 1)
191 {
192 return m_customParameters[m_customParameterIDs.at(parameterID)];
193 }
194 else
195 {
196 // Parameter ID not found.
197 jassertfalse;
198 return nullptr;
199 }
200 }
201
203 {
205 {
207 }
208 else
209 {
210 // Parameter Tree not found
211 jassertfalse;
212 return nullptr;
213 }
214 }
215
216 template <typename T> T* Kwidget::getCustomParameter(const Identifier& type)
217 {
218 static_assert(std::is_base_of<CustomParameterTree, T>::value, "T must be a subclass of CustomParameterTree");
219
221 {
222 auto index = m_customParameterTreeTypes.at(type);
223 return static_cast<T*>(m_customParameterTrees.getUnchecked(index));
224 }
225 else
226 {
227 // Parameter Tree not found
228 jassertfalse;
229 return nullptr;
230 }
231 }
232
234 {
235 auto& kParams = getParameters();
236 for (auto& kParam : kParams) // For very parameter in the kwidget ...
237 {
238 kParam->notifyListeners(); // ... send out a value changed message
239 }
240 }
241
242 const ValueTree& Kwidget::getState()
243 {
244 flushState();
245 return m_kwidgetTree;
246 }
247
249
250 String Kwidget::getParentID(String childKwidgetID)
251 {
252 if (childKwidgetID.contains(Kwidget::Constants::ChildDelimiter))
253 {
254 return childKwidgetID.upToLastOccurrenceOf(Kwidget::Constants::ChildDelimiter,
255 /*includeSubstring*/ false,
256 /*ignoreCase*/ true);
257 }
258 return ""; // is not a child kwidget
259 };
260
267
268 void Kwidget::setState(const ValueTree& newState, KwidgetAudioProcessor& processor)
269 {
270 m_stateChanging = true;
271 const auto& id = XmlType::Property::id;
272 const auto& value = XmlType::Property::value;
273
274 auto kwidgetTree = newState.createCopy();
275 auto paramTree = kwidgetTree.getChildWithName(XmlType::Tag::params);
276 auto customParamTree = kwidgetTree.getChildWithName(XmlType::Tag::customParams);
277 auto childParamTree = kwidgetTree.getChildWithName(XmlType::Tag::kwidgets);
278
280 kwidgetTree[XmlType::Property::version] ? kwidgetTree[XmlType::Property::version] : "1.0";
281
282 for (const auto& param : paramTree)
283 {
284 auto paramID = param[id].toString();
285 auto tree = m_paramTree.getChildWithProperty(id, paramID);
286 if (tree.isValid())
287 {
288 tree.copyPropertiesAndChildrenFrom(param, nullptr);
289 getParameter(paramID)->set(tree[value]);
290 }
291 }
292
293 for (const auto& param : customParamTree)
294 {
295 auto tree = m_customParamTree.getChildWithProperty(id, param[id]);
296 if (tree.isValid())
297 tree.copyPropertiesAndChildrenFrom(param, nullptr);
298 }
299
300 for (auto childTree : childParamTree)
301 {
302 // TODO: investigate what this is here for
303 // m_childKwidgets.push_back(processor.addKwidget("", "", "", true, &childTree));
304 m_childKwidgets.push_back(processor.addKwidgetFromState(childTree));
305
306 m_childTree.addChild(m_childKwidgets.back()->getState(), -1, nullptr);
307 }
308
309 m_stateChanging = false;
310 }
311
313 {
314 for (auto param : m_paramTree)
315 {
316 auto paramID = param[XmlType::Property::id].toString();
317 param.setProperty(XmlType::Property::value, getParameter(paramID)->get(), nullptr);
318 }
319 for (auto child : m_childKwidgets)
320 {
321 child->flushState();
322 }
323 }
324
326 {
327 for (int i = 0; i < m_childKwidgets.size(); i++)
328 {
329 if (m_childKwidgets.at(i)->getKwidgetID() == child->getKwidgetID())
330 {
331 // if the child is already there, remove it
332 m_childTree.removeChild(m_childKwidgets.at(i)->getState(), nullptr);
333 m_childKwidgets.erase(m_childKwidgets.begin() + i);
334
335 // need to break out from here as the structure of the array has just changed.
336 break;
337 }
338 }
339
340 m_childKwidgets.push_back(child);
341 m_childTree.appendChild(child->getState(), nullptr);
342 }
343
345 {
346 Kwidget* child = findChildKwidget(kwidgetID);
347
348 if (child != nullptr)
349 {
350 // found the kwidget so we can remove the kwidget from the value tree
351 m_childTree.removeChild(child->getState(), nullptr);
352 }
353 }
354
355 bool Kwidget::isModulator() const { return getNumModulators() > 0; }
356
358 {
359 // You must call init() in your child class before calling this function.
360 jassert(!m_processors.isEmpty());
361
362 return m_processors.getUnchecked(0)->getNumModulators();
363 }
364
365 const String& Kwidget::getKwidgetType() const { return m_kwidgetType; }
366
367 const String& Kwidget::getKwidgetID() const { return m_kwidgetID; }
368
370
371 void Kwidget::setKwidgetVersion(const String& kwidgetVersionString)
372 {
373 m_kwidgetTree.setProperty(XmlType::Property::version, kwidgetVersionString, /*undoMan*/ nullptr);
374 }
375
377
379 {
380 return getKwidgetType();
381 /* Deterministic label generation from ID
382 String id = m_kwidgetID;
383 int separator = id.indexOf(":");
384 id = id.substring(separator + 1);
385 int index = id.indexOfAnyOf("0123456789");
386 int number = std::stoi(id.substring(index).toStdString());
387 number+=1;
388 id = id.replaceSection(index, id.substring(index).length(), String(number));
389 id = id.replaceCharacters("_", " ");
390 return id;
391 */
392 }
393
394 StringArray Kwidget::getDragID(const String& parameterID)
395 {
396 StringArray identifier;
397 identifier.insert(DragID_Index::KwidgetID, m_kwidgetID);
398 identifier.insert(DragID_Index::ParameterID, parameterID);
399 return identifier;
400 }
401
403 {
404 m_parameters.push_back(
405 std::make_shared<KParameter>(info.id, m_kwidgetID + " " + info.name, info.range, info.defaultValue));
406 auto param = m_parameters.back();
407 m_parameterIDs[info.id] = m_parameters.size() - 1;
408
409 ValueTree paramTree{XmlType::Tag::param,
410 {{XmlType::Property::id, param->paramID},
411 {XmlType::Property::value, param->get()},
413
414 m_paramTree.appendChild(paramTree, nullptr);
415
416 return param.get();
417 }
418
419 CustomParameter* Kwidget::createAndAddCustomParameter(const String& paramID, const var& value)
420 {
421 ValueTree customParamTree{XmlType::Tag::customParam,
422 {{XmlType::Property::id, paramID}, {XmlType::Property::value, value}}};
423
424 m_customParamTree.appendChild(customParamTree, nullptr);
426
427 auto idx = m_customParameters.size() - 1;
428 m_customParameterIDs[paramID] = idx;
429
430 return m_customParameters.getUnchecked(idx);
431 }
432
433 template <typename T> T* Kwidget::createAndAddCustomParameter(const Identifier& type)
434 {
435 static_assert(std::is_base_of<CustomParameterTree, T>::value, "T must be a subclass of CustomParameterTree");
436
438 {
439 // Tree type already used! CustomParameterTrees should have unique types.
440 // If you need multiple of the same child, create a CustomParameterTree
441 // and add them as children.
442 jassertfalse;
443 return nullptr;
444 }
445
446 std::unique_ptr<T> treeToCreate = std::make_unique<T>();
447 jassert(type == treeToCreate->getType()); // The type given must be the same as the tree type!
448
449 m_customParamTree.appendChild(treeToCreate->getParameterTree(), nullptr);
450 m_customParameterTrees.add(std::move(treeToCreate));
451
452 auto index = m_customParameterTrees.size() - 1;
453 m_customParameterTreeTypes[type] = index;
454
455 return static_cast<T*>(m_customParameterTrees.getUnchecked(index));
456 }
457
458 void Kwidget::addParameterCallback(const String& paramID, std::function<void(float)> callback)
459 {
461 new KParameter::AudioListenerObject(getParameterToAttach(paramID), std::move(callback)));
462 }
463
464 void Kwidget::addVersionedParameterCallback(StringRef parameterVersion, const String& paramID,
465 std::function<void(float)> callback)
466 {
467 auto versionCheckCallback = [this, callback, parameterVersion](float newValue) {
469 utils::getVersionAsHexInteger(parameterVersion))
470 {
471 callback(newValue);
472 }
473 };
474
475 addParameterCallback(paramID, versionCheckCallback);
476 }
477
479 {
480 // search through the child kwidgets looking for the matching ID.
481 for (auto k : m_childKwidgets)
482 {
483 if (k != nullptr)
484 {
485 if (k->getKwidgetID() == kwidgetID)
486 {
487 return k;
488 }
489 }
490 }
491
492 // if we have any more that a 2 level hierarchy then we will need to split the kwidget ID into child and parent
493 // IDs so that we can search these children.
494
495 return nullptr;
496 }
497
498 void Kwidget::addChildGuis(std::unique_ptr<KwidgetGUI>& parentGui)
499 {
500 if (m_childKwidgets.size() > 0)
501 {
502 for (auto k : m_childKwidgets)
503 {
504 auto gui = k->createControls();
505
506 gui->setComponentID(k->getKwidgetID());
507 parentGui->addAndMakeVisible(gui.get());
508 }
509 }
510 }
511} // namespace krotos
A wrapper around juce::ValueTree designed to store custom plugin state (strings, arrays,...
Definition CustomParameter.h:9
const var & getValue() const
Definition CustomParameter.cpp:39
Definition CustomParameterTree.h:15
Polarity
Definition KAttachment.h:120
Internal Kwidget parameter that can receive changes from a GenericParameter.
Definition KParameter.h:17
float get() const
Definition KParameter.cpp:126
void set(float newValue)
Definition KParameter.cpp:128
Definition KwidgetAudioProcessor.h:12
Kwidget * addKwidgetFromState(const ValueTree &kwidgetTree)
Definition KwidgetAudioProcessor.cpp:1221
Definition Kwidget.h:8
const String m_kwidgetType
Definition Kwidget.h:324
void init()
Definition Kwidget.cpp:27
static String getParentID(String childKwidgetID)
Definition Kwidget.cpp:250
virtual void setState(const ValueTree &newState, KwidgetAudioProcessor &processor)
Definition Kwidget.cpp:268
OwnedArray< KParameter::AudioListenerObject > m_parameterCallbacks
Definition Kwidget.h:348
String m_kwidgetStateVersion
Definition Kwidget.h:327
int getNumVoices() const
Definition Kwidget.cpp:65
std::map< String, int > m_customParameterIDs
Definition Kwidget.h:343
const String & getKwidgetVersionFromCurrentState() const
Definition Kwidget.cpp:369
virtual std::vector< ParameterInfo > createParameters()=0
ValueTree m_kwidgetTree
Definition Kwidget.h:329
void addVersionedParameterCallback(StringRef kwidgetVersionTheParameterChangedIn, const String &paramID, std::function< void(float)> callback)
Add an action to be performed when a specified parameter of a specific kwidget version changes value....
Definition Kwidget.cpp:464
ValueTree m_customParamTree
Definition Kwidget.h:331
void addChildKwidget(Kwidget *child)
Definition Kwidget.cpp:325
void flushState()
Definition Kwidget.cpp:312
void setKwidgetVersion(const String &kwidgetVersionString)
Definition Kwidget.cpp:371
std::unique_ptr< KwidgetProcessor > m_initialVoice
Definition Kwidget.h:340
virtual std::unique_ptr< KwidgetProcessor > createProcessor()=0
virtual bool isActive(int voiceIdx)
Definition Kwidget.cpp:80
const String m_kwidgetID
Definition Kwidget.h:325
bool isAChildKwidget()
Definition Kwidget.cpp:248
KwidgetProcessor * getVoice(int idx) const
Definition Kwidget.cpp:38
virtual void noteOn(int voiceIdx, int midiNote, float velocity)
Definition Kwidget.cpp:67
OwnedArray< CustomParameterTree > m_customParameterTrees
Definition Kwidget.h:345
virtual void noteCleared(int voiceIdx)
Definition Kwidget.cpp:78
OwnedArray< CustomParameter > m_customParameters
Definition Kwidget.h:342
void addChildGuis(std::unique_ptr< KwidgetGUI > &parentGui)
Definition Kwidget.cpp:498
const ValueTree & getState()
Definition Kwidget.cpp:242
std::vector< Kwidget * > m_childKwidgets
Definition Kwidget.h:319
KwidgetProcessor * m_activeVoice
Definition Kwidget.h:339
void addModulator(const String &paramID, Kwidget *modulator, int modulatorIdx, float depth=0.99f, KAttachment::Polarity=KAttachment::Polarity::Bipolar)
Definition Kwidget.cpp:82
KParameter * getParameter(const String &parameterID) const noexcept
Get a raw pointer to a KParameter belonging to this Kwidget's KwidgetProcessor. Useful for low overhe...
Definition Kwidget.cpp:168
String getKwidgetVersion() const
Definition Kwidget.cpp:376
const String & getKwidgetType() const
Definition Kwidget.cpp:365
int getNumModulators() const
Definition Kwidget.cpp:357
Kwidget * findChildKwidget(String kiwdgetID)
Definition Kwidget.cpp:478
void removeModulator(const String &paramID, Kwidget *modulator, int modulatorIdx)
Definition Kwidget.cpp:108
CustomParameter * createAndAddCustomParameter(const String &paramID, const var &value)
Definition Kwidget.cpp:419
const String & getKwidgetID() const
Definition Kwidget.cpp:367
std::vector< std::shared_ptr< KParameter > > m_parameters
Definition Kwidget.h:335
CustomParameter * getCustomParameter(const String &parameterID)
Definition Kwidget.cpp:188
CustomParameterTree * getCustomParameterTree(const Identifier &type)
Get a CustomParameterTree belonging to this Kwidget.
Definition Kwidget.cpp:202
std::map< Identifier, int > m_customParameterTreeTypes
Definition Kwidget.h:346
std::unique_ptr< KwidgetProcessor > createVoice()
Definition Kwidget.cpp:44
StringArray getDragID(const String &parameterID)
Definition Kwidget.cpp:394
bool m_stateChanging
Definition Kwidget.h:350
Kwidget(const String &kwidgetType, const String &kwidgetID)
Definition Kwidget.cpp:8
bool isModulator() const
Definition Kwidget.cpp:355
void setModulatorDepth(const String &paramID, Kwidget *modulator, int modulatorIdx, float depth)
Definition Kwidget.cpp:127
KParameter * createAndAddParameter(const ParameterInfo &info)
Definition Kwidget.cpp:402
Array< KwidgetProcessor * > m_processors
Definition Kwidget.h:338
virtual void noteOff(int voiceIdx, float velocity)
Definition Kwidget.cpp:76
@ KwidgetID
Definition Kwidget.h:204
@ ParameterID
Definition Kwidget.h:205
void setModulatorPolarity(const String &paramID, Kwidget *modulator, int modulatorIdx, KAttachment::Polarity polarity)
Definition Kwidget.cpp:146
int getTemplateID()
Definition Kwidget.cpp:261
std::unique_ptr< KwidgetGUI > createControls()
Definition Kwidget.cpp:58
std::map< String, int > m_parameterIDs
Definition Kwidget.h:336
ValueTree m_paramTree
Definition Kwidget.h:330
virtual const String & getKwidgetLabel()
Definition Kwidget.cpp:378
std::shared_ptr< KParameter > getParameterToAttach(const String &parameterID) const noexcept
Get a shared pointer to a KParameter, for use with KParameter::Listener objects and situations where ...
Definition Kwidget.cpp:178
void notifyAllParametersListeners()
Call every parameter's value changed listeners with their current values.
Definition Kwidget.cpp:233
void removeChildKwidgetFromTree(String kwidgetID)
Definition Kwidget.cpp:344
virtual std::unique_ptr< KwidgetGUI > createGUI()=0
const std::vector< std::shared_ptr< KParameter > > & getParameters() const
Definition Kwidget.cpp:166
ValueTree m_childTree
Definition Kwidget.h:332
void addParameterCallback(const String &paramID, std::function< void(float)> callback)
Definition Kwidget.cpp:458
An interface for an audio processor designed for modular use.
Definition KwidgetProcessor.h:8
virtual bool isActive()
Definition KwidgetProcessor.cpp:24
Modulator * getModulator(int index)
Definition KwidgetProcessor.cpp:34
std::shared_ptr< KAttachment > getAttachment(const String &paramID)
Definition KwidgetProcessor.cpp:26
virtual void noteOff(float velocity)
Definition KwidgetProcessor.cpp:22
virtual void noteCleared()
Definition KwidgetProcessor.h:49
void setAccessible(bool isAccessible)
Called by the resource to grant or deny access to clients.
Definition ResourceLock.cpp:54
int getVersionAsHexInteger(StringRef versionString)
Definition helpers.cpp:86
Definition AirAbsorptionFilter.cpp:2
A KParameter Listener which can be used to trigger a callback syncrhonously.
Definition KParameter.h:30
static const String Parent
Definition Kwidget.h:24
static const String Renderstyle
Definition Kwidget.h:26
static const String ChildDelimiter
Definition Kwidget.h:23
static const String Bounds
Definition Kwidget.h:25
Holds the information needed to create a new Kwidget parameter.
Definition Kwidget.h:14
NormalisableRange< float > range
Definition Kwidget.h:17
String name
Definition Kwidget.h:16
String id
Definition Kwidget.h:15
float defaultValue
Definition Kwidget.h:18
static const Identifier id
Definition XmlType.h:41
static const Identifier version
Definition XmlType.h:52
static const Identifier value
Definition XmlType.h:42
static const Identifier linkIndex
Definition XmlType.h:44
static const Identifier type
Definition XmlType.h:43
static const Identifier kwidgets
Definition XmlType.h:22
static const Identifier params
Definition XmlType.h:18
static const Identifier customParam
Definition XmlType.h:21
static const Identifier customParams
Definition XmlType.h:20
static const Identifier param
Definition XmlType.h:19
Common names for storing data in a ValueTree.
Definition XmlType.h:7