diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index b51b1a4a13..71bf928b88 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -94441,357 +94441,6 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_PositionedRectangle.cpp ***/ BEGIN_JUCE_NAMESPACE -PositionedRectangle::PositionedRectangle() throw() - : x (0.0), - y (0.0), - w (0.0), - h (0.0), - xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), - yMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), - wMode (absoluteSize), - hMode (absoluteSize) -{ -} - -PositionedRectangle::PositionedRectangle (const PositionedRectangle& other) throw() - : x (other.x), - y (other.y), - w (other.w), - h (other.h), - xMode (other.xMode), - yMode (other.yMode), - wMode (other.wMode), - hMode (other.hMode) -{ -} - -PositionedRectangle& PositionedRectangle::operator= (const PositionedRectangle& other) throw() -{ - 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; -} - -PositionedRectangle::~PositionedRectangle() throw() -{ -} - -bool PositionedRectangle::operator== (const PositionedRectangle& other) const throw() -{ - 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; -} - -bool PositionedRectangle::operator!= (const PositionedRectangle& other) const throw() -{ - return ! operator== (other); -} - -PositionedRectangle::PositionedRectangle (const String& stringVersion) throw() -{ - 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); -} - -const String PositionedRectangle::toString() const throw() -{ - String s; - s.preallocateStorage (12); - - addPosDescription (s, xMode, x); - s << ' '; - addPosDescription (s, yMode, y); - s << ' '; - addSizeDescription (s, wMode, w); - s << ' '; - addSizeDescription (s, hMode, h); - - return s; -} - -const Rectangle PositionedRectangle::getRectangle (const Rectangle& target) const throw() -{ - 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 (roundToInt (x_), roundToInt (y_), - roundToInt (w_), roundToInt (h_)); -} - -void PositionedRectangle::getRectangleDouble (const Rectangle& target, - double& x_, double& y_, - double& w_, double& h_) const throw() -{ - 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()); -} - -void PositionedRectangle::applyToComponent (Component& comp) const throw() -{ - comp.setBounds (getRectangle (Rectangle (comp.getParentWidth(), comp.getParentHeight()))); -} - -void PositionedRectangle::updateFrom (const Rectangle& rectangle, - const Rectangle& target) throw() -{ - updatePosAndSize (x, w, rectangle.getX(), rectangle.getWidth(), xMode, wMode, target.getX(), target.getWidth()); - updatePosAndSize (y, h, rectangle.getY(), rectangle.getHeight(), yMode, hMode, target.getY(), target.getHeight()); -} - -void PositionedRectangle::updateFromDouble (const double newX, const double newY, - const double newW, const double newH, - const Rectangle& target) throw() -{ - updatePosAndSize (x, w, newX, newW, xMode, wMode, target.getX(), target.getWidth()); - updatePosAndSize (y, h, newY, newH, yMode, hMode, target.getY(), target.getHeight()); -} - -void PositionedRectangle::updateFromComponent (const Component& comp) throw() -{ - if (comp.getParentComponent() == 0 && ! comp.isOnDesktop()) - updateFrom (comp.getBounds(), Rectangle()); - else - updateFrom (comp.getBounds(), Rectangle (comp.getParentWidth(), comp.getParentHeight())); -} - -PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointX() const throw() -{ - return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); -} - -PositionedRectangle::PositionMode PositionedRectangle::getPositionModeX() const throw() -{ - return (PositionMode) (xMode & (absoluteFromParentTopLeft - | absoluteFromParentBottomRight - | absoluteFromParentCentre - | proportionOfParentSize)); -} - -PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointY() const throw() -{ - return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); -} - -PositionedRectangle::PositionMode PositionedRectangle::getPositionModeY() const throw() -{ - return (PositionMode) (yMode & (absoluteFromParentTopLeft - | absoluteFromParentBottomRight - | absoluteFromParentCentre - | proportionOfParentSize)); -} - -PositionedRectangle::SizeMode PositionedRectangle::getWidthMode() const throw() -{ - return (SizeMode) wMode; -} - -PositionedRectangle::SizeMode PositionedRectangle::getHeightMode() const throw() -{ - return (SizeMode) hMode; -} - -void PositionedRectangle::setModes (const AnchorPoint xAnchor, - const PositionMode xMode_, - const AnchorPoint yAnchor, - const PositionMode yMode_, - const SizeMode widthMode, - const SizeMode heightMode, - const Rectangle& target) throw() -{ - if (xMode != (xAnchor | xMode_) || wMode != widthMode) - { - double tx, tw; - applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); - - xMode = (uint8) (xAnchor | xMode_); - wMode = (uint8) widthMode; - - updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); - } - - if (yMode != (yAnchor | yMode_) || hMode != heightMode) - { - double ty, th; - applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); - - yMode = (uint8) (yAnchor | yMode_); - hMode = (uint8) heightMode; - - updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); - } -} - -bool PositionedRectangle::isPositionAbsolute() const throw() -{ - return xMode == absoluteFromParentTopLeft - && yMode == absoluteFromParentTopLeft - && wMode == absoluteSize - && hMode == absoluteSize; -} - -void PositionedRectangle::addPosDescription (String& s, const uint8 mode, const double value) const throw() -{ - 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 PositionedRectangle::addSizeDescription (String& s, const uint8 mode, const double value) const throw() -{ - 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 PositionedRectangle::decodePosString (const String& s, uint8& mode, double& value) throw() -{ - 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 PositionedRectangle::decodeSizeString (const String& s, uint8& mode, double& value) throw() -{ - 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 PositionedRectangle::applyPosAndSize (double& xOut, double& wOut, - const double x_, const double w_, - const uint8 xMode_, const uint8 wMode_, - const int parentPos, - const int parentSize) const throw() -{ - 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 PositionedRectangle::updatePosAndSize (double& xOut, double& wOut, - double x_, const double w_, - const uint8 xMode_, const uint8 wMode_, - const int parentPos, - const int parentSize) const throw() -{ - 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; -} - END_JUCE_NAMESPACE /*** End of inlined file: juce_PositionedRectangle.cpp ***/ @@ -265918,7 +265567,8 @@ public: return im; } - static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) + static CGImageRef createImage (const Image& juceImage, const bool forAlpha, + CGColorSpaceRef colourSpace, const bool mustOutliveSource) { const CoreGraphicsImage* nativeImage = dynamic_cast (juceImage.getSharedImage()); @@ -265929,8 +265579,18 @@ public: else { const Image::BitmapData srcData (juceImage, false); + CGDataProviderRef provider; - CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + if (mustOutliveSource) + { + CFDataRef data = CFDataCreate (0, (const UInt8*) srcData.data, (CFIndex) (srcData.lineStride * srcData.height)); + provider = CGDataProviderCreateWithCFData (data); + CFRelease (data); + } + else + { + provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + } CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height, 8, srcData.pixelStride * 8, srcData.lineStride, @@ -265952,7 +265612,7 @@ public: [im lockFocus]; CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef imageRef = createImage (image, false, colourSpace); + CGImageRef imageRef = createImage (image, false, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; @@ -266114,7 +265774,7 @@ public: if (sourceImage.getFormat() != Image::SingleChannel) singleChannelImage = sourceImage.convertedToFormat (Image::SingleChannel); - CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace, true); flip(); AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform)); @@ -266126,7 +265786,6 @@ public: applyTransform (t.inverted()); flip(); - CGContextFlush (context); CGImageRelease (image); lastClipRectIsValid = false; } @@ -266303,7 +265962,7 @@ public: { const int iw = sourceImage.getWidth(); const int ih = sourceImage.getHeight(); - CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace, false); CGContextSaveGState (context); CGContextSetAlpha (context, state->fillType.getOpacity()); @@ -270615,7 +270274,8 @@ public: return im; } - static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) + static CGImageRef createImage (const Image& juceImage, const bool forAlpha, + CGColorSpaceRef colourSpace, const bool mustOutliveSource) { const CoreGraphicsImage* nativeImage = dynamic_cast (juceImage.getSharedImage()); @@ -270626,8 +270286,18 @@ public: else { const Image::BitmapData srcData (juceImage, false); + CGDataProviderRef provider; - CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + if (mustOutliveSource) + { + CFDataRef data = CFDataCreate (0, (const UInt8*) srcData.data, (CFIndex) (srcData.lineStride * srcData.height)); + provider = CGDataProviderCreateWithCFData (data); + CFRelease (data); + } + else + { + provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + } CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height, 8, srcData.pixelStride * 8, srcData.lineStride, @@ -270649,7 +270319,7 @@ public: [im lockFocus]; CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef imageRef = createImage (image, false, colourSpace); + CGImageRef imageRef = createImage (image, false, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; @@ -270811,7 +270481,7 @@ public: if (sourceImage.getFormat() != Image::SingleChannel) singleChannelImage = sourceImage.convertedToFormat (Image::SingleChannel); - CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace, true); flip(); AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform)); @@ -270823,7 +270493,6 @@ public: applyTransform (t.inverted()); flip(); - CGContextFlush (context); CGImageRelease (image); lastClipRectIsValid = false; } @@ -271000,7 +270669,7 @@ public: { const int iw = sourceImage.getWidth(); const int ih = sourceImage.getHeight(); - CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace, false); CGContextSaveGState (context); CGContextSetAlpha (context, state->fillType.getOpacity()); @@ -272902,7 +272571,7 @@ void NSViewComponentPeer::drawRect (NSRect r) if (! component->isOpaque()) CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); -#if USE_COREGRAPHICS_RENDERING + #if USE_COREGRAPHICS_RENDERING if (usingCoreGraphics) { CoreGraphicsContext context (cg, (float) [view frame].size.height); @@ -272912,7 +272581,7 @@ void NSViewComponentPeer::drawRect (NSRect r) insideDrawRect = false; } else -#endif + #endif { Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB, (int) (r.size.width + 0.5f), @@ -272946,7 +272615,7 @@ void NSViewComponentPeer::drawRect (NSRect r) insideDrawRect = false; CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace); + CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image); CGImageRelease (image); @@ -272958,9 +272627,9 @@ const StringArray NSViewComponentPeer::getAvailableRenderingEngines() { StringArray s (ComponentPeer::getAvailableRenderingEngines()); -#if USE_COREGRAPHICS_RENDERING + #if USE_COREGRAPHICS_RENDERING s.add ("CoreGraphics Renderer"); -#endif + #endif return s; } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 8227483cb5..821173e632 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -62708,7 +62708,7 @@ private: }; @endcode */ -class JUCE_API PositionedRectangle +class PositionedRectangle { public: @@ -62716,22 +62716,51 @@ public: The default anchor point is top-left; the default */ - PositionedRectangle() throw(); + PositionedRectangle() throw() + : x (0.0), y (0.0), w (0.0), h (0.0), + xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), + yMode (anchorAtLeftOrTop | 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) throw(); + PositionedRectangle (const String& stringVersion) throw() + { + 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) throw(); + PositionedRectangle (const PositionedRectangle& other) throw() + : 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) throw(); + PositionedRectangle& operator= (const PositionedRectangle& other) throw() + { + x = other.x; + y = other.y; + w = other.w; + h = other.h; + xMode = other.xMode; + yMode = other.yMode; + wMode = other.wMode; + hMode = other.hMode; - /** Destructor. */ - ~PositionedRectangle() throw(); + return *this; + } /** Returns a string version of this position, from which it can later be re-generated. @@ -62758,7 +62787,16 @@ public: To reload a stored string, use the constructor that takes a string parameter. */ - const String toString() const throw(); + const String toString() const throw() + { + String s; + s.preallocateStorage (12); + 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. @@ -62768,15 +62806,24 @@ public: @see applyToComponent */ - const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw(); + const Rectangle getRectangle (const Rectangle& target) const throw() + { + jassert (! target.isEmpty()); - /** Same as getRectangle(), but returning the values as doubles rather than ints. - */ - void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo, - double& x, - double& y, - double& width, - double& height) const throw(); + 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 (roundToInt (x_), roundToInt (y_), roundToInt (w_), roundToInt (h_)); + } + + /** Same as getRectangle(), but returning the values as doubles rather than ints. */ + void getRectangleDouble (const Rectangle& target, + double& x_, double& y_, double& w_, double& h_) const throw() + { + 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. @@ -62787,7 +62834,10 @@ public: @see getRectangle, updateFromComponent */ - void applyToComponent (Component& comp) const throw(); + void applyToComponent (Component& comp) const throw() + { + comp.setBounds (getRectangle (Rectangle (comp.getParentWidth(), comp.getParentHeight()))); + } /** Updates this object's co-ordinates to match the given rectangle. @@ -62803,12 +62853,21 @@ public: will not be changed. */ void updateFrom (const Rectangle& newPosition, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + const Rectangle& targetSpaceToBeRelativeTo) throw() + { + 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 (double x, double y, double width, double height, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + void updateFromDouble (const double newX, const double newY, + const double newW, const double newH, + const Rectangle& target) throw() + { + 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 co-ordinates to match the bounds of this component. @@ -62819,7 +62878,13 @@ public: 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) throw(); + void updateFromComponent (const Component& comp) throw() + { + if (comp.getParentComponent() == 0 && ! comp.isOnDesktop()) + updateFrom (comp.getBounds(), Rectangle()); + else + updateFrom (comp.getBounds(), Rectangle (comp.getParentWidth(), comp.getParentHeight())); + } /** Specifies the point within the rectangle, relative to which it should be positioned. */ enum AnchorPoint @@ -62852,23 +62917,50 @@ public: of the modes from proportional to absolute or vice-versa, then it'll need to convert the co-ordinates, and will need to know the parent size so it can calculate this. */ - void setModes (const AnchorPoint xAnchorMode, - const PositionMode xPositionMode, - const AnchorPoint yAnchorMode, - const PositionMode yPositionMode, - const SizeMode widthMode, - const SizeMode heightMode, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + void setModes (const AnchorPoint xAnchor, const PositionMode xMode_, + const AnchorPoint yAnchor, const PositionMode yMode_, + const SizeMode widthMode, const SizeMode heightMode, + const Rectangle& target) throw() + { + if (xMode != (xAnchor | xMode_) || wMode != widthMode) + { + double tx, tw; + applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); + + xMode = (uint8) (xAnchor | xMode_); + wMode = (uint8) widthMode; + + updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); + } + + if (yMode != (yAnchor | yMode_) || hMode != heightMode) + { + double ty, th; + applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); + + yMode = (uint8) (yAnchor | yMode_); + hMode = (uint8) heightMode; + + updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); + } + } /** Returns the anchoring mode for the x co-ordinate. To change any of the modes, use setModes(). */ - AnchorPoint getAnchorPointX() const throw(); + AnchorPoint getAnchorPointX() const throw() + { + return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); + } /** Returns the positioning mode for the x co-ordinate. To change any of the modes, use setModes(). */ - PositionMode getPositionModeX() const throw(); + PositionMode getPositionModeX() const throw() + { + return (PositionMode) (xMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight + | absoluteFromParentCentre | proportionOfParentSize)); + } /** Returns the raw x co-ordinate. @@ -62887,12 +62979,19 @@ public: /** Returns the anchoring mode for the y co-ordinate. To change any of the modes, use setModes(). */ - AnchorPoint getAnchorPointY() const throw(); + AnchorPoint getAnchorPointY() const throw() + { + return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); + } /** Returns the positioning mode for the y co-ordinate. To change any of the modes, use setModes(). */ - PositionMode getPositionModeY() const throw(); + PositionMode getPositionModeY() const throw() + { + return (PositionMode) (yMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight + | absoluteFromParentCentre | proportionOfParentSize)); + } /** Returns the raw y co-ordinate. @@ -62911,7 +63010,7 @@ public: /** Returns the mode used to calculate the width. To change any of the modes, use setModes(). */ - SizeMode getWidthMode() const throw(); + SizeMode getWidthMode() const throw() { return (SizeMode) wMode; } /** Returns the raw width value. @@ -62930,7 +63029,7 @@ public: /** Returns the mode used to calculate the height. To change any of the modes, use setModes(). */ - SizeMode getHeightMode() const throw(); + SizeMode getHeightMode() const throw() { return (SizeMode) hMode; } /** Returns the raw height value. @@ -62949,29 +63048,169 @@ public: /** 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 throw(); + bool isPositionAbsolute() const throw() + { + return xMode == absoluteFromParentTopLeft + && yMode == absoluteFromParentTopLeft + && wMode == absoluteSize + && hMode == absoluteSize; + } /** Compares two objects. */ - bool operator== (const PositionedRectangle& other) const throw(); + bool operator== (const PositionedRectangle& other) const throw() + { + 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 throw(); + bool operator!= (const PositionedRectangle& other) const throw() + { + return ! operator== (other); + } private: double x, y, w, h; uint8 xMode, yMode, wMode, hMode; - void addPosDescription (String& result, uint8 mode, double value) const throw(); - void addSizeDescription (String& result, uint8 mode, double value) const throw(); - void decodePosString (const String& s, uint8& mode, double& value) throw(); - void decodeSizeString (const String& s, uint8& mode, double& value) throw(); - void applyPosAndSize (double& xOut, double& wOut, double x, double w, - uint8 xMode, uint8 wMode, - int parentPos, int parentSize) const throw(); - void updatePosAndSize (double& xOut, double& wOut, double x, double w, - uint8 xMode, uint8 wMode, - int parentPos, int parentSize) const throw(); + void addPosDescription (String& s, const uint8 mode, const double value) const throw() + { + 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 throw() + { + 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) throw() + { + 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) throw() + { + 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 throw() + { + 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 throw() + { + 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; + } JUCE_LEAK_DETECTOR (PositionedRectangle); }; diff --git a/src/gui/graphics/geometry/juce_PositionedRectangle.cpp b/src/gui/graphics/geometry/juce_PositionedRectangle.cpp index 035074204a..541c7f02fa 100644 --- a/src/gui/graphics/geometry/juce_PositionedRectangle.cpp +++ b/src/gui/graphics/geometry/juce_PositionedRectangle.cpp @@ -30,361 +30,5 @@ BEGIN_JUCE_NAMESPACE #include "juce_PositionedRectangle.h" -//============================================================================== -PositionedRectangle::PositionedRectangle() throw() - : x (0.0), - y (0.0), - w (0.0), - h (0.0), - xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), - yMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), - wMode (absoluteSize), - hMode (absoluteSize) -{ -} - -PositionedRectangle::PositionedRectangle (const PositionedRectangle& other) throw() - : x (other.x), - y (other.y), - w (other.w), - h (other.h), - xMode (other.xMode), - yMode (other.yMode), - wMode (other.wMode), - hMode (other.hMode) -{ -} - -PositionedRectangle& PositionedRectangle::operator= (const PositionedRectangle& other) throw() -{ - 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; -} - -PositionedRectangle::~PositionedRectangle() throw() -{ -} - -bool PositionedRectangle::operator== (const PositionedRectangle& other) const throw() -{ - 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; -} - -bool PositionedRectangle::operator!= (const PositionedRectangle& other) const throw() -{ - return ! operator== (other); -} - -//============================================================================== -PositionedRectangle::PositionedRectangle (const String& stringVersion) throw() -{ - 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); -} - -const String PositionedRectangle::toString() const throw() -{ - String s; - s.preallocateStorage (12); - - addPosDescription (s, xMode, x); - s << ' '; - addPosDescription (s, yMode, y); - s << ' '; - addSizeDescription (s, wMode, w); - s << ' '; - addSizeDescription (s, hMode, h); - - return s; -} - -//============================================================================== -const Rectangle PositionedRectangle::getRectangle (const Rectangle& target) const throw() -{ - 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 (roundToInt (x_), roundToInt (y_), - roundToInt (w_), roundToInt (h_)); -} - -void PositionedRectangle::getRectangleDouble (const Rectangle& target, - double& x_, double& y_, - double& w_, double& h_) const throw() -{ - 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()); -} - -void PositionedRectangle::applyToComponent (Component& comp) const throw() -{ - comp.setBounds (getRectangle (Rectangle (comp.getParentWidth(), comp.getParentHeight()))); -} - -//============================================================================== -void PositionedRectangle::updateFrom (const Rectangle& rectangle, - const Rectangle& target) throw() -{ - updatePosAndSize (x, w, rectangle.getX(), rectangle.getWidth(), xMode, wMode, target.getX(), target.getWidth()); - updatePosAndSize (y, h, rectangle.getY(), rectangle.getHeight(), yMode, hMode, target.getY(), target.getHeight()); -} - -void PositionedRectangle::updateFromDouble (const double newX, const double newY, - const double newW, const double newH, - const Rectangle& target) throw() -{ - updatePosAndSize (x, w, newX, newW, xMode, wMode, target.getX(), target.getWidth()); - updatePosAndSize (y, h, newY, newH, yMode, hMode, target.getY(), target.getHeight()); -} - -void PositionedRectangle::updateFromComponent (const Component& comp) throw() -{ - if (comp.getParentComponent() == 0 && ! comp.isOnDesktop()) - updateFrom (comp.getBounds(), Rectangle()); - else - updateFrom (comp.getBounds(), Rectangle (comp.getParentWidth(), comp.getParentHeight())); -} - -//============================================================================== -PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointX() const throw() -{ - return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); -} - -PositionedRectangle::PositionMode PositionedRectangle::getPositionModeX() const throw() -{ - return (PositionMode) (xMode & (absoluteFromParentTopLeft - | absoluteFromParentBottomRight - | absoluteFromParentCentre - | proportionOfParentSize)); -} - -PositionedRectangle::AnchorPoint PositionedRectangle::getAnchorPointY() const throw() -{ - return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); -} - -PositionedRectangle::PositionMode PositionedRectangle::getPositionModeY() const throw() -{ - return (PositionMode) (yMode & (absoluteFromParentTopLeft - | absoluteFromParentBottomRight - | absoluteFromParentCentre - | proportionOfParentSize)); -} - -PositionedRectangle::SizeMode PositionedRectangle::getWidthMode() const throw() -{ - return (SizeMode) wMode; -} - -PositionedRectangle::SizeMode PositionedRectangle::getHeightMode() const throw() -{ - return (SizeMode) hMode; -} - -void PositionedRectangle::setModes (const AnchorPoint xAnchor, - const PositionMode xMode_, - const AnchorPoint yAnchor, - const PositionMode yMode_, - const SizeMode widthMode, - const SizeMode heightMode, - const Rectangle& target) throw() -{ - if (xMode != (xAnchor | xMode_) || wMode != widthMode) - { - double tx, tw; - applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); - - xMode = (uint8) (xAnchor | xMode_); - wMode = (uint8) widthMode; - - updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); - } - - if (yMode != (yAnchor | yMode_) || hMode != heightMode) - { - double ty, th; - applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); - - yMode = (uint8) (yAnchor | yMode_); - hMode = (uint8) heightMode; - - updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); - } -} - -bool PositionedRectangle::isPositionAbsolute() const throw() -{ - return xMode == absoluteFromParentTopLeft - && yMode == absoluteFromParentTopLeft - && wMode == absoluteSize - && hMode == absoluteSize; -} - -//============================================================================== -void PositionedRectangle::addPosDescription (String& s, const uint8 mode, const double value) const throw() -{ - 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 PositionedRectangle::addSizeDescription (String& s, const uint8 mode, const double value) const throw() -{ - 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 PositionedRectangle::decodePosString (const String& s, uint8& mode, double& value) throw() -{ - 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 PositionedRectangle::decodeSizeString (const String& s, uint8& mode, double& value) throw() -{ - 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 PositionedRectangle::applyPosAndSize (double& xOut, double& wOut, - const double x_, const double w_, - const uint8 xMode_, const uint8 wMode_, - const int parentPos, - const int parentSize) const throw() -{ - 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 PositionedRectangle::updatePosAndSize (double& xOut, double& wOut, - double x_, const double w_, - const uint8 xMode_, const uint8 wMode_, - const int parentPos, - const int parentSize) const throw() -{ - 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; -} END_JUCE_NAMESPACE diff --git a/src/gui/graphics/geometry/juce_PositionedRectangle.h b/src/gui/graphics/geometry/juce_PositionedRectangle.h index 84757beb0f..63b47a019f 100644 --- a/src/gui/graphics/geometry/juce_PositionedRectangle.h +++ b/src/gui/graphics/geometry/juce_PositionedRectangle.h @@ -66,7 +66,7 @@ }; @endcode */ -class JUCE_API PositionedRectangle +class PositionedRectangle { public: //============================================================================== @@ -74,22 +74,51 @@ public: The default anchor point is top-left; the default */ - PositionedRectangle() throw(); + PositionedRectangle() throw() + : x (0.0), y (0.0), w (0.0), h (0.0), + xMode (anchorAtLeftOrTop | absoluteFromParentTopLeft), + yMode (anchorAtLeftOrTop | 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) throw(); + PositionedRectangle (const String& stringVersion) throw() + { + 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) throw(); + PositionedRectangle (const PositionedRectangle& other) throw() + : 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) throw(); - - /** Destructor. */ - ~PositionedRectangle() throw(); + PositionedRectangle& operator= (const PositionedRectangle& other) throw() + { + 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 @@ -117,7 +146,16 @@ public: To reload a stored string, use the constructor that takes a string parameter. */ - const String toString() const throw(); + const String toString() const throw() + { + String s; + s.preallocateStorage (12); + 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 @@ -128,15 +166,24 @@ public: @see applyToComponent */ - const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw(); + const Rectangle getRectangle (const Rectangle& target) const throw() + { + jassert (! target.isEmpty()); - /** Same as getRectangle(), but returning the values as doubles rather than ints. - */ - void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo, - double& x, - double& y, - double& width, - double& height) const throw(); + 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 (roundToInt (x_), roundToInt (y_), roundToInt (w_), roundToInt (h_)); + } + + /** Same as getRectangle(), but returning the values as doubles rather than ints. */ + void getRectangleDouble (const Rectangle& target, + double& x_, double& y_, double& w_, double& h_) const throw() + { + 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. @@ -147,7 +194,10 @@ public: @see getRectangle, updateFromComponent */ - void applyToComponent (Component& comp) const throw(); + void applyToComponent (Component& comp) const throw() + { + comp.setBounds (getRectangle (Rectangle (comp.getParentWidth(), comp.getParentHeight()))); + } //============================================================================== /** Updates this object's co-ordinates to match the given rectangle. @@ -164,12 +214,21 @@ public: will not be changed. */ void updateFrom (const Rectangle& newPosition, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + const Rectangle& targetSpaceToBeRelativeTo) throw() + { + 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 (double x, double y, double width, double height, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + void updateFromDouble (const double newX, const double newY, + const double newW, const double newH, + const Rectangle& target) throw() + { + 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 co-ordinates to match the bounds of this component. @@ -180,7 +239,13 @@ public: 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) throw(); + void updateFromComponent (const Component& comp) throw() + { + if (comp.getParentComponent() == 0 && ! comp.isOnDesktop()) + updateFrom (comp.getBounds(), Rectangle()); + else + updateFrom (comp.getBounds(), Rectangle (comp.getParentWidth(), comp.getParentHeight())); + } //============================================================================== /** Specifies the point within the rectangle, relative to which it should be positioned. */ @@ -215,23 +280,50 @@ public: of the modes from proportional to absolute or vice-versa, then it'll need to convert the co-ordinates, and will need to know the parent size so it can calculate this. */ - void setModes (const AnchorPoint xAnchorMode, - const PositionMode xPositionMode, - const AnchorPoint yAnchorMode, - const PositionMode yPositionMode, - const SizeMode widthMode, - const SizeMode heightMode, - const Rectangle& targetSpaceToBeRelativeTo) throw(); + void setModes (const AnchorPoint xAnchor, const PositionMode xMode_, + const AnchorPoint yAnchor, const PositionMode yMode_, + const SizeMode widthMode, const SizeMode heightMode, + const Rectangle& target) throw() + { + if (xMode != (xAnchor | xMode_) || wMode != widthMode) + { + double tx, tw; + applyPosAndSize (tx, tw, x, w, xMode, wMode, target.getX(), target.getWidth()); + + xMode = (uint8) (xAnchor | xMode_); + wMode = (uint8) widthMode; + + updatePosAndSize (x, w, tx, tw, xMode, wMode, target.getX(), target.getWidth()); + } + + if (yMode != (yAnchor | yMode_) || hMode != heightMode) + { + double ty, th; + applyPosAndSize (ty, th, y, h, yMode, hMode, target.getY(), target.getHeight()); + + yMode = (uint8) (yAnchor | yMode_); + hMode = (uint8) heightMode; + + updatePosAndSize (y, h, ty, th, yMode, hMode, target.getY(), target.getHeight()); + } + } /** Returns the anchoring mode for the x co-ordinate. To change any of the modes, use setModes(). */ - AnchorPoint getAnchorPointX() const throw(); + AnchorPoint getAnchorPointX() const throw() + { + return (AnchorPoint) (xMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); + } /** Returns the positioning mode for the x co-ordinate. To change any of the modes, use setModes(). */ - PositionMode getPositionModeX() const throw(); + PositionMode getPositionModeX() const throw() + { + return (PositionMode) (xMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight + | absoluteFromParentCentre | proportionOfParentSize)); + } /** Returns the raw x co-ordinate. @@ -250,12 +342,19 @@ public: /** Returns the anchoring mode for the y co-ordinate. To change any of the modes, use setModes(). */ - AnchorPoint getAnchorPointY() const throw(); + AnchorPoint getAnchorPointY() const throw() + { + return (AnchorPoint) (yMode & (anchorAtLeftOrTop | anchorAtRightOrBottom | anchorAtCentre)); + } /** Returns the positioning mode for the y co-ordinate. To change any of the modes, use setModes(). */ - PositionMode getPositionModeY() const throw(); + PositionMode getPositionModeY() const throw() + { + return (PositionMode) (yMode & (absoluteFromParentTopLeft | absoluteFromParentBottomRight + | absoluteFromParentCentre | proportionOfParentSize)); + } /** Returns the raw y co-ordinate. @@ -274,7 +373,7 @@ public: /** Returns the mode used to calculate the width. To change any of the modes, use setModes(). */ - SizeMode getWidthMode() const throw(); + SizeMode getWidthMode() const throw() { return (SizeMode) wMode; } /** Returns the raw width value. @@ -293,7 +392,7 @@ public: /** Returns the mode used to calculate the height. To change any of the modes, use setModes(). */ - SizeMode getHeightMode() const throw(); + SizeMode getHeightMode() const throw() { return (SizeMode) hMode; } /** Returns the raw height value. @@ -313,30 +412,170 @@ public: /** 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 throw(); + bool isPositionAbsolute() const throw() + { + return xMode == absoluteFromParentTopLeft + && yMode == absoluteFromParentTopLeft + && wMode == absoluteSize + && hMode == absoluteSize; + } //============================================================================== /** Compares two objects. */ - bool operator== (const PositionedRectangle& other) const throw(); + bool operator== (const PositionedRectangle& other) const throw() + { + 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 throw(); + bool operator!= (const PositionedRectangle& other) const throw() + { + return ! operator== (other); + } private: //============================================================================== double x, y, w, h; uint8 xMode, yMode, wMode, hMode; - void addPosDescription (String& result, uint8 mode, double value) const throw(); - void addSizeDescription (String& result, uint8 mode, double value) const throw(); - void decodePosString (const String& s, uint8& mode, double& value) throw(); - void decodeSizeString (const String& s, uint8& mode, double& value) throw(); - void applyPosAndSize (double& xOut, double& wOut, double x, double w, - uint8 xMode, uint8 wMode, - int parentPos, int parentSize) const throw(); - void updatePosAndSize (double& xOut, double& wOut, double x, double w, - uint8 xMode, uint8 wMode, - int parentPos, int parentSize) const throw(); + void addPosDescription (String& s, const uint8 mode, const double value) const throw() + { + 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 throw() + { + 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) throw() + { + 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) throw() + { + 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 throw() + { + 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 throw() + { + 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; + } JUCE_LEAK_DETECTOR (PositionedRectangle); }; diff --git a/src/native/juce_linux_NativeCode.cpp b/src/native/juce_linux_NativeCode.cpp index 3a18ef43f2..7e6f2f9139 100644 --- a/src/native/juce_linux_NativeCode.cpp +++ b/src/native/juce_linux_NativeCode.cpp @@ -90,6 +90,7 @@ BEGIN_JUCE_NAMESPACE #include "../gui/components/special/juce_WebBrowserComponent.h" #include "../gui/components/special/juce_OpenGLComponent.h" #include "../gui/components/special/juce_SystemTrayIconComponent.h" +#include "../containers/juce_ScopedValueSetter.h" //============================================================================== #define JUCE_INCLUDED_FILE 1 diff --git a/src/native/juce_mac_NativeCode.mm b/src/native/juce_mac_NativeCode.mm index af6f09d60d..673640d0b2 100644 --- a/src/native/juce_mac_NativeCode.mm +++ b/src/native/juce_mac_NativeCode.mm @@ -89,6 +89,7 @@ BEGIN_JUCE_NAMESPACE #include "../audio/devices/juce_AudioIODeviceType.h" #include "../audio/devices/juce_MidiOutput.h" #include "../audio/devices/juce_MidiInput.h" +#include "../containers/juce_ScopedValueSetter.h" #include "common/juce_MidiDataConcatenator.h" #undef Point diff --git a/src/native/juce_win32_NativeCode.cpp b/src/native/juce_win32_NativeCode.cpp index 209e2a7f83..1a4f516a4d 100644 --- a/src/native/juce_win32_NativeCode.cpp +++ b/src/native/juce_win32_NativeCode.cpp @@ -86,6 +86,7 @@ BEGIN_JUCE_NAMESPACE #include "../audio/devices/juce_AudioIODeviceType.h" #include "../audio/devices/juce_MidiOutput.h" #include "../audio/devices/juce_MidiInput.h" +#include "../containers/juce_ScopedValueSetter.h" #include "common/juce_MidiDataConcatenator.h" //============================================================================== diff --git a/src/native/mac/juce_mac_CoreGraphicsContext.mm b/src/native/mac/juce_mac_CoreGraphicsContext.mm index a01a4ae231..2d887f6386 100644 --- a/src/native/mac/juce_mac_CoreGraphicsContext.mm +++ b/src/native/mac/juce_mac_CoreGraphicsContext.mm @@ -66,7 +66,8 @@ public: } //============================================================================== - static CGImageRef createImage (const Image& juceImage, const bool forAlpha, CGColorSpaceRef colourSpace) + static CGImageRef createImage (const Image& juceImage, const bool forAlpha, + CGColorSpaceRef colourSpace, const bool mustOutliveSource) { const CoreGraphicsImage* nativeImage = dynamic_cast (juceImage.getSharedImage()); @@ -77,8 +78,18 @@ public: else { const Image::BitmapData srcData (juceImage, false); + CGDataProviderRef provider; - CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + if (mustOutliveSource) + { + CFDataRef data = CFDataCreate (0, (const UInt8*) srcData.data, (CFIndex) (srcData.lineStride * srcData.height)); + provider = CGDataProviderCreateWithCFData (data); + CFRelease (data); + } + else + { + provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); + } CGImageRef imageRef = CGImageCreate (srcData.width, srcData.height, 8, srcData.pixelStride * 8, srcData.lineStride, @@ -100,7 +111,7 @@ public: [im lockFocus]; CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef imageRef = createImage (image, false, colourSpace); + CGImageRef imageRef = createImage (image, false, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; @@ -265,7 +276,7 @@ public: if (sourceImage.getFormat() != Image::SingleChannel) singleChannelImage = sourceImage.convertedToFormat (Image::SingleChannel); - CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace, true); flip(); AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform)); @@ -277,7 +288,6 @@ public: applyTransform (t.inverted()); flip(); - CGContextFlush (context); CGImageRelease (image); lastClipRectIsValid = false; } @@ -457,7 +467,7 @@ public: { const int iw = sourceImage.getWidth(); const int ih = sourceImage.getHeight(); - CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace); + CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace, false); CGContextSaveGState (context); CGContextSetAlpha (context, state->fillType.getOpacity()); diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index 5304a8896e..fae5828983 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -1546,7 +1546,7 @@ void NSViewComponentPeer::drawRect (NSRect r) if (! component->isOpaque()) CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); -#if USE_COREGRAPHICS_RENDERING + #if USE_COREGRAPHICS_RENDERING if (usingCoreGraphics) { CoreGraphicsContext context (cg, (float) [view frame].size.height); @@ -1556,7 +1556,7 @@ void NSViewComponentPeer::drawRect (NSRect r) insideDrawRect = false; } else -#endif + #endif { Image temp (getComponent()->isOpaque() ? Image::RGB : Image::ARGB, (int) (r.size.width + 0.5f), @@ -1590,7 +1590,7 @@ void NSViewComponentPeer::drawRect (NSRect r) insideDrawRect = false; CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace); + CGImageRef image = CoreGraphicsImage::createImage (temp, false, colourSpace, false); CGColorSpaceRelease (colourSpace); CGContextDrawImage (cg, CGRectMake (r.origin.x, r.origin.y, temp.getWidth(), temp.getHeight()), image); CGImageRelease (image); @@ -1602,9 +1602,9 @@ const StringArray NSViewComponentPeer::getAvailableRenderingEngines() { StringArray s (ComponentPeer::getAvailableRenderingEngines()); -#if USE_COREGRAPHICS_RENDERING + #if USE_COREGRAPHICS_RENDERING s.add ("CoreGraphics Renderer"); -#endif + #endif return s; }