| @@ -104,21 +104,21 @@ ProjectInformationComponent::ProjectInformationComponent (Project& project_) | |||||
| configTabBox (TabbedButtonBar::TabsAtTop) | configTabBox (TabbedButtonBar::TabsAtTop) | ||||
| { | { | ||||
| addAndMakeVisible (&configTabBox); | addAndMakeVisible (&configTabBox); | ||||
| configTabBox.setBounds (RelativeRectangle ("8, 0, this.left + parent.right - 16, this.top + parent.bottom - 36")); | |||||
| configTabBox.setBounds (RelativeRectangle ("8, 0, this.left + parent.width - 16, this.top + parent.height - 36")); | |||||
| addAndMakeVisible (&editConfigsButton); | addAndMakeVisible (&editConfigsButton); | ||||
| editConfigsButton.setBounds (RelativeRectangle ("8, parent.bottom - 30, this.left + 192, this.top + 22")); | |||||
| editConfigsButton.setBounds (RelativeRectangle ("8, parent.height - 30, this.left + 192, this.top + 22")); | |||||
| editConfigsButton.setButtonText ("Add/Remove Configurations..."); | editConfigsButton.setButtonText ("Add/Remove Configurations..."); | ||||
| editConfigsButton.addListener (this); | editConfigsButton.addListener (this); | ||||
| addAndMakeVisible (&openProjectButton); | addAndMakeVisible (&openProjectButton); | ||||
| openProjectButton.setBounds (RelativeRectangle ("608, parent.bottom - 30, this.left + 208, this.top + 22")); | |||||
| openProjectButton.setBounds (RelativeRectangle ("608, parent.height - 30, this.left + 208, this.top + 22")); | |||||
| openProjectButton.setButtonText ("Open Project in "); | openProjectButton.setButtonText ("Open Project in "); | ||||
| openProjectButton.addListener (this); | openProjectButton.addListener (this); | ||||
| addAndMakeVisible (&editExportersButton); | addAndMakeVisible (&editExportersButton); | ||||
| editExportersButton.setBounds (RelativeRectangle ("208, parent.bottom - 30, this.left + 160, this.top + 22")); | |||||
| editExportersButton.setBounds (RelativeRectangle ("208, parent.height - 30, this.left + 160, this.top + 22")); | |||||
| editExportersButton.setButtonText ("Add/Remove Exporters..."); | editExportersButton.setButtonText ("Add/Remove Exporters..."); | ||||
| editExportersButton.addListener (this); | editExportersButton.addListener (this); | ||||
| addAndMakeVisible (&saveAndOpenButton); | addAndMakeVisible (&saveAndOpenButton); | ||||
| saveAndOpenButton.setBounds (RelativeRectangle ("391, parent.bottom - 30, this.left + 208, this.top + 22")); | |||||
| saveAndOpenButton.setBounds (RelativeRectangle ("391, parent.height - 30, this.left + 208, this.top + 22")); | |||||
| saveAndOpenButton.setButtonText ("Save And Open in"); | saveAndOpenButton.setButtonText ("Save And Open in"); | ||||
| saveAndOpenButton.addListener (this); | saveAndOpenButton.addListener (this); | ||||
| @@ -354,22 +354,22 @@ JUCER_COMPONENT_METADATA_START | |||||
| constructorParams="Project& project_" memberInitialisers="project (project_)"> | constructorParams="Project& project_" memberInitialisers="project (project_)"> | ||||
| <COMPONENTS> | <COMPONENTS> | ||||
| <TABBEDCOMPONENT id="962c1575c4142253" memberName="configTabBox" focusOrder="0" | <TABBEDCOMPONENT id="962c1575c4142253" memberName="configTabBox" focusOrder="0" | ||||
| position="8, 0, this.left + parent.right - 16, this.top + parent.bottom - 36"/> | |||||
| position="8, 0, this.left + parent.width - 16, this.top + parent.height - 36"/> | |||||
| <TEXTBUTTON id="b6625dfcdb1f4755" memberName="editConfigsButton" focusOrder="0" | <TEXTBUTTON id="b6625dfcdb1f4755" memberName="editConfigsButton" focusOrder="0" | ||||
| text="Add/Remove Configurations..." createCallback="1" radioGroup="0" | text="Add/Remove Configurations..." createCallback="1" radioGroup="0" | ||||
| connectedLeft="0" connectedRight="0" connectedTop="0" connectedBottom="0" | connectedLeft="0" connectedRight="0" connectedTop="0" connectedBottom="0" | ||||
| backgroundColour="" textColour="" backgroundColourOn="" textColourOn="" | backgroundColour="" textColour="" backgroundColourOn="" textColourOn="" | ||||
| position="8, parent.bottom - 30, this.left + 192, this.top + 22"/> | |||||
| position="8, parent.height - 30, this.left + 192, this.top + 22"/> | |||||
| <TEXTBUTTON id="a550a652e2666ee7" memberName="openProjectButton" focusOrder="0" | <TEXTBUTTON id="a550a652e2666ee7" memberName="openProjectButton" focusOrder="0" | ||||
| text="Open Project in " createCallback="1" radioGroup="0" connectedLeft="0" | text="Open Project in " createCallback="1" radioGroup="0" connectedLeft="0" | ||||
| connectedRight="0" connectedTop="0" connectedBottom="0" backgroundColour="" | connectedRight="0" connectedTop="0" connectedBottom="0" backgroundColour="" | ||||
| textColour="" backgroundColourOn="" textColourOn="" position="608, parent.bottom - 30, this.left + 208, this.top + 22"/> | |||||
| textColour="" backgroundColourOn="" textColourOn="" position="608, parent.height - 30, this.left + 208, this.top + 22"/> | |||||
| <TEXTBUTTON id="c1f6e5f9811b307e" memberName="editExportersButton" focusOrder="0" | <TEXTBUTTON id="c1f6e5f9811b307e" memberName="editExportersButton" focusOrder="0" | ||||
| text="Add/Remove Exporters..." createCallback="1" radioGroup="0" | text="Add/Remove Exporters..." createCallback="1" radioGroup="0" | ||||
| connectedLeft="0" connectedRight="0" connectedTop="0" connectedBottom="0" | connectedLeft="0" connectedRight="0" connectedTop="0" connectedBottom="0" | ||||
| backgroundColour="" textColour="" backgroundColourOn="" textColourOn="" | backgroundColour="" textColour="" backgroundColourOn="" textColourOn="" | ||||
| position="208, parent.bottom - 30, this.left + 160, this.top + 22"/> | |||||
| <TEXTBUTTON id="dRGMyYx" name="" memberName="saveAndOpenButton" position="391, parent.bottom - 30, this.left + 208, this.top + 22" | |||||
| position="208, parent.height - 30, this.left + 160, this.top + 22"/> | |||||
| <TEXTBUTTON id="dRGMyYx" name="" memberName="saveAndOpenButton" position="391, parent.height - 30, this.left + 208, this.top + 22" | |||||
| text="Save And Open in" createCallback="1" radioGroup="0" connectedLeft="0" | text="Save And Open in" createCallback="1" radioGroup="0" connectedLeft="0" | ||||
| connectedRight="0" connectedTop="0" connectedBottom="0"/> | connectedRight="0" connectedTop="0" connectedBottom="0"/> | ||||
| </COMPONENTS> | </COMPONENTS> | ||||
| @@ -112,6 +112,7 @@ namespace Ids | |||||
| DECLARE_ID (tooltip); | DECLARE_ID (tooltip); | ||||
| DECLARE_ID (memberName); | DECLARE_ID (memberName); | ||||
| DECLARE_ID (focusOrder); | DECLARE_ID (focusOrder); | ||||
| DECLARE_ID (hidden); | |||||
| const Identifier class_ ("class"); | const Identifier class_ ("class"); | ||||
| const Identifier id_ ("id"); | const Identifier id_ ("id"); | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 14 | |||||
| #define JUCE_BUILDNUMBER 15 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -17817,7 +17817,7 @@ private: | |||||
| evaluated. | evaluated. | ||||
| Expressions which use identifiers and functions require a subclass of | Expressions which use identifiers and functions require a subclass of | ||||
| Expression::EvaluationContext to be supplied when evaluating them, and this object | |||||
| Expression::Scope to be supplied when evaluating them, and this object | |||||
| is expected to be able to resolve the symbol names and perform the functions that | is expected to be able to resolve the symbol names and perform the functions that | ||||
| are used. | are used. | ||||
| */ | */ | ||||
| @@ -17879,11 +17879,14 @@ public: | |||||
| /** When evaluating an Expression object, this class is used to resolve symbols and | /** When evaluating an Expression object, this class is used to resolve symbols and | ||||
| perform functions that the expression uses. | perform functions that the expression uses. | ||||
| */ | */ | ||||
| class JUCE_API EvaluationContext | |||||
| class JUCE_API Scope | |||||
| { | { | ||||
| public: | public: | ||||
| EvaluationContext(); | |||||
| virtual ~EvaluationContext(); | |||||
| Scope(); | |||||
| virtual ~Scope(); | |||||
| /** Returns some kind of globally unique ID that identifies this scope. */ | |||||
| virtual const String getScopeUID() const; | |||||
| /** Returns the value of a symbol. | /** Returns the value of a symbol. | ||||
| If the symbol is unknown, this can throw an Expression::EvaluationError exception. | If the symbol is unknown, this can throw an Expression::EvaluationError exception. | ||||
| @@ -17891,55 +17894,97 @@ public: | |||||
| one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| virtual const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
| virtual const Expression getSymbolValue (const String& symbol) const; | |||||
| /** Executes a named function. | /** Executes a named function. | ||||
| If the function name is unknown, this can throw an Expression::EvaluationError exception. | If the function name is unknown, this can throw an Expression::EvaluationError exception. | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| virtual double evaluateFunction (const String& functionName, const double* parameters, int numParams) const; | |||||
| virtual double evaluateFunction (const String& functionName, | |||||
| const double* parameters, int numParameters) const; | |||||
| /** Used as a callback by the Scope::visitRelativeScope() method. | |||||
| You should never create an instance of this class yourself, it's used by the | |||||
| expression evaluation code. | |||||
| */ | |||||
| class Visitor | |||||
| { | |||||
| public: | |||||
| virtual ~Visitor() {} | |||||
| virtual void visit (const Scope&) = 0; | |||||
| }; | |||||
| /** Creates a Scope object for a named scope, and then calls a visitor | |||||
| to do some kind of processing with this new scope. | |||||
| If the name is valid, this method must create a suitable (temporary) Scope | |||||
| object to represent it, and must call the Visitor::visit() method with this | |||||
| new scope. | |||||
| */ | |||||
| virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const; | |||||
| }; | }; | ||||
| /** Evaluates this expression, without using an EvaluationContext. | |||||
| Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | |||||
| /** Evaluates this expression, without using a Scope. | |||||
| Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan, | |||||
| min, max are available. | min, max are available. | ||||
| @throws Expression::EvaluationError | |||||
| To find out about any errors during evaluation, use the other version of this method which | |||||
| takes a String parameter. | |||||
| */ | */ | ||||
| double evaluate() const; | double evaluate() const; | ||||
| /** Evaluates this expression, providing a context that should be able to evaluate any symbols | |||||
| /** Evaluates this expression, providing a scope that should be able to evaluate any symbols | |||||
| or functions that it uses. | |||||
| To find out about any errors during evaluation, use the other version of this method which | |||||
| takes a String parameter. | |||||
| */ | |||||
| double evaluate (const Scope& scope) const; | |||||
| /** Evaluates this expression, providing a scope that should be able to evaluate any symbols | |||||
| or functions that it uses. | or functions that it uses. | ||||
| @throws Expression::EvaluationError | |||||
| */ | */ | ||||
| double evaluate (const EvaluationContext& context) const; | |||||
| double evaluate (const Scope& scope, String& evaluationError) const; | |||||
| /** Attempts to return an expression which is a copy of this one, but with a constant adjusted | /** Attempts to return an expression which is a copy of this one, but with a constant adjusted | ||||
| to make the expression resolve to a target value. | to make the expression resolve to a target value. | ||||
| E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | ||||
| the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | ||||
| case they might just be adjusted by adding a constant to them. | |||||
| case they might just be adjusted by adding a constant to the original expression. | |||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | |||||
| const Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const; | |||||
| /** Represents a symbol that is used in an Expression. */ | |||||
| struct Symbol | |||||
| { | |||||
| Symbol (const String& scopeUID, const String& symbolName); | |||||
| bool operator== (const Symbol&) const throw(); | |||||
| bool operator!= (const Symbol&) const throw(); | |||||
| String scopeUID; /**< The unique ID of the Scope that contains this symbol. */ | |||||
| String symbolName; /**< The name of the symbol. */ | |||||
| }; | |||||
| /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ | /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ | ||||
| const Expression withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const; | |||||
| const Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const; | |||||
| /** Returns true if this expression makes use of the specified symbol. | /** Returns true if this expression makes use of the specified symbol. | ||||
| If a suitable context is supplied, the search will dereference and recursively check | |||||
| If a suitable scope is supplied, the search will dereference and recursively check | |||||
| all symbols, so that it can be determined whether this expression relies on the given | all symbols, so that it can be determined whether this expression relies on the given | ||||
| symbol at any level in its evaluation. If the context parameter is null, this just checks | |||||
| symbol at any level in its evaluation. If the scope parameter is null, this just checks | |||||
| whether the expression contains any direct references to the symbol. | whether the expression contains any direct references to the symbol. | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| bool referencesSymbol (const String& symbol, const EvaluationContext* context) const; | |||||
| bool referencesSymbol (const Symbol& symbol, const Scope& scope) const; | |||||
| /** Returns true if this expression contains any symbols. */ | /** Returns true if this expression contains any symbols. */ | ||||
| bool usesAnySymbols() const; | bool usesAnySymbols() const; | ||||
| /** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */ | |||||
| void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const; | |||||
| /** An exception that can be thrown by Expression::parse(). */ | /** An exception that can be thrown by Expression::parse(). */ | ||||
| class ParseError : public std::exception | class ParseError : public std::exception | ||||
| { | { | ||||
| @@ -17949,16 +17994,6 @@ public: | |||||
| String description; | String description; | ||||
| }; | }; | ||||
| /** An exception that can be thrown by Expression::evaluate(). */ | |||||
| class EvaluationError : public std::exception | |||||
| { | |||||
| public: | |||||
| EvaluationError (const String& message); | |||||
| EvaluationError (const String& symbolName, const String& memberName); | |||||
| String description; | |||||
| }; | |||||
| /** Expression type. | /** Expression type. | ||||
| @see Expression::getType() | @see Expression::getType() | ||||
| */ | */ | ||||
| @@ -17973,19 +18008,8 @@ public: | |||||
| /** Returns the type of this expression. */ | /** Returns the type of this expression. */ | ||||
| Type getType() const throw(); | Type getType() const throw(); | ||||
| /** If this expression is a symbol, this returns its full name. */ | |||||
| const String getSymbol() const; | |||||
| /** For a symbol that contains a dot, this returns the two */ | |||||
| void getSymbolParts (String& objectName, String& memberName) const; | |||||
| /** If this expression is a function, this returns its name. */ | |||||
| const String getFunction() const; | |||||
| /** If this expression is an operator, this returns its name. | |||||
| E.g. "+", "-", "*", "/", etc. | |||||
| */ | |||||
| const String getOperator() const; | |||||
| /** If this expression is a symbol, function or operator, this returns its identifier. */ | |||||
| const String getSymbolOrFunction() const; | |||||
| /** Returns the number of inputs to this expression. | /** Returns the number of inputs to this expression. | ||||
| @see getInput | @see getInput | ||||
| @@ -17999,35 +18023,12 @@ public: | |||||
| private: | private: | ||||
| class Term; | |||||
| class Helpers; | class Helpers; | ||||
| friend class Term; | |||||
| friend class Helpers; | friend class Helpers; | ||||
| class Term : public ReferenceCountedObject | |||||
| { | |||||
| public: | |||||
| Term() {} | |||||
| virtual ~Term() {} | |||||
| virtual Term* clone() const = 0; | |||||
| virtual double evaluate (const EvaluationContext&, int recursionDepth) const = 0; | |||||
| virtual int getNumInputs() const = 0; | |||||
| virtual Term* getInput (int index) const = 0; | |||||
| virtual int getInputIndexFor (const Term* possibleInput) const; | |||||
| virtual const String toString() const = 0; | |||||
| virtual int getOperatorPrecedence() const; | |||||
| virtual bool referencesSymbol (const String& symbol, const EvaluationContext*, int recursionDepth) const; | |||||
| virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | |||||
| double overallTarget, Term* topLevelTerm) const; | |||||
| virtual const ReferenceCountedObjectPtr<Term> negated(); | |||||
| virtual Type getType() const throw() = 0; | |||||
| virtual void getSymbolParts (String& objectName, String& memberName) const; | |||||
| virtual const String getFunctionName() const; | |||||
| private: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Term); | |||||
| }; | |||||
| friend class ScopedPointer<Term>; | friend class ScopedPointer<Term>; | ||||
| friend class ReferenceCountedObjectPtr<Term>; | |||||
| ReferenceCountedObjectPtr<Term> term; | ReferenceCountedObjectPtr<Term> term; | ||||
| explicit Expression (Term* term); | explicit Expression (Term* term); | ||||
| @@ -27477,35 +27478,35 @@ public: | |||||
| for more details. | for more details. | ||||
| When using relative expressions, the following symbols are available: | When using relative expressions, the following symbols are available: | ||||
| - "this.left", "this.right", "this.top", "this.bottom" refer to the position of those | |||||
| edges in this component, so e.g. for a component whose width is always 100, you might | |||||
| set the right edge to the "this.left + 100". | |||||
| - "parent.left", "parent.right", "parent.top", "parent.bottom" refer to the parent component's | |||||
| positions, in its own coordinate space, so "parent.left", "parent.right" are always 0, and | |||||
| "parent.top", "parent.bottom" will actually be the width and height of the parent. So | |||||
| for example to make your component's right-hand edge always 10 pixels away from its parent's | |||||
| right-hand edge, you could set it to "parent.right - 10" | |||||
| - "[id].left", "[id].right", "[id].top", "[id].bottom", where [id] is the identifier of one of | |||||
| this component's siblings. A component's identifier is set with Component::setComponentID(). | |||||
| So for example if you want your component to always be 50 pixels to the right of the one | |||||
| called "xyz", you could set your left edge to be "xyz.right + 50" | |||||
| - The name of a marker that is defined in the parent component. For markers to be used, the parent | |||||
| component must implement its Component::getMarkers() method, and return at least one | |||||
| - "left", "right", "top", "bottom" refer to the position of those edges in this component, so | |||||
| e.g. for a component whose width is always 100, you might set the right edge to the "left + 100". | |||||
| - "[id].left", "[id].right", "[id].top", "[id].bottom", "[id].width", "[id].height", where [id] is | |||||
| the identifier of one of this component's siblings. A component's identifier is set with | |||||
| Component::setComponentID(). So for example if you want your component to always be 50 pixels to the | |||||
| right of the one called "xyz", you could set your left edge to be "xyz.right + 50". | |||||
| - Instead of an [id], you can use the name "parent" to refer to this component's parent. Like | |||||
| any other component, these values are relative to their component's parent, so "parent.right" won't be | |||||
| very useful for positioning a component because it refers to a position with the parent's parent.. but | |||||
| "parent.width" can be used for setting positions relative to the parent's size. E.g. to make a 10x10 | |||||
| component which remains 1 pixel away from its parent's bottom-right, you could use | |||||
| "right - 10, bottom - 10, parent.width - 1, parent.height - 1". | |||||
| - The name of one of the parent component's markers can also be used as a symbol. For markers to be | |||||
| used, the parent component must implement its Component::getMarkers() method, and return at least one | |||||
| valid MarkerList. So if you want your component's top edge to be 10 pixels below the | valid MarkerList. So if you want your component's top edge to be 10 pixels below the | ||||
| marker called "foobar", you'd set it to "foobar + 10". | marker called "foobar", you'd set it to "foobar + 10". | ||||
| See the Expression class for details about the operators that are supported, but for example | See the Expression class for details about the operators that are supported, but for example | ||||
| if you wanted to make your component remain centred within its parent with a size of 100, 100, | if you wanted to make your component remain centred within its parent with a size of 100, 100, | ||||
| you could express it as: | you could express it as: | ||||
| @code myComp.setBounds (RelativeBounds ("parent.right / 2 - 50, parent.bottom / 2 - 50, this.left + 100, this.top + 100")); | |||||
| @code myComp.setBounds (RelativeBounds ("parent.width / 2 - 50, parent.height / 2 - 50, left + 100, top + 100")); | |||||
| @endcode | @endcode | ||||
| ..or an alternative way to achieve the same thing: | ..or an alternative way to achieve the same thing: | ||||
| @code myComp.setBounds (RelativeBounds ("this.right - 100, this.bottom - 100, parent.right / 2 + 50, parent.bottom / 2 + 50")); | |||||
| @code myComp.setBounds (RelativeBounds ("right - 100, bottom - 100, parent.width / 2 + 50, parent.height / 2 + 50")); | |||||
| @endcode | @endcode | ||||
| Or if you wanted a 100x100 component whose top edge is lined up to a marker called "topMarker" and | Or if you wanted a 100x100 component whose top edge is lined up to a marker called "topMarker" and | ||||
| which is positioned 50 pixels to the right of another component called "otherComp", you could write: | which is positioned 50 pixels to the right of another component called "otherComp", you could write: | ||||
| @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, this.left + 100, this.top + 100")); | |||||
| @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, left + 100, top + 100")); | |||||
| @endcode | @endcode | ||||
| Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will | Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will | ||||
| @@ -43481,7 +43482,6 @@ public: | |||||
| AudioProcessorGraph(); | AudioProcessorGraph(); | ||||
| /** Destructor. | /** Destructor. | ||||
| Any processor objects that have been added to the graph will also be deleted. | Any processor objects that have been added to the graph will also be deleted. | ||||
| */ | */ | ||||
| ~AudioProcessorGraph(); | ~AudioProcessorGraph(); | ||||
| @@ -43493,9 +43493,6 @@ public: | |||||
| class JUCE_API Node : public ReferenceCountedObject | class JUCE_API Node : public ReferenceCountedObject | ||||
| { | { | ||||
| public: | public: | ||||
| /** Destructor. | |||||
| */ | |||||
| ~Node(); | |||||
| /** The ID number assigned to this node. | /** The ID number assigned to this node. | ||||
| @@ -45643,18 +45640,18 @@ public: | |||||
| /** Calculates the absolute position of this coordinate. | /** Calculates the absolute position of this coordinate. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| double resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| double resolve (const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | ||||
| This will recursively check any coordinates upon which this one depends. | This will recursively check any coordinates upon which this one depends. | ||||
| */ | */ | ||||
| bool references (const String& coordName, const Expression::EvaluationContext* evaluationContext) const; | |||||
| bool references (const String& coordName, const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | ||||
| bool isRecursive (const Expression::EvaluationContext* evaluationContext) const; | |||||
| bool isRecursive (const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if this coordinate depends on any other coordinates for its position. */ | /** Returns true if this coordinate depends on any other coordinates for its position. */ | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| @@ -45665,10 +45662,7 @@ public: | |||||
| or relative position to whatever value is necessary to make its resultant position | or relative position to whatever value is necessary to make its resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (double absoluteTargetPosition, const Expression::EvaluationContext* evaluationContext); | |||||
| /** Changes the name of a symbol if it is used as part of the coordinate's expression. */ | |||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| void moveToAbsolute (double absoluteTargetPosition, const Expression::Scope* evaluationScope); | |||||
| /** Returns the expression that defines this coordinate. */ | /** Returns the expression that defines this coordinate. */ | ||||
| const Expression& getExpression() const { return term; } | const Expression& getExpression() const { return term; } | ||||
| @@ -45688,15 +45682,27 @@ public: | |||||
| struct Strings | struct Strings | ||||
| { | { | ||||
| static const String parent; /**< "parent" */ | static const String parent; /**< "parent" */ | ||||
| static const String this_; /**< "this" */ | |||||
| static const String left; /**< "left" */ | static const String left; /**< "left" */ | ||||
| static const String right; /**< "right" */ | static const String right; /**< "right" */ | ||||
| static const String top; /**< "top" */ | static const String top; /**< "top" */ | ||||
| static const String bottom; /**< "bottom" */ | static const String bottom; /**< "bottom" */ | ||||
| static const String parentLeft; /**< "parent.left" */ | |||||
| static const String parentTop; /**< "parent.top" */ | |||||
| static const String parentRight; /**< "parent.right" */ | |||||
| static const String parentBottom; /**< "parent.bottom" */ | |||||
| static const String x; /**< "x" */ | |||||
| static const String y; /**< "y" */ | |||||
| static const String width; /**< "width" */ | |||||
| static const String height; /**< "height" */ | |||||
| }; | |||||
| struct StandardStrings | |||||
| { | |||||
| enum Type | |||||
| { | |||||
| left, right, top, bottom, | |||||
| x, y, width, height, | |||||
| parent, | |||||
| unknown | |||||
| }; | |||||
| static Type getTypeOf (const String& s) throw(); | |||||
| }; | }; | ||||
| private: | private: | ||||
| @@ -45749,10 +45755,10 @@ public: | |||||
| /** Calculates the absolute position of this point. | /** Calculates the absolute position of this point. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| const Point<float> resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| const Point<float> resolve (const Expression::Scope* evaluationContext) const; | |||||
| /** Changes the values of this point's coordinates to make it resolve to the specified position. | /** Changes the values of this point's coordinates to make it resolve to the specified position. | ||||
| @@ -45760,7 +45766,7 @@ public: | |||||
| or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (const Point<float>& newPos, const Expression::EvaluationContext* evaluationContext); | |||||
| void moveToAbsolute (const Point<float>& newPos, const Expression::Scope* evaluationContext); | |||||
| /** Returns a string which represents this point. | /** Returns a string which represents this point. | ||||
| This returns a comma-separated pair of coordinates. For details of the string syntax used by the | This returns a comma-separated pair of coordinates. For details of the string syntax used by the | ||||
| @@ -45769,11 +45775,6 @@ public: | |||||
| */ | */ | ||||
| const String toString() const; | const String toString() const; | ||||
| /** Renames a symbol if it is used by any of the coordinates. | |||||
| This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. | |||||
| */ | |||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| /** Returns true if this point depends on any other coordinates for its position. */ | /** Returns true if this point depends on any other coordinates for its position. */ | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| @@ -45946,15 +45947,12 @@ private: | |||||
| */ | */ | ||||
| class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner, | class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner, | ||||
| public ComponentListener, | public ComponentListener, | ||||
| public MarkerList::Listener, | |||||
| public Expression::EvaluationContext | |||||
| public MarkerList::Listener | |||||
| { | { | ||||
| public: | public: | ||||
| RelativeCoordinatePositionerBase (Component& component_); | RelativeCoordinatePositionerBase (Component& component_); | ||||
| ~RelativeCoordinatePositionerBase(); | ~RelativeCoordinatePositionerBase(); | ||||
| const Expression getSymbolValue (const String& objectName, const String& member) const; | |||||
| void componentMovedOrResized (Component&, bool, bool); | void componentMovedOrResized (Component&, bool, bool); | ||||
| void componentParentHierarchyChanged (Component&); | void componentParentHierarchyChanged (Component&); | ||||
| void componentBeingDeleted (Component& component); | void componentBeingDeleted (Component& component); | ||||
| @@ -45966,25 +45964,40 @@ public: | |||||
| bool addCoordinate (const RelativeCoordinate& coord); | bool addCoordinate (const RelativeCoordinate& coord); | ||||
| bool addPoint (const RelativePoint& point); | bool addPoint (const RelativePoint& point); | ||||
| /** Used for resolving a RelativeCoordinate expression in the context of a component. */ | |||||
| class ComponentScope : public Expression::Scope | |||||
| { | |||||
| public: | |||||
| ComponentScope (Component& component_); | |||||
| const Expression getSymbolValue (const String& symbol) const; | |||||
| void visitRelativeScope (const String& scopeName, Visitor& visitor) const; | |||||
| const String getScopeUID() const; | |||||
| protected: | |||||
| Component& component; | |||||
| Component* findSiblingComponent (const String& componentID) const; | |||||
| const MarkerList::Marker* findMarker (const String& name, MarkerList*& list) const; | |||||
| private: | |||||
| JUCE_DECLARE_NON_COPYABLE (ComponentScope); | |||||
| }; | |||||
| protected: | protected: | ||||
| virtual bool registerCoordinates() = 0; | virtual bool registerCoordinates() = 0; | ||||
| virtual void applyToComponentBounds() = 0; | virtual void applyToComponentBounds() = 0; | ||||
| private: | private: | ||||
| class DependencyFinderScope; | |||||
| friend class DependencyFinderScope; | |||||
| Array <Component*> sourceComponents; | Array <Component*> sourceComponents; | ||||
| Array <MarkerList*> sourceMarkerLists; | Array <MarkerList*> sourceMarkerLists; | ||||
| bool registeredOk; | bool registeredOk; | ||||
| bool registerListeners (const Expression& e); | |||||
| bool registerComponent (const String& componentID); | |||||
| bool registerMarker (const String markerName); | |||||
| void registerComponentListener (Component* const comp); | |||||
| void registerComponentListener (Component& comp); | |||||
| void registerMarkerListListener (MarkerList* const list); | void registerMarkerListListener (MarkerList* const list); | ||||
| void unregisterListeners(); | void unregisterListeners(); | ||||
| Component* findComponent (const String& componentID) const; | |||||
| Component* getSourceComponent (const String& objectName) const; | |||||
| const Expression xToExpression (const Component* const source, const int x) const; | |||||
| const Expression yToExpression (const Component* const source, const int y) const; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase); | ||||
| }; | }; | ||||
| @@ -46395,7 +46408,11 @@ protected: | |||||
| {} | {} | ||||
| bool registerCoordinates() { return owner.registerCoordinates (*this); } | bool registerCoordinates() { return owner.registerCoordinates (*this); } | ||||
| void applyToComponentBounds() { owner.recalculateCoordinates (this); } | |||||
| void applyToComponentBounds() | |||||
| { | |||||
| ComponentScope scope (getComponent()); | |||||
| owner.recalculateCoordinates (&scope); | |||||
| } | |||||
| private: | private: | ||||
| DrawableType& owner; | DrawableType& owner; | ||||
| @@ -57857,11 +57874,11 @@ public: | |||||
| RelativeParallelogram (const String& topLeft, const String& topRight, const String& bottomLeft); | RelativeParallelogram (const String& topLeft, const String& topRight, const String& bottomLeft); | ||||
| ~RelativeParallelogram(); | ~RelativeParallelogram(); | ||||
| void resolveThreePoints (Point<float>* points, Expression::EvaluationContext* coordFinder) const; | |||||
| void resolveFourCorners (Point<float>* points, Expression::EvaluationContext* coordFinder) const; | |||||
| const Rectangle<float> getBounds (Expression::EvaluationContext* coordFinder) const; | |||||
| void getPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| const AffineTransform resetToPerpendicular (Expression::EvaluationContext* coordFinder); | |||||
| void resolveThreePoints (Point<float>* points, Expression::Scope* scope) const; | |||||
| void resolveFourCorners (Point<float>* points, Expression::Scope* scope) const; | |||||
| const Rectangle<float> getBounds (Expression::Scope* scope) const; | |||||
| void getPath (Path& path, Expression::Scope* scope) const; | |||||
| const AffineTransform resetToPerpendicular (Expression::Scope* scope); | |||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| bool operator== (const RelativeParallelogram& other) const throw(); | bool operator== (const RelativeParallelogram& other) const throw(); | ||||
| @@ -57911,7 +57928,7 @@ public: | |||||
| bool operator!= (const RelativePointPath& other) const throw(); | bool operator!= (const RelativePointPath& other) const throw(); | ||||
| /** Resolves this points in this path and adds them to a normal Path object. */ | /** Resolves this points in this path and adds them to a normal Path object. */ | ||||
| void createPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void createPath (Path& path, Expression::Scope* scope) const; | |||||
| /** Returns true if the path contains any non-fixed points. */ | /** Returns true if the path contains any non-fixed points. */ | ||||
| bool containsAnyDynamicPoints() const; | bool containsAnyDynamicPoints() const; | ||||
| @@ -57940,7 +57957,7 @@ public: | |||||
| ElementBase (ElementType type); | ElementBase (ElementType type); | ||||
| virtual ~ElementBase() {} | virtual ~ElementBase() {} | ||||
| virtual const ValueTree createTree() const = 0; | virtual const ValueTree createTree() const = 0; | ||||
| virtual void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const = 0; | |||||
| virtual void addToPath (Path& path, Expression::Scope*) const = 0; | |||||
| virtual RelativePoint* getControlPoints (int& numPoints) = 0; | virtual RelativePoint* getControlPoints (int& numPoints) = 0; | ||||
| virtual ElementBase* clone() const = 0; | virtual ElementBase* clone() const = 0; | ||||
| bool isDynamic(); | bool isDynamic(); | ||||
| @@ -57956,7 +57973,7 @@ public: | |||||
| public: | public: | ||||
| StartSubPath (const RelativePoint& pos); | StartSubPath (const RelativePoint& pos); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -57971,7 +57988,7 @@ public: | |||||
| public: | public: | ||||
| CloseSubPath(); | CloseSubPath(); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -57984,7 +58001,7 @@ public: | |||||
| public: | public: | ||||
| LineTo (const RelativePoint& endPoint); | LineTo (const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -57999,7 +58016,7 @@ public: | |||||
| public: | public: | ||||
| QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); | QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -58014,7 +58031,7 @@ public: | |||||
| public: | public: | ||||
| CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); | CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -58087,10 +58104,10 @@ public: | |||||
| /** Calculates the absolute position of this rectangle. | /** Calculates the absolute position of this rectangle. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| const Rectangle<float> resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| const Rectangle<float> resolve (const Expression::Scope* scope) const; | |||||
| /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | ||||
| @@ -58098,7 +58115,7 @@ public: | |||||
| or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (const Rectangle<float>& newPos, const Expression::EvaluationContext* evaluationContext); | |||||
| void moveToAbsolute (const Rectangle<float>& newPos, const Expression::Scope* scope); | |||||
| /** Returns true if this rectangle depends on any external symbols for its position. | /** Returns true if this rectangle depends on any external symbols for its position. | ||||
| Coordinates that refer to symbols based on "this" are assumed not to be dynamic. | Coordinates that refer to symbols based on "this" are assumed not to be dynamic. | ||||
| @@ -58113,9 +58130,9 @@ public: | |||||
| const String toString() const; | const String toString() const; | ||||
| /** Renames a symbol if it is used by any of the coordinates. | /** Renames a symbol if it is used by any of the coordinates. | ||||
| This calls RelativeCoordinate::renameSymbolIfUsed() on the rectangle's coordinates. | |||||
| This calls Expression::withRenamedSymbol() on the rectangle's coordinates. | |||||
| */ | */ | ||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| void renameSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Expression::Scope& scope); | |||||
| /** Creates and sets an appropriate Component::Positioner object for the given component, which will | /** Creates and sets an appropriate Component::Positioner object for the given component, which will | ||||
| keep it positioned with this rectangle. | keep it positioned with this rectangle. | ||||
| @@ -61907,7 +61924,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableComposite>; | friend class Drawable::Positioner<DrawableComposite>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| void updateBoundsToFitChildren(); | void updateBoundsToFitChildren(); | ||||
| @@ -62024,7 +62041,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableImage>; | friend class Drawable::Positioner<DrawableImage>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| DrawableImage& operator= (const DrawableImage&); | DrawableImage& operator= (const DrawableImage&); | ||||
| JUCE_LEAK_DETECTOR (DrawableImage); | JUCE_LEAK_DETECTOR (DrawableImage); | ||||
| @@ -62077,7 +62094,7 @@ public: | |||||
| bool operator!= (const RelativeFillType&) const; | bool operator!= (const RelativeFillType&) const; | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| bool recalculateCoords (Expression::EvaluationContext* context); | |||||
| bool recalculateCoords (Expression::Scope* scope); | |||||
| void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; | void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; | ||||
| bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); | bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); | ||||
| @@ -62260,7 +62277,7 @@ public: | |||||
| const RelativePoint getStartPoint() const; | const RelativePoint getStartPoint() const; | ||||
| const RelativePoint getEndPoint() const; | const RelativePoint getEndPoint() const; | ||||
| void setControlPoint (int index, const RelativePoint& point, UndoManager*); | void setControlPoint (int index, const RelativePoint& point, UndoManager*); | ||||
| float getLength (Expression::EvaluationContext*) const; | |||||
| float getLength (Expression::Scope*) const; | |||||
| ValueTreeWrapper getParent() const; | ValueTreeWrapper getParent() const; | ||||
| Element getPreviousElement() const; | Element getPreviousElement() const; | ||||
| @@ -62269,11 +62286,11 @@ public: | |||||
| void setModeOfEndPoint (const String& newMode, UndoManager*); | void setModeOfEndPoint (const String& newMode, UndoManager*); | ||||
| void convertToLine (UndoManager*); | void convertToLine (UndoManager*); | ||||
| void convertToCubic (Expression::EvaluationContext*, UndoManager*); | |||||
| void convertToCubic (Expression::Scope*, UndoManager*); | |||||
| void convertToPathBreak (UndoManager* undoManager); | void convertToPathBreak (UndoManager* undoManager); | ||||
| ValueTree insertPoint (const Point<float>& targetPoint, Expression::EvaluationContext*, UndoManager*); | |||||
| ValueTree insertPoint (const Point<float>& targetPoint, Expression::Scope*, UndoManager*); | |||||
| void removePoint (UndoManager* undoManager); | void removePoint (UndoManager* undoManager); | ||||
| float findProportionAlongLine (const Point<float>& targetPoint, Expression::EvaluationContext*) const; | |||||
| float findProportionAlongLine (const Point<float>& targetPoint, Expression::Scope*) const; | |||||
| static const Identifier mode, startSubPathElement, closeSubPathElement, | static const Identifier mode, startSubPathElement, closeSubPathElement, | ||||
| lineToElement, quadraticToElement, cubicToElement; | lineToElement, quadraticToElement, cubicToElement; | ||||
| @@ -62298,7 +62315,7 @@ private: | |||||
| class RelativePositioner; | class RelativePositioner; | ||||
| friend class RelativePositioner; | friend class RelativePositioner; | ||||
| void applyRelativePath (const RelativePointPath&, Expression::EvaluationContext*); | |||||
| void applyRelativePath (const RelativePointPath&, Expression::Scope*); | |||||
| DrawablePath& operator= (const DrawablePath&); | DrawablePath& operator= (const DrawablePath&); | ||||
| JUCE_LEAK_DETECTOR (DrawablePath); | JUCE_LEAK_DETECTOR (DrawablePath); | ||||
| @@ -62377,7 +62394,7 @@ private: | |||||
| void rebuildPath(); | void rebuildPath(); | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| DrawableRectangle& operator= (const DrawableRectangle&); | DrawableRectangle& operator= (const DrawableRectangle&); | ||||
| JUCE_LEAK_DETECTOR (DrawableRectangle); | JUCE_LEAK_DETECTOR (DrawableRectangle); | ||||
| @@ -62503,7 +62520,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableText>; | friend class Drawable::Positioner<DrawableText>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| void refreshBounds(); | void refreshBounds(); | ||||
| const AffineTransform getArrangementAndTransform (GlyphArrangement& glyphs) const; | const AffineTransform getArrangementAndTransform (GlyphArrangement& glyphs) const; | ||||
| @@ -370,10 +370,6 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| ~WavAudioFormatReader() | |||||
| { | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | ||||
| int64 startSampleInFile, int numSamples) | int64 startSampleInFile, int numSamples) | ||||
| @@ -532,7 +528,8 @@ private: | |||||
| const int bytesPerFrame = numChannels * bitsPerSample / 8; | const int bytesPerFrame = numChannels * bitsPerSample / 8; | ||||
| output->writeInt (chunkName ("RIFF")); | output->writeInt (chunkName ("RIFF")); | ||||
| output->writeInt ((int) (lengthInSamples * bytesPerFrame | output->writeInt ((int) (lengthInSamples * bytesPerFrame | ||||
| + ((bwavChunk.getSize() > 0) ? (44 + bwavChunk.getSize()) : 36))); | |||||
| + ((bwavChunk.getSize() > 0) ? (44 + bwavChunk.getSize()) : 36) | |||||
| + (smplChunk.getSize() > 0 ? smplChunk.getSize() + 8 : 0))); | |||||
| output->writeInt (chunkName ("WAVE")); | output->writeInt (chunkName ("WAVE")); | ||||
| output->writeInt (chunkName ("fmt ")); | output->writeInt (chunkName ("fmt ")); | ||||
| @@ -42,10 +42,6 @@ AudioProcessorGraph::Node::Node (const uint32 id_, AudioProcessor* const process | |||||
| jassert (processor_ != 0); | jassert (processor_ != 0); | ||||
| } | } | ||||
| AudioProcessorGraph::Node::~Node() | |||||
| { | |||||
| } | |||||
| void AudioProcessorGraph::Node::prepare (const double sampleRate, const int blockSize, | void AudioProcessorGraph::Node::prepare (const double sampleRate, const int blockSize, | ||||
| AudioProcessorGraph* const graph) | AudioProcessorGraph* const graph) | ||||
| { | { | ||||
| @@ -57,7 +57,6 @@ public: | |||||
| AudioProcessorGraph(); | AudioProcessorGraph(); | ||||
| /** Destructor. | /** Destructor. | ||||
| Any processor objects that have been added to the graph will also be deleted. | Any processor objects that have been added to the graph will also be deleted. | ||||
| */ | */ | ||||
| ~AudioProcessorGraph(); | ~AudioProcessorGraph(); | ||||
| @@ -70,10 +69,6 @@ public: | |||||
| class JUCE_API Node : public ReferenceCountedObject | class JUCE_API Node : public ReferenceCountedObject | ||||
| { | { | ||||
| public: | public: | ||||
| /** Destructor. | |||||
| */ | |||||
| ~Node(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** The ID number assigned to this node. | /** The ID number assigned to this node. | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 14 | |||||
| #define JUCE_BUILDNUMBER 15 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -888,8 +888,13 @@ const Image ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||||
| Graphics g (snapshot); | Graphics g (snapshot); | ||||
| g.setOrigin (pos.getX() - imageX, pos.getY() - imageY); | g.setOrigin (pos.getX() - imageX, pos.getY() - imageY); | ||||
| if (g.reduceClipRegion (rowComp->getLocalBounds())) | if (g.reduceClipRegion (rowComp->getLocalBounds())) | ||||
| { | |||||
| g.beginTransparencyLayer (0.6f); | |||||
| rowComp->paintEntireComponent (g, false); | rowComp->paintEntireComponent (g, false); | ||||
| g.endTransparencyLayer(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -905,7 +910,6 @@ void ListBox::startDragAndDrop (const MouseEvent& e, const String& dragDescripti | |||||
| { | { | ||||
| int x, y; | int x, y; | ||||
| Image dragImage (createSnapshotOfSelectedRows (x, y)); | Image dragImage (createSnapshotOfSelectedRows (x, y)); | ||||
| dragImage.multiplyAllAlphas (0.6f); | |||||
| MouseEvent e2 (e.getEventRelativeTo (this)); | MouseEvent e2 (e.getEventRelativeTo (this)); | ||||
| const Point<int> p (x - e2.x, y - e2.y); | const Point<int> p (x - e2.x, y - e2.y); | ||||
| @@ -488,35 +488,35 @@ public: | |||||
| for more details. | for more details. | ||||
| When using relative expressions, the following symbols are available: | When using relative expressions, the following symbols are available: | ||||
| - "this.left", "this.right", "this.top", "this.bottom" refer to the position of those | |||||
| edges in this component, so e.g. for a component whose width is always 100, you might | |||||
| set the right edge to the "this.left + 100". | |||||
| - "parent.left", "parent.right", "parent.top", "parent.bottom" refer to the parent component's | |||||
| positions, in its own coordinate space, so "parent.left", "parent.right" are always 0, and | |||||
| "parent.top", "parent.bottom" will actually be the width and height of the parent. So | |||||
| for example to make your component's right-hand edge always 10 pixels away from its parent's | |||||
| right-hand edge, you could set it to "parent.right - 10" | |||||
| - "[id].left", "[id].right", "[id].top", "[id].bottom", where [id] is the identifier of one of | |||||
| this component's siblings. A component's identifier is set with Component::setComponentID(). | |||||
| So for example if you want your component to always be 50 pixels to the right of the one | |||||
| called "xyz", you could set your left edge to be "xyz.right + 50" | |||||
| - The name of a marker that is defined in the parent component. For markers to be used, the parent | |||||
| component must implement its Component::getMarkers() method, and return at least one | |||||
| - "left", "right", "top", "bottom" refer to the position of those edges in this component, so | |||||
| e.g. for a component whose width is always 100, you might set the right edge to the "left + 100". | |||||
| - "[id].left", "[id].right", "[id].top", "[id].bottom", "[id].width", "[id].height", where [id] is | |||||
| the identifier of one of this component's siblings. A component's identifier is set with | |||||
| Component::setComponentID(). So for example if you want your component to always be 50 pixels to the | |||||
| right of the one called "xyz", you could set your left edge to be "xyz.right + 50". | |||||
| - Instead of an [id], you can use the name "parent" to refer to this component's parent. Like | |||||
| any other component, these values are relative to their component's parent, so "parent.right" won't be | |||||
| very useful for positioning a component because it refers to a position with the parent's parent.. but | |||||
| "parent.width" can be used for setting positions relative to the parent's size. E.g. to make a 10x10 | |||||
| component which remains 1 pixel away from its parent's bottom-right, you could use | |||||
| "right - 10, bottom - 10, parent.width - 1, parent.height - 1". | |||||
| - The name of one of the parent component's markers can also be used as a symbol. For markers to be | |||||
| used, the parent component must implement its Component::getMarkers() method, and return at least one | |||||
| valid MarkerList. So if you want your component's top edge to be 10 pixels below the | valid MarkerList. So if you want your component's top edge to be 10 pixels below the | ||||
| marker called "foobar", you'd set it to "foobar + 10". | marker called "foobar", you'd set it to "foobar + 10". | ||||
| See the Expression class for details about the operators that are supported, but for example | See the Expression class for details about the operators that are supported, but for example | ||||
| if you wanted to make your component remain centred within its parent with a size of 100, 100, | if you wanted to make your component remain centred within its parent with a size of 100, 100, | ||||
| you could express it as: | you could express it as: | ||||
| @code myComp.setBounds (RelativeBounds ("parent.right / 2 - 50, parent.bottom / 2 - 50, this.left + 100, this.top + 100")); | |||||
| @code myComp.setBounds (RelativeBounds ("parent.width / 2 - 50, parent.height / 2 - 50, left + 100, top + 100")); | |||||
| @endcode | @endcode | ||||
| ..or an alternative way to achieve the same thing: | ..or an alternative way to achieve the same thing: | ||||
| @code myComp.setBounds (RelativeBounds ("this.right - 100, this.bottom - 100, parent.right / 2 + 50, parent.bottom / 2 + 50")); | |||||
| @code myComp.setBounds (RelativeBounds ("right - 100, bottom - 100, parent.width / 2 + 50, parent.height / 2 + 50")); | |||||
| @endcode | @endcode | ||||
| Or if you wanted a 100x100 component whose top edge is lined up to a marker called "topMarker" and | Or if you wanted a 100x100 component whose top edge is lined up to a marker called "topMarker" and | ||||
| which is positioned 50 pixels to the right of another component called "otherComp", you could write: | which is positioned 50 pixels to the right of another component called "otherComp", you could write: | ||||
| @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, this.left + 100, this.top + 100")); | |||||
| @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, left + 100, top + 100")); | |||||
| @endcode | @endcode | ||||
| Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will | Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will | ||||
| @@ -65,6 +65,8 @@ public: | |||||
| void componentBeingDeleted (Component& comp) | void componentBeingDeleted (Component& comp) | ||||
| { | { | ||||
| ComponentMovementWatcher::componentBeingDeleted (comp); | |||||
| if (component == &comp || comp.isParentOf (component)) | if (component == &comp || comp.isParentOf (component)) | ||||
| cancel(); | cancel(); | ||||
| } | } | ||||
| @@ -201,9 +203,14 @@ void ModalComponentManager::handleAsyncUpdate() | |||||
| if (! item->isActive) | if (! item->isActive) | ||||
| { | { | ||||
| for (int j = item->callbacks.size(); --j >= 0;) | for (int j = item->callbacks.size(); --j >= 0;) | ||||
| { | |||||
| item->callbacks.getUnchecked(j)->modalStateFinished (item->returnValue); | item->callbacks.getUnchecked(j)->modalStateFinished (item->returnValue); | ||||
| stack.remove (i); | |||||
| if (! stack.contains (item)) | |||||
| break; | |||||
| } | |||||
| stack.removeObject (item); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -28,8 +28,10 @@ | |||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| #include "juce_MarkerList.h" | #include "juce_MarkerList.h" | ||||
| #include "juce_RelativeCoordinatePositioner.h" | |||||
| #include "../juce_Component.h" | #include "../juce_Component.h" | ||||
| //============================================================================== | //============================================================================== | ||||
| MarkerList::MarkerList() | MarkerList::MarkerList() | ||||
| { | { | ||||
| @@ -246,44 +248,17 @@ void MarkerList::ValueTreeWrapper::removeMarker (const ValueTree& marker, UndoMa | |||||
| state.removeChild (marker, undoManager); | state.removeChild (marker, undoManager); | ||||
| } | } | ||||
| //============================================================================== | |||||
| class MarkerListEvaluator : public Expression::EvaluationContext | |||||
| double MarkerList::getMarkerPosition (const Marker& marker, Component* parentComponent) const | |||||
| { | { | ||||
| public: | |||||
| MarkerListEvaluator (const MarkerList& markerList_, Component* const parentComponent_) | |||||
| : markerList (markerList_), parentComponent (parentComponent_) | |||||
| if (parentComponent != 0) | |||||
| { | { | ||||
| RelativeCoordinatePositionerBase::ComponentScope scope (*parentComponent); | |||||
| return marker.position.resolve (&scope); | |||||
| } | } | ||||
| const Expression getSymbolValue (const String& objectName, const String& member) const | |||||
| else | |||||
| { | { | ||||
| if (member.isEmpty()) | |||||
| { | |||||
| const MarkerList::Marker* const marker = markerList.getMarker (objectName); | |||||
| if (marker != 0) | |||||
| return Expression (marker->position.resolve (this)); | |||||
| } | |||||
| else if (parentComponent != 0 && objectName == RelativeCoordinate::Strings::parent) | |||||
| { | |||||
| if (member == RelativeCoordinate::Strings::right) return Expression ((double) parentComponent->getWidth()); | |||||
| if (member == RelativeCoordinate::Strings::bottom) return Expression ((double) parentComponent->getHeight()); | |||||
| } | |||||
| return Expression::EvaluationContext::getSymbolValue (objectName, member); | |||||
| return marker.position.resolve (0); | |||||
| } | } | ||||
| private: | |||||
| const MarkerList& markerList; | |||||
| Component* parentComponent; | |||||
| JUCE_DECLARE_NON_COPYABLE (MarkerListEvaluator); | |||||
| }; | |||||
| double MarkerList::getMarkerPosition (const Marker& marker, Component* const parentComponent) const | |||||
| { | |||||
| MarkerListEvaluator context (*this, parentComponent); | |||||
| return marker.position.resolve (&context); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -32,15 +32,28 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| const String RelativeCoordinate::Strings::parent ("parent"); | const String RelativeCoordinate::Strings::parent ("parent"); | ||||
| const String RelativeCoordinate::Strings::this_ ("this"); | |||||
| const String RelativeCoordinate::Strings::left ("left"); | const String RelativeCoordinate::Strings::left ("left"); | ||||
| const String RelativeCoordinate::Strings::right ("right"); | const String RelativeCoordinate::Strings::right ("right"); | ||||
| const String RelativeCoordinate::Strings::top ("top"); | const String RelativeCoordinate::Strings::top ("top"); | ||||
| const String RelativeCoordinate::Strings::bottom ("bottom"); | const String RelativeCoordinate::Strings::bottom ("bottom"); | ||||
| const String RelativeCoordinate::Strings::parentLeft ("parent.left"); | |||||
| const String RelativeCoordinate::Strings::parentTop ("parent.top"); | |||||
| const String RelativeCoordinate::Strings::parentRight ("parent.right"); | |||||
| const String RelativeCoordinate::Strings::parentBottom ("parent.bottom"); | |||||
| const String RelativeCoordinate::Strings::x ("x"); | |||||
| const String RelativeCoordinate::Strings::y ("y"); | |||||
| const String RelativeCoordinate::Strings::width ("width"); | |||||
| const String RelativeCoordinate::Strings::height ("height"); | |||||
| RelativeCoordinate::StandardStrings::Type RelativeCoordinate::StandardStrings::getTypeOf (const String& s) throw() | |||||
| { | |||||
| if (s == Strings::left) return left; | |||||
| if (s == Strings::right) return right; | |||||
| if (s == Strings::top) return top; | |||||
| if (s == Strings::bottom) return bottom; | |||||
| if (s == Strings::x) return x; | |||||
| if (s == Strings::y) return y; | |||||
| if (s == Strings::width) return width; | |||||
| if (s == Strings::height) return height; | |||||
| if (s == Strings::parent) return parent; | |||||
| return unknown; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| RelativeCoordinate::RelativeCoordinate() | RelativeCoordinate::RelativeCoordinate() | ||||
| @@ -92,12 +105,12 @@ bool RelativeCoordinate::operator!= (const RelativeCoordinate& other) const thro | |||||
| return ! operator== (other); | return ! operator== (other); | ||||
| } | } | ||||
| double RelativeCoordinate::resolve (const Expression::EvaluationContext* context) const | |||||
| double RelativeCoordinate::resolve (const Expression::Scope* scope) const | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| if (context != 0) | |||||
| return term.evaluate (*context); | |||||
| if (scope != 0) | |||||
| return term.evaluate (*scope); | |||||
| else | else | ||||
| return term.evaluate(); | return term.evaluate(); | ||||
| } | } | ||||
| @@ -107,12 +120,12 @@ double RelativeCoordinate::resolve (const Expression::EvaluationContext* context | |||||
| return 0.0; | return 0.0; | ||||
| } | } | ||||
| bool RelativeCoordinate::isRecursive (const Expression::EvaluationContext* context) const | |||||
| bool RelativeCoordinate::isRecursive (const Expression::Scope* scope) const | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| if (context != 0) | |||||
| term.evaluate (*context); | |||||
| if (scope != 0) | |||||
| term.evaluate (*scope); | |||||
| else | else | ||||
| term.evaluate(); | term.evaluate(); | ||||
| } | } | ||||
| @@ -124,36 +137,24 @@ bool RelativeCoordinate::isRecursive (const Expression::EvaluationContext* conte | |||||
| return false; | return false; | ||||
| } | } | ||||
| void RelativeCoordinate::moveToAbsolute (double newPos, const Expression::EvaluationContext* context) | |||||
| void RelativeCoordinate::moveToAbsolute (double newPos, const Expression::Scope* scope) | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| if (context != 0) | |||||
| if (scope != 0) | |||||
| { | { | ||||
| term = term.adjustedToGiveNewResult (newPos, *context); | |||||
| term = term.adjustedToGiveNewResult (newPos, *scope); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| Expression::EvaluationContext defaultContext; | |||||
| term = term.adjustedToGiveNewResult (newPos, defaultContext); | |||||
| Expression::Scope defaultScope; | |||||
| term = term.adjustedToGiveNewResult (newPos, defaultScope); | |||||
| } | } | ||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| {} | {} | ||||
| } | } | ||||
| bool RelativeCoordinate::references (const String& coordName, const Expression::EvaluationContext* context) const | |||||
| { | |||||
| try | |||||
| { | |||||
| return term.referencesSymbol (coordName, context); | |||||
| } | |||||
| catch (...) | |||||
| {} | |||||
| return false; | |||||
| } | |||||
| bool RelativeCoordinate::isDynamic() const | bool RelativeCoordinate::isDynamic() const | ||||
| { | { | ||||
| return term.usesAnySymbols(); | return term.usesAnySymbols(); | ||||
| @@ -164,13 +165,6 @@ const String RelativeCoordinate::toString() const | |||||
| return term.toString(); | return term.toString(); | ||||
| } | } | ||||
| void RelativeCoordinate::renameSymbolIfUsed (const String& oldName, const String& newName) | |||||
| { | |||||
| jassert (newName.isNotEmpty() && newName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_")); | |||||
| if (term.referencesSymbol (oldName, 0)) | |||||
| term = term.withRenamedSymbol (oldName, newName); | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -69,18 +69,18 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Calculates the absolute position of this coordinate. | /** Calculates the absolute position of this coordinate. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| double resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| double resolve (const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. | ||||
| This will recursively check any coordinates upon which this one depends. | This will recursively check any coordinates upon which this one depends. | ||||
| */ | */ | ||||
| bool references (const String& coordName, const Expression::EvaluationContext* evaluationContext) const; | |||||
| bool references (const String& coordName, const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ | ||||
| bool isRecursive (const Expression::EvaluationContext* evaluationContext) const; | |||||
| bool isRecursive (const Expression::Scope* evaluationScope) const; | |||||
| /** Returns true if this coordinate depends on any other coordinates for its position. */ | /** Returns true if this coordinate depends on any other coordinates for its position. */ | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| @@ -92,10 +92,7 @@ public: | |||||
| or relative position to whatever value is necessary to make its resultant position | or relative position to whatever value is necessary to make its resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (double absoluteTargetPosition, const Expression::EvaluationContext* evaluationContext); | |||||
| /** Changes the name of a symbol if it is used as part of the coordinate's expression. */ | |||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| void moveToAbsolute (double absoluteTargetPosition, const Expression::Scope* evaluationScope); | |||||
| /** Returns the expression that defines this coordinate. */ | /** Returns the expression that defines this coordinate. */ | ||||
| const Expression& getExpression() const { return term; } | const Expression& getExpression() const { return term; } | ||||
| @@ -118,15 +115,27 @@ public: | |||||
| struct Strings | struct Strings | ||||
| { | { | ||||
| static const String parent; /**< "parent" */ | static const String parent; /**< "parent" */ | ||||
| static const String this_; /**< "this" */ | |||||
| static const String left; /**< "left" */ | static const String left; /**< "left" */ | ||||
| static const String right; /**< "right" */ | static const String right; /**< "right" */ | ||||
| static const String top; /**< "top" */ | static const String top; /**< "top" */ | ||||
| static const String bottom; /**< "bottom" */ | static const String bottom; /**< "bottom" */ | ||||
| static const String parentLeft; /**< "parent.left" */ | |||||
| static const String parentTop; /**< "parent.top" */ | |||||
| static const String parentRight; /**< "parent.right" */ | |||||
| static const String parentBottom; /**< "parent.bottom" */ | |||||
| static const String x; /**< "x" */ | |||||
| static const String y; /**< "y" */ | |||||
| static const String width; /**< "width" */ | |||||
| static const String height; /**< "height" */ | |||||
| }; | |||||
| struct StandardStrings | |||||
| { | |||||
| enum Type | |||||
| { | |||||
| left, right, top, bottom, | |||||
| x, y, width, height, | |||||
| parent, | |||||
| unknown | |||||
| }; | |||||
| static Type getTypeOf (const String& s) throw(); | |||||
| }; | }; | ||||
| private: | private: | ||||
| @@ -31,51 +31,171 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| RelativeCoordinatePositionerBase::RelativeCoordinatePositionerBase (Component& component_) | |||||
| : Component::Positioner (component_), registeredOk (false) | |||||
| RelativeCoordinatePositionerBase::ComponentScope::ComponentScope (Component& component_) | |||||
| : component (component_) | |||||
| { | { | ||||
| } | } | ||||
| RelativeCoordinatePositionerBase::~RelativeCoordinatePositionerBase() | |||||
| const Expression RelativeCoordinatePositionerBase::ComponentScope::getSymbolValue (const String& symbol) const | |||||
| { | { | ||||
| unregisterListeners(); | |||||
| switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol)) | |||||
| { | |||||
| case RelativeCoordinate::StandardStrings::x: | |||||
| case RelativeCoordinate::StandardStrings::left: return Expression ((double) component.getX()); | |||||
| case RelativeCoordinate::StandardStrings::y: | |||||
| case RelativeCoordinate::StandardStrings::top: return Expression ((double) component.getY()); | |||||
| case RelativeCoordinate::StandardStrings::width: return Expression ((double) component.getWidth()); | |||||
| case RelativeCoordinate::StandardStrings::height: return Expression ((double) component.getHeight()); | |||||
| case RelativeCoordinate::StandardStrings::right: return Expression ((double) component.getRight()); | |||||
| case RelativeCoordinate::StandardStrings::bottom: return Expression ((double) component.getBottom()); | |||||
| default: break; | |||||
| } | |||||
| MarkerList* list; | |||||
| const MarkerList::Marker* const marker = findMarker (symbol, list); | |||||
| if (marker != 0) | |||||
| return marker->position.getExpression(); | |||||
| return Expression::Scope::getSymbolValue (symbol); | |||||
| } | } | ||||
| const Expression RelativeCoordinatePositionerBase::getSymbolValue (const String& objectName, const String& member) const | |||||
| void RelativeCoordinatePositionerBase::ComponentScope::visitRelativeScope (const String& scopeName, Visitor& visitor) const | |||||
| { | { | ||||
| jassert (objectName.isNotEmpty()); | |||||
| Component* targetComp = 0; | |||||
| if (member.isNotEmpty()) | |||||
| if (scopeName == RelativeCoordinate::Strings::parent) | |||||
| targetComp = component.getParentComponent(); | |||||
| else | |||||
| targetComp = findSiblingComponent (scopeName); | |||||
| if (targetComp != 0) | |||||
| visitor.visit (ComponentScope (*targetComp)); | |||||
| } | |||||
| const String RelativeCoordinatePositionerBase::ComponentScope::getScopeUID() const | |||||
| { | |||||
| return String::toHexString ((pointer_sized_int) (void*) &component); | |||||
| } | |||||
| Component* RelativeCoordinatePositionerBase::ComponentScope::findSiblingComponent (const String& componentID) const | |||||
| { | |||||
| Component* const parent = component.getParentComponent(); | |||||
| if (parent != 0) | |||||
| { | { | ||||
| const Component* comp = getSourceComponent (objectName); | |||||
| for (int i = parent->getNumChildComponents(); --i >= 0;) | |||||
| { | |||||
| Component* const c = parent->getChildComponent(i); | |||||
| if (c->getComponentID() == componentID) | |||||
| return c; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| const MarkerList::Marker* RelativeCoordinatePositionerBase::ComponentScope::findMarker (const String& name, MarkerList*& list) const | |||||
| { | |||||
| const MarkerList::Marker* marker = 0; | |||||
| Component* const parent = component.getParentComponent(); | |||||
| if (comp == 0) | |||||
| if (parent != 0) | |||||
| { | |||||
| list = parent->getMarkers (true); | |||||
| if (list != 0) | |||||
| marker = list->getMarker (name); | |||||
| if (marker == 0) | |||||
| { | { | ||||
| if (objectName == RelativeCoordinate::Strings::parent) | |||||
| comp = getComponent().getParentComponent(); | |||||
| else if (objectName == RelativeCoordinate::Strings::this_ || objectName == getComponent().getComponentID()) | |||||
| comp = &getComponent(); | |||||
| list = parent->getMarkers (false); | |||||
| if (list != 0) | |||||
| marker = list->getMarker (name); | |||||
| } | } | ||||
| } | |||||
| return marker; | |||||
| } | |||||
| //============================================================================== | |||||
| class RelativeCoordinatePositionerBase::DependencyFinderScope : public ComponentScope | |||||
| { | |||||
| public: | |||||
| DependencyFinderScope (Component& component_, RelativeCoordinatePositionerBase& positioner_, bool& ok_) | |||||
| : ComponentScope (component_), positioner (positioner_), ok (ok_) | |||||
| { | |||||
| } | |||||
| if (comp != 0) | |||||
| const Expression getSymbolValue (const String& symbol) const | |||||
| { | |||||
| if (symbol == RelativeCoordinate::Strings::left || symbol == RelativeCoordinate::Strings::x | |||||
| || symbol == RelativeCoordinate::Strings::width || symbol == RelativeCoordinate::Strings::right | |||||
| || symbol == RelativeCoordinate::Strings::top || symbol == RelativeCoordinate::Strings::y | |||||
| || symbol == RelativeCoordinate::Strings::height || symbol == RelativeCoordinate::Strings::bottom) | |||||
| { | { | ||||
| if (member == RelativeCoordinate::Strings::left) return xToExpression (comp, 0); | |||||
| if (member == RelativeCoordinate::Strings::right) return xToExpression (comp, comp->getWidth()); | |||||
| if (member == RelativeCoordinate::Strings::top) return yToExpression (comp, 0); | |||||
| if (member == RelativeCoordinate::Strings::bottom) return yToExpression (comp, comp->getHeight()); | |||||
| positioner.registerComponentListener (component); | |||||
| } | } | ||||
| else | |||||
| { | |||||
| MarkerList* list; | |||||
| const MarkerList::Marker* const marker = findMarker (symbol, list); | |||||
| if (marker != 0) | |||||
| { | |||||
| positioner.registerMarkerListListener (list); | |||||
| } | |||||
| else | |||||
| { | |||||
| // The marker we want doesn't exist, so watch all lists in case they change and the marker appears later.. | |||||
| positioner.registerMarkerListListener (component.getMarkers (true)); | |||||
| positioner.registerMarkerListListener (component.getMarkers (false)); | |||||
| ok = false; | |||||
| } | |||||
| } | |||||
| return ComponentScope::getSymbolValue (symbol); | |||||
| } | } | ||||
| for (int i = sourceMarkerLists.size(); --i >= 0;) | |||||
| void visitRelativeScope (const String& scopeName, Visitor& visitor) const | |||||
| { | { | ||||
| MarkerList* const markerList = sourceMarkerLists.getUnchecked(i); | |||||
| const MarkerList::Marker* const marker = markerList->getMarker (objectName); | |||||
| Component* targetComp = 0; | |||||
| if (marker != 0) | |||||
| return Expression (markerList->getMarkerPosition (*marker, getComponent().getParentComponent())); | |||||
| if (scopeName == RelativeCoordinate::Strings::parent) | |||||
| targetComp = component.getParentComponent(); | |||||
| else | |||||
| targetComp = findSiblingComponent (scopeName); | |||||
| if (targetComp != 0) | |||||
| { | |||||
| visitor.visit (DependencyFinderScope (*targetComp, positioner, ok)); | |||||
| } | |||||
| else | |||||
| { | |||||
| // The named component doesn't exist, so we'll watch the parent for changes in case it appears later.. | |||||
| positioner.registerComponentListener (component); | |||||
| ok = false; | |||||
| } | |||||
| } | } | ||||
| return Expression::EvaluationContext::getSymbolValue (objectName, member); | |||||
| private: | |||||
| RelativeCoordinatePositionerBase& positioner; | |||||
| bool& ok; | |||||
| JUCE_DECLARE_NON_COPYABLE (DependencyFinderScope); | |||||
| }; | |||||
| //============================================================================== | |||||
| RelativeCoordinatePositionerBase::RelativeCoordinatePositionerBase (Component& component_) | |||||
| : Component::Positioner (component_), registeredOk (false) | |||||
| { | |||||
| } | |||||
| RelativeCoordinatePositionerBase::~RelativeCoordinatePositionerBase() | |||||
| { | |||||
| unregisterListeners(); | |||||
| } | } | ||||
| void RelativeCoordinatePositionerBase::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/) | void RelativeCoordinatePositionerBase::componentMovedOrResized (Component&, bool /*wasMoved*/, bool /*wasResized*/) | ||||
| @@ -118,7 +238,10 @@ void RelativeCoordinatePositionerBase::apply() | |||||
| bool RelativeCoordinatePositionerBase::addCoordinate (const RelativeCoordinate& coord) | bool RelativeCoordinatePositionerBase::addCoordinate (const RelativeCoordinate& coord) | ||||
| { | { | ||||
| return registerListeners (coord.getExpression()); | |||||
| bool ok = true; | |||||
| DependencyFinderScope finderScope (getComponent(), *this, ok); | |||||
| coord.getExpression().evaluate (finderScope); | |||||
| return ok; | |||||
| } | } | ||||
| bool RelativeCoordinatePositionerBase::addPoint (const RelativePoint& point) | bool RelativeCoordinatePositionerBase::addPoint (const RelativePoint& point) | ||||
| @@ -127,95 +250,12 @@ bool RelativeCoordinatePositionerBase::addPoint (const RelativePoint& point) | |||||
| return addCoordinate (point.y) && ok; | return addCoordinate (point.y) && ok; | ||||
| } | } | ||||
| bool RelativeCoordinatePositionerBase::registerListeners (const Expression& e) | |||||
| { | |||||
| bool ok = true; | |||||
| if (e.getType() == Expression::symbolType) | |||||
| { | |||||
| String objectName, memberName; | |||||
| e.getSymbolParts (objectName, memberName); | |||||
| if (memberName.isNotEmpty()) | |||||
| ok = registerComponent (objectName) && ok; | |||||
| else | |||||
| ok = registerMarker (objectName) && ok; | |||||
| } | |||||
| else | |||||
| { | |||||
| for (int i = e.getNumInputs(); --i >= 0;) | |||||
| ok = registerListeners (e.getInput (i)) && ok; | |||||
| } | |||||
| return ok; | |||||
| } | |||||
| bool RelativeCoordinatePositionerBase::registerComponent (const String& componentID) | |||||
| void RelativeCoordinatePositionerBase::registerComponentListener (Component& comp) | |||||
| { | { | ||||
| Component* comp = findComponent (componentID); | |||||
| if (comp == 0) | |||||
| if (! sourceComponents.contains (&comp)) | |||||
| { | { | ||||
| if (componentID == RelativeCoordinate::Strings::parent) | |||||
| comp = getComponent().getParentComponent(); | |||||
| else if (componentID == RelativeCoordinate::Strings::this_ || componentID == getComponent().getComponentID()) | |||||
| comp = &getComponent(); | |||||
| } | |||||
| if (comp != 0) | |||||
| { | |||||
| if (comp != &getComponent()) | |||||
| registerComponentListener (comp); | |||||
| return true; | |||||
| } | |||||
| else | |||||
| { | |||||
| // The component we want doesn't exist, so watch the parent in case the hierarchy changes and it appears later.. | |||||
| Component* const parent = getComponent().getParentComponent(); | |||||
| if (parent != 0) | |||||
| registerComponentListener (parent); | |||||
| else | |||||
| registerComponentListener (&getComponent()); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| bool RelativeCoordinatePositionerBase::registerMarker (const String markerName) | |||||
| { | |||||
| Component* const parent = getComponent().getParentComponent(); | |||||
| if (parent != 0) | |||||
| { | |||||
| MarkerList* list = parent->getMarkers (true); | |||||
| if (list == 0 || list->getMarker (markerName) == 0) | |||||
| list = parent->getMarkers (false); | |||||
| if (list != 0 && list->getMarker (markerName) != 0) | |||||
| { | |||||
| registerMarkerListListener (list); | |||||
| return true; | |||||
| } | |||||
| else | |||||
| { | |||||
| // The marker we want doesn't exist, so watch all lists in case they change and the marker appears later.. | |||||
| registerMarkerListListener (parent->getMarkers (true)); | |||||
| registerMarkerListListener (parent->getMarkers (false)); | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| void RelativeCoordinatePositionerBase::registerComponentListener (Component* const comp) | |||||
| { | |||||
| if (comp != 0 && ! sourceComponents.contains (comp)) | |||||
| { | |||||
| comp->addComponentListener (this); | |||||
| sourceComponents.add (comp); | |||||
| comp.addComponentListener (this); | |||||
| sourceComponents.add (&comp); | |||||
| } | } | ||||
| } | } | ||||
| @@ -241,45 +281,5 @@ void RelativeCoordinatePositionerBase::unregisterListeners() | |||||
| sourceMarkerLists.clear(); | sourceMarkerLists.clear(); | ||||
| } | } | ||||
| Component* RelativeCoordinatePositionerBase::findComponent (const String& componentID) const | |||||
| { | |||||
| Component* const parent = getComponent().getParentComponent(); | |||||
| if (parent != 0) | |||||
| { | |||||
| for (int i = parent->getNumChildComponents(); --i >= 0;) | |||||
| { | |||||
| Component* const c = parent->getChildComponent(i); | |||||
| if (c->getComponentID() == componentID) | |||||
| return c; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| Component* RelativeCoordinatePositionerBase::getSourceComponent (const String& objectName) const | |||||
| { | |||||
| for (int i = sourceComponents.size(); --i >= 0;) | |||||
| { | |||||
| Component* const comp = sourceComponents.getUnchecked(i); | |||||
| if (comp->getComponentID() == objectName) | |||||
| return comp; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| const Expression RelativeCoordinatePositionerBase::xToExpression (const Component* const source, const int x) const | |||||
| { | |||||
| return Expression ((double) (getComponent().getLocalPoint (source, Point<int> (x, 0)).getX() + getComponent().getX())); | |||||
| } | |||||
| const Expression RelativeCoordinatePositionerBase::yToExpression (const Component* const source, const int y) const | |||||
| { | |||||
| return Expression ((double) (getComponent().getLocalPoint (source, Point<int> (0, y)).getY() + getComponent().getY())); | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -37,15 +37,12 @@ | |||||
| */ | */ | ||||
| class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner, | class JUCE_API RelativeCoordinatePositionerBase : public Component::Positioner, | ||||
| public ComponentListener, | public ComponentListener, | ||||
| public MarkerList::Listener, | |||||
| public Expression::EvaluationContext | |||||
| public MarkerList::Listener | |||||
| { | { | ||||
| public: | public: | ||||
| RelativeCoordinatePositionerBase (Component& component_); | RelativeCoordinatePositionerBase (Component& component_); | ||||
| ~RelativeCoordinatePositionerBase(); | ~RelativeCoordinatePositionerBase(); | ||||
| const Expression getSymbolValue (const String& objectName, const String& member) const; | |||||
| void componentMovedOrResized (Component&, bool, bool); | void componentMovedOrResized (Component&, bool, bool); | ||||
| void componentParentHierarchyChanged (Component&); | void componentParentHierarchyChanged (Component&); | ||||
| void componentBeingDeleted (Component& component); | void componentBeingDeleted (Component& component); | ||||
| @@ -57,25 +54,41 @@ public: | |||||
| bool addCoordinate (const RelativeCoordinate& coord); | bool addCoordinate (const RelativeCoordinate& coord); | ||||
| bool addPoint (const RelativePoint& point); | bool addPoint (const RelativePoint& point); | ||||
| //============================================================================== | |||||
| /** Used for resolving a RelativeCoordinate expression in the context of a component. */ | |||||
| class ComponentScope : public Expression::Scope | |||||
| { | |||||
| public: | |||||
| ComponentScope (Component& component_); | |||||
| const Expression getSymbolValue (const String& symbol) const; | |||||
| void visitRelativeScope (const String& scopeName, Visitor& visitor) const; | |||||
| const String getScopeUID() const; | |||||
| protected: | |||||
| Component& component; | |||||
| Component* findSiblingComponent (const String& componentID) const; | |||||
| const MarkerList::Marker* findMarker (const String& name, MarkerList*& list) const; | |||||
| private: | |||||
| JUCE_DECLARE_NON_COPYABLE (ComponentScope); | |||||
| }; | |||||
| protected: | protected: | ||||
| virtual bool registerCoordinates() = 0; | virtual bool registerCoordinates() = 0; | ||||
| virtual void applyToComponentBounds() = 0; | virtual void applyToComponentBounds() = 0; | ||||
| private: | private: | ||||
| class DependencyFinderScope; | |||||
| friend class DependencyFinderScope; | |||||
| Array <Component*> sourceComponents; | Array <Component*> sourceComponents; | ||||
| Array <MarkerList*> sourceMarkerLists; | Array <MarkerList*> sourceMarkerLists; | ||||
| bool registeredOk; | bool registeredOk; | ||||
| bool registerListeners (const Expression& e); | |||||
| bool registerComponent (const String& componentID); | |||||
| bool registerMarker (const String markerName); | |||||
| void registerComponentListener (Component* const comp); | |||||
| void registerComponentListener (Component& comp); | |||||
| void registerMarkerListListener (MarkerList* const list); | void registerMarkerListListener (MarkerList* const list); | ||||
| void unregisterListeners(); | void unregisterListeners(); | ||||
| Component* findComponent (const String& componentID) const; | |||||
| Component* getSourceComponent (const String& objectName) const; | |||||
| const Expression xToExpression (const Component* const source, const int x) const; | |||||
| const Expression yToExpression (const Component* const source, const int y) const; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeCoordinatePositionerBase); | ||||
| }; | }; | ||||
| @@ -53,30 +53,30 @@ RelativeParallelogram::~RelativeParallelogram() | |||||
| { | { | ||||
| } | } | ||||
| void RelativeParallelogram::resolveThreePoints (Point<float>* points, Expression::EvaluationContext* const coordFinder) const | |||||
| void RelativeParallelogram::resolveThreePoints (Point<float>* points, Expression::Scope* const scope) const | |||||
| { | { | ||||
| points[0] = topLeft.resolve (coordFinder); | |||||
| points[1] = topRight.resolve (coordFinder); | |||||
| points[2] = bottomLeft.resolve (coordFinder); | |||||
| points[0] = topLeft.resolve (scope); | |||||
| points[1] = topRight.resolve (scope); | |||||
| points[2] = bottomLeft.resolve (scope); | |||||
| } | } | ||||
| void RelativeParallelogram::resolveFourCorners (Point<float>* points, Expression::EvaluationContext* const coordFinder) const | |||||
| void RelativeParallelogram::resolveFourCorners (Point<float>* points, Expression::Scope* const scope) const | |||||
| { | { | ||||
| resolveThreePoints (points, coordFinder); | |||||
| resolveThreePoints (points, scope); | |||||
| points[3] = points[1] + (points[2] - points[0]); | points[3] = points[1] + (points[2] - points[0]); | ||||
| } | } | ||||
| const Rectangle<float> RelativeParallelogram::getBounds (Expression::EvaluationContext* const coordFinder) const | |||||
| const Rectangle<float> RelativeParallelogram::getBounds (Expression::Scope* const scope) const | |||||
| { | { | ||||
| Point<float> points[4]; | Point<float> points[4]; | ||||
| resolveFourCorners (points, coordFinder); | |||||
| resolveFourCorners (points, scope); | |||||
| return Rectangle<float>::findAreaContainingPoints (points, 4); | return Rectangle<float>::findAreaContainingPoints (points, 4); | ||||
| } | } | ||||
| void RelativeParallelogram::getPath (Path& path, Expression::EvaluationContext* const coordFinder) const | |||||
| void RelativeParallelogram::getPath (Path& path, Expression::Scope* const scope) const | |||||
| { | { | ||||
| Point<float> points[4]; | Point<float> points[4]; | ||||
| resolveFourCorners (points, coordFinder); | |||||
| resolveFourCorners (points, scope); | |||||
| path.startNewSubPath (points[0]); | path.startNewSubPath (points[0]); | ||||
| path.lineTo (points[1]); | path.lineTo (points[1]); | ||||
| @@ -85,18 +85,18 @@ void RelativeParallelogram::getPath (Path& path, Expression::EvaluationContext* | |||||
| path.closeSubPath(); | path.closeSubPath(); | ||||
| } | } | ||||
| const AffineTransform RelativeParallelogram::resetToPerpendicular (Expression::EvaluationContext* const coordFinder) | |||||
| const AffineTransform RelativeParallelogram::resetToPerpendicular (Expression::Scope* const scope) | |||||
| { | { | ||||
| Point<float> corners[3]; | Point<float> corners[3]; | ||||
| resolveThreePoints (corners, coordFinder); | |||||
| resolveThreePoints (corners, scope); | |||||
| const Line<float> top (corners[0], corners[1]); | const Line<float> top (corners[0], corners[1]); | ||||
| const Line<float> left (corners[0], corners[2]); | const Line<float> left (corners[0], corners[2]); | ||||
| const Point<float> newTopRight (corners[0] + Point<float> (top.getLength(), 0.0f)); | const Point<float> newTopRight (corners[0] + Point<float> (top.getLength(), 0.0f)); | ||||
| const Point<float> newBottomLeft (corners[0] + Point<float> (0.0f, left.getLength())); | const Point<float> newBottomLeft (corners[0] + Point<float> (0.0f, left.getLength())); | ||||
| topRight.moveToAbsolute (newTopRight, coordFinder); | |||||
| bottomLeft.moveToAbsolute (newBottomLeft, coordFinder); | |||||
| topRight.moveToAbsolute (newTopRight, scope); | |||||
| bottomLeft.moveToAbsolute (newBottomLeft, scope); | |||||
| return AffineTransform::fromTargetPoints (corners[0].getX(), corners[0].getY(), corners[0].getX(), corners[0].getY(), | return AffineTransform::fromTargetPoints (corners[0].getX(), corners[0].getY(), corners[0].getX(), corners[0].getY(), | ||||
| corners[1].getX(), corners[1].getY(), newTopRight.getX(), newTopRight.getY(), | corners[1].getX(), corners[1].getY(), newTopRight.getX(), newTopRight.getY(), | ||||
| @@ -46,11 +46,11 @@ public: | |||||
| ~RelativeParallelogram(); | ~RelativeParallelogram(); | ||||
| //============================================================================== | //============================================================================== | ||||
| void resolveThreePoints (Point<float>* points, Expression::EvaluationContext* coordFinder) const; | |||||
| void resolveFourCorners (Point<float>* points, Expression::EvaluationContext* coordFinder) const; | |||||
| const Rectangle<float> getBounds (Expression::EvaluationContext* coordFinder) const; | |||||
| void getPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| const AffineTransform resetToPerpendicular (Expression::EvaluationContext* coordFinder); | |||||
| void resolveThreePoints (Point<float>* points, Expression::Scope* scope) const; | |||||
| void resolveFourCorners (Point<float>* points, Expression::Scope* scope) const; | |||||
| const Rectangle<float> getBounds (Expression::Scope* scope) const; | |||||
| void getPath (Path& path, Expression::Scope* scope) const; | |||||
| const AffineTransform resetToPerpendicular (Expression::Scope* scope); | |||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| bool operator== (const RelativeParallelogram& other) const throw(); | bool operator== (const RelativeParallelogram& other) const throw(); | ||||
| @@ -79,16 +79,16 @@ bool RelativePoint::operator!= (const RelativePoint& other) const throw() | |||||
| return ! operator== (other); | return ! operator== (other); | ||||
| } | } | ||||
| const Point<float> RelativePoint::resolve (const Expression::EvaluationContext* context) const | |||||
| const Point<float> RelativePoint::resolve (const Expression::Scope* scope) const | |||||
| { | { | ||||
| return Point<float> ((float) x.resolve (context), | |||||
| (float) y.resolve (context)); | |||||
| return Point<float> ((float) x.resolve (scope), | |||||
| (float) y.resolve (scope)); | |||||
| } | } | ||||
| void RelativePoint::moveToAbsolute (const Point<float>& newPos, const Expression::EvaluationContext* context) | |||||
| void RelativePoint::moveToAbsolute (const Point<float>& newPos, const Expression::Scope* scope) | |||||
| { | { | ||||
| x.moveToAbsolute (newPos.getX(), context); | |||||
| y.moveToAbsolute (newPos.getY(), context); | |||||
| x.moveToAbsolute (newPos.getX(), scope); | |||||
| y.moveToAbsolute (newPos.getY(), scope); | |||||
| } | } | ||||
| const String RelativePoint::toString() const | const String RelativePoint::toString() const | ||||
| @@ -96,12 +96,6 @@ const String RelativePoint::toString() const | |||||
| return x.toString() + ", " + y.toString(); | return x.toString() + ", " + y.toString(); | ||||
| } | } | ||||
| void RelativePoint::renameSymbolIfUsed (const String& oldName, const String& newName) | |||||
| { | |||||
| x.renameSymbolIfUsed (oldName, newName); | |||||
| y.renameSymbolIfUsed (oldName, newName); | |||||
| } | |||||
| bool RelativePoint::isDynamic() const | bool RelativePoint::isDynamic() const | ||||
| { | { | ||||
| return x.isDynamic() || y.isDynamic(); | return x.isDynamic() || y.isDynamic(); | ||||
| @@ -62,10 +62,10 @@ public: | |||||
| /** Calculates the absolute position of this point. | /** Calculates the absolute position of this point. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| const Point<float> resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| const Point<float> resolve (const Expression::Scope* evaluationContext) const; | |||||
| /** Changes the values of this point's coordinates to make it resolve to the specified position. | /** Changes the values of this point's coordinates to make it resolve to the specified position. | ||||
| @@ -73,7 +73,7 @@ public: | |||||
| or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (const Point<float>& newPos, const Expression::EvaluationContext* evaluationContext); | |||||
| void moveToAbsolute (const Point<float>& newPos, const Expression::Scope* evaluationContext); | |||||
| /** Returns a string which represents this point. | /** Returns a string which represents this point. | ||||
| This returns a comma-separated pair of coordinates. For details of the string syntax used by the | This returns a comma-separated pair of coordinates. For details of the string syntax used by the | ||||
| @@ -82,11 +82,6 @@ public: | |||||
| */ | */ | ||||
| const String toString() const; | const String toString() const; | ||||
| /** Renames a symbol if it is used by any of the coordinates. | |||||
| This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. | |||||
| */ | |||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| /** Returns true if this point depends on any other coordinates for its position. */ | /** Returns true if this point depends on any other coordinates for its position. */ | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| @@ -109,10 +109,10 @@ void RelativePointPath::swapWith (RelativePointPath& other) throw() | |||||
| swapVariables (containsDynamicPoints, other.containsDynamicPoints); | swapVariables (containsDynamicPoints, other.containsDynamicPoints); | ||||
| } | } | ||||
| void RelativePointPath::createPath (Path& path, Expression::EvaluationContext* coordFinder) const | |||||
| void RelativePointPath::createPath (Path& path, Expression::Scope* scope) const | |||||
| { | { | ||||
| for (int i = 0; i < elements.size(); ++i) | for (int i = 0; i < elements.size(); ++i) | ||||
| elements.getUnchecked(i)->addToPath (path, coordFinder); | |||||
| elements.getUnchecked(i)->addToPath (path, scope); | |||||
| } | } | ||||
| bool RelativePointPath::containsAnyDynamicPoints() const | bool RelativePointPath::containsAnyDynamicPoints() const | ||||
| @@ -159,9 +159,9 @@ const ValueTree RelativePointPath::StartSubPath::createTree() const | |||||
| return v; | return v; | ||||
| } | } | ||||
| void RelativePointPath::StartSubPath::addToPath (Path& path, Expression::EvaluationContext* coordFinder) const | |||||
| void RelativePointPath::StartSubPath::addToPath (Path& path, Expression::Scope* scope) const | |||||
| { | { | ||||
| path.startNewSubPath (startPos.resolve (coordFinder)); | |||||
| path.startNewSubPath (startPos.resolve (scope)); | |||||
| } | } | ||||
| RelativePoint* RelativePointPath::StartSubPath::getControlPoints (int& numPoints) | RelativePoint* RelativePointPath::StartSubPath::getControlPoints (int& numPoints) | ||||
| @@ -186,7 +186,7 @@ const ValueTree RelativePointPath::CloseSubPath::createTree() const | |||||
| return ValueTree (DrawablePath::ValueTreeWrapper::Element::closeSubPathElement); | return ValueTree (DrawablePath::ValueTreeWrapper::Element::closeSubPathElement); | ||||
| } | } | ||||
| void RelativePointPath::CloseSubPath::addToPath (Path& path, Expression::EvaluationContext*) const | |||||
| void RelativePointPath::CloseSubPath::addToPath (Path& path, Expression::Scope*) const | |||||
| { | { | ||||
| path.closeSubPath(); | path.closeSubPath(); | ||||
| } | } | ||||
| @@ -215,9 +215,9 @@ const ValueTree RelativePointPath::LineTo::createTree() const | |||||
| return v; | return v; | ||||
| } | } | ||||
| void RelativePointPath::LineTo::addToPath (Path& path, Expression::EvaluationContext* coordFinder) const | |||||
| void RelativePointPath::LineTo::addToPath (Path& path, Expression::Scope* scope) const | |||||
| { | { | ||||
| path.lineTo (endPoint.resolve (coordFinder)); | |||||
| path.lineTo (endPoint.resolve (scope)); | |||||
| } | } | ||||
| RelativePoint* RelativePointPath::LineTo::getControlPoints (int& numPoints) | RelativePoint* RelativePointPath::LineTo::getControlPoints (int& numPoints) | ||||
| @@ -247,10 +247,10 @@ const ValueTree RelativePointPath::QuadraticTo::createTree() const | |||||
| return v; | return v; | ||||
| } | } | ||||
| void RelativePointPath::QuadraticTo::addToPath (Path& path, Expression::EvaluationContext* coordFinder) const | |||||
| void RelativePointPath::QuadraticTo::addToPath (Path& path, Expression::Scope* scope) const | |||||
| { | { | ||||
| path.quadraticTo (controlPoints[0].resolve (coordFinder), | |||||
| controlPoints[1].resolve (coordFinder)); | |||||
| path.quadraticTo (controlPoints[0].resolve (scope), | |||||
| controlPoints[1].resolve (scope)); | |||||
| } | } | ||||
| RelativePoint* RelativePointPath::QuadraticTo::getControlPoints (int& numPoints) | RelativePoint* RelativePointPath::QuadraticTo::getControlPoints (int& numPoints) | ||||
| @@ -283,11 +283,11 @@ const ValueTree RelativePointPath::CubicTo::createTree() const | |||||
| return v; | return v; | ||||
| } | } | ||||
| void RelativePointPath::CubicTo::addToPath (Path& path, Expression::EvaluationContext* coordFinder) const | |||||
| void RelativePointPath::CubicTo::addToPath (Path& path, Expression::Scope* scope) const | |||||
| { | { | ||||
| path.cubicTo (controlPoints[0].resolve (coordFinder), | |||||
| controlPoints[1].resolve (coordFinder), | |||||
| controlPoints[2].resolve (coordFinder)); | |||||
| path.cubicTo (controlPoints[0].resolve (scope), | |||||
| controlPoints[1].resolve (scope), | |||||
| controlPoints[2].resolve (scope)); | |||||
| } | } | ||||
| RelativePoint* RelativePointPath::CubicTo::getControlPoints (int& numPoints) | RelativePoint* RelativePointPath::CubicTo::getControlPoints (int& numPoints) | ||||
| @@ -54,7 +54,7 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Resolves this points in this path and adds them to a normal Path object. */ | /** Resolves this points in this path and adds them to a normal Path object. */ | ||||
| void createPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void createPath (Path& path, Expression::Scope* scope) const; | |||||
| /** Returns true if the path contains any non-fixed points. */ | /** Returns true if the path contains any non-fixed points. */ | ||||
| bool containsAnyDynamicPoints() const; | bool containsAnyDynamicPoints() const; | ||||
| @@ -85,7 +85,7 @@ public: | |||||
| ElementBase (ElementType type); | ElementBase (ElementType type); | ||||
| virtual ~ElementBase() {} | virtual ~ElementBase() {} | ||||
| virtual const ValueTree createTree() const = 0; | virtual const ValueTree createTree() const = 0; | ||||
| virtual void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const = 0; | |||||
| virtual void addToPath (Path& path, Expression::Scope*) const = 0; | |||||
| virtual RelativePoint* getControlPoints (int& numPoints) = 0; | virtual RelativePoint* getControlPoints (int& numPoints) = 0; | ||||
| virtual ElementBase* clone() const = 0; | virtual ElementBase* clone() const = 0; | ||||
| bool isDynamic(); | bool isDynamic(); | ||||
| @@ -102,7 +102,7 @@ public: | |||||
| public: | public: | ||||
| StartSubPath (const RelativePoint& pos); | StartSubPath (const RelativePoint& pos); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -118,7 +118,7 @@ public: | |||||
| public: | public: | ||||
| CloseSubPath(); | CloseSubPath(); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -132,7 +132,7 @@ public: | |||||
| public: | public: | ||||
| LineTo (const RelativePoint& endPoint); | LineTo (const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -148,7 +148,7 @@ public: | |||||
| public: | public: | ||||
| QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); | QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -164,7 +164,7 @@ public: | |||||
| public: | public: | ||||
| CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); | CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); | ||||
| const ValueTree createTree() const; | const ValueTree createTree() const; | ||||
| void addToPath (Path& path, Expression::EvaluationContext* coordFinder) const; | |||||
| void addToPath (Path& path, Expression::Scope*) const; | |||||
| RelativePoint* getControlPoints (int& numPoints); | RelativePoint* getControlPoints (int& numPoints); | ||||
| ElementBase* clone() const; | ElementBase* clone() const; | ||||
| @@ -30,6 +30,8 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_RelativeRectangle.h" | #include "juce_RelativeRectangle.h" | ||||
| #include "juce_RelativeCoordinatePositioner.h" | #include "juce_RelativeCoordinatePositioner.h" | ||||
| //============================================================================== | |||||
| namespace RelativeRectangleHelpers | namespace RelativeRectangleHelpers | ||||
| { | { | ||||
| inline void skipComma (const juce_wchar* const s, int& i) | inline void skipComma (const juce_wchar* const s, int& i) | ||||
| @@ -43,13 +45,23 @@ namespace RelativeRectangleHelpers | |||||
| bool dependsOnSymbolsOtherThanThis (const Expression& e) | bool dependsOnSymbolsOtherThanThis (const Expression& e) | ||||
| { | { | ||||
| if (e.getType() == Expression::operatorType && e.getSymbolOrFunction() == ".") | |||||
| return true; | |||||
| if (e.getType() == Expression::symbolType) | if (e.getType() == Expression::symbolType) | ||||
| { | { | ||||
| String objectName, memberName; | |||||
| e.getSymbolParts (objectName, memberName); | |||||
| if (objectName != RelativeCoordinate::Strings::this_) | |||||
| return true; | |||||
| switch (RelativeCoordinate::StandardStrings::getTypeOf (e.getSymbolOrFunction())) | |||||
| { | |||||
| case RelativeCoordinate::StandardStrings::x: | |||||
| case RelativeCoordinate::StandardStrings::y: | |||||
| case RelativeCoordinate::StandardStrings::left: | |||||
| case RelativeCoordinate::StandardStrings::right: | |||||
| case RelativeCoordinate::StandardStrings::top: | |||||
| case RelativeCoordinate::StandardStrings::bottom: return false; | |||||
| default: break; | |||||
| } | |||||
| return true; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -75,11 +87,9 @@ RelativeRectangle::RelativeRectangle (const RelativeCoordinate& left_, const Rel | |||||
| RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect) | RelativeRectangle::RelativeRectangle (const Rectangle<float>& rect) | ||||
| : left (rect.getX()), | : left (rect.getX()), | ||||
| right (Expression::symbol (RelativeCoordinate::Strings::this_ + "." + RelativeCoordinate::Strings::left) | |||||
| + Expression ((double) rect.getWidth())), | |||||
| right (Expression::symbol (RelativeCoordinate::Strings::left) + Expression ((double) rect.getWidth())), | |||||
| top (rect.getY()), | top (rect.getY()), | ||||
| bottom (Expression::symbol (RelativeCoordinate::Strings::this_ + "." + RelativeCoordinate::Strings::top) | |||||
| + Expression ((double) rect.getHeight())) | |||||
| bottom (Expression::symbol (RelativeCoordinate::Strings::top) + Expression ((double) rect.getHeight())) | |||||
| { | { | ||||
| } | } | ||||
| @@ -105,22 +115,59 @@ bool RelativeRectangle::operator!= (const RelativeRectangle& other) const throw( | |||||
| return ! operator== (other); | return ! operator== (other); | ||||
| } | } | ||||
| const Rectangle<float> RelativeRectangle::resolve (const Expression::EvaluationContext* context) const | |||||
| //============================================================================== | |||||
| // An expression context that can evaluate expressions using "this" | |||||
| class RelativeRectangleLocalScope : public Expression::Scope | |||||
| { | { | ||||
| const double l = left.resolve (context); | |||||
| const double r = right.resolve (context); | |||||
| const double t = top.resolve (context); | |||||
| const double b = bottom.resolve (context); | |||||
| public: | |||||
| RelativeRectangleLocalScope (const RelativeRectangle& rect_) : rect (rect_) {} | |||||
| const Expression getSymbolValue (const String& symbol) const | |||||
| { | |||||
| switch (RelativeCoordinate::StandardStrings::getTypeOf (symbol)) | |||||
| { | |||||
| case RelativeCoordinate::StandardStrings::x: | |||||
| case RelativeCoordinate::StandardStrings::left: return rect.left.getExpression(); | |||||
| case RelativeCoordinate::StandardStrings::y: | |||||
| case RelativeCoordinate::StandardStrings::top: return rect.top.getExpression(); | |||||
| case RelativeCoordinate::StandardStrings::right: return rect.right.getExpression(); | |||||
| case RelativeCoordinate::StandardStrings::bottom: return rect.bottom.getExpression(); | |||||
| default: break; | |||||
| } | |||||
| return Rectangle<float> ((float) l, (float) t, (float) jmax (0.0, r - l), (float) jmax (0.0, b - t)); | |||||
| return Expression::Scope::getSymbolValue (symbol); | |||||
| } | |||||
| private: | |||||
| const RelativeRectangle& rect; | |||||
| JUCE_DECLARE_NON_COPYABLE (RelativeRectangleLocalScope); | |||||
| }; | |||||
| const Rectangle<float> RelativeRectangle::resolve (const Expression::Scope* scope) const | |||||
| { | |||||
| if (scope == 0) | |||||
| { | |||||
| RelativeRectangleLocalScope scope (*this); | |||||
| return resolve (&scope); | |||||
| } | |||||
| else | |||||
| { | |||||
| const double l = left.resolve (scope); | |||||
| const double r = right.resolve (scope); | |||||
| const double t = top.resolve (scope); | |||||
| const double b = bottom.resolve (scope); | |||||
| return Rectangle<float> ((float) l, (float) t, (float) jmax (0.0, r - l), (float) jmax (0.0, b - t)); | |||||
| } | |||||
| } | } | ||||
| void RelativeRectangle::moveToAbsolute (const Rectangle<float>& newPos, const Expression::EvaluationContext* context) | |||||
| void RelativeRectangle::moveToAbsolute (const Rectangle<float>& newPos, const Expression::Scope* scope) | |||||
| { | { | ||||
| left.moveToAbsolute (newPos.getX(), context); | |||||
| right.moveToAbsolute (newPos.getRight(), context); | |||||
| top.moveToAbsolute (newPos.getY(), context); | |||||
| bottom.moveToAbsolute (newPos.getBottom(), context); | |||||
| left.moveToAbsolute (newPos.getX(), scope); | |||||
| right.moveToAbsolute (newPos.getRight(), scope); | |||||
| top.moveToAbsolute (newPos.getY(), scope); | |||||
| bottom.moveToAbsolute (newPos.getBottom(), scope); | |||||
| } | } | ||||
| bool RelativeRectangle::isDynamic() const | bool RelativeRectangle::isDynamic() const | ||||
| @@ -138,12 +185,12 @@ const String RelativeRectangle::toString() const | |||||
| return left.toString() + ", " + top.toString() + ", " + right.toString() + ", " + bottom.toString(); | return left.toString() + ", " + top.toString() + ", " + right.toString() + ", " + bottom.toString(); | ||||
| } | } | ||||
| void RelativeRectangle::renameSymbolIfUsed (const String& oldName, const String& newName) | |||||
| void RelativeRectangle::renameSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Expression::Scope& scope) | |||||
| { | { | ||||
| left.renameSymbolIfUsed (oldName, newName); | |||||
| right.renameSymbolIfUsed (oldName, newName); | |||||
| top.renameSymbolIfUsed (oldName, newName); | |||||
| bottom.renameSymbolIfUsed (oldName, newName); | |||||
| left = left.getExpression().withRenamedSymbol (oldSymbol, newName, scope); | |||||
| right = right.getExpression().withRenamedSymbol (oldSymbol, newName, scope); | |||||
| top = top.getExpression().withRenamedSymbol (oldSymbol, newName, scope); | |||||
| bottom = bottom.getExpression().withRenamedSymbol (oldSymbol, newName, scope); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -174,7 +221,8 @@ public: | |||||
| { | { | ||||
| for (int i = 4; --i >= 0;) | for (int i = 4; --i >= 0;) | ||||
| { | { | ||||
| const Rectangle<int> newBounds (rectangle.resolve (this).getSmallestIntegerContainer()); | |||||
| ComponentScope scope (getComponent()); | |||||
| const Rectangle<int> newBounds (rectangle.resolve (&scope).getSmallestIntegerContainer()); | |||||
| if (newBounds == getComponent().getBounds()) | if (newBounds == getComponent().getBounds()) | ||||
| return; | return; | ||||
| @@ -191,31 +239,6 @@ private: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeRectangleComponentPositioner); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativeRectangleComponentPositioner); | ||||
| }; | }; | ||||
| // An expression context that can evaluate expressions using "this" | |||||
| class TemporaryRectangleContext : public Expression::EvaluationContext | |||||
| { | |||||
| public: | |||||
| TemporaryRectangleContext (const RelativeRectangle& rect_) : rect (rect_) {} | |||||
| const Expression getSymbolValue (const String& objectName, const String& edge) const | |||||
| { | |||||
| if (objectName == RelativeCoordinate::Strings::this_) | |||||
| { | |||||
| if (edge == RelativeCoordinate::Strings::left) return rect.left.getExpression(); | |||||
| if (edge == RelativeCoordinate::Strings::right) return rect.right.getExpression(); | |||||
| if (edge == RelativeCoordinate::Strings::top) return rect.top.getExpression(); | |||||
| if (edge == RelativeCoordinate::Strings::bottom) return rect.bottom.getExpression(); | |||||
| } | |||||
| return Expression::EvaluationContext::getSymbolValue (objectName, edge); | |||||
| } | |||||
| private: | |||||
| const RelativeRectangle& rect; | |||||
| JUCE_DECLARE_NON_COPYABLE (TemporaryRectangleContext); | |||||
| }; | |||||
| void RelativeRectangle::applyToComponent (Component& component) const | void RelativeRectangle::applyToComponent (Component& component) const | ||||
| { | { | ||||
| if (isDynamic()) | if (isDynamic()) | ||||
| @@ -233,9 +256,7 @@ void RelativeRectangle::applyToComponent (Component& component) const | |||||
| else | else | ||||
| { | { | ||||
| component.setPositioner (0); | component.setPositioner (0); | ||||
| TemporaryRectangleContext context (*this); | |||||
| component.setBounds (resolve (&context).getSmallestIntegerContainer()); | |||||
| component.setBounds (resolve (0).getSmallestIntegerContainer()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -65,10 +65,10 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Calculates the absolute position of this rectangle. | /** Calculates the absolute position of this rectangle. | ||||
| You'll need to provide a suitable Expression::EvaluationContext for looking up any coordinates that may | |||||
| You'll need to provide a suitable Expression::Scope for looking up any coordinates that may | |||||
| be needed to calculate the result. | be needed to calculate the result. | ||||
| */ | */ | ||||
| const Rectangle<float> resolve (const Expression::EvaluationContext* evaluationContext) const; | |||||
| const Rectangle<float> resolve (const Expression::Scope* scope) const; | |||||
| /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. | ||||
| @@ -76,7 +76,7 @@ public: | |||||
| or relative positions to whatever values are necessary to make the resultant position | or relative positions to whatever values are necessary to make the resultant position | ||||
| match the position that is provided. | match the position that is provided. | ||||
| */ | */ | ||||
| void moveToAbsolute (const Rectangle<float>& newPos, const Expression::EvaluationContext* evaluationContext); | |||||
| void moveToAbsolute (const Rectangle<float>& newPos, const Expression::Scope* scope); | |||||
| /** Returns true if this rectangle depends on any external symbols for its position. | /** Returns true if this rectangle depends on any external symbols for its position. | ||||
| Coordinates that refer to symbols based on "this" are assumed not to be dynamic. | Coordinates that refer to symbols based on "this" are assumed not to be dynamic. | ||||
| @@ -91,9 +91,9 @@ public: | |||||
| const String toString() const; | const String toString() const; | ||||
| /** Renames a symbol if it is used by any of the coordinates. | /** Renames a symbol if it is used by any of the coordinates. | ||||
| This calls RelativeCoordinate::renameSymbolIfUsed() on the rectangle's coordinates. | |||||
| This calls Expression::withRenamedSymbol() on the rectangle's coordinates. | |||||
| */ | */ | ||||
| void renameSymbolIfUsed (const String& oldName, const String& newName); | |||||
| void renameSymbol (const Expression::Symbol& oldSymbol, const String& newName, const Expression::Scope& scope); | |||||
| /** Creates and sets an appropriate Component::Positioner object for the given component, which will | /** Creates and sets an appropriate Component::Positioner object for the given component, which will | ||||
| keep it positioned with this rectangle. | keep it positioned with this rectangle. | ||||
| @@ -228,7 +228,11 @@ protected: | |||||
| {} | {} | ||||
| bool registerCoordinates() { return owner.registerCoordinates (*this); } | bool registerCoordinates() { return owner.registerCoordinates (*this); } | ||||
| void applyToComponentBounds() { owner.recalculateCoordinates (this); } | |||||
| void applyToComponentBounds() | |||||
| { | |||||
| ComponentScope scope (getComponent()); | |||||
| owner.recalculateCoordinates (&scope); | |||||
| } | |||||
| private: | private: | ||||
| DrawableType& owner; | DrawableType& owner; | ||||
| @@ -153,12 +153,12 @@ bool DrawableComposite::registerCoordinates (RelativeCoordinatePositionerBase& p | |||||
| return positioner.addPoint (bounds.bottomLeft) && ok; | return positioner.addPoint (bounds.bottomLeft) && ok; | ||||
| } | } | ||||
| void DrawableComposite::recalculateCoordinates (Expression::EvaluationContext* context) | |||||
| void DrawableComposite::recalculateCoordinates (Expression::Scope* scope) | |||||
| { | { | ||||
| Point<float> resolved[3]; | Point<float> resolved[3]; | ||||
| bounds.resolveThreePoints (resolved, context); | |||||
| bounds.resolveThreePoints (resolved, scope); | |||||
| const Rectangle<float> content (getContentArea().resolve (context)); | |||||
| const Rectangle<float> content (getContentArea().resolve (scope)); | |||||
| AffineTransform t (AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].getX(), resolved[0].getY(), | AffineTransform t (AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].getX(), resolved[0].getY(), | ||||
| content.getRight(), content.getY(), resolved[1].getX(), resolved[1].getY(), | content.getRight(), content.getY(), resolved[1].getX(), resolved[1].getY(), | ||||
| @@ -150,7 +150,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableComposite>; | friend class Drawable::Positioner<DrawableComposite>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| void updateBoundsToFitChildren(); | void updateBoundsToFitChildren(); | ||||
| @@ -106,12 +106,12 @@ bool DrawableImage::registerCoordinates (RelativeCoordinatePositionerBase& posit | |||||
| return positioner.addPoint (bounds.bottomLeft) && ok; | return positioner.addPoint (bounds.bottomLeft) && ok; | ||||
| } | } | ||||
| void DrawableImage::recalculateCoordinates (Expression::EvaluationContext* context) | |||||
| void DrawableImage::recalculateCoordinates (Expression::Scope* scope) | |||||
| { | { | ||||
| if (image.isValid()) | if (image.isValid()) | ||||
| { | { | ||||
| Point<float> resolved[3]; | Point<float> resolved[3]; | ||||
| bounds.resolveThreePoints (resolved, context); | |||||
| bounds.resolveThreePoints (resolved, scope); | |||||
| const Point<float> tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); | const Point<float> tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); | ||||
| const Point<float> bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); | const Point<float> bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); | ||||
| @@ -133,7 +133,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableImage>; | friend class Drawable::Positioner<DrawableImage>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| DrawableImage& operator= (const DrawableImage&); | DrawableImage& operator= (const DrawableImage&); | ||||
| JUCE_LEAK_DETECTOR (DrawableImage); | JUCE_LEAK_DETECTOR (DrawableImage); | ||||
| @@ -72,10 +72,10 @@ const Path& DrawablePath::getStrokePath() const | |||||
| return strokePath; | return strokePath; | ||||
| } | } | ||||
| void DrawablePath::applyRelativePath (const RelativePointPath& newRelativePath, Expression::EvaluationContext* context) | |||||
| void DrawablePath::applyRelativePath (const RelativePointPath& newRelativePath, Expression::Scope* scope) | |||||
| { | { | ||||
| Path newPath; | Path newPath; | ||||
| newRelativePath.createPath (newPath, context); | |||||
| newRelativePath.createPath (newPath, scope); | |||||
| if (path != newPath) | if (path != newPath) | ||||
| { | { | ||||
| @@ -118,7 +118,9 @@ public: | |||||
| void applyToComponentBounds() | void applyToComponentBounds() | ||||
| { | { | ||||
| jassert (owner.relativePath != 0); | jassert (owner.relativePath != 0); | ||||
| owner.applyRelativePath (*owner.relativePath, this); | |||||
| ComponentScope scope (getComponent()); | |||||
| owner.applyRelativePath (*owner.relativePath, &scope); | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -299,26 +301,26 @@ const RelativePoint DrawablePath::ValueTreeWrapper::Element::getEndPoint() const | |||||
| return RelativePoint(); | return RelativePoint(); | ||||
| } | } | ||||
| float DrawablePath::ValueTreeWrapper::Element::getLength (Expression::EvaluationContext* context) const | |||||
| float DrawablePath::ValueTreeWrapper::Element::getLength (Expression::Scope* scope) const | |||||
| { | { | ||||
| const Identifier i (state.getType()); | const Identifier i (state.getType()); | ||||
| if (i == lineToElement || i == closeSubPathElement) | if (i == lineToElement || i == closeSubPathElement) | ||||
| return getEndPoint().resolve (context).getDistanceFrom (getStartPoint().resolve (context)); | |||||
| return getEndPoint().resolve (scope).getDistanceFrom (getStartPoint().resolve (scope)); | |||||
| if (i == cubicToElement) | if (i == cubicToElement) | ||||
| { | { | ||||
| Path p; | Path p; | ||||
| p.startNewSubPath (getStartPoint().resolve (context)); | |||||
| p.cubicTo (getControlPoint (0).resolve (context), getControlPoint (1).resolve (context), getControlPoint (2).resolve (context)); | |||||
| p.startNewSubPath (getStartPoint().resolve (scope)); | |||||
| p.cubicTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope), getControlPoint (2).resolve (scope)); | |||||
| return p.getLength(); | return p.getLength(); | ||||
| } | } | ||||
| if (i == quadraticToElement) | if (i == quadraticToElement) | ||||
| { | { | ||||
| Path p; | Path p; | ||||
| p.startNewSubPath (getStartPoint().resolve (context)); | |||||
| p.quadraticTo (getControlPoint (0).resolve (context), getControlPoint (1).resolve (context)); | |||||
| p.startNewSubPath (getStartPoint().resolve (scope)); | |||||
| p.quadraticTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope)); | |||||
| return p.getLength(); | return p.getLength(); | ||||
| } | } | ||||
| @@ -350,7 +352,7 @@ void DrawablePath::ValueTreeWrapper::Element::convertToLine (UndoManager* undoMa | |||||
| } | } | ||||
| } | } | ||||
| void DrawablePath::ValueTreeWrapper::Element::convertToCubic (Expression::EvaluationContext* context, UndoManager* undoManager) | |||||
| void DrawablePath::ValueTreeWrapper::Element::convertToCubic (Expression::Scope* scope, UndoManager* undoManager) | |||||
| { | { | ||||
| const Identifier i (state.getType()); | const Identifier i (state.getType()); | ||||
| @@ -361,8 +363,8 @@ void DrawablePath::ValueTreeWrapper::Element::convertToCubic (Expression::Evalua | |||||
| const RelativePoint start (getStartPoint()); | const RelativePoint start (getStartPoint()); | ||||
| const RelativePoint end (getEndPoint()); | const RelativePoint end (getEndPoint()); | ||||
| const Point<float> startResolved (start.resolve (context)); | |||||
| const Point<float> endResolved (end.resolve (context)); | |||||
| const Point<float> startResolved (start.resolve (scope)); | |||||
| const Point<float> endResolved (end.resolve (scope)); | |||||
| e.setControlPoint (0, startResolved + (endResolved - startResolved) * 0.3f, undoManager); | e.setControlPoint (0, startResolved + (endResolved - startResolved) * 0.3f, undoManager); | ||||
| e.setControlPoint (1, startResolved + (endResolved - startResolved) * 0.7f, undoManager); | e.setControlPoint (1, startResolved + (endResolved - startResolved) * 0.7f, undoManager); | ||||
| e.setControlPoint (2, end, undoManager); | e.setControlPoint (2, end, undoManager); | ||||
| @@ -407,7 +409,7 @@ namespace DrawablePathHelpers | |||||
| } | } | ||||
| } | } | ||||
| float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, Expression::EvaluationContext* context) const | |||||
| float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, Expression::Scope* scope) const | |||||
| { | { | ||||
| using namespace DrawablePathHelpers; | using namespace DrawablePathHelpers; | ||||
| const Identifier type (state.getType()); | const Identifier type (state.getType()); | ||||
| @@ -417,7 +419,7 @@ float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Po | |||||
| { | { | ||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (context), rp2.resolve (context), rp3.resolve (context), rp4.resolve (context) }; | |||||
| const Point<float> points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; | |||||
| float bestDistance = std::numeric_limits<float>::max(); | float bestDistance = std::numeric_limits<float>::max(); | ||||
| @@ -437,7 +439,7 @@ float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Po | |||||
| else if (type == quadraticToElement) | else if (type == quadraticToElement) | ||||
| { | { | ||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (context), rp2.resolve (context), rp3.resolve (context) }; | |||||
| const Point<float> points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; | |||||
| float bestDistance = std::numeric_limits<float>::max(); | float bestDistance = std::numeric_limits<float>::max(); | ||||
| @@ -457,24 +459,24 @@ float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Po | |||||
| else if (type == lineToElement) | else if (type == lineToElement) | ||||
| { | { | ||||
| RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); | ||||
| const Line<float> line (rp1.resolve (context), rp2.resolve (context)); | |||||
| const Line<float> line (rp1.resolve (scope), rp2.resolve (scope)); | |||||
| bestProp = line.findNearestProportionalPositionTo (targetPoint); | bestProp = line.findNearestProportionalPositionTo (targetPoint); | ||||
| } | } | ||||
| return bestProp; | return bestProp; | ||||
| } | } | ||||
| ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<float>& targetPoint, Expression::EvaluationContext* context, UndoManager* undoManager) | |||||
| ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<float>& targetPoint, Expression::Scope* scope, UndoManager* undoManager) | |||||
| { | { | ||||
| ValueTree newTree; | ValueTree newTree; | ||||
| const Identifier type (state.getType()); | const Identifier type (state.getType()); | ||||
| if (type == cubicToElement) | if (type == cubicToElement) | ||||
| { | { | ||||
| float bestProp = findProportionAlongLine (targetPoint, context); | |||||
| float bestProp = findProportionAlongLine (targetPoint, scope); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (context), rp2.resolve (context), rp3.resolve (context), rp4.resolve (context) }; | |||||
| const Point<float> points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; | |||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp), | ||||
| mid2 (points[1] + (points[2] - points[1]) * bestProp), | mid2 (points[1] + (points[2] - points[1]) * bestProp), | ||||
| @@ -499,10 +501,10 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| } | } | ||||
| else if (type == quadraticToElement) | else if (type == quadraticToElement) | ||||
| { | { | ||||
| float bestProp = findProportionAlongLine (targetPoint, context); | |||||
| float bestProp = findProportionAlongLine (targetPoint, scope); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (context), rp2.resolve (context), rp3.resolve (context) }; | |||||
| const Point<float> points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; | |||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * bestProp), | ||||
| mid2 (points[1] + (points[2] - points[1]) * bestProp); | mid2 (points[1] + (points[2] - points[1]) * bestProp); | ||||
| @@ -522,7 +524,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| else if (type == lineToElement) | else if (type == lineToElement) | ||||
| { | { | ||||
| RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); | ||||
| const Line<float> line (rp1.resolve (context), rp2.resolve (context)); | |||||
| const Line<float> line (rp1.resolve (scope), rp2.resolve (scope)); | |||||
| const Point<float> newPoint (line.findNearestPointTo (targetPoint)); | const Point<float> newPoint (line.findNearestPointTo (targetPoint)); | ||||
| setControlPoint (0, newPoint, undoManager); | setControlPoint (0, newPoint, undoManager); | ||||
| @@ -101,7 +101,7 @@ public: | |||||
| const RelativePoint getStartPoint() const; | const RelativePoint getStartPoint() const; | ||||
| const RelativePoint getEndPoint() const; | const RelativePoint getEndPoint() const; | ||||
| void setControlPoint (int index, const RelativePoint& point, UndoManager*); | void setControlPoint (int index, const RelativePoint& point, UndoManager*); | ||||
| float getLength (Expression::EvaluationContext*) const; | |||||
| float getLength (Expression::Scope*) const; | |||||
| ValueTreeWrapper getParent() const; | ValueTreeWrapper getParent() const; | ||||
| Element getPreviousElement() const; | Element getPreviousElement() const; | ||||
| @@ -110,11 +110,11 @@ public: | |||||
| void setModeOfEndPoint (const String& newMode, UndoManager*); | void setModeOfEndPoint (const String& newMode, UndoManager*); | ||||
| void convertToLine (UndoManager*); | void convertToLine (UndoManager*); | ||||
| void convertToCubic (Expression::EvaluationContext*, UndoManager*); | |||||
| void convertToCubic (Expression::Scope*, UndoManager*); | |||||
| void convertToPathBreak (UndoManager* undoManager); | void convertToPathBreak (UndoManager* undoManager); | ||||
| ValueTree insertPoint (const Point<float>& targetPoint, Expression::EvaluationContext*, UndoManager*); | |||||
| ValueTree insertPoint (const Point<float>& targetPoint, Expression::Scope*, UndoManager*); | |||||
| void removePoint (UndoManager* undoManager); | void removePoint (UndoManager* undoManager); | ||||
| float findProportionAlongLine (const Point<float>& targetPoint, Expression::EvaluationContext*) const; | |||||
| float findProportionAlongLine (const Point<float>& targetPoint, Expression::Scope*) const; | |||||
| static const Identifier mode, startSubPathElement, closeSubPathElement, | static const Identifier mode, startSubPathElement, closeSubPathElement, | ||||
| lineToElement, quadraticToElement, cubicToElement; | lineToElement, quadraticToElement, cubicToElement; | ||||
| @@ -139,7 +139,7 @@ private: | |||||
| class RelativePositioner; | class RelativePositioner; | ||||
| friend class RelativePositioner; | friend class RelativePositioner; | ||||
| void applyRelativePath (const RelativePointPath&, Expression::EvaluationContext*); | |||||
| void applyRelativePath (const RelativePointPath&, Expression::Scope*); | |||||
| DrawablePath& operator= (const DrawablePath&); | DrawablePath& operator= (const DrawablePath&); | ||||
| JUCE_LEAK_DETECTOR (DrawablePath); | JUCE_LEAK_DETECTOR (DrawablePath); | ||||
| @@ -95,13 +95,13 @@ bool DrawableRectangle::registerCoordinates (RelativeCoordinatePositionerBase& p | |||||
| return positioner.addPoint (cornerSize) && ok; | return positioner.addPoint (cornerSize) && ok; | ||||
| } | } | ||||
| void DrawableRectangle::recalculateCoordinates (Expression::EvaluationContext* context) | |||||
| void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope) | |||||
| { | { | ||||
| Point<float> points[3]; | Point<float> points[3]; | ||||
| bounds.resolveThreePoints (points, context); | |||||
| bounds.resolveThreePoints (points, scope); | |||||
| const float cornerSizeX = (float) cornerSize.x.resolve (context); | |||||
| const float cornerSizeY = (float) cornerSize.y.resolve (context); | |||||
| const float cornerSizeX = (float) cornerSize.x.resolve (scope); | |||||
| const float cornerSizeY = (float) cornerSize.y.resolve (scope); | |||||
| const float w = Line<float> (points[0], points[1]).getLength(); | const float w = Line<float> (points[0], points[1]).getLength(); | ||||
| const float h = Line<float> (points[0], points[2]).getLength(); | const float h = Line<float> (points[0], points[2]).getLength(); | ||||
| @@ -97,7 +97,7 @@ private: | |||||
| void rebuildPath(); | void rebuildPath(); | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| DrawableRectangle& operator= (const DrawableRectangle&); | DrawableRectangle& operator= (const DrawableRectangle&); | ||||
| JUCE_LEAK_DETECTOR (DrawableRectangle); | JUCE_LEAK_DETECTOR (DrawableRectangle); | ||||
| @@ -71,8 +71,9 @@ public: | |||||
| void applyToComponentBounds() | void applyToComponentBounds() | ||||
| { | { | ||||
| if (isMainFill ? owner.mainFill.recalculateCoords (this) | |||||
| : owner.strokeFill.recalculateCoords (this)) | |||||
| ComponentScope scope (owner); | |||||
| if (isMainFill ? owner.mainFill.recalculateCoords (&scope) | |||||
| : owner.strokeFill.recalculateCoords (&scope)) | |||||
| owner.repaint(); | owner.repaint(); | ||||
| } | } | ||||
| @@ -256,19 +257,19 @@ bool DrawableShape::RelativeFillType::operator!= (const RelativeFillType& other) | |||||
| return ! operator== (other); | return ! operator== (other); | ||||
| } | } | ||||
| bool DrawableShape::RelativeFillType::recalculateCoords (Expression::EvaluationContext* context) | |||||
| bool DrawableShape::RelativeFillType::recalculateCoords (Expression::Scope* scope) | |||||
| { | { | ||||
| if (fill.isGradient()) | if (fill.isGradient()) | ||||
| { | { | ||||
| const Point<float> g1 (gradientPoint1.resolve (context)); | |||||
| const Point<float> g2 (gradientPoint2.resolve (context)); | |||||
| const Point<float> g1 (gradientPoint1.resolve (scope)); | |||||
| const Point<float> g2 (gradientPoint2.resolve (scope)); | |||||
| AffineTransform t; | AffineTransform t; | ||||
| ColourGradient& g = *fill.gradient; | ColourGradient& g = *fill.gradient; | ||||
| if (g.isRadial) | if (g.isRadial) | ||||
| { | { | ||||
| const Point<float> g3 (gradientPoint3.resolve (context)); | |||||
| const Point<float> g3 (gradientPoint3.resolve (scope)); | |||||
| const Point<float> g3Source (g1.getX() + g2.getY() - g1.getY(), | const Point<float> g3Source (g1.getX() + g2.getY() - g1.getY(), | ||||
| g1.getY() + g1.getX() - g2.getX()); | g1.getY() + g1.getX() - g2.getX()); | ||||
| @@ -65,7 +65,7 @@ public: | |||||
| bool operator!= (const RelativeFillType&) const; | bool operator!= (const RelativeFillType&) const; | ||||
| bool isDynamic() const; | bool isDynamic() const; | ||||
| bool recalculateCoords (Expression::EvaluationContext* context); | |||||
| bool recalculateCoords (Expression::Scope* scope); | |||||
| void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; | void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; | ||||
| bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); | bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); | ||||
| @@ -138,14 +138,14 @@ bool DrawableText::registerCoordinates (RelativeCoordinatePositionerBase& positi | |||||
| return positioner.addPoint (fontSizeControlPoint) && ok; | return positioner.addPoint (fontSizeControlPoint) && ok; | ||||
| } | } | ||||
| void DrawableText::recalculateCoordinates (Expression::EvaluationContext* context) | |||||
| void DrawableText::recalculateCoordinates (Expression::Scope* scope) | |||||
| { | { | ||||
| bounds.resolveThreePoints (resolvedPoints, context); | |||||
| bounds.resolveThreePoints (resolvedPoints, scope); | |||||
| const float w = Line<float> (resolvedPoints[0], resolvedPoints[1]).getLength(); | const float w = Line<float> (resolvedPoints[0], resolvedPoints[1]).getLength(); | ||||
| const float h = Line<float> (resolvedPoints[0], resolvedPoints[2]).getLength(); | const float h = Line<float> (resolvedPoints[0], resolvedPoints[2]).getLength(); | ||||
| const Point<float> fontCoords (RelativeParallelogram::getInternalCoordForPoint (resolvedPoints, fontSizeControlPoint.resolve (context))); | |||||
| const Point<float> fontCoords (RelativeParallelogram::getInternalCoordForPoint (resolvedPoints, fontSizeControlPoint.resolve (scope))); | |||||
| const float fontHeight = jlimit (0.01f, jmax (0.01f, h), fontCoords.getY()); | const float fontHeight = jlimit (0.01f, jmax (0.01f, h), fontCoords.getY()); | ||||
| const float fontWidth = jlimit (0.01f, jmax (0.01f, w), fontCoords.getX()); | const float fontWidth = jlimit (0.01f, jmax (0.01f, w), fontCoords.getX()); | ||||
| @@ -142,7 +142,7 @@ private: | |||||
| friend class Drawable::Positioner<DrawableText>; | friend class Drawable::Positioner<DrawableText>; | ||||
| bool registerCoordinates (RelativeCoordinatePositionerBase&); | bool registerCoordinates (RelativeCoordinatePositionerBase&); | ||||
| void recalculateCoordinates (Expression::EvaluationContext*); | |||||
| void recalculateCoordinates (Expression::Scope*); | |||||
| void refreshBounds(); | void refreshBounds(); | ||||
| const AffineTransform getArrangementAndTransform (GlyphArrangement& glyphs) const; | const AffineTransform getArrangementAndTransform (GlyphArrangement& glyphs) const; | ||||
| @@ -42,7 +42,7 @@ | |||||
| evaluated. | evaluated. | ||||
| Expressions which use identifiers and functions require a subclass of | Expressions which use identifiers and functions require a subclass of | ||||
| Expression::EvaluationContext to be supplied when evaluating them, and this object | |||||
| Expression::Scope to be supplied when evaluating them, and this object | |||||
| is expected to be able to resolve the symbol names and perform the functions that | is expected to be able to resolve the symbol names and perform the functions that | ||||
| are used. | are used. | ||||
| */ | */ | ||||
| @@ -105,11 +105,14 @@ public: | |||||
| /** When evaluating an Expression object, this class is used to resolve symbols and | /** When evaluating an Expression object, this class is used to resolve symbols and | ||||
| perform functions that the expression uses. | perform functions that the expression uses. | ||||
| */ | */ | ||||
| class JUCE_API EvaluationContext | |||||
| class JUCE_API Scope | |||||
| { | { | ||||
| public: | public: | ||||
| EvaluationContext(); | |||||
| virtual ~EvaluationContext(); | |||||
| Scope(); | |||||
| virtual ~Scope(); | |||||
| /** Returns some kind of globally unique ID that identifies this scope. */ | |||||
| virtual const String getScopeUID() const; | |||||
| /** Returns the value of a symbol. | /** Returns the value of a symbol. | ||||
| If the symbol is unknown, this can throw an Expression::EvaluationError exception. | If the symbol is unknown, this can throw an Expression::EvaluationError exception. | ||||
| @@ -117,55 +120,97 @@ public: | |||||
| one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | one, e.g. for "foo.bar", symbol = "foo" and member = "bar". | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| virtual const Expression getSymbolValue (const String& symbol, const String& member) const; | |||||
| virtual const Expression getSymbolValue (const String& symbol) const; | |||||
| /** Executes a named function. | /** Executes a named function. | ||||
| If the function name is unknown, this can throw an Expression::EvaluationError exception. | If the function name is unknown, this can throw an Expression::EvaluationError exception. | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| virtual double evaluateFunction (const String& functionName, const double* parameters, int numParams) const; | |||||
| virtual double evaluateFunction (const String& functionName, | |||||
| const double* parameters, int numParameters) const; | |||||
| /** Used as a callback by the Scope::visitRelativeScope() method. | |||||
| You should never create an instance of this class yourself, it's used by the | |||||
| expression evaluation code. | |||||
| */ | |||||
| class Visitor | |||||
| { | |||||
| public: | |||||
| virtual ~Visitor() {} | |||||
| virtual void visit (const Scope&) = 0; | |||||
| }; | |||||
| /** Creates a Scope object for a named scope, and then calls a visitor | |||||
| to do some kind of processing with this new scope. | |||||
| If the name is valid, this method must create a suitable (temporary) Scope | |||||
| object to represent it, and must call the Visitor::visit() method with this | |||||
| new scope. | |||||
| */ | |||||
| virtual void visitRelativeScope (const String& scopeName, Visitor& visitor) const; | |||||
| }; | }; | ||||
| /** Evaluates this expression, without using an EvaluationContext. | |||||
| Without an EvaluationContext, no symbols can be used, and only basic functions such as sin, cos, tan, | |||||
| /** Evaluates this expression, without using a Scope. | |||||
| Without a Scope, no symbols can be used, and only basic functions such as sin, cos, tan, | |||||
| min, max are available. | min, max are available. | ||||
| @throws Expression::EvaluationError | |||||
| To find out about any errors during evaluation, use the other version of this method which | |||||
| takes a String parameter. | |||||
| */ | */ | ||||
| double evaluate() const; | double evaluate() const; | ||||
| /** Evaluates this expression, providing a context that should be able to evaluate any symbols | |||||
| /** Evaluates this expression, providing a scope that should be able to evaluate any symbols | |||||
| or functions that it uses. | or functions that it uses. | ||||
| @throws Expression::EvaluationError | |||||
| To find out about any errors during evaluation, use the other version of this method which | |||||
| takes a String parameter. | |||||
| */ | */ | ||||
| double evaluate (const EvaluationContext& context) const; | |||||
| double evaluate (const Scope& scope) const; | |||||
| /** Evaluates this expression, providing a scope that should be able to evaluate any symbols | |||||
| or functions that it uses. | |||||
| */ | |||||
| double evaluate (const Scope& scope, String& evaluationError) const; | |||||
| /** Attempts to return an expression which is a copy of this one, but with a constant adjusted | /** Attempts to return an expression which is a copy of this one, but with a constant adjusted | ||||
| to make the expression resolve to a target value. | to make the expression resolve to a target value. | ||||
| E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | E.g. if the expression is "x + 10" and x is 5, then asking for a target value of 8 will return | ||||
| the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | the expression "x + 3". Obviously some expressions can't be reversed in this way, in which | ||||
| case they might just be adjusted by adding a constant to them. | |||||
| case they might just be adjusted by adding a constant to the original expression. | |||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| const Expression adjustedToGiveNewResult (double targetValue, const EvaluationContext& context) const; | |||||
| const Expression adjustedToGiveNewResult (double targetValue, const Scope& scope) const; | |||||
| /** Represents a symbol that is used in an Expression. */ | |||||
| struct Symbol | |||||
| { | |||||
| Symbol (const String& scopeUID, const String& symbolName); | |||||
| bool operator== (const Symbol&) const throw(); | |||||
| bool operator!= (const Symbol&) const throw(); | |||||
| String scopeUID; /**< The unique ID of the Scope that contains this symbol. */ | |||||
| String symbolName; /**< The name of the symbol. */ | |||||
| }; | |||||
| /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ | /** Returns a copy of this expression in which all instances of a given symbol have been renamed. */ | ||||
| const Expression withRenamedSymbol (const String& oldSymbol, const String& newSymbol) const; | |||||
| const Expression withRenamedSymbol (const Symbol& oldSymbol, const String& newName, const Scope& scope) const; | |||||
| /** Returns true if this expression makes use of the specified symbol. | /** Returns true if this expression makes use of the specified symbol. | ||||
| If a suitable context is supplied, the search will dereference and recursively check | |||||
| If a suitable scope is supplied, the search will dereference and recursively check | |||||
| all symbols, so that it can be determined whether this expression relies on the given | all symbols, so that it can be determined whether this expression relies on the given | ||||
| symbol at any level in its evaluation. If the context parameter is null, this just checks | |||||
| symbol at any level in its evaluation. If the scope parameter is null, this just checks | |||||
| whether the expression contains any direct references to the symbol. | whether the expression contains any direct references to the symbol. | ||||
| @throws Expression::EvaluationError | @throws Expression::EvaluationError | ||||
| */ | */ | ||||
| bool referencesSymbol (const String& symbol, const EvaluationContext* context) const; | |||||
| bool referencesSymbol (const Symbol& symbol, const Scope& scope) const; | |||||
| /** Returns true if this expression contains any symbols. */ | /** Returns true if this expression contains any symbols. */ | ||||
| bool usesAnySymbols() const; | bool usesAnySymbols() const; | ||||
| /** Returns a list of all symbols that may be needed to resolve this expression in the given scope. */ | |||||
| void findReferencedSymbols (Array<Symbol>& results, const Scope& scope) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** An exception that can be thrown by Expression::parse(). */ | /** An exception that can be thrown by Expression::parse(). */ | ||||
| class ParseError : public std::exception | class ParseError : public std::exception | ||||
| @@ -176,17 +221,6 @@ public: | |||||
| String description; | String description; | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| /** An exception that can be thrown by Expression::evaluate(). */ | |||||
| class EvaluationError : public std::exception | |||||
| { | |||||
| public: | |||||
| EvaluationError (const String& message); | |||||
| EvaluationError (const String& symbolName, const String& memberName); | |||||
| String description; | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Expression type. | /** Expression type. | ||||
| @see Expression::getType() | @see Expression::getType() | ||||
| @@ -202,19 +236,8 @@ public: | |||||
| /** Returns the type of this expression. */ | /** Returns the type of this expression. */ | ||||
| Type getType() const throw(); | Type getType() const throw(); | ||||
| /** If this expression is a symbol, this returns its full name. */ | |||||
| const String getSymbol() const; | |||||
| /** For a symbol that contains a dot, this returns the two */ | |||||
| void getSymbolParts (String& objectName, String& memberName) const; | |||||
| /** If this expression is a function, this returns its name. */ | |||||
| const String getFunction() const; | |||||
| /** If this expression is an operator, this returns its name. | |||||
| E.g. "+", "-", "*", "/", etc. | |||||
| */ | |||||
| const String getOperator() const; | |||||
| /** If this expression is a symbol, function or operator, this returns its identifier. */ | |||||
| const String getSymbolOrFunction() const; | |||||
| /** Returns the number of inputs to this expression. | /** Returns the number of inputs to this expression. | ||||
| @see getInput | @see getInput | ||||
| @@ -228,35 +251,12 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| class Term; | |||||
| class Helpers; | class Helpers; | ||||
| friend class Term; | |||||
| friend class Helpers; | friend class Helpers; | ||||
| class Term : public ReferenceCountedObject | |||||
| { | |||||
| public: | |||||
| Term() {} | |||||
| virtual ~Term() {} | |||||
| virtual Term* clone() const = 0; | |||||
| virtual double evaluate (const EvaluationContext&, int recursionDepth) const = 0; | |||||
| virtual int getNumInputs() const = 0; | |||||
| virtual Term* getInput (int index) const = 0; | |||||
| virtual int getInputIndexFor (const Term* possibleInput) const; | |||||
| virtual const String toString() const = 0; | |||||
| virtual int getOperatorPrecedence() const; | |||||
| virtual bool referencesSymbol (const String& symbol, const EvaluationContext*, int recursionDepth) const; | |||||
| virtual const ReferenceCountedObjectPtr<Term> createTermToEvaluateInput (const EvaluationContext&, const Term* inputTerm, | |||||
| double overallTarget, Term* topLevelTerm) const; | |||||
| virtual const ReferenceCountedObjectPtr<Term> negated(); | |||||
| virtual Type getType() const throw() = 0; | |||||
| virtual void getSymbolParts (String& objectName, String& memberName) const; | |||||
| virtual const String getFunctionName() const; | |||||
| private: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Term); | |||||
| }; | |||||
| friend class ScopedPointer<Term>; | friend class ScopedPointer<Term>; | ||||
| friend class ReferenceCountedObjectPtr<Term>; | |||||
| ReferenceCountedObjectPtr<Term> term; | ReferenceCountedObjectPtr<Term> term; | ||||
| explicit Expression (Term* term); | explicit Expression (Term* term); | ||||