|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2020 - Raw Material Software Limited
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 6 End-User License
- Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
-
- End User License Agreement: www.juce.com/juce-6-licence
- Privacy Policy: www.juce.com/juce-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- namespace juce
- {
-
- //==============================================================================
- /**
- This class acts as a wrapper around a property inside a ValueTree.
-
- If the property inside the ValueTree is missing the ValueWithDefault will automatically
- return a default value, which can be specified when initialising the ValueWithDefault.
-
- @tags{DataStructures}
- */
- class ValueWithDefault
- {
- public:
- //==============================================================================
- /** Creates an unitialised ValueWithDefault. Initialise it using one of the referTo() methods. */
- ValueWithDefault() = default;
-
- /** Creates an ValueWithDefault object. The default value will be an empty var. */
- ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um)
- : targetTree (tree),
- targetProperty (propertyID),
- undoManager (um),
- defaultValue()
- {
- }
-
- /** Creates an ValueWithDefault object. The default value will be defaultToUse. */
- ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um,
- const var& defaultToUse)
- : targetTree (tree),
- targetProperty (propertyID),
- undoManager (um),
- defaultValue (defaultToUse)
- {
- }
-
- /** Creates an ValueWithDefault object. The default value will be defaultToUse.
-
- Use this constructor if the underlying var object being controlled is an array and
- it will handle the conversion to/from a delimited String that can be written to
- XML format.
- */
- ValueWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um,
- const var& defaultToUse, StringRef arrayDelimiter)
- : targetTree (tree),
- targetProperty (propertyID),
- undoManager (um),
- defaultValue (defaultToUse),
- delimiter (arrayDelimiter)
- {
- }
-
- /** Creates a ValueWithDefault object from another ValueWithDefault object. */
- ValueWithDefault (const ValueWithDefault& other)
- : targetTree (other.targetTree),
- targetProperty (other.targetProperty),
- undoManager (other.undoManager),
- defaultValue (other.defaultValue),
- delimiter (other.delimiter)
- {
- }
-
- //==============================================================================
- /** Returns the current value of the property. If the property does not exist this
- returns the default value.
- */
- var get() const noexcept
- {
- if (isUsingDefault())
- return defaultValue;
-
- if (delimiter.isNotEmpty())
- return delimitedStringToVarArray (targetTree[targetProperty].toString());
-
- return targetTree[targetProperty];
- }
-
- /** Returns the current property as a Value object. */
- Value getPropertyAsValue() { return targetTree.getPropertyAsValue (targetProperty, undoManager); }
-
- /** Returns the current default value. */
- var getDefault() const { return defaultValue; }
-
- /** Sets the default value to a new var. */
- void setDefault (const var& newDefault)
- {
- if (defaultValue != newDefault)
- {
- defaultValue = newDefault;
-
- if (onDefaultChange != nullptr)
- onDefaultChange();
- }
- }
-
- /** Returns true if the property does not exist in the referenced ValueTree. */
- bool isUsingDefault() const
- {
- return ! targetTree.hasProperty (targetProperty);
- }
-
- /** Removes the property from the referenced ValueTree. */
- void resetToDefault() noexcept
- {
- targetTree.removeProperty (targetProperty, nullptr);
- }
-
- /** You can assign a lambda to this callback object to have it called when the default value is changed. */
- std::function<void()> onDefaultChange;
-
- //==============================================================================
- /** Sets the property and returns the new ValueWithDefault. This will modify the property in the referenced ValueTree. */
- ValueWithDefault& operator= (const var& newValue)
- {
- setValue (newValue, undoManager);
- return *this;
- }
-
- /** Sets the property. This will actually modify the property in the referenced ValueTree. */
- void setValue (const var& newValue, UndoManager* undoManagerToUse)
- {
- if (auto* array = newValue.getArray())
- targetTree.setProperty (targetProperty, varArrayToDelimitedString (*array), undoManagerToUse);
- else
- targetTree.setProperty (targetProperty, newValue, undoManagerToUse);
- }
-
- //==============================================================================
- /** Makes the ValueWithDefault refer to the specified property inside the given ValueTree. */
- void referTo (ValueTree& tree, const Identifier& property, UndoManager* um)
- {
- referToWithDefault (tree, property, um, var(), {});
- }
-
- /** Makes the ValueWithDefault refer to the specified property inside the given ValueTree,
- and specifies a default value to use.
- */
- void referTo (ValueTree& tree, const Identifier& property, UndoManager* um, const var& defaultVal)
- {
- referToWithDefault (tree, property, um, defaultVal, {});
- }
-
- void referTo (ValueTree& tree, const Identifier& property, UndoManager* um,
- const var& defaultVal, StringRef arrayDelimiter)
- {
- referToWithDefault (tree, property, um, defaultVal, arrayDelimiter);
- }
-
- //==============================================================================
- /** Returns a reference to the ValueTree containing the referenced property. */
- ValueTree& getValueTree() noexcept { return targetTree; }
-
- /** Returns the property ID of the referenced property. */
- Identifier& getPropertyID() noexcept { return targetProperty; }
-
- /** Returns the UndoManager that is being used. */
- UndoManager* getUndoManager() noexcept { return undoManager; }
-
- //==============================================================================
- ValueWithDefault& operator= (const ValueWithDefault& other)
- {
- referToWithDefault (other.targetTree, other.targetProperty, other.undoManager,
- other.defaultValue, other.delimiter);
-
- return *this;
- }
-
- private:
- //==============================================================================
- ValueTree targetTree;
- Identifier targetProperty;
- UndoManager* undoManager = nullptr;
- var defaultValue;
-
- String delimiter;
-
- //==============================================================================
- void referToWithDefault (const ValueTree& v, const Identifier& i, UndoManager* um,
- const var& defaultVal, StringRef del)
- {
- targetTree = v;
- targetProperty = i;
- undoManager = um;
- defaultValue = defaultVal;
- delimiter = del;
- }
-
- //==============================================================================
- String varArrayToDelimitedString (const Array<var>& input) const noexcept
- {
- // if you are trying to control a var that is an array then you need to
- // set a delimiter string that will be used when writing to XML!
- jassert (delimiter.isNotEmpty());
-
- StringArray elements;
-
- for (auto& v : input)
- elements.add (v.toString());
-
- return elements.joinIntoString (delimiter);
- }
-
- Array<var> delimitedStringToVarArray (StringRef input) const noexcept
- {
- Array<var> arr;
-
- for (auto t : StringArray::fromTokens (input, delimiter, {}))
- arr.add (t);
-
- return arr;
- }
-
- //==============================================================================
- JUCE_DECLARE_WEAK_REFERENCEABLE (ValueWithDefault)
- };
-
- } // namespace juce
|