diff --git a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h index f5aa33ce28..a8f83e87fd 100644 --- a/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h +++ b/extras/Jucer (experimental)/Source/Utility/jucer_MiscUtilities.h @@ -162,27 +162,22 @@ public: drawable = newDrawable; drawable.addListener (this); drawableObject = Drawable::createFromValueTree (drawable, 0); // xxx image provider missing + addAndMakeVisible (drawableObject); resized(); repaint(); } - void paint (Graphics& g) - { - if (drawableObject != 0) - drawableObject->drawAt (g, 0, 0, 1.0f); - } - void resized() { - DrawableComposite* dc = dynamic_cast (static_cast (drawableObject)); +/* DrawableComposite* dc = dynamic_cast (static_cast (drawableObject)); if (dc != 0) { const RelativeCoordinate origin, right (getWidth()), bottom (getHeight()); dc->setContentArea (RelativeRectangle (origin, right, origin, bottom)); - dc->resetBoundingBoxToContentArea(); - } + //dc->resetBoundingBoxToContentArea(); + }*/ } void valueTreePropertyChanged (ValueTree&, const Identifier&) { updateGraphics(); } @@ -196,10 +191,7 @@ private: void updateGraphics() { if (drawableObject != 0) - { - const Rectangle dirtyArea (drawableObject->refreshFromValueTree (drawable, 0)); - repaint (dirtyArea.getSmallestIntegerContainer()); - } + drawableObject->refreshFromValueTree (drawable, 0); } }; diff --git a/extras/the jucer/src/model/jucer_PaintRoutine.cpp b/extras/the jucer/src/model/jucer_PaintRoutine.cpp index 1fc2ab93dc..6196a52fff 100644 --- a/extras/the jucer/src/model/jucer_PaintRoutine.cpp +++ b/extras/the jucer/src/model/jucer_PaintRoutine.cpp @@ -540,7 +540,7 @@ void PaintRoutine::dropImageAt (const File& f, int x, int y) if (d != 0) { - Rectangle bounds (d->getBounds()); + Rectangle bounds (d->getDrawableBounds()); delete d; PaintElement* newElement diff --git a/extras/the jucer/src/model/paintelements/jucer_PaintElementImage.h b/extras/the jucer/src/model/paintelements/jucer_PaintElementImage.h index a86a4b3038..2d4daeaa8d 100644 --- a/extras/the jucer/src/model/paintelements/jucer_PaintElementImage.h +++ b/extras/the jucer/src/model/paintelements/jucer_PaintElementImage.h @@ -310,7 +310,7 @@ public: const Rectangle parentArea (((PaintRoutineEditor*) getParentComponent())->getComponentArea()); Rectangle r (getCurrentBounds (parentArea)); - Rectangle bounds (image->getBounds()); + Rectangle bounds (image->getDrawableBounds()); r.setSize ((int) (bounds.getWidth() + 0.999f), (int) (bounds.getHeight() + 0.999f)); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 3b9b8f2db8..f845075805 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 95 +#define JUCE_BUILDNUMBER 96 /** Current Juce version number. diff --git a/src/gui/components/buttons/juce_DrawableButton.cpp b/src/gui/components/buttons/juce_DrawableButton.cpp index 00835db3fc..6ef746bd0e 100644 --- a/src/gui/components/buttons/juce_DrawableButton.cpp +++ b/src/gui/components/buttons/juce_DrawableButton.cpp @@ -36,6 +36,7 @@ DrawableButton::DrawableButton (const String& name, const DrawableButton::ButtonStyle buttonStyle) : Button (name), style (buttonStyle), + currentImage (0), edgeIndent (3) { if (buttonStyle == ImageOnButtonBackground) @@ -52,14 +53,9 @@ DrawableButton::DrawableButton (const String& name, DrawableButton::~DrawableButton() { - deleteImages(); } //============================================================================== -void DrawableButton::deleteImages() -{ -} - void DrawableButton::setImages (const Drawable* normal, const Drawable* over, const Drawable* down, @@ -69,36 +65,18 @@ void DrawableButton::setImages (const Drawable* normal, const Drawable* downOn, const Drawable* disabledOn) { - deleteImages(); - jassert (normal != 0); // you really need to give it at least a normal image.. - if (normal != 0) - normalImage = normal->createCopy(); - - if (over != 0) - overImage = over->createCopy(); - - if (down != 0) - downImage = down->createCopy(); - - if (disabled != 0) - disabledImage = disabled->createCopy(); - - - if (normalOn != 0) - normalImageOn = normalOn->createCopy(); - - if (overOn != 0) - overImageOn = overOn->createCopy(); - - if (downOn != 0) - downImageOn = downOn->createCopy(); + if (normal != 0) normalImage = normal->createCopy(); + if (over != 0) overImage = over->createCopy(); + if (down != 0) downImage = down->createCopy(); + if (disabled != 0) disabledImage = disabled->createCopy(); + if (normalOn != 0) normalImageOn = normalOn->createCopy(); + if (overOn != 0) overImageOn = overOn->createCopy(); + if (downOn != 0) downImageOn = downOn->createCopy(); + if (disabledOn != 0) disabledImageOn = disabledOn->createCopy(); - if (disabledOn != 0) - disabledImageOn = disabledOn->createCopy(); - - repaint(); + buttonStateChanged(); } //============================================================================== @@ -107,7 +85,7 @@ void DrawableButton::setButtonStyle (const DrawableButton::ButtonStyle newStyle) if (style != newStyle) { style = newStyle; - repaint(); + buttonStateChanged(); } } @@ -134,21 +112,88 @@ void DrawableButton::setEdgeIndent (const int numPixelsIndent) { edgeIndent = numPixelsIndent; repaint(); + resized(); +} + +void DrawableButton::resized() +{ + Button::resized(); + + if (style == ImageRaw) + { + currentImage->setOriginWithOriginalSize (Point()); + } + else if (currentImage != 0) + { + Rectangle imageSpace; + + if (style == ImageOnButtonBackground) + { + imageSpace = getLocalBounds().reduced (getWidth() / 4, getHeight() / 4); + } + else + { + const int textH = (style == ImageAboveTextLabel) + ? jmin (16, proportionOfHeight (0.25f)) + : 0; + + const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); + const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); + + imageSpace.setBounds (indentX, indentY, + getWidth() - indentX * 2, + getHeight() - indentY * 2 - textH); + } + + currentImage->setTransformToFit (imageSpace.toFloat(), RectanglePlacement::centred); + } +} + +void DrawableButton::buttonStateChanged() +{ + repaint(); + + Drawable* imageToDraw = 0; + float opacity = 1.0f; + + if (isEnabled()) + { + imageToDraw = getCurrentImage(); + } + else + { + imageToDraw = getToggleState() ? disabledImageOn + : disabledImage; + + if (imageToDraw == 0) + { + opacity = 0.4f; + imageToDraw = getNormalImage(); + } + } + + if (imageToDraw != currentImage) + { + removeChildComponent (currentImage); + currentImage = imageToDraw; + + if (currentImage != 0) + { + addAndMakeVisible (currentImage); + DrawableButton::resized(); + } + } + + if (currentImage != 0) + currentImage->setAlpha (opacity); } void DrawableButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) { - Rectangle imageSpace; - if (style == ImageOnButtonBackground) { - const int insetX = getWidth() / 4; - const int insetY = getHeight() / 4; - - imageSpace.setBounds (insetX, insetY, getWidth() - insetX * 2, getHeight() - insetY * 2); - getLookAndFeel().drawButtonBackground (g, *this, getBackgroundColour(), isMouseOverButton, @@ -162,13 +207,6 @@ void DrawableButton::paintButton (Graphics& g, ? jmin (16, proportionOfHeight (0.25f)) : 0; - const int indentX = jmin (edgeIndent, proportionOfWidth (0.3f)); - const int indentY = jmin (edgeIndent, proportionOfHeight (0.3f)); - - imageSpace.setBounds (indentX, indentY, - getWidth() - indentX * 2, - getHeight() - indentY * 2 - textH); - if (textH > 0) { g.setFont ((float) textH); @@ -182,39 +220,10 @@ void DrawableButton::paintButton (Graphics& g, Justification::centred, 1); } } - - g.setImageResamplingQuality (Graphics::mediumResamplingQuality); - g.setOpacity (1.0f); - - const Drawable* imageToDraw = 0; - - if (isEnabled()) - { - imageToDraw = getCurrentImage(); - } - else - { - imageToDraw = getToggleState() ? disabledImageOn - : disabledImage; - - if (imageToDraw == 0) - { - g.setOpacity (0.4f); - imageToDraw = getNormalImage(); - } - } - - if (imageToDraw != 0) - { - if (style == ImageRaw) - imageToDraw->draw (g, 1.0f); - else - imageToDraw->drawWithin (g, imageSpace.toFloat(), RectanglePlacement::centred, 1.0f); - } } //============================================================================== -const Drawable* DrawableButton::getCurrentImage() const throw() +Drawable* DrawableButton::getCurrentImage() const throw() { if (isDown()) return getDownImage(); @@ -225,15 +234,15 @@ const Drawable* DrawableButton::getCurrentImage() const throw() return getNormalImage(); } -const Drawable* DrawableButton::getNormalImage() const throw() +Drawable* DrawableButton::getNormalImage() const throw() { return (getToggleState() && normalImageOn != 0) ? normalImageOn : normalImage; } -const Drawable* DrawableButton::getOverImage() const throw() +Drawable* DrawableButton::getOverImage() const throw() { - const Drawable* d = normalImage; + Drawable* d = normalImage; if (getToggleState()) { @@ -253,9 +262,9 @@ const Drawable* DrawableButton::getOverImage() const throw() return d; } -const Drawable* DrawableButton::getDownImage() const throw() +Drawable* DrawableButton::getDownImage() const throw() { - const Drawable* d = normalImage; + Drawable* d = normalImage; if (getToggleState()) { diff --git a/src/gui/components/buttons/juce_DrawableButton.h b/src/gui/components/buttons/juce_DrawableButton.h index 1711bbefc9..f9052a94ea 100644 --- a/src/gui/components/buttons/juce_DrawableButton.h +++ b/src/gui/components/buttons/juce_DrawableButton.h @@ -148,10 +148,10 @@ public: //============================================================================== /** Returns the image that the button is currently displaying. */ - const Drawable* getCurrentImage() const throw(); - const Drawable* getNormalImage() const throw(); - const Drawable* getOverImage() const throw(); - const Drawable* getDownImage() const throw(); + Drawable* getCurrentImage() const throw(); + Drawable* getNormalImage() const throw(); + Drawable* getOverImage() const throw(); + Drawable* getDownImage() const throw(); //============================================================================== /** A set of colour IDs to use to change the colour of various aspects of the link. @@ -174,16 +174,20 @@ protected: void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown); + /** @internal */ + void buttonStateChanged(); + /** @internal */ + void resized(); private: //============================================================================== ButtonStyle style; ScopedPointer normalImage, overImage, downImage, disabledImage; ScopedPointer normalImageOn, overImageOn, downImageOn, disabledImageOn; + Drawable* currentImage; Colour backgroundOff, backgroundOn; int edgeIndent; - void deleteImages(); DrawableButton (const DrawableButton&); DrawableButton& operator= (const DrawableButton&); }; diff --git a/src/gui/components/buttons/juce_ToolbarButton.cpp b/src/gui/components/buttons/juce_ToolbarButton.cpp index df719490da..69992c535b 100644 --- a/src/gui/components/buttons/juce_ToolbarButton.cpp +++ b/src/gui/components/buttons/juce_ToolbarButton.cpp @@ -34,13 +34,12 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -ToolbarButton::ToolbarButton (const int itemId_, - const String& buttonText, - Drawable* const normalImage_, - Drawable* const toggledOnImage_) +ToolbarButton::ToolbarButton (const int itemId_, const String& buttonText, + Drawable* const normalImage_, Drawable* const toggledOnImage_) : ToolbarItemComponent (itemId_, buttonText, true), normalImage (normalImage_), - toggledOnImage (toggledOnImage_) + toggledOnImage (toggledOnImage_), + currentImage (0) { jassert (normalImage_ != 0); } @@ -50,47 +49,61 @@ ToolbarButton::~ToolbarButton() } //============================================================================== -bool ToolbarButton::getToolbarItemSizes (int toolbarDepth, - bool /*isToolbarVertical*/, - int& preferredSize, - int& minSize, int& maxSize) +bool ToolbarButton::getToolbarItemSizes (int toolbarDepth, bool /*isToolbarVertical*/, int& preferredSize, int& minSize, int& maxSize) { preferredSize = minSize = maxSize = toolbarDepth; return true; } -void ToolbarButton::paintButtonArea (Graphics& g, - int width, int height, - bool /*isMouseOver*/, - bool /*isMouseDown*/) +void ToolbarButton::paintButtonArea (Graphics&, int /*width*/, int /*height*/, bool /*isMouseOver*/, bool /*isMouseDown*/) +{ +} + +void ToolbarButton::contentAreaChanged (const Rectangle&) +{ + buttonStateChanged(); +} + +void ToolbarButton::updateDrawable() +{ + if (currentImage != 0) + { + currentImage->setTransformToFit (getContentArea().toFloat(), RectanglePlacement::centred); + currentImage->setAlpha (isEnabled() ? 1.0f : 0.5f); + } +} + +void ToolbarButton::resized() +{ + ToolbarItemComponent::resized(); + updateDrawable(); +} + +void ToolbarButton::enablementChanged() +{ + ToolbarItemComponent::enablementChanged(); + updateDrawable(); +} + +void ToolbarButton::buttonStateChanged() { Drawable* d = normalImage; if (getToggleState() && toggledOnImage != 0) d = toggledOnImage; - const Rectangle area (0.0f, 0.0f, (float) width, (float) height); - - if (! isEnabled()) + if (d != currentImage) { - Image im (Image::ARGB, width, height, true); + removeChildComponent (currentImage); + currentImage = d; + if (d != 0) { - Graphics g2 (im); - d->drawWithin (g2, area, RectanglePlacement::centred, 1.0f); + enablementChanged(); + addAndMakeVisible (d); + updateDrawable(); } - - im.desaturate(); - g.drawImageAt (im, 0, 0); } - else - { - d->drawWithin (g, area, RectanglePlacement::centred, 1.0f); - } -} - -void ToolbarButton::contentAreaChanged (const Rectangle&) -{ } diff --git a/src/gui/components/buttons/juce_ToolbarButton.h b/src/gui/components/buttons/juce_ToolbarButton.h index 03810d39a5..16c7fc0d0f 100644 --- a/src/gui/components/buttons/juce_ToolbarButton.h +++ b/src/gui/components/buttons/juce_ToolbarButton.h @@ -77,11 +77,20 @@ public: void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown); /** @internal */ void contentAreaChanged (const Rectangle& newBounds); + /** @internal */ + void buttonStateChanged(); + /** @internal */ + void resized(); + /** @internal */ + void enablementChanged(); juce_UseDebuggingNewOperator private: - ScopedPointer normalImage, toggledOnImage; + ScopedPointer normalImage, toggledOnImage; + Drawable* currentImage; + + void updateDrawable(); ToolbarButton (const ToolbarButton&); ToolbarButton& operator= (const ToolbarButton&); diff --git a/src/gui/components/controls/juce_ToolbarItemComponent.cpp b/src/gui/components/controls/juce_ToolbarItemComponent.cpp index 696482a68e..cc08be32a8 100644 --- a/src/gui/components/controls/juce_ToolbarItemComponent.cpp +++ b/src/gui/components/controls/juce_ToolbarItemComponent.cpp @@ -44,7 +44,6 @@ ToolbarItemFactory::~ToolbarItemFactory() { } - //============================================================================== class ItemDragAndDropOverlayComponent : public Component { @@ -57,10 +56,6 @@ public: setMouseCursor (MouseCursor::DraggingHandCursor); } - ~ItemDragAndDropOverlayComponent() - { - } - void paint (Graphics& g) { ToolbarItemComponent* const tc = dynamic_cast (getParentComponent()); diff --git a/src/gui/graphics/drawables/juce_Drawable.cpp b/src/gui/graphics/drawables/juce_Drawable.cpp index 9d3c45029e..107cf0a624 100644 --- a/src/gui/graphics/drawables/juce_Drawable.cpp +++ b/src/gui/graphics/drawables/juce_Drawable.cpp @@ -40,42 +40,90 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -Drawable::RenderingContext::RenderingContext (Graphics& g_, - const AffineTransform& transform_, - const float opacity_) throw() - : g (g_), - transform (transform_), - opacity (opacity_) +Drawable::Drawable() { + setInterceptsMouseClicks (false, false); + setPaintingIsUnclipped (true); } -//============================================================================== -Drawable::Drawable() - : parent (0) +Drawable::~Drawable() { } -Drawable::~Drawable() +//============================================================================== +void Drawable::draw (Graphics& g, float opacity, const AffineTransform& transform) const { + const_cast (this)->nonConstDraw (g, opacity, transform); } -void Drawable::draw (Graphics& g, const float opacity, const AffineTransform& transform) const +void Drawable::nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform) { - render (RenderingContext (g, transform, opacity)); + g.saveState(); + const float oldOpacity = getAlpha(); + setAlpha (opacity); + g.addTransform (AffineTransform::translation (-originRelativeToComponent.getX(), + -originRelativeToComponent.getY()) + .followedBy (getTransform()) + .followedBy (transform)); + + paintEntireComponent (g, false); + setAlpha (oldOpacity); + g.restoreState(); } -void Drawable::drawAt (Graphics& g, const float x, const float y, const float opacity) const +void Drawable::drawAt (Graphics& g, float x, float y, float opacity) const { draw (g, opacity, AffineTransform::translation (x, y)); } -void Drawable::drawWithin (Graphics& g, - const Rectangle& destArea, - const RectanglePlacement& placement, - const float opacity) const +void Drawable::drawWithin (Graphics& g, const Rectangle& destArea, const RectanglePlacement& placement, float opacity) const +{ + draw (g, opacity, placement.getTransformToFit (getDrawableBounds(), destArea)); +} + +//============================================================================== +DrawableComposite* Drawable::getParent() const +{ + return dynamic_cast (getParentComponent()); +} + +void Drawable::transformContextToCorrectOrigin (Graphics& g) +{ + g.setOrigin (originRelativeToComponent.getX(), + originRelativeToComponent.getY()); +} + +void Drawable::markerHasMoved() +{ +} + +void Drawable::parentHierarchyChanged() { - if (! destArea.isEmpty()) - draw (g, opacity, placement.getTransformToFit (getBounds(), destArea)); + setBoundsToEnclose (getDrawableBounds()); +} + +void Drawable::setBoundsToEnclose (const Rectangle& area) +{ + Drawable* const parent = getParent(); + Point parentOrigin; + if (parent != 0) + parentOrigin = parent->originRelativeToComponent; + + const Rectangle newBounds (area.getSmallestIntegerContainer() + parentOrigin); + originRelativeToComponent = parentOrigin - newBounds.getPosition(); + setBounds (newBounds); +} + +//============================================================================== +void Drawable::setOriginWithOriginalSize (const Point& originWithinParent) +{ + setTransform (AffineTransform::translation (originWithinParent.getX(), originWithinParent.getY())); +} + +void Drawable::setTransformToFit (const Rectangle& area, const RectanglePlacement& placement) +{ + if (! area.isEmpty()) + setTransform (placement.getTransformToFit (getDrawableBounds(), area)); } //============================================================================== @@ -136,20 +184,17 @@ Drawable* Drawable::createChildFromValueTree (DrawableComposite* parent, const V const Identifier type (tree.getType()); Drawable* d = 0; - if (type == DrawablePath::valueTreeType) - d = new DrawablePath(); - else if (type == DrawableComposite::valueTreeType) - d = new DrawableComposite(); - else if (type == DrawableRectangle::valueTreeType) - d = new DrawableRectangle(); - else if (type == DrawableImage::valueTreeType) - d = new DrawableImage(); - else if (type == DrawableText::valueTreeType) - d = new DrawableText(); + if (type == DrawablePath::valueTreeType) d = new DrawablePath(); + else if (type == DrawableComposite::valueTreeType) d = new DrawableComposite(); + else if (type == DrawableRectangle::valueTreeType) d = new DrawableRectangle(); + else if (type == DrawableImage::valueTreeType) d = new DrawableImage(); + else if (type == DrawableText::valueTreeType) d = new DrawableText(); if (d != 0) { - d->parent = parent; + if (parent != 0) + parent->insertDrawable (d); + d->refreshFromValueTree (tree, imageProvider); } diff --git a/src/gui/graphics/drawables/juce_Drawable.h b/src/gui/graphics/drawables/juce_Drawable.h index 3527b5e921..38d9eb2253 100644 --- a/src/gui/graphics/drawables/juce_Drawable.h +++ b/src/gui/graphics/drawables/juce_Drawable.h @@ -26,7 +26,7 @@ #ifndef __JUCE_DRAWABLE_JUCEHEADER__ #define __JUCE_DRAWABLE_JUCEHEADER__ -#include "../contexts/juce_Graphics.h" +#include "../../components/juce_Component.h" #include "../geometry/juce_RelativeCoordinate.h" #include "../../../text/juce_XmlElement.h" #include "../../../containers/juce_ValueTree.h" @@ -39,7 +39,7 @@ class DrawableComposite; @see DrawableComposite, DrawableImage, DrawablePath, DrawableText */ -class JUCE_API Drawable +class JUCE_API Drawable : public Component { protected: //============================================================================== @@ -62,6 +62,11 @@ public: //============================================================================== /** Renders this Drawable object. + + Note that the preferred way to render a drawable in future is by using it + as a component and adding it to a parent, so you might want to consider that + before using this method. + @see drawWithin */ void draw (Graphics& g, float opacity, @@ -75,10 +80,12 @@ public: @code draw (g, AffineTransform::translation (x, y)). @endcode + + Note that the preferred way to render a drawable in future is by using it + as a component and adding it to a parent, so you might want to consider that + before using this method. */ - void drawAt (Graphics& g, - float x, float y, - float opacity) const; + void drawAt (Graphics& g, float x, float y, float opacity) const; /** Renders the Drawable within a rectangle, scaling it to fit neatly inside without changing its aspect-ratio. @@ -86,6 +93,10 @@ public: The object can placed arbitrarily within the rectangle based on a Justification type, and can either be made as big as possible, or just reduced to fit. + Note that the preferred way to render a drawable in future is by using it + as a component and adding it to a parent, so you might want to consider that + before using this method. + @param g the graphics context to render onto @param destArea the target rectangle to fit the drawable into @param placement defines the alignment and rescaling to use to fit @@ -99,51 +110,18 @@ public: //============================================================================== - /** Holds the information needed when telling a drawable to render itself. - @see Drawable::draw + /** Resets any transformations on this drawable, and positions its origin within + its parent component. */ - class RenderingContext - { - public: - RenderingContext (Graphics& g, const AffineTransform& transform, float opacity) throw(); + void setOriginWithOriginalSize (const Point& originWithinParent); - Graphics& g; - AffineTransform transform; - float opacity; - - private: - RenderingContext& operator= (const RenderingContext&); - }; - - /** Renders this Drawable object. - @see draw + /** Sets a transform for this drawable that will position it within the specified + area of its parent component. */ - virtual void render (const RenderingContext& context) const = 0; - - //============================================================================== - /** Returns the smallest rectangle that can contain this Drawable object. - - Co-ordinates are relative to the object's own origin. - */ - virtual const Rectangle getBounds() const = 0; - - /** Returns true if the given point is somewhere inside this Drawable. - - Co-ordinates are relative to the object's own origin. - */ - virtual bool hitTest (float x, float y) const = 0; - - //============================================================================== - /** Returns the name given to this drawable. - @see setName - */ - const String& getName() const throw() { return name; } - - /** Assigns a name to this drawable. */ - void setName (const String& newName) throw() { name = newName; } + void setTransformToFit (const Rectangle& areaInParent, const RectanglePlacement& placement); /** Returns the DrawableComposite that contains this object, if there is one. */ - DrawableComposite* getParent() const throw() { return parent; } + DrawableComposite* getParent() const; //============================================================================== /** Tries to turn some kind of image file into a drawable. @@ -215,7 +193,7 @@ public: /** Tries to refresh a Drawable from the same ValueTree that was used to create it. @returns the damage rectangle that will need repainting due to any changes that were made. */ - virtual const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) = 0; + virtual void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) = 0; /** Creates a ValueTree to represent this Drawable. The VarTree that is returned can be turned back into a Drawable with @@ -228,6 +206,12 @@ public: /** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */ virtual const Identifier getValueTreeType() const = 0; + /** Returns the area that this drawble covers. + The result is expressed in this drawable's own coordinate space, and does not take + into account any transforms that may be applied to the component. + */ + virtual const Rectangle getDrawableBounds() const = 0; + //============================================================================== /** Internal class used to manage ValueTrees that represent Drawables. */ class ValueTreeWrapperBase @@ -250,15 +234,23 @@ public: protected: friend class DrawableComposite; + friend class DrawableShape; + /** @internal */ - DrawableComposite* parent; + static Drawable* createChildFromValueTree (DrawableComposite* parent, const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ - virtual void invalidatePoints() = 0; + void transformContextToCorrectOrigin (Graphics& g); /** @internal */ - static Drawable* createChildFromValueTree (DrawableComposite* parent, const ValueTree& tree, ImageProvider* imageProvider); + void markerHasMoved(); + /** @internal */ + void parentHierarchyChanged(); + /** @internal */ + void setBoundsToEnclose (const Rectangle& area); + + Point originRelativeToComponent; private: - String name; + void nonConstDraw (Graphics& g, float opacity, const AffineTransform& transform); Drawable (const Drawable&); Drawable& operator= (const Drawable&); diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.cpp b/src/gui/graphics/drawables/juce_DrawableComposite.cpp index 24f6e0fa3e..642656f0fd 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.cpp +++ b/src/gui/graphics/drawables/juce_DrawableComposite.cpp @@ -36,7 +36,8 @@ BEGIN_JUCE_NAMESPACE //============================================================================== DrawableComposite::DrawableComposite() - : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)) + : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)), + updateBoundsReentrant (false) { setContentArea (RelativeRectangle (RelativeCoordinate (0.0), RelativeCoordinate (100.0), @@ -48,8 +49,8 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other) { bounds = other.bounds; - for (int i = 0; i < other.drawables.size(); ++i) - drawables.add (other.drawables.getUnchecked(i)->createCopy()); + for (int i = 0; i < other.getNumDrawables(); ++i) + insertDrawable (other.getDrawable(i)->createCopy()); markersX.addCopiesOf (other.markersX); markersY.addCopiesOf (other.markersY); @@ -57,18 +58,24 @@ DrawableComposite::DrawableComposite (const DrawableComposite& other) DrawableComposite::~DrawableComposite() { + deleteAllChildren(); } //============================================================================== +int DrawableComposite::getNumDrawables() const throw() +{ + return getNumChildComponents(); +} + +Drawable* DrawableComposite::getDrawable (int index) const +{ + return dynamic_cast (getChildComponent (index)); +} + void DrawableComposite::insertDrawable (Drawable* drawable, const int index) { if (drawable != 0) - { - jassert (! drawables.contains (drawable)); // trying to add a drawable that's already in here! - jassert (drawable->parent == 0); // A drawable can only live inside one parent at a time! - drawables.insert (index, drawable); - drawable->parent = this; - } + addAndMakeVisible (drawable, index); } void DrawableComposite::insertDrawable (const Drawable& drawable, const int index) @@ -78,50 +85,60 @@ void DrawableComposite::insertDrawable (const Drawable& drawable, const int inde void DrawableComposite::removeDrawable (const int index, const bool deleteDrawable) { - drawables.remove (index, deleteDrawable); + Drawable* const d = getDrawable (index); + + if (deleteDrawable) + delete d; + else + removeChildComponent (d); } Drawable* DrawableComposite::getDrawableWithName (const String& name) const throw() { - for (int i = drawables.size(); --i >= 0;) - if (drawables.getUnchecked(i)->getName() == name) - return drawables.getUnchecked(i); + for (int i = getNumChildComponents(); --i >= 0;) + if (getChildComponent(i)->getName() == name) + return getDrawable (i); return 0; } void DrawableComposite::bringToFront (const int index) { - if (index >= 0 && index < drawables.size() - 1) - drawables.move (index, -1); + Drawable* d = getDrawable (index); + if (d != 0) + d->toFront (false); } -void DrawableComposite::setBoundingBox (const RelativeParallelogram& newBoundingBox) +const Rectangle DrawableComposite::getDrawableBounds() const { - bounds = newBoundingBox; -} + Rectangle r; -//============================================================================== -DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) - : name (other.name), position (other.position) -{ -} + for (int i = getNumDrawables(); --i >= 0;) + { + Drawable* const d = getDrawable(i); -DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_) - : name (name_), position (position_) -{ + if (d != 0) + { + if (d->isTransformed()) + r = r.getUnion (d->getDrawableBounds().transformed (d->getTransform())); + else + r = r.getUnion (d->getDrawableBounds()); + } + } + + return r; } -bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() +void DrawableComposite::markerHasMoved() { - return name != other.name || position != other.position; -} + for (int i = getNumDrawables(); --i >= 0;) + { + Drawable* const d = getDrawable(i); -//============================================================================== -const char* const DrawableComposite::contentLeftMarkerName = "left"; -const char* const DrawableComposite::contentRightMarkerName = "right"; -const char* const DrawableComposite::contentTopMarkerName = "top"; -const char* const DrawableComposite::contentBottomMarkerName = "bottom"; + if (d != 0) + d->markerHasMoved(); + } +} const RelativeRectangle DrawableComposite::getContentArea() const { @@ -138,6 +155,13 @@ void DrawableComposite::setContentArea (const RelativeRectangle& newArea) setMarker (contentRightMarkerName, true, newArea.right); setMarker (contentTopMarkerName, false, newArea.top); setMarker (contentBottomMarkerName, false, newArea.bottom); + refreshTransformFromBounds(); +} + +void DrawableComposite::setBoundingBox (const RelativeParallelogram& newBoundingBox) +{ + bounds = newBoundingBox; + refreshTransformFromBounds(); } void DrawableComposite::resetBoundingBoxToContentArea() @@ -151,15 +175,111 @@ void DrawableComposite::resetBoundingBoxToContentArea() void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() { - const Rectangle bounds (getUntransformedBounds (false)); + const Rectangle activeArea (getDrawableBounds()); - setContentArea (RelativeRectangle (RelativeCoordinate (bounds.getX()), - RelativeCoordinate (bounds.getRight()), - RelativeCoordinate (bounds.getY()), - RelativeCoordinate (bounds.getBottom()))); + setContentArea (RelativeRectangle (RelativeCoordinate (activeArea.getX()), + RelativeCoordinate (activeArea.getRight()), + RelativeCoordinate (activeArea.getY()), + RelativeCoordinate (activeArea.getBottom()))); resetBoundingBoxToContentArea(); } +void DrawableComposite::refreshTransformFromBounds() +{ + Point resolved[3]; + bounds.resolveThreePoints (resolved, getParent()); + + const Rectangle content (getContentArea().resolve (getParent())); + + AffineTransform t (AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].getX(), resolved[0].getY(), + content.getRight(), content.getY(), resolved[1].getX(), resolved[1].getY(), + content.getX(), content.getBottom(), resolved[2].getX(), resolved[2].getY())); + + if (! t.isSingularity()) + setTransform (t); +} + +void DrawableComposite::parentHierarchyChanged() +{ + DrawableComposite* parent = getParent(); + if (parent != 0) + originRelativeToComponent = parent->originRelativeToComponent - getPosition(); +} + +void DrawableComposite::childBoundsChanged (Component*) +{ + updateBoundsToFitChildren(); +} + +void DrawableComposite::childrenChanged() +{ + updateBoundsToFitChildren(); +} + +void DrawableComposite::updateBoundsToFitChildren() +{ + if (! updateBoundsReentrant) + { + struct RentrancyCheckSetter + { + RentrancyCheckSetter (bool& b_) : b (b_) { b_ = true; } + ~RentrancyCheckSetter() { b = false; } + + private: + bool& b; + }; + + const RentrancyCheckSetter checkSetter (updateBoundsReentrant); + + Rectangle childArea; + + for (int i = getNumChildComponents(); --i >= 0;) + childArea = childArea.getUnion (getChildComponent(i)->getBoundsInParent()); + + const Point delta (childArea.getPosition()); + childArea += getPosition(); + + if (childArea != getBounds()) + { + if (! delta.isOrigin()) + { + originRelativeToComponent -= delta; + + for (int i = getNumChildComponents(); --i >= 0;) + { + Component* const c = getChildComponent(i); + + if (c != 0) + c->setBounds (c->getBounds() - delta); + } + } + + setBounds (childArea); + } + } +} + +//============================================================================== +const char* const DrawableComposite::contentLeftMarkerName = "left"; +const char* const DrawableComposite::contentRightMarkerName = "right"; +const char* const DrawableComposite::contentTopMarkerName = "top"; +const char* const DrawableComposite::contentBottomMarkerName = "bottom"; + +DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) + : name (other.name), position (other.position) +{ +} + +DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_) + : name (name_), position (position_) +{ +} + +bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() +{ + return name != other.name || position != other.position; +} + int DrawableComposite::getNumMarkers (const bool xAxis) const throw() { return (xAxis ? markersX : markersY).size(); @@ -182,7 +302,7 @@ void DrawableComposite::setMarker (const String& name, const bool xAxis, const R if (m->position != position) { m->position = position; - invalidatePoints(); + markerHasMoved(); } return; @@ -190,7 +310,7 @@ void DrawableComposite::setMarker (const String& name, const bool xAxis, const R } (xAxis ? markersX : markersY).add (new Marker (name, position)); - invalidatePoints(); + markerHasMoved(); } void DrawableComposite::removeMarker (const bool xAxis, const int index) @@ -202,55 +322,6 @@ void DrawableComposite::removeMarker (const bool xAxis, const int index) } //============================================================================== -const AffineTransform DrawableComposite::calculateTransform() const -{ - Point resolved[3]; - bounds.resolveThreePoints (resolved, parent); - - const Rectangle content (getContentArea().resolve (parent)); - - return AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].getX(), resolved[0].getY(), - content.getRight(), content.getY(), resolved[1].getX(), resolved[1].getY(), - content.getX(), content.getBottom(), resolved[2].getX(), resolved[2].getY()); -} - -void DrawableComposite::render (const Drawable::RenderingContext& context) const -{ - if (drawables.size() > 0 && context.opacity > 0) - { - if (context.opacity >= 1.0f || drawables.size() == 1) - { - Drawable::RenderingContext contextCopy (context); - contextCopy.transform = calculateTransform().followedBy (context.transform); - - for (int i = 0; i < drawables.size(); ++i) - drawables.getUnchecked(i)->render (contextCopy); - } - else - { - // To correctly render a whole composite layer with an overall transparency, - // we need to render everything opaquely into a temp buffer, then blend that - // with the target opacity... - const Rectangle clipBounds (context.g.getClipBounds()); - - if (! clipBounds.isEmpty()) - { - Image tempImage (Image::ARGB, clipBounds.getWidth(), clipBounds.getHeight(), true); - - { - Graphics tempG (tempImage); - tempG.setOrigin (-clipBounds.getX(), -clipBounds.getY()); - Drawable::RenderingContext tempContext (tempG, context.transform, 1.0f); - render (tempContext); - } - - context.g.setOpacity (context.opacity); - context.g.drawImageAt (tempImage, clipBounds.getX(), clipBounds.getY()); - } - } - } -} - const Expression DrawableComposite::getSymbolValue (const String& symbol, const String& member) const { jassert (member.isEmpty()) // the only symbols available in a Drawable are markers. @@ -273,99 +344,11 @@ const Expression DrawableComposite::getSymbolValue (const String& symbol, const throw Expression::EvaluationError (symbol, member); } -const Rectangle DrawableComposite::getUntransformedBounds (const bool includeMarkers) const -{ - Rectangle bounds; - - int i; - for (i = 0; i < drawables.size(); ++i) - bounds = bounds.getUnion (drawables.getUnchecked(i)->getBounds()); - - if (includeMarkers) - { - if (markersX.size() > 0) - { - float minX = std::numeric_limits::max(); - float maxX = std::numeric_limits::min(); - - for (i = markersX.size(); --i >= 0;) - { - const Marker* m = markersX.getUnchecked(i); - const float pos = (float) m->position.resolve (this); - minX = jmin (minX, pos); - maxX = jmax (maxX, pos); - } - - if (minX <= maxX) - { - if (bounds.getHeight() > 0) - { - minX = jmin (minX, bounds.getX()); - maxX = jmax (maxX, bounds.getRight()); - } - - bounds.setLeft (minX); - bounds.setWidth (maxX - minX); - } - } - - if (markersY.size() > 0) - { - float minY = std::numeric_limits::max(); - float maxY = std::numeric_limits::min(); - - for (i = markersY.size(); --i >= 0;) - { - const Marker* m = markersY.getUnchecked(i); - const float pos = (float) m->position.resolve (this); - minY = jmin (minY, pos); - maxY = jmax (maxY, pos); - } - - if (minY <= maxY) - { - if (bounds.getHeight() > 0) - { - minY = jmin (minY, bounds.getY()); - maxY = jmax (maxY, bounds.getBottom()); - } - - bounds.setTop (minY); - bounds.setHeight (maxY - minY); - } - } - } - - return bounds; -} - -const Rectangle DrawableComposite::getBounds() const -{ - return getUntransformedBounds (true).transformed (calculateTransform()); -} - -bool DrawableComposite::hitTest (float x, float y) const -{ - calculateTransform().inverted().transformPoint (x, y); - - for (int i = 0; i < drawables.size(); ++i) - if (drawables.getUnchecked(i)->hitTest (x, y)) - return true; - - return false; -} - Drawable* DrawableComposite::createCopy() const { return new DrawableComposite (*this); } -void DrawableComposite::invalidatePoints() -{ - for (int i = 0; i < drawables.size(); ++i) - drawables.getUnchecked(i)->invalidatePoints(); -} - //============================================================================== const Identifier DrawableComposite::valueTreeType ("Group"); @@ -564,21 +547,14 @@ void DrawableComposite::ValueTreeWrapper::removeMarker (bool xAxis, const ValueT } //============================================================================== -const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { const ValueTreeWrapper wrapper (tree); setName (wrapper.getID()); - Rectangle damage; - bool redrawAll = false; - const RelativeParallelogram newBounds (wrapper.getBoundingBox()); if (bounds != newBounds) - { - redrawAll = true; - damage = getBounds(); bounds = newBounds; - } const int numMarkersX = wrapper.getNumMarkers (true); const int numMarkersY = wrapper.getNumMarkers (false); @@ -586,12 +562,6 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& // Remove deleted markers... if (markersX.size() > numMarkersX || markersY.size() > numMarkersY) { - if (! redrawAll) - { - redrawAll = true; - damage = getBounds(); - } - markersX.removeRange (jmax (2, numMarkersX), markersX.size()); markersY.removeRange (jmax (2, numMarkersY), markersY.size()); } @@ -603,19 +573,10 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& const Marker newMarker (wrapper.getMarker (true, wrapper.getMarkerState (true, i))); Marker* m = markersX[i]; - if (m == 0 || newMarker != *m) - { - if (! redrawAll) - { - redrawAll = true; - damage = getBounds(); - } - - if (m == 0) - markersX.add (new Marker (newMarker)); - else - *m = newMarker; - } + if (m == 0) + markersX.add (new Marker (newMarker)); + else if (newMarker != *m) + *m = newMarker; } for (i = 0; i < numMarkersY; ++i) @@ -623,78 +584,43 @@ const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& const Marker newMarker (wrapper.getMarker (false, wrapper.getMarkerState (false, i))); Marker* m = markersY[i]; - if (m == 0 || newMarker != *m) - { - if (! redrawAll) - { - redrawAll = true; - damage = getBounds(); - } - - if (m == 0) - markersY.add (new Marker (newMarker)); - else - *m = newMarker; - } + if (m == 0) + markersY.add (new Marker (newMarker)); + else if (newMarker != *m) + *m = newMarker; } // Remove deleted drawables.. - for (i = drawables.size(); --i >= wrapper.getNumDrawables();) - { - Drawable* const d = drawables.getUnchecked(i); - - if (! redrawAll) - damage = damage.getUnion (d->getBounds()); - - d->parent = 0; - drawables.remove (i); - } + for (i = getNumDrawables(); --i >= wrapper.getNumDrawables();) + delete getDrawable(i); // Update drawables and add new ones.. for (i = 0; i < wrapper.getNumDrawables(); ++i) { const ValueTree newDrawable (wrapper.getDrawableState (i)); - Drawable* d = drawables[i]; + Drawable* d = getDrawable(i); if (d != 0) { if (newDrawable.hasType (d->getValueTreeType())) { - const Rectangle area (d->refreshFromValueTree (newDrawable, imageProvider)); - - if (! redrawAll) - damage = damage.getUnion (area); + d->refreshFromValueTree (newDrawable, imageProvider); } else { - if (! redrawAll) - damage = damage.getUnion (d->getBounds()); - - d = createChildFromValueTree (this, newDrawable, imageProvider); - drawables.set (i, d); - - if (! redrawAll) - damage = damage.getUnion (d->getBounds()); + delete d; + d = 0; } } - else + + if (d == 0) { d = createChildFromValueTree (this, newDrawable, imageProvider); - drawables.set (i, d); - - if (! redrawAll) - damage = damage.getUnion (d->getBounds()); + addAndMakeVisible (d, i); } } - invalidatePoints(); - - if (redrawAll) - damage = damage.getUnion (getBounds()); - else if (! damage.isEmpty()) - damage = damage.transformed (calculateTransform()); - - return damage; + refreshTransformFromBounds(); } const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider) const @@ -706,8 +632,8 @@ const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider v.setBoundingBox (bounds, 0); int i; - for (i = 0; i < drawables.size(); ++i) - v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); + for (i = 0; i < getNumDrawables(); ++i) + v.addDrawable (getDrawable(i)->createValueTree (imageProvider), -1, 0); for (i = 0; i < markersX.size(); ++i) v.setMarker (true, *markersX.getUnchecked(i), 0); diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.h b/src/gui/graphics/drawables/juce_DrawableComposite.h index 799cb32c68..d0b175a756 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.h +++ b/src/gui/graphics/drawables/juce_DrawableComposite.h @@ -93,7 +93,7 @@ public: @see getDrawable */ - int getNumDrawables() const throw() { return drawables.size(); } + int getNumDrawables() const throw(); /** Returns one of the drawables that are contained in this one. @@ -105,7 +105,7 @@ public: @see getNumDrawables */ - Drawable* getDrawable (int index) const throw() { return drawables [index]; } + Drawable* getDrawable (int index) const; /** Looks for a child drawable with the specified name. */ Drawable* getDrawableWithName (const String& name) const throw(); @@ -119,20 +119,6 @@ public: void bringToFront (int index); //============================================================================== - /** Returns the main content rectangle. - The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that returns them all at once. - @see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName - */ - const RelativeRectangle getContentArea() const; - - /** Changes the main content area. - The content area is actually defined by the markers named "left", "right", "top" and - "bottom", but this method is a shortcut that sets them all at once. - @see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName - */ - void setContentArea (const RelativeRectangle& newArea); - /** Sets the parallelogram that defines the target position of the content rectangle when the drawable is rendered. @see setContentArea */ @@ -148,6 +134,20 @@ public: */ void resetBoundingBoxToContentArea(); + /** Returns the main content rectangle. + The content area is actually defined by the markers named "left", "right", "top" and + "bottom", but this method is a shortcut that returns them all at once. + @see contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName + */ + const RelativeRectangle getContentArea() const; + + /** Changes the main content area. + The content area is actually defined by the markers named "left", "right", "top" and + "bottom", but this method is a shortcut that sets them all at once. + @see setBoundingBox, contentLeftMarkerName, contentRightMarkerName, contentTopMarkerName, contentBottomMarkerName + */ + void setContentArea (const RelativeRectangle& newArea); + /** Resets the content area and the bounding transform to fit around the area occupied by the child components (ignoring any markers). */ @@ -183,17 +183,9 @@ public: //============================================================================== /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - const Rectangle getBounds() const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ Drawable* createCopy() const; /** @internal */ - void invalidatePoints(); - /** @internal */ - const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; /** @internal */ @@ -202,6 +194,16 @@ public: const Identifier getValueTreeType() const { return valueTreeType; } /** @internal */ const Expression getSymbolValue (const String& symbol, const String& member) const; + /** @internal */ + const Rectangle getDrawableBounds() const; + /** @internal */ + void markerHasMoved(); + /** @internal */ + void childBoundsChanged (Component*); + /** @internal */ + void childrenChanged(); + /** @internal */ + void parentHierarchyChanged(); //============================================================================== /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ @@ -248,12 +250,12 @@ public: juce_UseDebuggingNewOperator private: - OwnedArray drawables; RelativeParallelogram bounds; OwnedArray markersX, markersY; + bool updateBoundsReentrant; - const Rectangle getUntransformedBounds (bool includeMarkers) const; - const AffineTransform calculateTransform() const; + void refreshTransformFromBounds(); + void updateBoundsToFitChildren(); DrawableComposite& operator= (const DrawableComposite&); }; diff --git a/src/gui/graphics/drawables/juce_DrawableImage.cpp b/src/gui/graphics/drawables/juce_DrawableImage.cpp index 65f638206b..a54329cdc2 100644 --- a/src/gui/graphics/drawables/juce_DrawableImage.cpp +++ b/src/gui/graphics/drawables/juce_DrawableImage.cpp @@ -59,12 +59,16 @@ void DrawableImage::setImage (const Image& imageToUse) { image = imageToUse; + setBounds (imageToUse.getBounds()); + if (image.isValid()) { bounds.topLeft = RelativePoint (Point (0.0f, 0.0f)); bounds.topRight = RelativePoint (Point ((float) image.getWidth(), 0.0f)); bounds.bottomLeft = RelativePoint (Point (0.0f, (float) image.getHeight())); } + + refreshTransformFromBounds(); } void DrawableImage::setOpacity (const float newOpacity) @@ -80,68 +84,57 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) void DrawableImage::setBoundingBox (const RelativeParallelogram& newBounds) { bounds = newBounds; + refreshTransformFromBounds(); } //============================================================================== -const AffineTransform DrawableImage::calculateTransform() const +void DrawableImage::refreshTransformFromBounds() { - if (image.isNull()) - return AffineTransform::identity; + if (! image.isNull()) + { + Point resolved[3]; + bounds.resolveThreePoints (resolved, getParent()); - Point resolved[3]; - bounds.resolveThreePoints (resolved, parent); + const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); + const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); - const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); - const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); + AffineTransform t (AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), + tr.getX(), tr.getY(), + bl.getX(), bl.getY())); - return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), - tr.getX(), tr.getY(), - bl.getX(), bl.getY()); + if (! t.isSingularity()) + setTransform (t); + } } -void DrawableImage::render (const Drawable::RenderingContext& context) const +//============================================================================== +void DrawableImage::paint (Graphics& g) { if (image.isValid()) { - const AffineTransform t (calculateTransform().followedBy (context.transform)); - if (opacity > 0.0f && ! overlayColour.isOpaque()) { - context.g.setOpacity (context.opacity * opacity); - context.g.drawImageTransformed (image, t, false); + g.setOpacity (opacity); + g.drawImageAt (image, 0, 0, false); } if (! overlayColour.isTransparent()) { - context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity)); - context.g.drawImageTransformed (image, t, true); + g.setColour (overlayColour.withMultipliedAlpha (opacity)); + g.drawImageAt (image, 0, 0, true); } } } -const Rectangle DrawableImage::getBounds() const +const Rectangle DrawableImage::getDrawableBounds() const { - if (image.isNull()) - return Rectangle(); - - return bounds.getBounds (parent); + return image.getBounds().toFloat(); } -bool DrawableImage::hitTest (float x, float y) const +bool DrawableImage::hitTest (int x, int y) const { - if (image.isNull()) - return false; - - calculateTransform().inverted().transformPoint (x, y); - - const int ix = roundToInt (x); - const int iy = roundToInt (y); - - return ix >= 0 - && iy >= 0 - && ix < image.getWidth() - && iy < image.getHeight() - && image.getPixelAt (ix, iy).getAlpha() >= 127; + return (! image.isNull()) + && image.getPixelAt (x, y).getAlpha() >= 127; } Drawable* DrawableImage::createCopy() const @@ -149,10 +142,6 @@ Drawable* DrawableImage::createCopy() const return new DrawableImage (*this); } -void DrawableImage::invalidatePoints() -{ -} - //============================================================================== const Identifier DrawableImage::valueTreeType ("Image"); @@ -237,7 +226,7 @@ void DrawableImage::ValueTreeWrapper::setBoundingBox (const RelativeParallelogra //============================================================================== -const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { const ValueTreeWrapper controller (tree); setName (controller.getID()); @@ -255,19 +244,14 @@ const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tre const RelativeParallelogram newBounds (controller.getBoundingBox()); - if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage || bounds != newBounds) + if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage) { - const Rectangle damage (getBounds()); - + repaint(); opacity = newOpacity; overlayColour = newOverlayColour; bounds = newBounds; - image = newImage; - - return damage.getUnion (getBounds()); + setImage (newImage); } - - return Rectangle(); } const ValueTree DrawableImage::createValueTree (ImageProvider* imageProvider) const diff --git a/src/gui/graphics/drawables/juce_DrawableImage.h b/src/gui/graphics/drawables/juce_DrawableImage.h index 5079ef1189..f78f383788 100644 --- a/src/gui/graphics/drawables/juce_DrawableImage.h +++ b/src/gui/graphics/drawables/juce_DrawableImage.h @@ -84,17 +84,15 @@ public: //============================================================================== /** @internal */ - void render (const Drawable::RenderingContext& context) const; + void paint (Graphics& g); /** @internal */ - const Rectangle getBounds() const; - /** @internal */ - bool hitTest (float x, float y) const; + bool hitTest (int x, int y) const; /** @internal */ Drawable* createCopy() const; /** @internal */ - void invalidatePoints(); + const Rectangle getDrawableBounds() const; /** @internal */ - const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; /** @internal */ @@ -136,7 +134,7 @@ private: Colour overlayColour; RelativeParallelogram bounds; - const AffineTransform calculateTransform() const; + void refreshTransformFromBounds(); DrawableImage& operator= (const DrawableImage&); }; diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index 8dd147a3b3..582574a840 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -42,7 +42,7 @@ DrawablePath::DrawablePath (const DrawablePath& other) if (other.relativePath != 0) relativePath = new RelativePointPath (*other.relativePath); else - cachedPath = other.cachedPath; + setPath (other.path); } DrawablePath::~DrawablePath() @@ -57,18 +57,18 @@ Drawable* DrawablePath::createCopy() const //============================================================================== void DrawablePath::setPath (const Path& newPath) { - cachedPath = newPath; - strokeChanged(); + path = newPath; + pathChanged(); } const Path& DrawablePath::getPath() const { - return getCachedPath(); + return path; } const Path& DrawablePath::getStrokePath() const { - return getCachedStrokePath(); + return strokePath; } bool DrawablePath::rebuildPath (Path& path) const @@ -76,7 +76,7 @@ bool DrawablePath::rebuildPath (Path& path) const if (relativePath != 0) { path.clear(); - relativePath->createPath (path, parent); + relativePath->createPath (path, getParent()); return true; } @@ -440,38 +440,31 @@ void DrawablePath::ValueTreeWrapper::Element::removePoint (UndoManager* undoMana } //============================================================================== -const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - Rectangle damageRect; ValueTreeWrapper v (tree); setName (v.getID()); - bool needsRedraw = refreshFillTypes (v, parent, imageProvider); + if (refreshFillTypes (v, getParent(), imageProvider)) + repaint(); ScopedPointer newRelativePath (new RelativePointPath (tree)); Path newPath; - newRelativePath->createPath (newPath, parent); + newRelativePath->createPath (newPath, getParent()); if (! newRelativePath->containsAnyDynamicPoints()) newRelativePath = 0; const PathStrokeType newStroke (v.getStrokeType()); - if (strokeType != newStroke || cachedPath != newPath) + if (strokeType != newStroke || path != newPath) { - damageRect = getBounds(); - cachedPath.swapWithPath (newPath); - strokeChanged(); + path.swapWithPath (newPath); strokeType = newStroke; - needsRedraw = true; + pathChanged(); } relativePath = newRelativePath; - - if (needsRedraw) - damageRect = damageRect.getUnion (getBounds()); - - return damageRect; } const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const @@ -488,7 +481,7 @@ const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) con } else { - RelativePointPath rp (getCachedPath()); + RelativePointPath rp (path); rp.writeTo (tree, 0); } diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index a471162851..d2637e9299 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -64,7 +64,7 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ - const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; /** @internal */ diff --git a/src/gui/graphics/drawables/juce_DrawableRectangle.cpp b/src/gui/graphics/drawables/juce_DrawableRectangle.cpp index cd053376c5..fb252bf6d3 100644 --- a/src/gui/graphics/drawables/juce_DrawableRectangle.cpp +++ b/src/gui/graphics/drawables/juce_DrawableRectangle.cpp @@ -68,13 +68,13 @@ void DrawableRectangle::setCornerSize (const RelativePoint& newSize) bool DrawableRectangle::rebuildPath (Path& path) const { Point points[3]; - bounds.resolveThreePoints (points, parent); + bounds.resolveThreePoints (points, getParent()); const float w = Line (points[0], points[1]).getLength(); const float h = Line (points[0], points[2]).getLength(); - const float cornerSizeX = (float) cornerSize.x.resolve (parent); - const float cornerSizeY = (float) cornerSize.y.resolve (parent); + const float cornerSizeX = (float) cornerSize.x.resolve (getParent()); + const float cornerSizeY = (float) cornerSize.y.resolve (getParent()); path.clear(); @@ -92,7 +92,7 @@ bool DrawableRectangle::rebuildPath (Path& path) const const AffineTransform DrawableRectangle::calculateTransform() const { Point resolved[3]; - bounds.resolveThreePoints (resolved, parent); + bounds.resolveThreePoints (resolved, getParent()); return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), resolved[1].getX(), resolved[1].getY(), @@ -143,13 +143,13 @@ Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undo } //============================================================================== -const Rectangle DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - Rectangle damageRect; ValueTreeWrapper v (tree); setName (v.getID()); - bool needsRedraw = refreshFillTypes (v, parent, imageProvider); + if (refreshFillTypes (v, getParent(), imageProvider)) + repaint(); RelativeParallelogram newBounds (v.getRectangle()); @@ -158,19 +158,12 @@ const Rectangle DrawableRectangle::refreshFromValueTree (const ValueTree& if (strokeType != newStroke || newBounds != bounds || newCornerSize != cornerSize) { - damageRect = getBounds(); + repaint(); bounds = newBounds; strokeType = newStroke; cornerSize = newCornerSize; pathChanged(); - strokeChanged(); - needsRedraw = true; } - - if (needsRedraw) - damageRect = damageRect.getUnion (getBounds()); - - return damageRect; } const ValueTree DrawableRectangle::createValueTree (ImageProvider* imageProvider) const diff --git a/src/gui/graphics/drawables/juce_DrawableRectangle.h b/src/gui/graphics/drawables/juce_DrawableRectangle.h index ee97230d67..ce139dfc00 100644 --- a/src/gui/graphics/drawables/juce_DrawableRectangle.h +++ b/src/gui/graphics/drawables/juce_DrawableRectangle.h @@ -64,7 +64,7 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ - const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; /** @internal */ diff --git a/src/gui/graphics/drawables/juce_DrawableShape.cpp b/src/gui/graphics/drawables/juce_DrawableShape.cpp index e1a7e9d7a8..a6545271d4 100644 --- a/src/gui/graphics/drawables/juce_DrawableShape.cpp +++ b/src/gui/graphics/drawables/juce_DrawableShape.cpp @@ -35,18 +35,14 @@ BEGIN_JUCE_NAMESPACE DrawableShape::DrawableShape() : strokeType (0.0f), mainFill (Colours::black), - strokeFill (Colours::black), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) + strokeFill (Colours::black) { } DrawableShape::DrawableShape (const DrawableShape& other) : strokeType (other.strokeType), mainFill (other.mainFill), - strokeFill (other.strokeFill), - pathNeedsUpdating (true), - strokeNeedsUpdating (true) + strokeFill (other.strokeFill) { } @@ -67,7 +63,7 @@ void DrawableShape::setStrokeFill (const FillType& newFill) void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType) { strokeType = newStrokeType; - strokeNeedsUpdating = true; + strokeChanged(); } void DrawableShape::setStrokeThickness (const float newThickness) @@ -80,18 +76,6 @@ bool DrawableShape::isStrokeVisible() const throw() return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); } -void DrawableShape::setBrush (const Drawable::RenderingContext& context, const FillType& type) -{ - FillType f (type); - if (f.isGradient()) - f.gradient->multiplyOpacity (context.opacity); - else - f.setOpacity (f.getOpacity() * context.opacity); - - f.transform = f.transform.followedBy (context.transform); - context.g.setFillType (f); -} - bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, Expression::EvaluationContext* /*nameFinder*/, ImageProvider* imageProvider) @@ -99,7 +83,7 @@ bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, bool hasChanged = false; { - const FillType f (newState.getMainFill (parent, imageProvider)); + const FillType f (newState.getMainFill (getParent(), imageProvider)); if (mainFill != f) { @@ -109,7 +93,7 @@ bool DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, } { - const FillType f (newState.getStrokeFill (parent, imageProvider)); + const FillType f (newState.getStrokeFill (getParent(), imageProvider)); if (strokeFill != f) { @@ -129,73 +113,50 @@ void DrawableShape::writeTo (FillAndStrokeState& state, ImageProvider* imageProv } //============================================================================== -void DrawableShape::render (const Drawable::RenderingContext& context) const +void DrawableShape::paint (Graphics& g) { - setBrush (context, mainFill); - context.g.fillPath (getCachedPath(), context.transform); + transformContextToCorrectOrigin (g); + + g.setFillType (mainFill); + g.fillPath (path); if (isStrokeVisible()) { - setBrush (context, strokeFill); - context.g.fillPath (getCachedStrokePath(), context.transform); + g.setFillType (strokeFill); + g.fillPath (strokePath); } } void DrawableShape::pathChanged() { - pathNeedsUpdating = true; + strokeChanged(); } void DrawableShape::strokeChanged() { - strokeNeedsUpdating = true; -} + strokePath.clear(); + strokeType.createStrokedPath (strokePath, path, AffineTransform::identity, 4.0f); -void DrawableShape::invalidatePoints() -{ - pathNeedsUpdating = true; - strokeNeedsUpdating = true; + setBoundsToEnclose (getDrawableBounds()); + repaint(); } -const Path& DrawableShape::getCachedPath() const -{ - if (pathNeedsUpdating) - { - pathNeedsUpdating = false; - - if (rebuildPath (cachedPath)) - strokeNeedsUpdating = true; - } - - return cachedPath; -} - -const Path& DrawableShape::getCachedStrokePath() const -{ - if (strokeNeedsUpdating) - { - cachedStroke.clear(); - strokeType.createStrokedPath (cachedStroke, getCachedPath(), AffineTransform::identity, 4.0f); - strokeNeedsUpdating = false; // (must be called after getCachedPath) - } - - return cachedStroke; -} - -const Rectangle DrawableShape::getBounds() const +const Rectangle DrawableShape::getDrawableBounds() const { if (isStrokeVisible()) - return getCachedStrokePath().getBounds(); + return strokePath.getBounds(); else - return getCachedPath().getBounds(); + return path.getBounds(); } -bool DrawableShape::hitTest (float x, float y) const +bool DrawableShape::hitTest (int x, int y) const { - return getCachedPath().contains (x, y) - || (isStrokeVisible() && getCachedStrokePath().contains (x, y)); -} + const float globalX = x - originRelativeToComponent.getX(); + const float globalY = y - originRelativeToComponent.getY(); + return path.contains (globalX, globalY) + || (isStrokeVisible() && strokePath.contains (globalX, globalY)); +} //============================================================================== const Identifier DrawableShape::FillAndStrokeState::type ("type"); diff --git a/src/gui/graphics/drawables/juce_DrawableShape.h b/src/gui/graphics/drawables/juce_DrawableShape.h index 6147665265..20eccebe76 100644 --- a/src/gui/graphics/drawables/juce_DrawableShape.h +++ b/src/gui/graphics/drawables/juce_DrawableShape.h @@ -127,13 +127,11 @@ public: }; /** @internal */ - void invalidatePoints(); + const Rectangle getDrawableBounds() const; /** @internal */ - void render (const Drawable::RenderingContext& context) const; + void paint (Graphics& g); /** @internal */ - const Rectangle getBounds() const; - /** @internal */ - bool hitTest (float x, float y) const; + bool hitTest (int x, int y) const; protected: //============================================================================== @@ -156,20 +154,13 @@ protected: /** Writes the stroke and fill details to a FillAndStrokeState object. */ void writeTo (FillAndStrokeState& state, ImageProvider* imageProvider, UndoManager* undoManager) const; - /** Returns the current cached path outline. */ - const Path& getCachedPath() const; - /** Returns the current cached stroke outline. */ - const Path& getCachedStrokePath() const; //============================================================================== PathStrokeType strokeType; - mutable Path cachedPath, cachedStroke; + Path path, strokePath; private: FillType mainFill, strokeFill; - mutable bool pathNeedsUpdating, strokeNeedsUpdating; - - static void setBrush (const Drawable::RenderingContext& context, const FillType& type); DrawableShape& operator= (const DrawableShape&); }; diff --git a/src/gui/graphics/drawables/juce_DrawableText.cpp b/src/gui/graphics/drawables/juce_DrawableText.cpp index 36abfcca4c..68d78fd93c 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.cpp +++ b/src/gui/graphics/drawables/juce_DrawableText.cpp @@ -57,14 +57,22 @@ DrawableText::~DrawableText() } //============================================================================== +void DrawableText::refreshBounds() +{ + setBoundsToEnclose (getDrawableBounds()); + repaint(); +} + void DrawableText::setText (const String& newText) { text = newText; + refreshBounds(); } void DrawableText::setColour (const Colour& newColour) { colour = newColour; + repaint(); } void DrawableText::setFont (const Font& newFont, bool applySizeAndScale) @@ -74,38 +82,45 @@ void DrawableText::setFont (const Font& newFont, bool applySizeAndScale) if (applySizeAndScale) { Point corners[3]; - bounds.resolveThreePoints (corners, parent); + bounds.resolveThreePoints (corners, getParent()); setFontSizeControlPoint (RelativePoint (RelativeParallelogram::getPointForInternalCoord (corners, Point (font.getHorizontalScale() * font.getHeight(), font.getHeight())))); } + + refreshBounds(); } void DrawableText::setJustification (const Justification& newJustification) { justification = newJustification; + repaint(); } void DrawableText::setBoundingBox (const RelativeParallelogram& newBounds) { bounds = newBounds; + refreshBounds(); } void DrawableText::setFontSizeControlPoint (const RelativePoint& newPoint) { fontSizeControlPoint = newPoint; + refreshBounds(); } //============================================================================== -void DrawableText::render (const Drawable::RenderingContext& context) const +void DrawableText::paint (Graphics& g) { + transformContextToCorrectOrigin (g); + Point points[3]; - bounds.resolveThreePoints (points, parent); + bounds.resolveThreePoints (points, getParent()); const float w = Line (points[0], points[1]).getLength(); const float h = Line (points[0], points[2]).getLength(); - const Point fontCoords (bounds.getInternalCoordForPoint (points, fontSizeControlPoint.resolve (parent))); + const Point fontCoords (bounds.getInternalCoordForPoint (points, fontSizeControlPoint.resolve (getParent()))); const float fontHeight = jlimit (0.01f, jmax (0.01f, h), fontCoords.getY()); const float fontWidth = jlimit (0.01f, jmax (0.01f, w), fontCoords.getX()); @@ -113,27 +128,18 @@ void DrawableText::render (const Drawable::RenderingContext& context) const f.setHeight (fontHeight); f.setHorizontalScale (fontWidth / fontHeight); - context.g.setColour (colour.withMultipliedAlpha (context.opacity)); + g.setColour (colour); GlyphArrangement ga; ga.addFittedText (f, text, 0, 0, w, h, justification, 0x100000); - ga.draw (context.g, - AffineTransform::fromTargetPoints (0, 0, points[0].getX(), points[0].getY(), - w, 0, points[1].getX(), points[1].getY(), - 0, h, points[2].getX(), points[2].getY()) - .followedBy (context.transform)); -} - -const Rectangle DrawableText::getBounds() const -{ - return bounds.getBounds (parent); + ga.draw (g, AffineTransform::fromTargetPoints (0, 0, points[0].getX(), points[0].getY(), + w, 0, points[1].getX(), points[1].getY(), + 0, h, points[2].getX(), points[2].getY())); } -bool DrawableText::hitTest (float x, float y) const +const Rectangle DrawableText::getDrawableBounds() const { - Path p; - bounds.getPath (p, parent); - return p.contains (x, y); + return bounds.getBounds (getParent()); } Drawable* DrawableText::createCopy() const @@ -141,10 +147,6 @@ Drawable* DrawableText::createCopy() const return new DrawableText (*this); } -void DrawableText::invalidatePoints() -{ -} - //============================================================================== const Identifier DrawableText::valueTreeType ("Text"); @@ -237,7 +239,7 @@ void DrawableText::ValueTreeWrapper::setFontSizeControlPoint (const RelativePoin } //============================================================================== -const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider*) +void DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider*) { ValueTreeWrapper v (tree); setName (v.getID()); @@ -252,20 +254,14 @@ const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree if (text != newText || font != newFont || justification != newJustification || colour != newColour || bounds != newBounds || newFontPoint != fontSizeControlPoint) { - const Rectangle damage (getBounds()); - + repaint(); setBoundingBox (newBounds); setFontSizeControlPoint (newFontPoint); setColour (newColour); setFont (newFont, false); setJustification (newJustification); setText (newText); - - return damage.getUnion (getBounds()); - } - - return Rectangle(); } const ValueTree DrawableText::createValueTree (ImageProvider*) const diff --git a/src/gui/graphics/drawables/juce_DrawableText.h b/src/gui/graphics/drawables/juce_DrawableText.h index 15c9cd199d..09a0b8572c 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.h +++ b/src/gui/graphics/drawables/juce_DrawableText.h @@ -87,23 +87,19 @@ public: //============================================================================== /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - const Rectangle getBounds() const; - /** @internal */ - bool hitTest (float x, float y) const; + void paint (Graphics& g); /** @internal */ Drawable* createCopy() const; /** @internal */ - void invalidatePoints(); - /** @internal */ - const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); + void refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; /** @internal */ static const Identifier valueTreeType; /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** @internal */ + const Rectangle getDrawableBounds() const; //============================================================================== /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ @@ -146,6 +142,8 @@ private: Colour colour; Justification justification; + void refreshBounds(); + DrawableText& operator= (const DrawableText&); };