OpenShot Library | OpenShotAudio 0.2.2
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 properties 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 std::unique_ptr<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 /** Tries to recreate a tree from its XML representation.
446 This isn't designed to cope with random XML data - it should only be fed XML that was created
447 by the createXml() method.
448 */
449 static ValueTree fromXml (const String& xmlText);
450
451 /** This returns a string containing an XML representation of the tree.
452 This is quite handy for debugging purposes, as it provides a quick way to view a tree.
453 @see createXml()
454 */
455 String toXmlString (const XmlElement::TextFormat& format = {}) const;
456
457 //==============================================================================
458 /** Stores this tree (and all its children) in a binary format.
459
460 Once written, the data can be read back with readFromStream().
461
462 It's much faster to load/save your tree in binary form than as XML, but
463 obviously isn't human-readable.
464 */
465 void writeToStream (OutputStream& output) const;
466
467 /** Reloads a tree from a stream that was written with writeToStream(). */
468 static ValueTree readFromStream (InputStream& input);
469
470 /** Reloads a tree from a data block that was written with writeToStream(). */
471 static ValueTree readFromData (const void* data, size_t numBytes);
472
473 /** Reloads a tree from a data block that was written with writeToStream() and
474 then zipped using GZIPCompressorOutputStream.
475 */
476 static ValueTree readFromGZIPData (const void* data, size_t numBytes);
477
478 //==============================================================================
479 /** Listener class for events that happen to a ValueTree.
480
481 To get events from a ValueTree, make your class implement this interface, and use
482 ValueTree::addListener() and ValueTree::removeListener() to register it.
483 */
485 {
486 public:
487 /** Destructor. */
488 virtual ~Listener() = default;
489
490 /** This method is called when a property of this tree (or of one of its sub-trees) is changed.
491 Note that when you register a listener to a tree, it will receive this callback for
492 property changes in that tree, and also for any of its children, (recursively, at any depth).
493 If your tree has sub-trees but you only want to know about changes to the top level tree,
494 simply check the tree parameter in this callback to make sure it's the tree you're interested in.
495 */
496 virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
497 const Identifier& property);
498
499 /** This method is called when a child sub-tree is added.
500 Note that when you register a listener to a tree, it will receive this callback for
501 child changes in both that tree and any of its children, (recursively, at any depth).
502 If your tree has sub-trees but you only want to know about changes to the top level tree,
503 just check the parentTree parameter to make sure it's the one that you're interested in.
504 */
505 virtual void valueTreeChildAdded (ValueTree& parentTree,
506 ValueTree& childWhichHasBeenAdded);
507
508 /** This method is called when a child sub-tree is removed.
509
510 Note that when you register a listener to a tree, it will receive this callback for
511 child changes in both that tree and any of its children, (recursively, at any depth).
512 If your tree has sub-trees but you only want to know about changes to the top level tree,
513 just check the parentTree parameter to make sure it's the one that you're interested in.
514 */
515 virtual void valueTreeChildRemoved (ValueTree& parentTree,
516 ValueTree& childWhichHasBeenRemoved,
517 int indexFromWhichChildWasRemoved);
518
519 /** This method is called when a tree's children have been re-shuffled.
520
521 Note that when you register a listener to a tree, it will receive this callback for
522 child changes in both that tree and any of its children, (recursively, at any depth).
523 If your tree has sub-trees but you only want to know about changes to the top level tree,
524 just check the parameter to make sure it's the tree that you're interested in.
525 */
526 virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved,
527 int oldIndex, int newIndex);
528
529 /** This method is called when a tree has been added or removed from a parent.
530
531 This callback happens when the tree to which the listener was registered is added or
532 removed from a parent. Unlike the other callbacks, it applies only to the tree to which
533 the listener is registered, and not to any of its children.
534 */
535 virtual void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
536
537 /** This method is called when a tree is made to point to a different internal shared object.
538 When operator= is used to make a ValueTree refer to a different object, this callback
539 will be made.
540 */
541 virtual void valueTreeRedirected (ValueTree& treeWhichHasBeenChanged);
542 };
543
544 /** Adds a listener to receive callbacks when this tree is changed in some way.
545
546 The listener is added to this specific ValueTree object, and not to the shared
547 object that it refers to. When this object is deleted, all the listeners will
548 be lost, even if other references to the same ValueTree still exist. And if you
549 use the operator= to make this refer to a different ValueTree, any listeners will
550 begin listening to changes to the new tree instead of the old one.
551
552 When you're adding a listener, make sure that you add it to a ValueTree instance that
553 will last for as long as you need the listener. In general, you'd never want to add a
554 listener to a local stack-based ValueTree, and would usually add one to a member variable.
555
556 @see removeListener
557 */
558 void addListener (Listener* listener);
559
560 /** Removes a listener that was previously added with addListener(). */
561 void removeListener (Listener* listener);
562
563 /** Changes a named property of the tree, but will not notify a specified listener of the change.
564 @see setProperty
565 */
566 ValueTree& setPropertyExcludingListener (Listener* listenerToExclude,
567 const Identifier& name, const var& newValue,
568 UndoManager* undoManager);
569
570 /** Causes a property-change callback to be triggered for the specified property,
571 calling any listeners that are registered.
572 */
573 void sendPropertyChangeMessage (const Identifier& property);
574
575 //==============================================================================
576 /** This method uses a comparator object to sort the tree's children into order.
577
578 The object provided must have a method of the form:
579 @code
580 int compareElements (const ValueTree& first, const ValueTree& second);
581 @endcode
582
583 ..and this method must return:
584 - a value of < 0 if the first comes before the second
585 - a value of 0 if the two objects are equivalent
586 - a value of > 0 if the second comes before the first
587
588 To improve performance, the compareElements() method can be declared as static or const.
589
590 @param comparator the comparator to use for comparing elements.
591 @param undoManager optional UndoManager for storing the changes
592 @param retainOrderOfEquivalentItems if this is true, then items which the comparator says are
593 equivalent will be kept in the order in which they currently appear in the array.
594 This is slower to perform, but may be important in some cases. If it's false, a
595 faster algorithm is used, but equivalent elements may be rearranged.
596 */
597 template <typename ElementComparator>
598 void sort (ElementComparator& comparator, UndoManager* undoManager, bool retainOrderOfEquivalentItems)
599 {
600 if (object != nullptr)
601 {
602 OwnedArray<ValueTree> sortedList;
603 createListOfChildren (sortedList);
604 ComparatorAdapter<ElementComparator> adapter (comparator);
605 sortedList.sort (adapter, retainOrderOfEquivalentItems);
606 reorderChildren (sortedList, undoManager);
607 }
608 }
609
610 /** Returns the total number of references to the shared underlying data structure that this
611 ValueTree is using.
612 */
613 int getReferenceCount() const noexcept;
614
615 /* An invalid ValueTree that can be used if you need to return one as an error condition, etc.
616 @deprecated If you need an empty ValueTree object, just use ValueTree() or {}.
617 */
618 JUCE_DEPRECATED_STATIC (static const ValueTree invalid;)
619
620private:
621 //==============================================================================
622 JUCE_PUBLIC_IN_DLL_BUILD (class SharedObject)
623 friend class SharedObject;
624
625 ReferenceCountedObjectPtr<SharedObject> object;
626 ListenerList<Listener> listeners;
627
628 template <typename ElementComparator>
629 struct ComparatorAdapter
630 {
631 ComparatorAdapter (ElementComparator& comp) noexcept : comparator (comp) {}
632
633 int compareElements (const ValueTree* const first, const ValueTree* const second)
634 {
635 return comparator.compareElements (*first, *second);
636 }
637
638 private:
639 ElementComparator& comparator;
640 JUCE_DECLARE_NON_COPYABLE (ComparatorAdapter)
641 };
642
643 void createListOfChildren (OwnedArray<ValueTree>&) const;
644 void reorderChildren (const OwnedArray<ValueTree>&, UndoManager*);
645
646 explicit ValueTree (ReferenceCountedObjectPtr<SharedObject>) noexcept;
647 explicit ValueTree (SharedObject&) noexcept;
648};
649
650} // namespace juce
651
652/** @}*/
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) 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 ~Listener()=default
Destructor.
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.
Definition: juce_Variant.h:46
#define JUCE_API
This macro is added to all JUCE public class declarations.
Iterator for a ValueTree.