| @@ -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<int> PositionedRectangle::getRectangle (const Rectangle<int>& 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<int> (roundToInt (x_), roundToInt (y_), | |||
| roundToInt (w_), roundToInt (h_)); | |||
| } | |||
| void PositionedRectangle::getRectangleDouble (const Rectangle<int>& 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<int> (comp.getParentWidth(), comp.getParentHeight()))); | |||
| } | |||
| void PositionedRectangle::updateFrom (const Rectangle<int>& rectangle, | |||
| const Rectangle<int>& 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<int>& 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<int>()); | |||
| else | |||
| updateFrom (comp.getBounds(), Rectangle<int> (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<int>& 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 <const CoreGraphicsImage*> (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 <const CoreGraphicsImage*> (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; | |||
| } | |||
| @@ -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<int> getRectangle (const Rectangle<int>& targetSpaceToBeRelativeTo) const throw(); | |||
| const Rectangle<int> getRectangle (const Rectangle<int>& target) const throw() | |||
| { | |||
| jassert (! target.isEmpty()); | |||
| /** Same as getRectangle(), but returning the values as doubles rather than ints. | |||
| */ | |||
| void getRectangleDouble (const Rectangle<int>& 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<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 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<int> (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<int>& newPosition, | |||
| const Rectangle<int>& targetSpaceToBeRelativeTo) throw(); | |||
| const Rectangle<int>& 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<int>& targetSpaceToBeRelativeTo) throw(); | |||
| void updateFromDouble (const double newX, const double newY, | |||
| const double newW, const double newH, | |||
| const Rectangle<int>& 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<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 | |||
| @@ -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<int>& targetSpaceToBeRelativeTo) throw(); | |||
| void setModes (const AnchorPoint xAnchor, const PositionMode xMode_, | |||
| const AnchorPoint yAnchor, const PositionMode yMode_, | |||
| const SizeMode widthMode, const SizeMode heightMode, | |||
| const Rectangle<int>& 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); | |||
| }; | |||
| @@ -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<int> PositionedRectangle::getRectangle (const Rectangle<int>& 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<int> (roundToInt (x_), roundToInt (y_), | |||
| roundToInt (w_), roundToInt (h_)); | |||
| } | |||
| void PositionedRectangle::getRectangleDouble (const Rectangle<int>& 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<int> (comp.getParentWidth(), comp.getParentHeight()))); | |||
| } | |||
| //============================================================================== | |||
| void PositionedRectangle::updateFrom (const Rectangle<int>& rectangle, | |||
| const Rectangle<int>& 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<int>& 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<int>()); | |||
| else | |||
| updateFrom (comp.getBounds(), Rectangle<int> (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<int>& 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 | |||
| @@ -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<int> getRectangle (const Rectangle<int>& targetSpaceToBeRelativeTo) const throw(); | |||
| const Rectangle<int> getRectangle (const Rectangle<int>& target) const throw() | |||
| { | |||
| jassert (! target.isEmpty()); | |||
| /** Same as getRectangle(), but returning the values as doubles rather than ints. | |||
| */ | |||
| void getRectangleDouble (const Rectangle<int>& 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<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 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<int> (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<int>& newPosition, | |||
| const Rectangle<int>& targetSpaceToBeRelativeTo) throw(); | |||
| const Rectangle<int>& 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<int>& targetSpaceToBeRelativeTo) throw(); | |||
| void updateFromDouble (const double newX, const double newY, | |||
| const double newW, const double newH, | |||
| const Rectangle<int>& 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<int>()); | |||
| else | |||
| updateFrom (comp.getBounds(), Rectangle<int> (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<int>& targetSpaceToBeRelativeTo) throw(); | |||
| void setModes (const AnchorPoint xAnchor, const PositionMode xMode_, | |||
| const AnchorPoint yAnchor, const PositionMode yMode_, | |||
| const SizeMode widthMode, const SizeMode heightMode, | |||
| const Rectangle<int>& 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); | |||
| }; | |||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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" | |||
| //============================================================================== | |||
| @@ -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 <const CoreGraphicsImage*> (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()); | |||
| @@ -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; | |||
| } | |||