diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 0c34abf510..142a62f4fd 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -480,42 +480,10 @@ public: component's bounds when the source values change. See RelativeRectangle::applyToComponent() for more details. - When using relative expressions, the following symbols are available: - - "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 - 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 - if you wanted to make your component remain centred within its parent with a size of 100, 100, - you could express it as: - @code myComp.setBounds (RelativeBounds ("parent.width / 2 - 50, parent.height / 2 - 50, left + 100, top + 100")); - @endcode - ..or an alternative way to achieve the same thing: - @code myComp.setBounds (RelativeBounds ("right - 100, bottom - 100, parent.width / 2 + 50, parent.height / 2 + 50")); - @endcode - - 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: - @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, left + 100, top + 100")); - @endcode - - Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will - be thrown! - - @see setBounds, RelativeRectangle::applyToComponent(), Expression + For the syntax of the expressions that are allowed in the string, see the notes + for the RelativeCoordinate class. + + @see RelativeCoordinate, setBounds, RelativeRectangle::applyToComponent(), Expression */ void setBounds (const RelativeRectangle& newBounds); diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.h b/modules/juce_gui_basics/drawables/juce_Drawable.h index b8956d5a0f..1338d7e92a 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.h +++ b/modules/juce_gui_basics/drawables/juce_Drawable.h @@ -227,14 +227,15 @@ protected: owner (c) {} - bool registerCoordinates() { return owner.registerCoordinates (*this); } - void applyToComponentBounds() + bool registerCoordinates() override { return owner.registerCoordinates (*this); } + + void applyToComponentBounds() override { ComponentScope scope (getComponent()); owner.recalculateCoordinates (&scope); } - void applyNewBounds (const Rectangle&) + void applyNewBounds (const Rectangle&) override { jassertfalse; // drawables can't be resized directly! } diff --git a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp index 6dc46ba649..0b437a4b6a 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp @@ -83,7 +83,7 @@ public: { } - bool registerCoordinates() + bool registerCoordinates() override { bool ok = true; @@ -104,7 +104,7 @@ public: return ok; } - void applyToComponentBounds() + void applyToComponentBounds() override { jassert (owner.relativePath != nullptr); @@ -112,7 +112,7 @@ public: owner.applyRelativePath (*owner.relativePath, &scope); } - void applyNewBounds (const Rectangle&) + void applyNewBounds (const Rectangle&) override { jassertfalse; // drawables can't be resized directly! } diff --git a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp index 5813493c81..907aafac7a 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp @@ -53,14 +53,14 @@ public: { } - bool registerCoordinates() + bool registerCoordinates() override { bool ok = addPoint (fill.gradientPoint1); ok = addPoint (fill.gradientPoint2) && ok; return addPoint (fill.gradientPoint3) && ok; } - void applyToComponentBounds() + void applyToComponentBounds() override { ComponentScope scope (owner); if (isMainFill ? owner.mainFill.recalculateCoords (&scope) @@ -68,7 +68,7 @@ public: owner.repaint(); } - void applyNewBounds (const Rectangle&) + void applyNewBounds (const Rectangle&) override { jassertfalse; // drawables can't be resized directly! } diff --git a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h index c1f4eb4747..dbf5fcbe25 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h +++ b/modules/juce_gui_basics/positioning/juce_RelativeCoordinate.h @@ -30,6 +30,41 @@ /** Expresses a coordinate as a dynamically evaluated expression. + When using relative coordinates to position components, the following symbols are available: + - "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 + 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 + if you wanted to make your component remains centred within its parent with a size of 100, 100, + you could express it as: + @code myComp.setBounds (RelativeBounds ("parent.width / 2 - 50, parent.height / 2 - 50, left + 100, top + 100")); + @endcode + ..or an alternative way to achieve the same thing: + @code myComp.setBounds (RelativeBounds ("right - 100, bottom - 100, parent.width / 2 + 50, parent.height / 2 + 50")); + @endcode + + 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: + @code myComp.setBounds (RelativeBounds ("otherComp.right + 50, topMarker, left + 100, top + 100")); + @endcode + + Be careful not to make your coordinate expressions recursive, though, or exceptions and assertions will + be thrown! + @see RelativePoint, RelativeRectangle */ class JUCE_API RelativeCoordinate diff --git a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp index 1c706e0d93..a8ff7b7975 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp @@ -192,7 +192,7 @@ public: { } - bool registerCoordinates() + bool registerCoordinates() override { bool ok = addCoordinate (rectangle.left); ok = addCoordinate (rectangle.right) && ok; @@ -206,7 +206,7 @@ public: return rectangle == other; } - void applyToComponentBounds() + void applyToComponentBounds() override { for (int i = 32; --i >= 0;) { @@ -222,7 +222,7 @@ public: jassertfalse; // Seems to be a recursive reference! } - void applyNewBounds (const Rectangle& newBounds) + void applyNewBounds (const Rectangle& newBounds) override { if (newBounds != getComponent().getBounds()) {