40 for (
auto* c : other.children)
52 jassert (parent ==
nullptr);
54 for (
auto i = children.size(); --i >= 0;)
56 const Ptr c (children.getObjectPointerUnchecked (i));
59 c->sendParentChangeMessage();
65 return parent ==
nullptr ? *this : parent->getRoot();
68 template <
typename Function>
71 auto numListeners = valueTreesWithListeners.size();
73 if (numListeners == 1)
75 valueTreesWithListeners.getUnchecked (0)->listeners.callExcluding (listenerToExclude, fn);
77 else if (numListeners > 0)
79 auto listenersCopy = valueTreesWithListeners;
81 for (
int i = 0; i < numListeners; ++i)
83 auto* v = listenersCopy.getUnchecked (i);
85 if (i == 0 || valueTreesWithListeners.contains (v))
86 v->listeners.callExcluding (listenerToExclude, fn);
91 template <
typename Function>
94 for (
auto* t =
this; t !=
nullptr; t = t->parent)
95 t->callListeners (listenerToExclude, fn);
104 void sendChildAddedMessage (
ValueTree child)
110 void sendChildRemovedMessage (
ValueTree child,
int index)
116 void sendChildOrderChangedMessage (
int oldIndex,
int newIndex)
122 void sendParentChangeMessage()
126 for (
auto j = children.size(); --j >= 0;)
127 if (
auto* child = children.getObjectPointer (j))
128 child->sendParentChangeMessage();
136 if (undoManager ==
nullptr)
138 if (properties.
set (name, newValue))
139 sendPropertyChangeMessage (name, listenerToExclude);
145 if (*existingValue != newValue)
147 false,
false, listenerToExclude));
152 true,
false, listenerToExclude));
157 bool hasProperty (
const Identifier& name)
const noexcept
164 if (undoManager ==
nullptr)
166 if (properties.
remove (name))
167 sendPropertyChangeMessage (name);
176 void removeAllProperties (
UndoManager* undoManager)
178 if (undoManager ==
nullptr)
180 while (properties.
size() > 0)
182 auto name = properties.
getName (properties.
size() - 1);
184 sendPropertyChangeMessage (name);
189 for (
auto i = properties.
size(); --i >= 0;)
197 for (
auto i = properties.
size(); --i >= 0;)
199 removeProperty (properties.
getName (i), undoManager);
201 for (
int i = 0; i < source.properties.
size(); ++i)
202 setProperty (source.properties.
getName (i), source.properties.
getValueAt (i), undoManager);
207 for (
auto* s : children)
208 if (s->type == typeToMatch)
216 for (
auto* s : children)
217 if (s->type == typeToMatch)
221 addChild (newObject, -1, undoManager);
227 for (
auto* s : children)
228 if (s->properties[propertyName] == propertyValue)
234 bool isAChildOf (
const SharedObject* possibleParent)
const noexcept
236 for (
auto* p = parent; p !=
nullptr; p = p->parent)
237 if (p == possibleParent)
243 int indexOf (
const ValueTree& child)
const noexcept
245 return children.indexOf (child.object);
250 if (child !=
nullptr && child->parent !=
this)
252 if (child !=
this && ! isAChildOf (child))
257 jassert (child->parent ==
nullptr);
259 if (child->parent !=
nullptr)
261 jassert (child->parent->children.
indexOf (child) >= 0);
265 if (undoManager ==
nullptr)
267 children.insert (index, child);
268 child->parent =
this;
269 sendChildAddedMessage (
ValueTree (*child));
270 child->sendParentChangeMessage();
274 if (! isPositiveAndBelow (index, children.size()))
275 index = children.size();
289 void removeChild (
int childIndex,
UndoManager* undoManager)
291 if (
auto child =
Ptr (children.getObjectPointer (childIndex)))
293 if (undoManager ==
nullptr)
295 children.remove (childIndex);
296 child->parent =
nullptr;
297 sendChildRemovedMessage (
ValueTree (child), childIndex);
298 child->sendParentChangeMessage();
309 while (children.size() > 0)
310 removeChild (children.size() - 1, undoManager);
313 void moveChild (
int currentIndex,
int newIndex,
UndoManager* undoManager)
316 jassert (isPositiveAndBelow (currentIndex, children.size()));
318 if (currentIndex != newIndex
319 && isPositiveAndBelow (currentIndex, children.size()))
321 if (undoManager ==
nullptr)
323 children.move (currentIndex, newIndex);
324 sendChildOrderChangedMessage (currentIndex, newIndex);
328 if (! isPositiveAndBelow (newIndex, children.size()))
329 newIndex = children.size() - 1;
338 jassert (newOrder.
size() == children.size());
340 for (
int i = 0; i < children.size(); ++i)
344 if (children.getObjectPointerUnchecked (i) != child)
346 auto oldIndex = children.indexOf (child);
347 jassert (oldIndex >= 0);
348 moveChild (oldIndex, i, undoManager);
353 bool isEquivalentTo (
const SharedObject& other)
const noexcept
355 if (type != other.type
356 || properties.
size() != other.properties.
size()
357 || children.size() != other.children.size()
358 || properties != other.properties)
361 for (
int i = 0; i < children.size(); ++i)
362 if (! children.getObjectPointerUnchecked (i)->isEquivalentTo (*other.children.getObjectPointerUnchecked (i)))
374 for (
auto i = children.size(); --i >= 0;)
375 xml->prependChildElement (children.getObjectPointerUnchecked (i)->createXml());
385 for (
int j = 0; j < properties.
size(); ++j)
393 for (
auto* c : children)
394 writeObjectToStream (output, c);
399 if (
object !=
nullptr)
401 object->writeToStream (output);
415 const var& newVal,
const var& oldVal,
bool isAdding,
bool isDeleting,
417 : target (std::move (targetObject)),
418 name (propertyName), newValue (newVal), oldValue (oldVal),
419 isAddingNewProperty (isAdding), isDeletingProperty (isDeleting),
420 excludeListener (listenerToExclude)
426 jassert (! (isAddingNewProperty && target->hasProperty (name)));
428 if (isDeletingProperty)
429 target->removeProperty (name,
nullptr);
431 target->setProperty (name, newValue,
nullptr, excludeListener);
438 if (isAddingNewProperty)
439 target->removeProperty (name,
nullptr);
441 target->setProperty (name, oldValue,
nullptr);
448 return (
int)
sizeof (*this);
453 if (! (isAddingNewProperty || isDeletingProperty))
456 if (next->target == target && next->name == name
457 && ! (next->isAddingNewProperty || next->isDeletingProperty))
458 return new SetPropertyAction (*target, name, next->newValue, oldValue,
false,
false);
469 const bool isAddingNewProperty : 1, isDeletingProperty : 1;
479 : target (std::move (parentObject)),
480 child (newChild !=
nullptr ? newChild : target->children.getObjectPointer (index)),
482 isDeleting (newChild ==
nullptr)
484 jassert (child !=
nullptr);
490 target->removeChild (childIndex,
nullptr);
492 target->addChild (child.get(), childIndex,
nullptr);
501 target->addChild (child.get(), childIndex,
nullptr);
507 jassert (childIndex < target->children.size());
508 target->removeChild (childIndex,
nullptr);
516 return (
int)
sizeof (*this);
520 const Ptr target, child;
521 const int childIndex;
522 const bool isDeleting;
531 : parent (std::move (parentObject)), startIndex (fromIndex), endIndex (toIndex)
537 parent->moveChild (startIndex, endIndex,
nullptr);
543 parent->moveChild (endIndex, startIndex,
nullptr);
549 return (
int)
sizeof (*this);
555 if (next->parent == parent && next->startIndex == endIndex)
563 const int startIndex, endIndex;
583 JUCE_DECLARE_DEPRECATED_STATIC (
const ValueTree ValueTree::invalid;)
591 std::initializer_list<NamedValueSet::NamedValue> properties,
592 std::initializer_list<ValueTree> subTrees)
597 for (
auto& tree : subTrees)
610 if (
object != other.object)
612 if (listeners.isEmpty())
614 object = other.object;
618 if (
object !=
nullptr)
619 object->valueTreesWithListeners.removeValue (
this);
621 if (other.object !=
nullptr)
622 other.object->valueTreesWithListeners.add (
this);
624 object = other.object;
634 : object (std::move (other.object))
636 if (
object !=
nullptr)
637 object->valueTreesWithListeners.removeValue (&other);
642 if (! listeners.isEmpty() &&
object !=
nullptr)
643 object->valueTreesWithListeners.removeValue (
this);
648 return object == other.object;
653 return object != other.object;
658 return object == other.object
659 || (
object !=
nullptr && other.object !=
nullptr
660 &&
object->isEquivalentTo (*other.object));
665 if (
object !=
nullptr)
673 jassert (
object !=
nullptr || source.object ==
nullptr);
675 if (source.object ==
nullptr)
677 else if (
object !=
nullptr)
678 object->copyPropertiesFrom (*(source.object), undoManager);
683 jassert (
object !=
nullptr || source.object ==
nullptr);
688 if (
object !=
nullptr && source.object !=
nullptr)
689 for (
auto& child : source.object->children)
690 object->addChild (createCopyIfNotNull (child), -1, undoManager);
695 return object !=
nullptr &&
object->type == typeName;
700 return object !=
nullptr ?
object->type :
Identifier();
705 if (
object !=
nullptr)
706 if (
auto p = object->parent)
714 if (
object !=
nullptr)
722 if (
object !=
nullptr)
723 if (
auto* p = object->parent)
724 if (
auto* c = p->children.getObjectPointer (p->indexOf (*
this) + delta))
730 static const var& getNullVarRef() noexcept
738 return object ==
nullptr ? getNullVarRef() :
object->properties[name];
743 return object ==
nullptr ? getNullVarRef() :
object->properties[name];
748 return object ==
nullptr ? defaultReturnValue
749 :
object->properties.getWithDefault (name, defaultReturnValue);
754 return object ==
nullptr ? nullptr
755 :
object->properties.getVarPointer (name);
767 jassert (
object !=
nullptr);
769 if (
object !=
nullptr)
770 object->setProperty (name, newValue, undoManager, listenerToExclude);
777 return object !=
nullptr &&
object->hasProperty (name);
782 if (
object !=
nullptr)
783 object->removeProperty (name, undoManager);
788 if (
object !=
nullptr)
789 object->removeAllProperties (undoManager);
794 return object ==
nullptr ? 0 :
object->properties.size();
800 :
object->properties.getName (index);
805 return object !=
nullptr ?
object->getReferenceCount() : 0;
813 : tree (vt), property (prop), undoManager (um), updateSynchronously (sync)
830 const bool updateSynchronously;
832 void valueTreePropertyChanged (
ValueTree& changedTree,
const Identifier& changedProperty)
override
834 if (tree == changedTree && property == changedProperty)
838 void valueTreeChildAdded (ValueTree&, ValueTree&)
override {}
839 void valueTreeChildRemoved (ValueTree&, ValueTree&,
int)
override {}
840 void valueTreeChildOrderChanged (ValueTree&,
int,
int)
override {}
841 void valueTreeParentChanged (ValueTree&)
override {}
843 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource)
854 return object ==
nullptr ? 0 :
object->children.size();
859 if (
object !=
nullptr)
860 if (
auto* c = object->children.getObjectPointer (index))
866 ValueTree::Iterator::Iterator (
const ValueTree& v,
bool isEnd)
867 : internal (v.object != nullptr ? (isEnd ? v.object->children.end() : v.object->children.begin()) : nullptr)
871 ValueTree::Iterator& ValueTree::Iterator::operator++()
873 internal =
static_cast<SharedObject**
> (
internal) + 1;
877 bool ValueTree::Iterator::operator== (
const Iterator& other)
const {
return internal == other.internal; }
878 bool ValueTree::Iterator::operator!= (
const Iterator& other)
const {
return internal != other.internal; }
880 ValueTree ValueTree::Iterator::operator*()
const
882 return ValueTree (SharedObject::Ptr (*
static_cast<SharedObject**
> (
internal)));
905 return object !=
nullptr &&
object->isAChildOf (possibleParent.object.get());
910 return object !=
nullptr ?
object->indexOf (child) : -1;
915 jassert (
object !=
nullptr);
917 if (
object !=
nullptr)
918 object->addChild (child.object.get(), index, undoManager);
928 if (
object !=
nullptr)
929 object->removeChild (childIndex, undoManager);
934 if (
object !=
nullptr)
935 object->removeChild (object->children.indexOf (child.object), undoManager);
940 if (
object !=
nullptr)
941 object->removeAllChildren (undoManager);
946 if (
object !=
nullptr)
947 object->moveChild (currentIndex, newIndex, undoManager);
953 jassert (
object !=
nullptr);
955 for (
auto* o : object->children)
957 jassert (o !=
nullptr);
962 void ValueTree::reorderChildren (
const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager)
964 jassert (
object !=
nullptr);
965 object->reorderChildren (newOrder, undoManager);
971 if (listener !=
nullptr)
973 if (listeners.isEmpty() &&
object !=
nullptr)
974 object->valueTreesWithListeners.add (
this);
976 listeners.add (listener);
982 listeners.remove (listener);
984 if (listeners.isEmpty() &&
object !=
nullptr)
985 object->valueTreesWithListeners.removeValue (
this);
990 if (
object !=
nullptr)
991 object->sendPropertyChangeMessage (property);
997 return std::unique_ptr<XmlElement> (
object !=
nullptr ? object->createXml() :
nullptr);
1005 v.object->properties.setFromXmlAttributes (xml);
1007 forEachXmlChildElement (xml, e)
1020 if (
auto xml = parseXML (xmlText))
1029 return xml->toString (format);
1037 SharedObject::writeObjectToStream (output,
object.get());
1057 for (
int i = 0; i < numProps; ++i)
1061 if (name.isNotEmpty())
1068 v.object->children.ensureStorageAllocated (numChildren);
1070 for (
int i = 0; i < numChildren; ++i)
1074 if (! child.isValid())
1077 v.object->children.add (child.object);
1078 child.object->parent = v.object.get();
1109 class ValueTreeTests :
public UnitTest
1113 :
UnitTest (
"ValueTrees", UnitTestCategories::values)
1118 char buffer[50] = { 0 };
1119 const char chars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:";
1121 for (
int i = 1 + r.
nextInt (numElementsInArray (buffer) - 2); --i >= 0;)
1122 buffer[i] = chars[r.
nextInt (sizeof (chars) - 1)];
1124 String result (buffer);
1127 result = createRandomIdentifier (r);
1132 static String createRandomWideCharString (Random& r)
1134 juce_wchar buffer[50] = { 0 };
1136 for (
int i = r.nextInt (numElementsInArray (buffer) - 1); --i >= 0;)
1142 buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
1147 buffer[i] = (juce_wchar) (1 + r.nextInt (0x7e));
1150 return CharPointer_UTF32 (buffer);
1153 static ValueTree createRandomTree (UndoManager* undoManager,
int depth, Random& r)
1155 ValueTree v (createRandomIdentifier (r));
1157 for (
int i = r.nextInt (10); --i >= 0;)
1159 switch (r.nextInt (5))
1161 case 0: v.setProperty (createRandomIdentifier (r), createRandomWideCharString (r), undoManager);
break;
1162 case 1: v.setProperty (createRandomIdentifier (r), r.nextInt(), undoManager);
break;
1163 case 2:
if (depth < 5) v.addChild (createRandomTree (undoManager, depth + 1, r), r.nextInt (v.getNumChildren() + 1), undoManager);
break;
1164 case 3: v.setProperty (createRandomIdentifier (r), r.nextBool(), undoManager);
break;
1165 case 4: v.setProperty (createRandomIdentifier (r), r.nextDouble(), undoManager);
break;
1173 void runTest()
override
1176 beginTest (
"ValueTree");
1178 auto r = getRandom();
1180 for (
int i = 10; --i >= 0;)
1182 MemoryOutputStream mo;
1183 auto v1 = createRandomTree (
nullptr, 0, r);
1184 v1.writeToStream (mo);
1186 MemoryInputStream mi (mo.getData(), mo.getDataSize(),
false);
1188 expect (v1.isEquivalentTo (v2));
1190 MemoryOutputStream zipped;
1192 GZIPCompressorOutputStream zippedOut (zipped);
1193 v1.writeToStream (zippedOut);
1197 auto xml1 = v1.createXml();
1198 auto xml2 = v2.createCopy().createXml();
1199 expect (xml1->isEquivalentTo (xml2.get(),
false));
1201 auto v4 = v2.createCopy();
1202 expect (v1.isEquivalentTo (v4));
1207 beginTest (
"Float formatting");
1210 Identifier number (
"number");
1212 std::map<double, String> tests;
1215 tests[1.01] =
"1.01";
1216 tests[0.76378] =
"0.76378";
1217 tests[-10] =
"-10.0";
1218 tests[10.01] =
"10.01";
1219 tests[0.0123] =
"0.0123";
1220 tests[-3.7e-27] =
"-3.7e-27";
1221 tests[1e+40] =
"1.0e40";
1222 tests[-12345678901234567.0] =
"-1.234567890123457e16";
1223 tests[192000] =
"192000.0";
1224 tests[1234567] =
"1.234567e6";
1225 tests[0.00006] =
"0.00006";
1226 tests[0.000006] =
"6.0e-6";
1228 for (
auto& test : tests)
1230 testVT.setProperty (number, test.first,
nullptr);
1232 lines.removeEmptyStrings();
1233 auto numLines = lines.size();
1234 expect (numLines > 1);
1235 expectEquals (lines[numLines - 1],
"<Test number=\"" + test.second +
"\"/>");
1241 static ValueTreeTests valueTreeTests;
static bool canRepresent(juce_wchar character) noexcept
Returns true if the given unicode character can be represented in this encoding.
Represents a string identifier, designed for accessing properties by name.
const String & toString() const noexcept
Returns this identifier as a string.
Holds a set of named var objects.
bool set(const Identifier &name, const var &newValue)
Changes or adds a named value.
bool contains(const Identifier &name) const noexcept
Returns true if the set contains an item with the specified name.
bool remove(const Identifier &name)
Removes a value from the set.
const var & getValueAt(int index) const noexcept
Returns the value of the item at a given index.
Identifier getName(int index) const noexcept
Returns the name of the value at a given index.
int size() const noexcept
Returns the total number of values that the set contains.
var * getVarPointer(const Identifier &name) noexcept
Returns a pointer to the var that holds a named value, or null if there is no value with this name.
void copyToXmlAttributes(XmlElement &xml) const
Sets attributes in an XML element corresponding to each of this object's properties.
The base class for streams that write data to some kind of destination.
virtual bool writeCompressedInt(int value)
Writes a condensed binary encoding of a 32-bit integer.
virtual bool writeString(const String &text)
Stores a string in the stream in a binary format.
An array designed for holding objects.
int size() const noexcept
Returns the number of items currently in the array.
ObjectClass * getUnchecked(int index) const noexcept
Returns a pointer to the object at this index in the array, without checking whether the index is in-...
ObjectClass * add(ObjectClass *newObject)
Appends a new object to the end of the array.
A random number generator.
int nextInt() noexcept
Returns the next random 32 bit integer.
Holds a list of objects derived from ReferenceCountedObject, or which implement basic reference-count...
A smart-pointer class which points to a reference-counted object.
A base class which provides methods for reference-counting.
ReferenceCountedObject()=default
Creates the reference-counted object (with an initial ref count of zero).
Holds a set of unique primitive objects, such as ints or doubles.
static StringArray fromLines(StringRef stringToBreakUp)
Returns an array containing the lines in a given string.
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
Manages a list of undo/redo commands.
bool perform(UndoableAction *action)
Performs an action and adds it to the undo history list.
Used by the UndoManager class to store an action which can be done and undone.
This is a base class for classes that perform a unit test.
Listener class for events that happen to a ValueTree.
virtual void valueTreeRedirected(ValueTree &treeWhichHasBeenChanged)
This method is called when a tree is made to point to a different internal shared object.
virtual void valueTreeChildRemoved(ValueTree &parentTree, ValueTree &childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved)
This method is called when a child sub-tree is removed.
virtual void valueTreeChildOrderChanged(ValueTree &parentTreeWhoseChildrenHaveMoved, int oldIndex, int newIndex)
This method is called when a tree's children have been re-shuffled.
virtual void valueTreeParentChanged(ValueTree &treeWhoseParentHasChanged)
This method is called when a tree has been added or removed from a parent.
virtual void valueTreePropertyChanged(ValueTree &treeWhosePropertyHasChanged, const Identifier &property)
This method is called when a property of this tree (or of one of its sub-trees) is changed.
virtual void valueTreeChildAdded(ValueTree &parentTree, ValueTree &childWhichHasBeenAdded)
This method is called when a child sub-tree is added.
A powerful tree structure that can be used to hold free-form data, and which can handle its own undo ...
Value getPropertyAsValue(const Identifier &name, UndoManager *undoManager, bool shouldUpdateSynchronously=false)
Returns a Value object that can be used to control and respond to one of the tree's properties.
Identifier getPropertyName(int index) const noexcept
Returns the identifier of the property with a given index.
Iterator begin() const noexcept
Returns a start iterator for the children in this tree.
bool operator!=(const ValueTree &) const noexcept
Returns true if this and the other tree refer to different underlying structures.
std::unique_ptr< XmlElement > createXml() const
Creates an XmlElement that holds a complete image of this tree and all its children.
bool hasType(const Identifier &typeName) const noexcept
Returns true if the tree has this type.
static ValueTree readFromStream(InputStream &input)
Reloads a tree from a stream that was written with writeToStream().
void removeChild(const ValueTree &child, UndoManager *undoManager)
Removes the specified child from this tree's child-list.
String toXmlString(const XmlElement::TextFormat &format={}) const
This returns a string containing an XML representation of the tree.
static ValueTree readFromGZIPData(const void *data, size_t numBytes)
Reloads a tree from a data block that was written with writeToStream() and then zipped using GZIPComp...
ValueTree getChild(int index) const
Returns one of this tree's sub-trees.
int getNumProperties() const noexcept
Returns the total number of properties that the tree contains.
int getNumChildren() const noexcept
Returns the number of child trees inside this one.
void copyPropertiesFrom(const ValueTree &source, UndoManager *undoManager)
Overwrites all the properties in this tree with the properties of the source tree.
int getReferenceCount() const noexcept
Returns the total number of references to the shared underlying data structure that this ValueTree is...
const var * getPropertyPointer(const Identifier &name) const noexcept
Returns a pointer to the value of a named property, or nullptr if the property doesn't exist.
ValueTree & setProperty(const Identifier &name, const var &newValue, UndoManager *undoManager)
Changes a named property of the tree.
void removeAllChildren(UndoManager *undoManager)
Removes all child-trees.
bool isAChildOf(const ValueTree &possibleParent) const noexcept
Returns true if this tree is a sub-tree (at any depth) of the given parent.
void removeAllProperties(UndoManager *undoManager)
Removes all properties from the tree.
void addListener(Listener *listener)
Adds a listener to receive callbacks when this tree is changed in some way.
void appendChild(const ValueTree &child, UndoManager *undoManager)
Appends a new child sub-tree to this tree.
int indexOf(const ValueTree &child) const noexcept
Returns the index of a child item in this parent.
bool operator==(const ValueTree &) const noexcept
Returns true if both this and the other tree refer to the same underlying structure.
ValueTree & setPropertyExcludingListener(Listener *listenerToExclude, const Identifier &name, const var &newValue, UndoManager *undoManager)
Changes a named property of the tree, but will not notify a specified listener of the change.
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
Adds a child to this tree.
ValueTree getParent() const noexcept
Returns the parent tree that contains this one.
const var & getProperty(const Identifier &name) const noexcept
Returns the value of a named property.
ValueTree() noexcept
Creates an empty, invalid ValueTree.
static ValueTree fromXml(const XmlElement &xml)
Tries to recreate a tree from its XML representation.
ValueTree createCopy() const
Returns a deep copy of this tree and all its sub-trees.
Identifier getType() const noexcept
Returns the type of this tree.
ValueTree getChildWithName(const Identifier &type) const
Returns the first sub-tree with the specified type name.
Iterator end() const noexcept
Returns an end iterator for the children in this tree.
ValueTree & operator=(const ValueTree &)
Changes this object to be a reference to the given tree.
void removeListener(Listener *listener)
Removes a listener that was previously added with addListener().
void writeToStream(OutputStream &output) const
Stores this tree (and all its children) in a binary format.
bool isEquivalentTo(const ValueTree &) const
Performs a deep comparison between the properties and children of two trees.
ValueTree getOrCreateChildWithName(const Identifier &type, UndoManager *undoManager)
Returns the first sub-tree with the specified type name, creating and adding a child with this name i...
void moveChild(int currentIndex, int newIndex, UndoManager *undoManager)
Moves one of the sub-trees to a different index.
void sendPropertyChangeMessage(const Identifier &property)
Causes a property-change callback to be triggered for the specified property, calling any listeners t...
void removeProperty(const Identifier &name, UndoManager *undoManager)
Removes a property from the tree.
const var & operator[](const Identifier &name) const noexcept
Returns the value of a named property.
ValueTree getSibling(int delta) const noexcept
Returns one of this tree's siblings in its parent's child list.
ValueTree getChildWithProperty(const Identifier &propertyName, const var &propertyValue) const
Looks for the first sub-tree that has the specified property value.
void copyPropertiesAndChildrenFrom(const ValueTree &source, UndoManager *undoManager)
Replaces all children and properties of this object with copies of those from the source object.
ValueTree getRoot() const noexcept
Recursively finds the highest-level parent tree that contains this one.
static ValueTree readFromData(const void *data, size_t numBytes)
Reloads a tree from a data block that was written with writeToStream().
bool hasProperty(const Identifier &name) const noexcept
Returns true if the tree contains a named property.
Used internally by the Value class as the base class for its shared value objects.
void sendChangeMessage(bool dispatchSynchronously)
Delivers a change message to all the listeners that are registered with this value.
Represents a shared variant value.
Used to build a tree of elements representing an XML document.
bool isTextElement() const noexcept
Returns true if this element is a section of text.
const String & getTagName() const noexcept
Returns this element's tag type name.
static bool isValidXmlName(StringRef possibleName) noexcept
Checks if a given string is a valid XML name.
A variant class, that can be used to hold a range of primitive values.
void writeToStream(OutputStream &output) const
Writes a binary representation of this value to a stream.
static var readFromStream(InputStream &input)
Reads back a stored binary representation of a value.
var getValue() const override
Returns the current value of this object.
void setValue(const var &newValue) override
Changes the current value.
Iterator for a ValueTree.
int getSizeInUnits() override
Returns a value to indicate how much memory this object takes up.
bool undo() override
Overridden by a subclass to undo the action.
bool perform() override
Overridden by a subclass to perform the action.
bool perform() override
Overridden by a subclass to perform the action.
UndoableAction * createCoalescedAction(UndoableAction *nextAction) override
Allows multiple actions to be coalesced into a single action object, to reduce storage space.
bool undo() override
Overridden by a subclass to undo the action.
int getSizeInUnits() override
Returns a value to indicate how much memory this object takes up.
bool undo() override
Overridden by a subclass to undo the action.
int getSizeInUnits() override
Returns a value to indicate how much memory this object takes up.
UndoableAction * createCoalescedAction(UndoableAction *nextAction) override
Allows multiple actions to be coalesced into a single action object, to reduce storage space.
bool perform() override
Overridden by a subclass to perform the action.
A struct containing options for formatting the text when representing an XML element as a string.