OpenShot Library | libopenshot-audio 0.2.0
juce_ValueTree.h
1
2/** @weakgroup juce_data_structures-values
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16 27th April 2017).
17
18 End User License Agreement: www.juce.com/juce-5-licence
19 Privacy Policy: www.juce.com/juce-5-privacy-policy
20
21 Or: You may also use this code under the terms of the GPL v3 (see
22 www.gnu.org/licenses).
23
24 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26 DISCLAIMED.
27
28 ==============================================================================
29*/
30
31namespace juce
32{
33
34//==============================================================================
35/**
36 A powerful tree structure that can be used to hold free-form data, and which can
37 handle its own undo and redo behaviour.
38
39 A ValueTree contains a list of named properties as var objects, and also holds
40 any number of sub-trees.
41
42 Create ValueTree objects on the stack, and don't be afraid to copy them around, as
43 they're simply a lightweight reference to a shared data container. Creating a copy
44 of another ValueTree simply creates a new reference to the same underlying object - to
45 make a separate, deep copy of a tree you should explicitly call createCopy().
46
47 Each ValueTree has a type name, in much the same way as an XmlElement has a tag name,
48 and much of the structure of a ValueTree is similar to an XmlElement tree.
49 You can convert a ValueTree to and from an XmlElement, and as long as the XML doesn't
50 contain text elements, the conversion works well and makes a good serialisation
51 format. They can also be serialised to a binary format, which is very fast and compact.
52
53 All the methods that change data take an optional UndoManager, which will be used
54 to track any changes to the object. For this to work, you have to be careful to
55 consistently always use the same UndoManager for all operations to any sub-tree inside
56 the tree.
57
58 A ValueTree can only be a child of one parent at a time, so if you're moving one from
59 one tree to another, be careful to always remove it first, before adding it. This
60 could also mess up your undo/redo chain, so be wary! In a debug build you should hit
61 assertions if you try to do anything dangerous, but there are still plenty of ways it
62 could go wrong.
63
64 Note that although the children in a tree have a fixed order, the properties are not
65 guaranteed to be stored in any particular order, so don't expect that a property's index
66 will correspond to the order in which the property was added, or that it will remain
67 constant when other properties are added or removed.
68
69 Listeners can be added to a ValueTree to be told when properies change and when
70 sub-trees are added or removed.
71
72 @see var, XmlElement
73
74 @tags{DataStructures}
75*/
77{
78public:
79 //==============================================================================
80 /** Creates an empty, invalid ValueTree.
81
82 A ValueTree that is created with this constructor can't actually be used for anything,
83 it's just a default 'null' ValueTree that can be returned to indicate some sort of failure.
84 To create a real one, use the constructor that takes a string.
85 */
86 ValueTree() noexcept;
87
88 /** Creates an empty ValueTree with the given type name.
89
90 Like an XmlElement, each ValueTree has a type, which you can access with
91 getType() and hasType().
92 */
93 explicit ValueTree (const Identifier& type);
94
95 /** Creates a value tree from nested lists of properties and ValueTrees.
96
97 This code,
98
99 @code
100 ValueTree groups
101 { "ParameterGroups", {},
102 {
103 { "Group", {{ "name", "Tone Controls" }},
104 {
105 { "Parameter", {{ "id", "distortion" }, { "value", 0.5 }}},
106 { "Parameter", {{ "id", "reverb" }, { "value", 0.5 }}}
107 }
108 },
109 { "Group", {{ "name", "Other Controls" }},
110 {
111 { "Parameter", {{ "id", "drywet" }, { "value", 0.5 }}},
112 { "Parameter", {{ "id", "gain" }, { "value", 0.5 }}}
113 }
114 }
115 }
116 };
117 @endcode
118
119 produces this tree:
120
121 @verbatim
122 <ParameterGroups>
123 <Group name="Tone Controls">
124 <Parameter id="distortion" value="0.5"/>
125 <Parameter id="reverb" value="0.5"/>
126 </Group>
127 <Group name="Other Controls">
128 <Parameter id="drywet" value="0.5"/>
129 <Parameter id="gain" value="0.5"/>
130 </Group>
131 </ParameterGroups>
132 @endverbatim
133 */
134 ValueTree (const Identifier& type,
135 std::initializer_list<NamedValueSet::NamedValue> properties,
136 std::initializer_list<ValueTree> subTrees = {});
137
138 /** Creates a reference to another ValueTree. */
139 ValueTree (const ValueTree&) noexcept;
140
141 /** Move constructor */
142 ValueTree (ValueTree&&) noexcept;
143
144 /** Changes this object to be a reference to the given tree.
145 Note that calling this just points this at the new object and invokes the
146 Listener::valueTreeRedirected callback, but it's not an undoable operation. If
147 you're trying to replace an entire tree in an undoable way, you probably want
148 to use copyPropertiesAndChildrenFrom() instead.
149 */
150 ValueTree& operator= (const ValueTree&);
151
152 /** Destructor. */
153 ~ValueTree();
154
155 /** Returns true if both this and the other tree refer to the same underlying structure.
156 Note that this isn't a value comparison - two independently-created trees which
157 contain identical data are NOT considered equal.
158 */
159 bool operator== (const ValueTree&) const noexcept;
160
161 /** Returns true if this and the other tree refer to different underlying structures.
162 Note that this isn't a value comparison - two independently-created trees which
163 contain identical data are not considered equal.
164 */
165 bool operator!= (const ValueTree&) const noexcept;
166
167 /** Performs a deep comparison between the properties and children of two trees.
168 If all the properties and children of the two trees are the same (recursively), this
169 returns true.
170 The normal operator==() only checks whether two trees refer to the same shared data
171 structure, so use this method if you need to do a proper value comparison.
172 */
173 bool isEquivalentTo (const ValueTree&) const;
174
175 //==============================================================================
176 /** Returns true if this tree refers to some valid data.
177 An invalid tree is one that was created with the default constructor.
178 */
179 bool isValid() const noexcept { return object != nullptr; }
180
181 /** Returns a deep copy of this tree and all its sub-trees. */
182 ValueTree createCopy() const;
183
184 /** Overwrites all the properties in this tree with the properties of the source tree.
185 Any properties that already exist will be updated; and new ones will be added, and
186 any that are not present in the source tree will be removed.
187 @see copyPropertiesAndChildrenFrom
188 */
189 void copyPropertiesFrom (const ValueTree& source, UndoManager* undoManager);
190
191 /** Replaces all children and properties of this object with copies of those from
192 the source object.
193 @see copyPropertiesFrom
194 */
195 void copyPropertiesAndChildrenFrom (const ValueTree& source, UndoManager* undoManager);
196
197 //==============================================================================
198 /** Returns the type of this tree.
199 The type is specified when the ValueTree is created.
200 @see hasType
201 */
202 Identifier getType() const noexcept;
203
204 /** Returns true if the tree has this type.
205 The comparison is case-sensitive.
206 @see getType
207 */
208 bool hasType (const Identifier& typeName) const noexcept;
209
210 //==============================================================================
211 /** Returns the value of a named property.
212 If no such property has been set, this will return a void variant.
213 You can also use operator[] to get a property.
214 @see var, setProperty, getPropertyPointer, hasProperty
215 */
216 const var& getProperty (const Identifier& name) const noexcept;
217
218 /** Returns the value of a named property, or the value of defaultReturnValue
219 if the property doesn't exist.
220 You can also use operator[] and getProperty to get a property.
221 @see var, getProperty, getPropertyPointer, setProperty, hasProperty
222 */
223 var getProperty (const Identifier& name, const var& defaultReturnValue) const;
224
225 /** Returns a pointer to the value of a named property, or nullptr if the property
226 doesn't exist.
227 @see var, getProperty, setProperty, hasProperty
228 */
229 const var* getPropertyPointer (const Identifier& name) const noexcept;
230
231 /** Returns the value of a named property.
232 If no such property has been set, this will return a void variant. This is the same as
233 calling getProperty().
234 @see getProperty
235 */
236 const var& operator[] (const Identifier& name) const noexcept;
237
238 /** Changes a named property of the tree.
239 The name identifier must not be an empty string.
240 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
241 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
242 @see var, getProperty, removeProperty
243 @returns a reference to the value tree, so that you can daisy-chain calls to this method.
244 */
245 ValueTree& setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager);
246
247 /** Returns true if the tree contains a named property. */
248 bool hasProperty (const Identifier& name) const noexcept;
249
250 /** Removes a property from the tree.
251 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
252 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
253 */
254 void removeProperty (const Identifier& name, UndoManager* undoManager);
255
256 /** Removes all properties from the tree.
257 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
258 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
259 */
260 void removeAllProperties (UndoManager* undoManager);
261
262 /** Returns the total number of properties that the tree contains.
263 @see getProperty.
264 */
265 int getNumProperties() const noexcept;
266
267 /** Returns the identifier of the property with a given index.
268 Note that properties are not guaranteed to be stored in any particular order, so don't
269 expect that the index will correspond to the order in which the property was added, or
270 that it will remain constant when other properties are added or removed.
271 @see getNumProperties
272 */
273 Identifier getPropertyName (int index) const noexcept;
274
275 /** Returns a Value object that can be used to control and respond to one of the tree's properties.
276
277 The Value object will maintain a reference to this tree, and will use the undo manager when
278 it needs to change the value. Attaching a Value::Listener to the value object will provide
279 callbacks whenever the property changes.
280 If shouldUpdateSynchronously is true the Value::Listener will be updated synchronously.
281 @see ValueSource::sendChangeMessage (bool)
282 */
283 Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager,
284 bool shouldUpdateSynchronously = false);
285
286 //==============================================================================
287 /** Returns the number of child trees inside this one.
288 @see getChild
289 */
290 int getNumChildren() const noexcept;
291
292 /** Returns one of this tree's sub-trees.
293 If the index is out of range, it'll return an invalid tree. (You can use isValid() to
294 check whether a tree is valid)
295 */
296 ValueTree getChild (int index) const;
297
298 /** Returns the first sub-tree with the specified type name.
299 If no such child tree exists, it'll return an invalid tree. (You can use isValid() to
300 check whether a tree is valid)
301 @see getOrCreateChildWithName
302 */
303 ValueTree getChildWithName (const Identifier& type) const;
304
305 /** Returns the first sub-tree with the specified type name, creating and adding
306 a child with this name if there wasn't already one there.
307 The only time this will return an invalid object is when the object that you're calling
308 the method on is itself invalid.
309 @see getChildWithName
310 */
311 ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager);
312
313 /** Looks for the first sub-tree that has the specified property value.
314 This will scan the child trees in order, until it finds one that has property that matches
315 the specified value.
316 If no such tree is found, it'll return an invalid object. (You can use isValid() to
317 check whether a tree is valid)
318 */
319 ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
320
321 /** Adds a child to this tree.
322 Make sure that the child being added has first been removed from any former parent before
323 calling this, or else you'll hit an assertion.
324 If the index is < 0 or greater than the current number of sub-trees, the new one will be
325 added at the end of the list.
326 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
327 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
328 @see appendChild, removeChild
329 */
330 void addChild (const ValueTree& child, int index, UndoManager* undoManager);
331
332 /** Appends a new child sub-tree to this tree.
333 This is equivalent to calling addChild() with an index of -1. See addChild() for more details.
334 @see addChild, removeChild
335 */
336 void appendChild (const ValueTree& child, UndoManager* undoManager);
337
338 /** Removes the specified child from this tree's child-list.
339 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
340 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
341 */
342 void removeChild (const ValueTree& child, UndoManager* undoManager);
343
344 /** Removes a sub-tree from this tree.
345 If the index is out-of-range, nothing will be changed.
346 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
347 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
348 */
349 void removeChild (int childIndex, UndoManager* undoManager);
350
351 /** Removes all child-trees.
352 If the undoManager parameter is not nullptr, its UndoManager::perform() method will be used,
353 so that this change can be undone. Be very careful not to mix undoable and non-undoable changes!
354 */
355 void removeAllChildren (UndoManager* undoManager);
356
357 /** Moves one of the sub-trees to a different index.
358 This will move the child to a specified index, shuffling along any intervening
359 items as required. So for example, if you have a list of { 0, 1, 2, 3, 4, 5 }, then
360 calling move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
361
362 @param currentIndex the index of the item to be moved. If this isn't a
363 valid index, then nothing will be done
364 @param newIndex the index at which you'd like this item to end up. If this
365 is less than zero, the value will be moved to the end
366 of the list
367 @param undoManager the optional UndoManager to use to store this transaction
368 */
369 void moveChild (int currentIndex, int newIndex, UndoManager* undoManager);
370
371 /** Returns true if this tree is a sub-tree (at any depth) of the given parent.
372 This searches recursively, so returns true if it's a sub-tree at any level below the parent.
373 */
374 bool isAChildOf (const ValueTree& possibleParent) const noexcept;
375
376 /** Returns the index of a child item in this parent.
377 If the child isn't found, this returns -1.
378 */
379 int indexOf (const ValueTree& child) const noexcept;
380
381 /** Returns the parent tree that contains this one.
382 If the tree has no parent, this will return an invalid object. (You can use isValid() to
383 check whether a tree is valid)
384 */
385 ValueTree getParent() const noexcept;
386
387 /** Recursively finds the highest-level parent tree that contains this one.
388 If the tree has no parent, this will return itself.
389 */
390 ValueTree getRoot() const noexcept;
391
392 /** Returns one of this tree's siblings in its parent's child list.
393 The delta specifies how far to move through the list, so a value of 1 would return the tree
394 that follows this one, -1 would return the tree before it, 0 will return this one, etc.
395 If the requested position is beyond the start or end of the child list, this will return an
396 invalid object.
397 */
398 ValueTree getSibling (int delta) const noexcept;
399
400 //==============================================================================
401 /** Iterator for a ValueTree.
402 You shouldn't ever need to use this class directly - it's used internally by ValueTree::begin()
403 and ValueTree::end() to allow range-based-for loops on a ValueTree.
404 */
405 struct Iterator
406 {
407 Iterator (const ValueTree&, bool isEnd);
408 Iterator& operator++();
409
410 bool operator== (const Iterator&) const;
411 bool operator!= (const Iterator&) const;
412 ValueTree operator*() const;
413
414 using difference_type = std::ptrdiff_t;
415 using value_type = ValueTree;
416 using reference = ValueTree&;
417 using pointer = ValueTree*;
418 using iterator_category = std::forward_iterator_tag;
419
420 private:
421 void* internal;
422 };
423
424 /** Returns a start iterator for the children in this tree. */
425 Iterator begin() const noexcept;
426
427 /** Returns an end iterator for the children in this tree. */
428 Iterator end() const noexcept;
429
430 //==============================================================================
431 /** Creates an XmlElement that holds a complete image of this tree and all its children.
432 If this tree is invalid, this may return nullptr. Otherwise, the XML that is produced can
433 be used to recreate a similar tree by calling ValueTree::fromXml().
434 The caller must delete the object that is returned.
435 @see fromXml, toXmlString
436 */
437 XmlElement* createXml() const;
438
439 /** Tries to recreate a tree from its XML representation.
440 This isn't designed to cope with random XML data - it should only be fed XML that was created
441 by the createXml() method.
442 */
443 static ValueTree fromXml (const XmlElement& xml);
444
445 /** This returns a string containing an XML representation of the tree.
446 This is quite handy for debugging purposes, as it provides a quick way to view a tree.
447 @see createXml()
448 */
449 String toXmlString() const;
450
451 //==============================================================================
452 /** Stores this tree (and all its children) in a binary format.
453
454 Once written, the data can be read back with readFromStream().
455
456 It's much faster to load/save your tree in binary form than as XML, but
457 obviously isn't human-readable.
458 */
459 void writeToStream (OutputStream& output) const;
460
461 /** Reloads a tree from a stream that was written with writeToStream(). */
462 static ValueTree readFromStream (InputStream& input);
463
464 /** Reloads a tree from a data block that was written with writeToStream(). */
465 static ValueTree readFromData (const void* data, size_t numBytes);
466
467 /** Reloads a tree from a data block that was written with writeToStream() and
468 then zipped using GZIPCompressorOutputStream.
469 */
470 static ValueTree readFromGZIPData (const void* data, size_t numBytes);
471
472 //==============================================================================
473 /** Listener class for events that happen to a ValueTree.
474
475 To get events from a ValueTree, make your class implement this interface, and use
476 ValueTree::addListener() and ValueTree::removeListener() to register it.
477 */
479 {
480 public:
481 /** Destructor. */
482 virtual ~Listener() = default;
483
484 /** This method is called when a property of this tree (or of one of its sub-trees) is changed.
485 Note that when you register a listener to a tree, it will receive this callback for
486 property changes in that tree, and also for any of its children, (recursively, at any depth).
487 If your tree has sub-trees but you only want to know about changes to the top level tree,
488 simply check the tree parameter in this callback to make sure it's the tree you're interested in.
489 */
490 virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
491 const Identifier& property) = 0;
492
493 /** This method is called when a child sub-tree is added.
494 Note that when you register a listener to a tree, it will receive this callback for
495 child changes in both that tree and any of its children, (recursively, at any depth).
496 If your tree has sub-trees but you only want to know about changes to the top level tree,
497 just check the parentTree parameter to make sure it's the one that you're interested in.
498 */
499 virtual void valueTreeChildAdded (ValueTree& parentTree,
500 ValueTree& childWhichHasBeenAdded) = 0;
501
502 /** This method is called when a child sub-tree is removed.
503
504 Note that when you register a listener to a tree, it will receive this callback for
505 child changes in both that tree and any of its children, (recursively, at any depth).
506 If your tree has sub-trees but you only want to know about changes to the top level tree,
507 just check the parentTree parameter to make sure it's the one that you're interested in.
508 */
509 virtual void valueTreeChildRemoved (ValueTree& parentTree,
510 ValueTree& childWhichHasBeenRemoved,
511 int indexFromWhichChildWasRemoved) = 0;
512
513 /** This method is called when a tree's children have been re-shuffled.
514
515 Note that when you register a listener to a tree, it will receive this callback for
516 child changes in both that tree and any of its children, (recursively, at any depth).
517 If your tree has sub-trees but you only want to know about changes to the top level tree,
518 just check the parameter to make sure it's the tree that you're interested in.
519 */
520 virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved,
521 int oldIndex, int newIndex) = 0;
522
523 /** This method is called when a tree has been added or removed from a parent.
524
525 This callback happens when the tree to which the listener was registered is added or
526 removed from a parent. Unlike the other callbacks, it applies only to the tree to which
527 the listener is registered, and not to any of its children.
528 */
529 virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) = 0;
530
531 /** This method is called when a tree is made to point to a different internal shared object.
532 When operator= is used to make a ValueTree refer to a different object, this callback
533 will be made.
534 */
535 virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged);
536 };
537
538 /** Adds a listener to receive callbacks when this tree is changed in some way.
539
540 The listener is added to this specific ValueTree object, and not to the shared
541 object that it refers to. When this object is deleted, all the listeners will
542 be lost, even if other references to the same ValueTree still exist. And if you
543 use the operator= to make this refer to a different ValueTree, any listeners will
544 begin listening to changes to the new tree instead of the old one.
545
546 When you're adding a listener, make sure that you add it to a ValueTree instance that
547 will last for as long as you need the listener. In general, you'd never want to add a
548 listener to a local stack-based ValueTree, and would usually add one to a member variable.
549
550 @see removeListener
551 */
552 void addListener (Listener* listener);
553
554 /** Removes a listener that was previously added with addListener(). */
555 void removeListener (Listener* listener);
556
557 /** Changes a named property of the tree, but will not notify a specified listener of the change.
558 @see setProperty
559 */
560 ValueTree& setPropertyExcludingListener (Listener* listenerToExclude,
561 const Identifier& name, const var& newValue,
562 UndoManager* undoManager);
563
564 /** Causes a property-change callback to be triggered for the specified property,
565 calling any listeners that are registered.
566 */
567 void sendPropertyChangeMessage (const Identifier& property);
568
569 //==============================================================================
570 /** This method uses a comparator object to sort the tree's children into order.
571
572 The object provided must have a method of the form:
573 @code
574 int compareElements (const ValueTree& first, const ValueTree& second);
575 @endcode
576
577 ..and this method must return:
578 - a value of < 0 if the first comes before the second
579 - a value of 0 if the two objects are equivalent
580 - a value of > 0 if the second comes before the first
581
582 To improve performance, the compareElements() method can be declared as static or const.
583
584 @param comparator the comparator to use for comparing elements.
585 @param undoManager optional UndoManager for storing the changes
586 @param retainOrderOfEquivalentItems if this is true, then items which the comparator says are
587 equivalent will be kept in the order in which they currently appear in the array.
588 This is slower to perform, but may be important in some cases. If it's false, a
589 faster algorithm is used, but equivalent elements may be rearranged.
590 */
591 template <typename ElementComparator>
592 void sort (ElementComparator& comparator, UndoManager* undoManager, bool retainOrderOfEquivalentItems)
593 {
594 if (object != nullptr)
595 {
596 OwnedArray<ValueTree> sortedList;
597 createListOfChildren (sortedList);
598 ComparatorAdapter<ElementComparator> adapter (comparator);
599 sortedList.sort (adapter, retainOrderOfEquivalentItems);
600 reorderChildren (sortedList, undoManager);
601 }
602 }
603
604 /** Returns the total number of references to the shared underlying data structure that this
605 ValueTree is using.
606 */
607 int getReferenceCount() const noexcept;
608
609 /* An invalid ValueTree that can be used if you need to return one as an error condition, etc.
610 @deprecated If you need an empty ValueTree object, just use ValueTree() or {}.
611 */
612 JUCE_DEPRECATED_STATIC (static const ValueTree invalid;)
613
614private:
615 //==============================================================================
616 JUCE_PUBLIC_IN_DLL_BUILD (class SharedObject)
617 friend class SharedObject;
618
619 ReferenceCountedObjectPtr<SharedObject> object;
620 ListenerList<Listener> listeners;
621
622 template <typename ElementComparator>
623 struct ComparatorAdapter
624 {
625 ComparatorAdapter (ElementComparator& comp) noexcept : comparator (comp) {}
626
627 int compareElements (const ValueTree* const first, const ValueTree* const second)
628 {
629 return comparator.compareElements (*first, *second);
630 }
631
632 private:
633 ElementComparator& comparator;
634 JUCE_DECLARE_NON_COPYABLE (ComparatorAdapter)
635 };
636
637 void createListOfChildren (OwnedArray<ValueTree>&) const;
638 void reorderChildren (const OwnedArray<ValueTree>&, UndoManager*);
639
640 explicit ValueTree (ReferenceCountedObjectPtr<SharedObject>) noexcept;
641 explicit ValueTree (SharedObject&) noexcept;
642};
643
644} // namespace juce
645
646/** @}*/
Represents a string identifier, designed for accessing properties by name.
The base class for streams that read data.
Holds a set of objects and can invoke a member function callback on each object in the set with a sin...
The base class for streams that write data to some kind of destination.
An array designed for holding objects.
void sort(ElementComparator &comparator, bool retainOrderOfEquivalentItems=false) const noexcept
Sorts the elements in the array.
A smart-pointer class which points to a reference-counted object.
The JUCE String class!
Definition juce_String.h:43
Manages a list of undo/redo commands.
Listener class for events that happen to a ValueTree.
virtual void valueTreeChildRemoved(ValueTree &parentTree, ValueTree &childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved)=0
This method is called when a child sub-tree is removed.
virtual void valueTreeChildAdded(ValueTree &parentTree, ValueTree &childWhichHasBeenAdded)=0
This method is called when a child sub-tree is added.
virtual ~Listener()=default
Destructor.
virtual void valueTreeParentChanged(ValueTree &treeWhoseParentHasChanged)=0
This method is called when a tree has been added or removed from a parent.
virtual void valueTreeChildOrderChanged(ValueTree &parentTreeWhoseChildrenHaveMoved, int oldIndex, int newIndex)=0
This method is called when a tree's children have been re-shuffled.
virtual void valueTreePropertyChanged(ValueTree &treeWhosePropertyHasChanged, const Identifier &property)=0
This method is called when a property of this tree (or of one of its sub-trees) is changed.
A powerful tree structure that can be used to hold free-form data, and which can handle its own undo ...
bool isValid() const noexcept
Returns true if this tree refers to some valid data.
void sort(ElementComparator &comparator, UndoManager *undoManager, bool retainOrderOfEquivalentItems)
This method uses a comparator object to sort the tree's children into order.
Represents a shared variant value.
Definition juce_Value.h:56
Used to build a tree of elements representing an XML document.
A variant class, that can be used to hold a range of primitive values.
#define JUCE_API
This macro is added to all JUCE public class declarations.
Iterator for a ValueTree.