| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2022 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 7 End-User License
 -    Agreement and JUCE Privacy Policy.
 - 
 -    End User License Agreement: www.juce.com/juce-7-licence
 -    Privacy Policy: www.juce.com/juce-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #pragma once
 - 
 - class ComponentLayout;
 - 
 - //==============================================================================
 - /**
 -     A rectangle whose coordinates can be defined in terms of absolute or
 -     proportional distances.
 - 
 -     Designed mainly for storing component positions, this gives you a lot of
 -     control over how each coordinate is stored, either as an absolute position,
 -     or as a proportion of the size of a parent rectangle.
 - 
 -     It also allows you to define the anchor points by which the rectangle is
 -     positioned, so for example you could specify that the top right of the
 -     rectangle should be an absolute distance from its parent's bottom-right corner.
 - 
 -     This object can be stored as a string, which takes the form "x y w h", including
 -     symbols like '%' and letters to indicate the anchor point. See its toString()
 -     method for more info.
 - 
 -     Example usage:
 -     @code
 -     class MyComponent
 -     {
 -         void resized()
 -         {
 -             // this will set the child component's x to be 20% of our width, its y
 -             // to be 30, its width to be 150, and its height to be 50% of our
 -             // height..
 -             const PositionedRectangle pos1 ("20% 30 150 50%");
 -             pos1.applyToComponent (*myChildComponent1);
 - 
 -             // this will inset the child component with a gap of 10 pixels
 -             // around each of its edges..
 -             const PositionedRectangle pos2 ("10 10 20M 20M");
 -             pos2.applyToComponent (*myChildComponent2);
 -         }
 -     };
 -     @endcode
 - */
 - class PositionedRectangle
 - {
 - public:
 -     //==============================================================================
 -     /** Creates an empty rectangle with all coordinates set to zero.
 - 
 -         The default anchor point is top-left; the default
 -     */
 -     PositionedRectangle() noexcept
 -         : x (0.0), y (0.0), w (0.0), h (0.0),
 -           xMode ((int) anchorAtLeftOrTop | (int) absoluteFromParentTopLeft),
 -           yMode ((int) anchorAtLeftOrTop | (int) absoluteFromParentTopLeft),
 -           wMode (absoluteSize), hMode (absoluteSize)
 -     {
 -     }
 - 
 -     /** Initialises a PositionedRectangle from a saved string version.
 - 
 -         The string must be in the format generated by toString().
 -     */
 -     PositionedRectangle (const String& stringVersion) noexcept
 -     {
 -         StringArray tokens;
 -         tokens.addTokens (stringVersion, false);
 - 
 -         decodePosString (tokens [0], xMode, x);
 -         decodePosString (tokens [1], yMode, y);
 -         decodeSizeString (tokens [2], wMode, w);
 -         decodeSizeString (tokens [3], hMode, h);
 -     }
 - 
 -     /** Creates a copy of another PositionedRectangle. */
 -     PositionedRectangle (const PositionedRectangle& other) noexcept
 -         : x (other.x), y (other.y), w (other.w), h (other.h),
 -           xMode (other.xMode), yMode (other.yMode),
 -           wMode (other.wMode), hMode (other.hMode)
 -     {
 -     }
 - 
 -     /** Copies another PositionedRectangle. */
 -     PositionedRectangle& operator= (const PositionedRectangle& other) noexcept
 -     {
 -         x = other.x;
 -         y = other.y;
 -         w = other.w;
 -         h = other.h;
 -         xMode = other.xMode;
 -         yMode = other.yMode;
 -         wMode = other.wMode;
 -         hMode = other.hMode;
 - 
 -         return *this;
 -     }
 - 
 -     //==============================================================================
 -     /** Returns a string version of this position, from which it can later be
 -         re-generated.
 - 
 -         The format is four coordinates, "x y w h".
 - 
 -         - If a coordinate is absolute, it is stored as an integer, e.g. "100".
 -         - If a coordinate is proportional to its parent's width or height, it is stored
 -           as a percentage, e.g. "80%".
 -         - If the X or Y coordinate is relative to the parent's right or bottom edge, the
 -           number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from
 -           the parent's right-hand edge.
 -         - If the X or Y coordinate is relative to the parent's centre, the number has "C"
 -           appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre.
 -         - If the X or Y coordinate should be anchored at the component's right or bottom
 -           edge, then it has "r" appended to it. So "-50Rr" would mean that this component's
 -           right-hand edge should be 50 pixels left of the parent's right-hand edge.
 -         - If the X or Y coordinate should be anchored at the component's centre, then it
 -           has "c" appended to it. So "-50Rc" would mean that this component's
 -           centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that
 -           this component's centre should be placed 40% across the parent's width.
 -         - If it's a width or height that should use the parentSizeMinusAbsolute mode, then
 -           the number has "M" appended to it.
 - 
 -         To reload a stored string, use the constructor that takes a string parameter.
 -     */
 -     String toString() const
 -     {
 -         String s;
 -         s.preallocateBytes (32);
 -         addPosDescription (s, xMode, x);  s << ' ';
 -         addPosDescription (s, yMode, y);  s << ' ';
 -         addSizeDescription (s, wMode, w); s << ' ';
 -         addSizeDescription (s, hMode, h);
 -         return s;
 -     }
 - 
 -     //==============================================================================
 -     /** Calculates the absolute position, given the size of the space that
 -         it should go in.
 - 
 -         This will work out any proportional distances and sizes relative to the
 -         target rectangle, and will return the absolute position.
 - 
 -         @see applyToComponent
 -     */
 -     Rectangle<int> getRectangle (const Rectangle<int>& target) const noexcept
 -     {
 -         jassert (! target.isEmpty());
 - 
 -         double x_, y_, w_, h_;
 -         applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth());
 -         applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight());
 -         return Rectangle<int> (roundToInt (x_), roundToInt (y_), roundToInt (w_), roundToInt (h_));
 -     }
 - 
 -     /** Same as getRectangle(), but returning the values as doubles rather than ints. */
 -     void getRectangleDouble (const Rectangle<int>& target,
 -                              double& x_, double& y_, double& w_, double& h_) const noexcept
 -     {
 -         jassert (! target.isEmpty());
 -         applyPosAndSize (x_, w_, x, w, xMode, wMode, target.getX(), target.getWidth());
 -         applyPosAndSize (y_, h_, y, h, yMode, hMode, target.getY(), target.getHeight());
 -     }
 - 
 -     /** This sets the bounds of the given component to this position.
 - 
 -         This is equivalent to writing:
 -         @code
 -         comp.setBounds (getRectangle (Rectangle<int> (0, 0, comp.getParentWidth(), comp.getParentHeight())));
 -         @endcode
 - 
 -         @see getRectangle, updateFromComponent
 -     */
 -     void applyToComponent (Component& comp) const noexcept
 -     {
 -         comp.setBounds (getRectangle (Rectangle<int> (comp.getParentWidth(), comp.getParentHeight())));
 -     }
 - 
 -     //==============================================================================
 -     /** Updates this object's coordinates to match the given rectangle.
 - 
 -         This will set all coordinates based on the given rectangle, re-calculating
 -         any proportional distances, and using the current anchor points.
 - 
 -         So for example if the x coordinate mode is currently proportional, this will
 -         re-calculate x based on the rectangle's relative position within the target
 -         rectangle's width.
 - 
 -         If the target rectangle's width or height are zero then it may not be possible
 -         to re-calculate some proportional coordinates. In this case, those coordinates
 -         will not be changed.
 -     */
 -     void updateFrom (const Rectangle<int>& newPosition,
 -                      const Rectangle<int>& targetSpaceToBeRelativeTo) noexcept
 -     {
 -         updatePosAndSize (x, w, newPosition.getX(), newPosition.getWidth(), xMode, wMode, targetSpaceToBeRelativeTo.getX(), targetSpaceToBeRelativeTo.getWidth());
 -         updatePosAndSize (y, h, newPosition.getY(), newPosition.getHeight(), yMode, hMode, targetSpaceToBeRelativeTo.getY(), targetSpaceToBeRelativeTo.getHeight());
 -     }
 - 
 -     /** Same functionality as updateFrom(), but taking doubles instead of ints.
 -     */
 -     void updateFromDouble (const double newX, const double newY,
 -                            const double newW, const double newH,
 -                            const Rectangle<int>& target) noexcept
 -     {
 -         updatePosAndSize (x, w, newX, newW, xMode, wMode, target.getX(), target.getWidth());
 -         updatePosAndSize (y, h, newY, newH, yMode, hMode, target.getY(), target.getHeight());
 -     }
 - 
 -     /** Updates this object's coordinates to match the bounds of this component.
 - 
 -         This is equivalent to calling updateFrom() with the component's bounds and
 -         it parent size.
 - 
 -         If the component doesn't currently have a parent, then proportional coordinates
 -         might not be updated because it would need to know the parent's size to do the
 -         maths for this.
 -     */
 -     void updateFromComponent (const Component& comp) noexcept
 -     {
 -         if (comp.getParentComponent() == nullptr && ! comp.isOnDesktop())
 -             updateFrom (comp.getBounds(), Rectangle<int>());
 -         else
 -             updateFrom (comp.getBounds(), Rectangle<int> (comp.getParentWidth(), comp.getParentHeight()));
 -     }
 - 
 -     //==============================================================================
 -     /** Specifies the point within the rectangle, relative to which it should be positioned. */
 -     enum AnchorPoint
 -     {
 -         anchorAtLeftOrTop              = 1 << 0,    /**< The x or y coordinate specifies where the left or top edge of the rectangle should be. */
 -         anchorAtRightOrBottom          = 1 << 1,    /**< The x or y coordinate specifies where the right or bottom edge of the rectangle should be. */
 -         anchorAtCentre                 = 1 << 2     /**< The x or y coordinate specifies where the centre of the rectangle should be. */
 -     };
 - 
 -     /** Specifies how an x or y coordinate should be interpreted. */
 -     enum PositionMode
 -     {
 -         absoluteFromParentTopLeft       = 1 << 3,   /**< The x or y coordinate specifies an absolute distance from the parent's top or left edge. */
 -         absoluteFromParentBottomRight   = 1 << 4,   /**< The x or y coordinate specifies an absolute distance from the parent's bottom or right edge. */
 -         absoluteFromParentCentre        = 1 << 5,   /**< The x or y coordinate specifies an absolute distance from the parent's centre. */
 -         proportionOfParentSize          = 1 << 6    /**< The x or y coordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */
 -     };
 - 
 -     /** Specifies how the width or height should be interpreted. */
 -     enum SizeMode
 -     {
 -         absoluteSize                    = 1 << 0,   /**< The width or height specifies an absolute size. */
 -         parentSizeMinusAbsolute         = 1 << 1,   /**< The width or height is an amount that should be subtracted from the parent's width or height. */
 -         proportionalSize                = 1 << 2,   /**< The width or height specifies a proportion of the parent's width or height. */
 -     };
 - 
 -     //==============================================================================
 -     /** Sets all options for all coordinates.
 - 
 -         This requires a reference rectangle to be specified, because if you're changing any
 -         of the modes from proportional to absolute or vice-versa, then it'll need to convert
 -         the coordinates, and will need to know the parent size so it can calculate this.
 -     */
 -     void setModes (const AnchorPoint xAnchor, const PositionMode xMode_,
 -                    const AnchorPoint yAnchor, const PositionMode yMode_,
 -                    const SizeMode widthMode, const SizeMode heightMode,
 -                    const Rectangle<int>& target) noexcept
 -     {
 -         if (xMode != ((int) xAnchor | (int) xMode_) || wMode != widthMode)
 -         {
 -             double tx, tw;
 -             applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth());
 - 
 -             xMode = (uint8) ((int) xAnchor | (int) xMode_);
 -             wMode = (uint8) widthMode;
 - 
 -             updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth());
 -         }
 - 
 -         if (yMode != ((int) yAnchor | (int) yMode_) || hMode != heightMode)
 -         {
 -             double ty, th;
 -             applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight());
 - 
 -             yMode = (uint8) ((int) yAnchor | (int) yMode_);
 -             hMode = (uint8) heightMode;
 - 
 -             updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight());
 -         }
 -     }
 - 
 -     /** Returns the anchoring mode for the x coordinate.
 -         To change any of the modes, use setModes().
 -     */
 -     AnchorPoint getAnchorPointX() const noexcept
 -     {
 -         return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre));
 -     }
 - 
 -     /** Returns the positioning mode for the x coordinate.
 -         To change any of the modes, use setModes().
 -     */
 -     PositionMode getPositionModeX() const noexcept
 -     {
 -         return (PositionMode) (xMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight
 -                                          | absoluteFromParentCentre | proportionOfParentSize));
 -     }
 - 
 -     /** Returns the raw x coordinate.
 - 
 -         If the x position mode is absolute, then this will be the absolute value. If it's
 -         proportional, then this will be a fractional proportion, where 1.0 means the full
 -         width of the parent space.
 -     */
 -     double getX() const noexcept                    { return x; }
 - 
 -     /** Sets the raw value of the x coordinate.
 -         See getX() for the meaning of this value.
 -     */
 -     void setX (const double newX) noexcept          { x = newX; }
 - 
 -     /** Returns the anchoring mode for the y coordinate.
 -         To change any of the modes, use setModes().
 -     */
 -     AnchorPoint getAnchorPointY() const noexcept
 -     {
 -         return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre));
 -     }
 - 
 -     /** Returns the positioning mode for the y coordinate.
 -         To change any of the modes, use setModes().
 -     */
 -     PositionMode getPositionModeY() const noexcept
 -     {
 -         return (PositionMode) (yMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight
 -                                          | absoluteFromParentCentre | proportionOfParentSize));
 -     }
 - 
 -     /** Returns the raw y coordinate.
 - 
 -         If the y position mode is absolute, then this will be the absolute value. If it's
 -         proportional, then this will be a fractional proportion, where 1.0 means the full
 -         height of the parent space.
 -     */
 -     double getY() const noexcept                    { return y; }
 - 
 -     /** Sets the raw value of the y coordinate.
 -         See getY() for the meaning of this value.
 -     */
 -     void setY (const double newY) noexcept          { y = newY; }
 - 
 -     /** Returns the mode used to calculate the width.
 -         To change any of the modes, use setModes().
 -     */
 -     SizeMode getWidthMode() const noexcept          { return (SizeMode) wMode; }
 - 
 -     /** Returns the raw width value.
 - 
 -         If the width mode is absolute, then this will be the absolute value. If the mode is
 -         proportional, then this will be a fractional proportion, where 1.0 means the full
 -         width of the parent space.
 -     */
 -     double getWidth() const noexcept                { return w; }
 - 
 -     /** Sets the raw width value.
 - 
 -         See getWidth() for the details about what this value means.
 -     */
 -     void setWidth (const double newWidth) noexcept  { w = newWidth; }
 - 
 -     /** Returns the mode used to calculate the height.
 -         To change any of the modes, use setModes().
 -     */
 -     SizeMode getHeightMode() const noexcept         { return (SizeMode) hMode; }
 - 
 -     /** Returns the raw height value.
 - 
 -         If the height mode is absolute, then this will be the absolute value. If the mode is
 -         proportional, then this will be a fractional proportion, where 1.0 means the full
 -         height of the parent space.
 -     */
 -     double getHeight() const noexcept               { return h; }
 - 
 -     /** Sets the raw height value.
 - 
 -         See getHeight() for the details about what this value means.
 -     */
 -     void setHeight (const double newHeight) noexcept    { h = newHeight; }
 - 
 -     //==============================================================================
 -     /** If the size and position are constance, and wouldn't be affected by changes
 -         in the parent's size, then this will return true.
 -     */
 -     bool isPositionAbsolute() const noexcept
 -     {
 -         return (xMode & ~anchorAtLeftOrTop) == absoluteFromParentTopLeft
 -             && (yMode & ~anchorAtLeftOrTop) == absoluteFromParentTopLeft
 -             && wMode == absoluteSize
 -             && hMode == absoluteSize;
 -     }
 - 
 -     //==============================================================================
 -     /** Compares two objects. */
 -     bool operator== (const PositionedRectangle& other) const noexcept
 -     {
 -         return x == other.x && y == other.y
 -             && w == other.w && h == other.h
 -             && xMode == other.xMode && yMode == other.yMode
 -             && wMode == other.wMode && hMode == other.hMode;
 -     }
 - 
 -     /** Compares two objects. */
 -     bool operator!= (const PositionedRectangle& other) const noexcept
 -     {
 -         return ! operator== (other);
 -     }
 - 
 - private:
 -     //==============================================================================
 -     double x, y, w, h;
 -     uint8 xMode, yMode, wMode, hMode;
 - 
 -     void addPosDescription (String& s, const uint8 mode, const double value) const noexcept
 -     {
 -         if ((mode & proportionOfParentSize) != 0)
 -         {
 -             s << (roundToInt (value * 100000.0) / 1000.0) << '%';
 -         }
 -         else
 -         {
 -             s << (roundToInt (value * 100.0) / 100.0);
 - 
 -             if ((mode & absoluteFromParentBottomRight) != 0)
 -                 s << 'R';
 -             else if ((mode & absoluteFromParentCentre) != 0)
 -                 s << 'C';
 -         }
 - 
 -         if ((mode & anchorAtRightOrBottom) != 0)
 -             s << 'r';
 -         else if ((mode & anchorAtCentre) != 0)
 -             s << 'c';
 -     }
 - 
 -     void addSizeDescription (String& s, const uint8 mode, const double value) const noexcept
 -     {
 -         if (mode == proportionalSize)
 -             s << (roundToInt (value * 100000.0) / 1000.0) << '%';
 -         else if (mode == parentSizeMinusAbsolute)
 -             s << (roundToInt (value * 100.0) / 100.0) << 'M';
 -         else
 -             s << (roundToInt (value * 100.0) / 100.0);
 -     }
 - 
 -     void decodePosString (const String& s, uint8& mode, double& value) noexcept
 -     {
 -         if (s.containsChar ('r'))
 -             mode = anchorAtRightOrBottom;
 -         else if (s.containsChar ('c'))
 -             mode = anchorAtCentre;
 -         else
 -             mode = anchorAtLeftOrTop;
 - 
 -         if (s.containsChar ('%'))
 -         {
 -             mode |= proportionOfParentSize;
 -             value = s.removeCharacters ("%rcRC").getDoubleValue() / 100.0;
 -         }
 -         else
 -         {
 -             if (s.containsChar ('R'))
 -                 mode |= absoluteFromParentBottomRight;
 -             else if (s.containsChar ('C'))
 -                 mode |= absoluteFromParentCentre;
 -             else
 -                 mode |= absoluteFromParentTopLeft;
 - 
 -             value = s.removeCharacters ("rcRC").getDoubleValue();
 -         }
 -     }
 - 
 -     void decodeSizeString (const String& s, uint8& mode, double& value) noexcept
 -     {
 -         if (s.containsChar ('%'))
 -         {
 -             mode = proportionalSize;
 -             value = s.upToFirstOccurrenceOf ("%", false, false).getDoubleValue() / 100.0;
 -         }
 -         else if (s.containsChar ('M'))
 -         {
 -             mode = parentSizeMinusAbsolute;
 -             value = s.getDoubleValue();
 -         }
 -         else
 -         {
 -             mode = absoluteSize;
 -             value = s.getDoubleValue();
 -         }
 -     }
 - 
 -     void applyPosAndSize (double& xOut, double& wOut, const double x_, const double w_,
 -                           const uint8 xMode_, const uint8 wMode_,
 -                           const int parentPos, const int parentSize) const noexcept
 -     {
 -         if (wMode_ == proportionalSize)
 -             wOut = roundToInt (w_ * parentSize);
 -         else if (wMode_ == parentSizeMinusAbsolute)
 -             wOut = jmax (0, parentSize - roundToInt (w_));
 -         else
 -             wOut = roundToInt (w_);
 - 
 -         if ((xMode_ & proportionOfParentSize) != 0)
 -             xOut = parentPos + x_ * parentSize;
 -         else if ((xMode_ & absoluteFromParentBottomRight) != 0)
 -             xOut = (parentPos + parentSize) - x_;
 -         else if ((xMode_ & absoluteFromParentCentre) != 0)
 -             xOut = x_ + (parentPos + parentSize / 2);
 -         else
 -             xOut = x_ + parentPos;
 - 
 -         if ((xMode_ & anchorAtRightOrBottom) != 0)
 -             xOut -= wOut;
 -         else if ((xMode_ & anchorAtCentre) != 0)
 -             xOut -= wOut / 2;
 -     }
 - 
 -     void updatePosAndSize (double& xOut, double& wOut, double x_, const double w_,
 -                            const uint8 xMode_, const uint8 wMode_,
 -                            const int parentPos, const int parentSize) const noexcept
 -     {
 -         if (wMode_ == proportionalSize)
 -         {
 -             if (parentSize > 0)
 -                 wOut = w_ / parentSize;
 -         }
 -         else if (wMode_ == parentSizeMinusAbsolute)
 -             wOut = parentSize - w_;
 -         else
 -             wOut = w_;
 - 
 -         if ((xMode_ & anchorAtRightOrBottom) != 0)
 -             x_ += w_;
 -         else if ((xMode_ & anchorAtCentre) != 0)
 -             x_ += w_ / 2;
 - 
 -         if ((xMode_ & proportionOfParentSize) != 0)
 -         {
 -             if (parentSize > 0)
 -                 xOut = (x_ - parentPos) / parentSize;
 -         }
 -         else if ((xMode_ & absoluteFromParentBottomRight) != 0)
 -             xOut = (parentPos + parentSize) - x_;
 -         else if ((xMode_ & absoluteFromParentCentre) != 0)
 -             xOut = x_ - (parentPos + parentSize / 2);
 -         else
 -             xOut = x_ - parentPos;
 -     }
 - };
 - 
 - //==============================================================================
 - struct RelativePositionedRectangle
 - {
 -     //==============================================================================
 -     RelativePositionedRectangle()
 -         : relativeToX (0),
 -           relativeToY (0),
 -           relativeToW (0),
 -           relativeToH (0)
 -     {
 -     }
 - 
 -     RelativePositionedRectangle (const RelativePositionedRectangle& other)
 -         : rect (other.rect),
 -           relativeToX (other.relativeToX),
 -           relativeToY (other.relativeToY),
 -           relativeToW (other.relativeToW),
 -           relativeToH (other.relativeToH)
 -     {
 -     }
 - 
 -     RelativePositionedRectangle& operator= (const RelativePositionedRectangle& other)
 -     {
 -         rect = other.rect;
 -         relativeToX = other.relativeToX;
 -         relativeToY = other.relativeToY;
 -         relativeToW = other.relativeToW;
 -         relativeToH = other.relativeToH;
 -         return *this;
 -     }
 - 
 -     //==============================================================================
 -     bool operator== (const RelativePositionedRectangle& other) const noexcept
 -     {
 -         return rect == other.rect
 -             && relativeToX == other.relativeToX
 -             && relativeToY == other.relativeToY
 -             && relativeToW == other.relativeToW
 -             && relativeToH == other.relativeToH;
 -     }
 - 
 -     bool operator!= (const RelativePositionedRectangle& other) const noexcept
 -     {
 -         return ! operator== (other);
 -     }
 - 
 -     template <typename LayoutType>
 -     void getRelativeTargetBounds (const Rectangle<int>& parentArea,
 -                                   const LayoutType* layout,
 -                                   int& x, int& xw, int& y, int& yh,
 -                                   int& w, int& h) const
 -     {
 -         Component* rx = {};
 -         Component* ry = {};
 -         Component* rw = {};
 -         Component* rh = {};
 - 
 -         if (layout != nullptr)
 -         {
 -             rx = layout->findComponentWithId (relativeToX);
 -             ry = layout->findComponentWithId (relativeToY);
 -             rw = layout->findComponentWithId (relativeToW);
 -             rh = layout->findComponentWithId (relativeToH);
 -         }
 - 
 -         x = parentArea.getX() + (rx != nullptr ? rx->getX() : 0);
 -         y = parentArea.getY() + (ry != nullptr ? ry->getY() : 0);
 -         w = rw != nullptr ? rw->getWidth() : parentArea.getWidth();
 -         h = rh != nullptr ? rh->getHeight() : parentArea.getHeight();
 -         xw = rx != nullptr ? rx->getWidth() : parentArea.getWidth();
 -         yh = ry != nullptr ? ry->getHeight() : parentArea.getHeight();
 -     }
 - 
 -     Rectangle<int> getRectangle (const Rectangle<int>& parentArea,
 -                                  const ComponentLayout* layout) const
 -     {
 -         int x, xw, y, yh, w, h;
 -         getRelativeTargetBounds (parentArea, layout, x, xw, y, yh, w, h);
 - 
 -         const Rectangle<int> xyRect ((xw <= 0 || yh <= 0) ? Rectangle<int>()
 -                                                           : rect.getRectangle (Rectangle<int> (x, y, xw, yh)));
 - 
 -         const Rectangle<int> whRect ((w <= 0 || h <= 0) ? Rectangle<int>()
 -                                                         : rect.getRectangle (Rectangle<int> (x, y, w, h)));
 - 
 -         return Rectangle<int> (xyRect.getX(), xyRect.getY(),
 -                                whRect.getWidth(), whRect.getHeight());
 -     }
 - 
 -     void getRectangleDouble (double& x, double& y, double& w, double& h,
 -                              const Rectangle<int>& parentArea,
 -                              const ComponentLayout* layout) const
 -     {
 -         int rx, rxw, ry, ryh, rw, rh;
 -         getRelativeTargetBounds (parentArea, layout, rx, rxw, ry, ryh, rw, rh);
 - 
 -         double dummy1, dummy2;
 -         rect.getRectangleDouble (Rectangle<int> (rx, ry, rxw, ryh), x, y, dummy1, dummy2);
 -         rect.getRectangleDouble (Rectangle<int> (rx, ry, rw, rh), dummy1, dummy2, w, h);
 -     }
 - 
 -     void updateFromComponent (const Component& comp, const ComponentLayout* layout)
 -     {
 -         int x, xw, y, yh, w, h;
 -         getRelativeTargetBounds (Rectangle<int> (0, 0, comp.getParentWidth(), comp.getParentHeight()),
 -                                  layout, x, xw, y, yh, w, h);
 - 
 -         PositionedRectangle xyRect (rect), whRect (rect);
 -         xyRect.updateFrom (comp.getBounds(), Rectangle<int> (x, y, xw, yh));
 -         whRect.updateFrom (comp.getBounds(), Rectangle<int> (x, y, w, h));
 - 
 -         rect.setX (xyRect.getX());
 -         rect.setY (xyRect.getY());
 -         rect.setWidth (whRect.getWidth());
 -         rect.setHeight (whRect.getHeight());
 -     }
 - 
 -     void updateFrom (double newX, double newY, double newW, double newH,
 -                      const Rectangle<int>& parentArea, const ComponentLayout* layout)
 -     {
 -         int x, xw, y, yh, w, h;
 -         getRelativeTargetBounds (parentArea, layout, x, xw, y, yh, w, h);
 - 
 -         PositionedRectangle xyRect (rect), whRect (rect);
 -         xyRect.updateFromDouble (newX, newY, newW, newH, Rectangle<int> (x, y, xw, yh));
 -         whRect.updateFromDouble (newX, newY, newW, newH, Rectangle<int> (x, y, w, h));
 - 
 -         rect.setX (xyRect.getX());
 -         rect.setY (xyRect.getY());
 -         rect.setWidth (whRect.getWidth());
 -         rect.setHeight (whRect.getHeight());
 -     }
 - 
 -     void applyToXml (XmlElement& e) const
 -     {
 -         e.setAttribute ("pos", rect.toString());
 - 
 -         if (relativeToX != 0)   e.setAttribute ("posRelativeX", String::toHexString (relativeToX));
 -         if (relativeToY != 0)   e.setAttribute ("posRelativeY", String::toHexString (relativeToY));
 -         if (relativeToW != 0)   e.setAttribute ("posRelativeW", String::toHexString (relativeToW));
 -         if (relativeToH != 0)   e.setAttribute ("posRelativeH", String::toHexString (relativeToH));
 -     }
 - 
 -     void restoreFromXml (const XmlElement& e, const RelativePositionedRectangle& defaultPos)
 -     {
 -         rect = PositionedRectangle (e.getStringAttribute ("pos", defaultPos.rect.toString()));
 -         relativeToX = e.getStringAttribute ("posRelativeX", String::toHexString (defaultPos.relativeToX)).getHexValue64();
 -         relativeToY = e.getStringAttribute ("posRelativeY", String::toHexString (defaultPos.relativeToY)).getHexValue64();
 -         relativeToW = e.getStringAttribute ("posRelativeW", String::toHexString (defaultPos.relativeToW)).getHexValue64();
 -         relativeToH = e.getStringAttribute ("posRelativeH", String::toHexString (defaultPos.relativeToH)).getHexValue64();
 -     }
 - 
 -     String toString() const
 -     {
 -         StringArray toks;
 -         toks.addTokens (rect.toString(), false);
 - 
 -         return toks[0] + " " + toks[1];
 -     }
 - 
 -     Point<float> toXY (const Rectangle<int>& parentArea,
 -                        const ComponentLayout* layout) const
 -     {
 -         double x, y, w, h;
 -         getRectangleDouble (x, y, w, h, parentArea, layout);
 -         return { (float) x, (float) y };
 -     }
 - 
 -     void getXY (double& x, double& y,
 -                 const Rectangle<int>& parentArea,
 -                 const ComponentLayout* layout) const
 -     {
 -         double w, h;
 -         getRectangleDouble (x, y, w, h, parentArea, layout);
 -     }
 - 
 -     //==============================================================================
 -     PositionedRectangle rect;
 -     int64 relativeToX;
 -     int64 relativeToY;
 -     int64 relativeToW;
 -     int64 relativeToH;
 - };
 
 
  |