From 3300e71e1770b522c4891974185cecb8c209f1ed Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 20 Dec 2017 12:37:25 +0000 Subject: [PATCH] Removal of RelativeCoordinate classes from the Drawables --- examples/Demo/Source/Demos/GraphicsDemo.cpp | 4 +- .../CodeEditor/jucer_ItemPreviewComponent.h | 10 +- .../components/juce_Component.h | 3 +- .../drawables/juce_Drawable.cpp | 70 --- .../juce_gui_basics/drawables/juce_Drawable.h | 78 +-- .../drawables/juce_DrawableComposite.cpp | 205 +------ .../drawables/juce_DrawableComposite.h | 71 +-- .../drawables/juce_DrawableImage.cpp | 223 +------- .../drawables/juce_DrawableImage.h | 48 +- .../drawables/juce_DrawablePath.cpp | 537 +----------------- .../drawables/juce_DrawablePath.h | 75 +-- .../drawables/juce_DrawableRectangle.cpp | 124 +--- .../drawables/juce_DrawableRectangle.h | 40 +- .../drawables/juce_DrawableShape.cpp | 349 +----------- .../drawables/juce_DrawableShape.h | 72 +-- .../drawables/juce_DrawableText.cpp | 219 +------ .../drawables/juce_DrawableText.h | 63 +- .../drawables/juce_SVGParser.cpp | 5 +- .../layout/juce_ComponentBuilder.cpp | 1 - .../juce_RelativeParallelogram.cpp | 6 +- .../positioning/juce_RelativePointPath.cpp | 36 -- .../positioning/juce_RelativePointPath.h | 4 - 22 files changed, 158 insertions(+), 2085 deletions(-) diff --git a/examples/Demo/Source/Demos/GraphicsDemo.cpp b/examples/Demo/Source/Demos/GraphicsDemo.cpp index 84d43977cf..27dd27ba8d 100644 --- a/examples/Demo/Source/Demos/GraphicsDemo.cpp +++ b/examples/Demo/Source/Demos/GraphicsDemo.cpp @@ -485,9 +485,7 @@ public: if (svgDrawable != nullptr) { // to make our icon the right size, we'll set its bounding box to the size and position that we want. - svgDrawable->setBoundingBox (RelativeParallelogram (Point (-100, -100), - Point (100, -100), - Point (-100, 100))); + svgDrawable->setBoundingBox ({ -100.0f, -100.0f, 200.0f, 200.0f }); } } } diff --git a/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h b/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h index 6f5e0765bc..9816794b49 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h +++ b/extras/Projucer/Source/CodeEditor/jucer_ItemPreviewComponent.h @@ -43,18 +43,18 @@ public: if (drawable != nullptr) { - Rectangle contentBounds (drawable->getDrawableBounds()); + auto contentBounds = drawable->getDrawableBounds(); - if (DrawableComposite* dc = dynamic_cast (drawable.get())) + if (auto* dc = dynamic_cast (drawable.get())) { - Rectangle r (dc->getContentArea().resolve (nullptr)); + auto r = dc->getContentArea(); if (! r.isEmpty()) contentBounds = r; } - Rectangle area = RectanglePlacement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize) - .appliedTo (contentBounds, Rectangle (4.0f, 22.0f, getWidth() - 8.0f, getHeight() - 26.0f)); + auto area = RectanglePlacement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize) + .appliedTo (contentBounds, Rectangle (4.0f, 22.0f, getWidth() - 8.0f, getHeight() - 26.0f)); Path p; p.addRectangle (area); diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index b68c9c3662..5389b5bbfc 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -2210,8 +2210,7 @@ public: /** Attempts to set the component's position to the given rectangle. Unlike simply calling Component::setBounds(), this may involve the positioner - being smart enough to adjust itself to fit the new bounds, e.g. a RelativeRectangle's - positioner may try to reverse the expressions used to make them fit these new coordinates. + being smart enough to adjust itself to fit the new bounds. */ virtual void applyNewBounds (const Rectangle& newBounds) = 0; diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.cpp b/modules/juce_gui_basics/drawables/juce_Drawable.cpp index 0589ee986d..99824590db 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.cpp +++ b/modules/juce_gui_basics/drawables/juce_Drawable.cpp @@ -209,74 +209,4 @@ Drawable* Drawable::createFromImageFile (const File& file) return fin.openedOk() ? createFromImageDataStream (fin) : nullptr; } -//============================================================================== -template -struct DrawableTypeHandler : public ComponentBuilder::TypeHandler -{ - DrawableTypeHandler() : ComponentBuilder::TypeHandler (DrawableClass::valueTreeType) - { - } - - Component* addNewComponentFromState (const ValueTree& state, Component* parent) - { - auto* d = new DrawableClass(); - - if (parent != nullptr) - parent->addAndMakeVisible (d); - - updateComponentFromState (d, state); - return d; - } - - void updateComponentFromState (Component* component, const ValueTree& state) - { - if (auto* d = dynamic_cast (component)) - d->refreshFromValueTree (state, *this->getBuilder()); - else - jassertfalse; - } -}; - -void Drawable::registerDrawableTypeHandlers (ComponentBuilder& builder) -{ - builder.registerTypeHandler (new DrawableTypeHandler()); - builder.registerTypeHandler (new DrawableTypeHandler()); - builder.registerTypeHandler (new DrawableTypeHandler()); - builder.registerTypeHandler (new DrawableTypeHandler()); - builder.registerTypeHandler (new DrawableTypeHandler()); -} - -Drawable* Drawable::createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider) -{ - ComponentBuilder builder (tree); - builder.setImageProvider (imageProvider); - registerDrawableTypeHandlers (builder); - - ScopedPointer comp (builder.createComponent()); - auto* d = dynamic_cast (static_cast (comp)); - - if (d != nullptr) - comp.release(); - - return d; -} - -//============================================================================== -Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& s) : state (s) -{ -} - -String Drawable::ValueTreeWrapperBase::getID() const -{ - return state [ComponentBuilder::idProperty]; -} - -void Drawable::ValueTreeWrapperBase::setID (const String& newID) -{ - if (newID.isEmpty()) - state.removeProperty (ComponentBuilder::idProperty, nullptr); - else - state.setProperty (ComponentBuilder::idProperty, newID, nullptr); -} - } // namespace juce diff --git a/modules/juce_gui_basics/drawables/juce_Drawable.h b/modules/juce_gui_basics/drawables/juce_Drawable.h index 798302e774..44289584c2 100644 --- a/modules/juce_gui_basics/drawables/juce_Drawable.h +++ b/modules/juce_gui_basics/drawables/juce_Drawable.h @@ -33,8 +33,7 @@ namespace juce @see DrawableComposite, DrawableImage, DrawablePath, DrawableText */ -class JUCE_API Drawable : public Component, - public MarkerList::MarkerListHolder +class JUCE_API Drawable : public Component { protected: //============================================================================== @@ -177,22 +176,6 @@ public: static Path parseSVGPath (const String& svgPath); //============================================================================== - /** Tries to create a Drawable from a previously-saved ValueTree. - The ValueTree must have been created by the createValueTree() method. - If there are any images used within the drawable, you'll need to provide a valid - ImageProvider object that can be used to retrieve these images from whatever type - of identifier is used to represent them. - Internally, this uses a ComponentBuilder, and registerDrawableTypeHandlers(). - */ - static Drawable* createFromValueTree (const ValueTree& tree, ComponentBuilder::ImageProvider* imageProvider); - - /** Creates a ValueTree to represent this Drawable. - The ValueTree that is returned can be turned back into a Drawable with createFromValueTree(). - If there are any images used in this drawable, you'll need to provide a valid ImageProvider - object that can be used to create storable representations of them. - */ - virtual ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) 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. @@ -204,30 +187,6 @@ public: */ virtual bool replaceColour (Colour originalColour, Colour replacementColour); - //============================================================================== - /** Internal class used to manage ValueTrees that represent Drawables. */ - class ValueTreeWrapperBase - { - public: - ValueTreeWrapperBase (const ValueTree& state); - - ValueTree& getState() noexcept { return state; } - - String getID() const; - void setID (const String& newID); - - ValueTree state; - }; - - //============================================================================== - /** Registers a set of ComponentBuilder::TypeHandler objects that can be used to - load all the different Drawable types from a saved state. - @see ComponentBuilder::registerTypeHandler() - */ - static void registerDrawableTypeHandlers (ComponentBuilder& componentBuilder); - - MarkerList* getMarkers (bool) override { return nullptr; } - protected: //============================================================================== friend class DrawableComposite; @@ -245,42 +204,9 @@ protected: Point originRelativeToComponent; ScopedPointer drawableClipPath; - #ifndef DOXYGEN - /** Internal utility class used by Drawables. */ - template - class Positioner : public RelativeCoordinatePositionerBase - { - public: - Positioner (DrawableType& c) - : RelativeCoordinatePositionerBase (c), - owner (c) - {} - - bool registerCoordinates() override { return owner.registerCoordinates (*this); } - - void applyToComponentBounds() override - { - ComponentScope scope (getComponent()); - owner.recalculateCoordinates (&scope); - } - - void applyNewBounds (const Rectangle&) override - { - jassertfalse; // drawables can't be resized directly! - } - - private: - DrawableType& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Positioner) - }; - - Drawable (const Drawable&); - #endif - -private: void nonConstDraw (Graphics&, float opacity, const AffineTransform&); + Drawable (const Drawable&); Drawable& operator= (const Drawable&); JUCE_LEAK_DETECTOR (Drawable) }; diff --git a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp index 9c93a3fb5e..6bdbed27b4 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableComposite.cpp @@ -28,16 +28,15 @@ namespace juce { DrawableComposite::DrawableComposite() - : bounds (Point(), Point (100.0f, 0.0f), Point (0.0f, 100.0f)) + : bounds ({ 0.0f, 0.0f, 100.0f, 100.0f }) { - setContentArea (RelativeRectangle (Rectangle (0.0f, 0.0f, 100.0f, 100.0f))); + setContentArea ({ 0.0f, 0.0f, 100.0f, 100.0f }); } DrawableComposite::DrawableComposite (const DrawableComposite& other) : Drawable (other), bounds (other.bounds), - markersX (other.markersX), - markersY (other.markersY) + contentArea (other.contentArea) { for (auto* c : other.getChildren()) if (auto* d = dynamic_cast (c)) @@ -67,87 +66,44 @@ Rectangle DrawableComposite::getDrawableBounds() const return r; } -MarkerList* DrawableComposite::getMarkers (bool xAxis) +void DrawableComposite::setContentArea (Rectangle newArea) { - return xAxis ? &markersX : &markersY; + contentArea = newArea; } -RelativeRectangle DrawableComposite::getContentArea() const +void DrawableComposite::setBoundingBox (Rectangle newBounds) { - jassert (markersX.getNumMarkers() >= 2 && markersX.getMarker (0)->name == contentLeftMarkerName && markersX.getMarker (1)->name == contentRightMarkerName); - jassert (markersY.getNumMarkers() >= 2 && markersY.getMarker (0)->name == contentTopMarkerName && markersY.getMarker (1)->name == contentBottomMarkerName); - - return RelativeRectangle (markersX.getMarker(0)->position, markersX.getMarker(1)->position, - markersY.getMarker(0)->position, markersY.getMarker(1)->position); + setBoundingBox (Parallelogram (newBounds)); } -void DrawableComposite::setContentArea (const RelativeRectangle& newArea) -{ - markersX.setMarker (contentLeftMarkerName, newArea.left); - markersX.setMarker (contentRightMarkerName, newArea.right); - markersY.setMarker (contentTopMarkerName, newArea.top); - markersY.setMarker (contentBottomMarkerName, newArea.bottom); -} - -void DrawableComposite::setBoundingBox (const RelativeParallelogram& newBounds) +void DrawableComposite::setBoundingBox (Parallelogram newBounds) { if (bounds != newBounds) { bounds = newBounds; - if (bounds.isDynamic()) - { - auto p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } + auto t = AffineTransform::fromTargetPoints (contentArea.getTopLeft(), bounds.topLeft, + contentArea.getTopRight(), bounds.topRight, + contentArea.getBottomLeft(), bounds.bottomLeft); + + if (t.isSingularity()) + t = {}; + + setTransform (t); } } void DrawableComposite::resetBoundingBoxToContentArea() { - const RelativeRectangle content (getContentArea()); - - setBoundingBox (RelativeParallelogram (RelativePoint (content.left, content.top), - RelativePoint (content.right, content.top), - RelativePoint (content.left, content.bottom))); + setBoundingBox (contentArea); } void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() { - setContentArea (RelativeRectangle (getDrawableBounds())); + setContentArea (getDrawableBounds()); resetBoundingBoxToContentArea(); } -bool DrawableComposite::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - return pos.addPoint (bounds.bottomLeft) && ok; -} - -void DrawableComposite::recalculateCoordinates (Expression::Scope* scope) -{ - Point resolved[3]; - bounds.resolveThreePoints (resolved, scope); - - auto content = getContentArea().resolve (scope); - - auto t = AffineTransform::fromTargetPoints (content.getX(), content.getY(), resolved[0].x, resolved[0].y, - content.getRight(), content.getY(), resolved[1].x, resolved[1].y, - content.getX(), content.getBottom(), resolved[2].x, resolved[2].y); - - if (t.isSingularity()) - t = AffineTransform(); - - setTransform (t); -} - void DrawableComposite::parentHierarchyChanged() { if (auto* parent = getParent()) @@ -194,131 +150,6 @@ void DrawableComposite::updateBoundsToFitChildren() } //============================================================================== -const char* const DrawableComposite::contentLeftMarkerName = "left"; -const char* const DrawableComposite::contentRightMarkerName = "right"; -const char* const DrawableComposite::contentTopMarkerName = "top"; -const char* const DrawableComposite::contentBottomMarkerName = "bottom"; - -//============================================================================== -const Identifier DrawableComposite::valueTreeType ("Group"); - -const Identifier DrawableComposite::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableComposite::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables"); -const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagX ("MarkersX"); -const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTagY ("MarkersY"); - -//============================================================================== -DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -ValueTree DrawableComposite::ValueTreeWrapper::getChildList() const -{ - return state.getChildWithName (childGroupTag); -} - -ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager* undoManager) -{ - return state.getOrCreateChildWithName (childGroupTag, undoManager); -} - -RelativeParallelogram DrawableComposite::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableComposite::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -void DrawableComposite::ValueTreeWrapper::resetBoundingBoxToContentArea (UndoManager* undoManager) -{ - const RelativeRectangle content (getContentArea()); - - setBoundingBox (RelativeParallelogram (RelativePoint (content.left, content.top), - RelativePoint (content.right, content.top), - RelativePoint (content.left, content.bottom)), undoManager); -} - -RelativeRectangle DrawableComposite::ValueTreeWrapper::getContentArea() const -{ - MarkerList::ValueTreeWrapper marksX (getMarkerList (true)); - MarkerList::ValueTreeWrapper marksY (getMarkerList (false)); - - return RelativeRectangle (marksX.getMarker (marksX.getMarkerState (0)).position, - marksX.getMarker (marksX.getMarkerState (1)).position, - marksY.getMarker (marksY.getMarkerState (0)).position, - marksY.getMarker (marksY.getMarkerState (1)).position); -} - -void DrawableComposite::ValueTreeWrapper::setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager) -{ - MarkerList::ValueTreeWrapper marksX (getMarkerListCreating (true, nullptr)); - MarkerList::ValueTreeWrapper marksY (getMarkerListCreating (false, nullptr)); - - marksX.setMarker (MarkerList::Marker (contentLeftMarkerName, newArea.left), undoManager); - marksX.setMarker (MarkerList::Marker (contentRightMarkerName, newArea.right), undoManager); - marksY.setMarker (MarkerList::Marker (contentTopMarkerName, newArea.top), undoManager); - marksY.setMarker (MarkerList::Marker (contentBottomMarkerName, newArea.bottom), undoManager); -} - -MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerList (bool xAxis) const -{ - return state.getChildWithName (xAxis ? markerGroupTagX : markerGroupTagY); -} - -MarkerList::ValueTreeWrapper DrawableComposite::ValueTreeWrapper::getMarkerListCreating (bool xAxis, UndoManager* undoManager) -{ - return state.getOrCreateChildWithName (xAxis ? markerGroupTagX : markerGroupTagY, undoManager); -} - -//============================================================================== -void DrawableComposite::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - const ValueTreeWrapper wrapper (tree); - setComponentID (wrapper.getID()); - - wrapper.getMarkerList (true).applyTo (markersX); - wrapper.getMarkerList (false).applyTo (markersY); - - setBoundingBox (wrapper.getBoundingBox()); - - builder.updateChildComponents (*this, wrapper.getChildList()); -} - -ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setBoundingBox (bounds, nullptr); - - ValueTree childList (v.getChildListCreating (nullptr)); - - for (auto* c : getChildren()) - { - auto* d = dynamic_cast (c); - jassert (d != nullptr); // You can't save a mix of Drawables and normal components! - - childList.appendChild (d->createValueTree (imageProvider), nullptr); - } - - v.getMarkerListCreating (true, nullptr).readFrom (markersX, nullptr); - v.getMarkerListCreating (false, nullptr).readFrom (markersY, nullptr); - - return tree; -} - Path DrawableComposite::getOutlineAsPath() const { Path p; diff --git a/modules/juce_gui_basics/drawables/juce_DrawableComposite.h b/modules/juce_gui_basics/drawables/juce_DrawableComposite.h index b98bb62375..de0acec3ac 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableComposite.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableComposite.h @@ -55,12 +55,17 @@ public: /** Sets the parallelogram that defines the target position of the content rectangle when the drawable is rendered. @see setContentArea */ - void setBoundingBox (const RelativeParallelogram& newBoundingBox); + void setBoundingBox (Parallelogram newBoundingBox); + + /** Sets the rectangle that defines the target position of the content rectangle when the drawable is rendered. + @see setContentArea + */ + void setBoundingBox (Rectangle newBoundingBox); /** Returns the parallelogram that defines the target position of the content rectangle when the drawable is rendered. @see setBoundingBox */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } + Parallelogram getBoundingBox() const noexcept { return bounds; } /** Changes the bounding box transform to match the content area, so that any sub-items will be drawn at their untransformed positions. @@ -68,44 +73,24 @@ 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 */ - RelativeRectangle getContentArea() const; + Rectangle getContentArea() const noexcept { return contentArea; } /** 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); + void setContentArea (Rectangle newArea); /** Resets the content area and the bounding transform to fit around the area occupied - by the child components (ignoring any markers). + by the child components. */ void resetContentAreaAndBoundingBoxToFitChildren(); - //============================================================================== - /** The name of the marker that defines the left edge of the content area. */ - static const char* const contentLeftMarkerName; - /** The name of the marker that defines the right edge of the content area. */ - static const char* const contentRightMarkerName; - /** The name of the marker that defines the top edge of the content area. */ - static const char* const contentTopMarkerName; - /** The name of the marker that defines the bottom edge of the content area. */ - static const char* const contentBottomMarkerName; - //============================================================================== /** @internal */ Drawable* createCopy() const override; /** @internal */ - void refreshFromValueTree (const ValueTree&, ComponentBuilder&); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const override; - /** @internal */ - static const Identifier valueTreeType; - /** @internal */ Rectangle getDrawableBounds() const override; /** @internal */ void childBoundsChanged (Component*) override; @@ -114,46 +99,14 @@ public: /** @internal */ void parentHierarchyChanged() override; /** @internal */ - MarkerList* getMarkers (bool xAxis) override; - /** @internal */ Path getOutlineAsPath() const override; - //============================================================================== - /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - ValueTree getChildList() const; - ValueTree getChildListCreating (UndoManager* undoManager); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager); - void resetBoundingBoxToContentArea (UndoManager* undoManager); - - RelativeRectangle getContentArea() const; - void setContentArea (const RelativeRectangle& newArea, UndoManager* undoManager); - - MarkerList::ValueTreeWrapper getMarkerList (bool xAxis) const; - MarkerList::ValueTreeWrapper getMarkerListCreating (bool xAxis, UndoManager* undoManager); - - static const Identifier topLeft, topRight, bottomLeft; - - private: - static const Identifier childGroupTag, markerGroupTagX, markerGroupTagY; - }; - private: //============================================================================== - RelativeParallelogram bounds; - MarkerList markersX, markersY; + Parallelogram bounds; + Rectangle contentArea; bool updateBoundsReentrant = false; - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); - void updateBoundsToFitChildren(); DrawableComposite& operator= (const DrawableComposite&); diff --git a/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp b/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp index c7675afce2..0e5d2e99a5 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp @@ -27,12 +27,8 @@ namespace juce { -DrawableImage::DrawableImage() - : opacity (1.0f), - overlayColour (0x00000000) +DrawableImage::DrawableImage() : bounds ({ 0.0f, 0.0f, 1.0f, 1.0f }) { - bounds.topRight = RelativePoint (Point (1.0f, 0.0f)); - bounds.bottomLeft = RelativePoint (Point (0.0f, 1.0f)); } DrawableImage::DrawableImage (const DrawableImage& other) @@ -49,18 +45,21 @@ DrawableImage::~DrawableImage() { } +Drawable* DrawableImage::createCopy() const +{ + return new DrawableImage (*this); +} + //============================================================================== void DrawableImage::setImage (const Image& imageToUse) { - image = imageToUse; - setBounds (imageToUse.getBounds()); - - 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())); - recalculateCoordinates (nullptr); - - repaint(); + if (image != imageToUse) + { + image = imageToUse; + setBounds (image.getBounds()); + setBoundingBox (image.getBounds().toFloat()); + repaint(); + } } void DrawableImage::setOpacity (const float newOpacity) @@ -73,52 +72,31 @@ void DrawableImage::setOverlayColour (Colour newOverlayColour) overlayColour = newOverlayColour; } -void DrawableImage::setBoundingBox (const RelativeParallelogram& newBounds) -{ - if (bounds != newBounds) - { - bounds = newBounds; - - if (bounds.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } - } -} - -//============================================================================== -bool DrawableImage::registerCoordinates (RelativeCoordinatePositionerBase& pos) +void DrawableImage::setBoundingBox (Rectangle newBounds) { - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - return pos.addPoint (bounds.bottomLeft) && ok; + setBoundingBox (Parallelogram (newBounds)); } -void DrawableImage::recalculateCoordinates (Expression::Scope* scope) +void DrawableImage::setBoundingBox (Parallelogram newBounds) { - if (image.isValid()) + if (bounds != newBounds) { - Point resolved[3]; - bounds.resolveThreePoints (resolved, scope); + bounds = newBounds; - const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image.getWidth()); - const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image.getHeight()); + if (image.isValid()) + { + auto tr = bounds.topLeft + (bounds.topRight - bounds.topLeft) / (float) image.getWidth(); + auto bl = bounds.topLeft + (bounds.bottomLeft - bounds.topLeft) / (float) image.getHeight(); - AffineTransform t (AffineTransform::fromTargetPoints (resolved[0].x, resolved[0].y, - tr.x, tr.y, - bl.x, bl.y)); + auto t = AffineTransform::fromTargetPoints (bounds.topLeft.x, bounds.topLeft.y, + tr.x, tr.y, + bl.x, bl.y); - if (t.isSingularity()) - t = AffineTransform(); + if (t.isSingularity()) + t = {}; - setTransform (t); + setTransform (t); + } } } @@ -151,149 +129,6 @@ bool DrawableImage::hitTest (int x, int y) return Drawable::hitTest (x, y) && image.isValid() && image.getPixelAt (x, y).getAlpha() >= 127; } -Drawable* DrawableImage::createCopy() const -{ - return new DrawableImage (*this); -} - -//============================================================================== -const Identifier DrawableImage::valueTreeType ("Image"); - -const Identifier DrawableImage::ValueTreeWrapper::opacity ("opacity"); -const Identifier DrawableImage::ValueTreeWrapper::overlay ("overlay"); -const Identifier DrawableImage::ValueTreeWrapper::image ("image"); -const Identifier DrawableImage::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableImage::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableImage::ValueTreeWrapper::bottomLeft ("bottomLeft"); - -//============================================================================== -DrawableImage::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -var DrawableImage::ValueTreeWrapper::getImageIdentifier() const -{ - return state [image]; -} - -Value DrawableImage::ValueTreeWrapper::getImageIdentifierValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (image, undoManager); -} - -void DrawableImage::ValueTreeWrapper::setImageIdentifier (const var& newIdentifier, UndoManager* undoManager) -{ - state.setProperty (image, newIdentifier, undoManager); -} - -float DrawableImage::ValueTreeWrapper::getOpacity() const -{ - return (float) state.getProperty (opacity, 1.0); -} - -Value DrawableImage::ValueTreeWrapper::getOpacityValue (UndoManager* undoManager) -{ - if (! state.hasProperty (opacity)) - state.setProperty (opacity, 1.0, undoManager); - - return state.getPropertyAsValue (opacity, undoManager); -} - -void DrawableImage::ValueTreeWrapper::setOpacity (float newOpacity, UndoManager* undoManager) -{ - state.setProperty (opacity, newOpacity, undoManager); -} - -Colour DrawableImage::ValueTreeWrapper::getOverlayColour() const -{ - return Colour::fromString (state [overlay].toString()); -} - -void DrawableImage::ValueTreeWrapper::setOverlayColour (Colour newColour, UndoManager* undoManager) -{ - if (newColour.isTransparent()) - state.removeProperty (overlay, undoManager); - else - state.setProperty (overlay, String::toHexString ((int) newColour.getARGB()), undoManager); -} - -Value DrawableImage::ValueTreeWrapper::getOverlayColourValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (overlay, undoManager); -} - -RelativeParallelogram DrawableImage::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableImage::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - - -//============================================================================== -void DrawableImage::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - const ValueTreeWrapper controller (tree); - setComponentID (controller.getID()); - - const float newOpacity = controller.getOpacity(); - const Colour newOverlayColour (controller.getOverlayColour()); - - Image newImage; - const var imageIdentifier (controller.getImageIdentifier()); - - - jassert (builder.getImageProvider() != 0 || imageIdentifier.isVoid()); // if you're using images, you need to provide something that can load and save them! - - if (builder.getImageProvider() != nullptr) - newImage = builder.getImageProvider()->getImageForIdentifier (imageIdentifier); - - const RelativeParallelogram newBounds (controller.getBoundingBox()); - - if (bounds != newBounds || newOpacity != opacity - || overlayColour != newOverlayColour || image != newImage) - { - repaint(); - opacity = newOpacity; - overlayColour = newOverlayColour; - - if (image != newImage) - setImage (newImage); - - setBoundingBox (newBounds); - } -} - -ValueTree DrawableImage::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setOpacity (opacity, nullptr); - v.setOverlayColour (overlayColour, nullptr); - v.setBoundingBox (bounds, nullptr); - - if (image.isValid()) - { - jassert (imageProvider != nullptr); // if you're using images, you need to provide something that can load and save them! - - if (imageProvider != nullptr) - v.setImageIdentifier (imageProvider->getIdentifierForImage (image), nullptr); - } - - return tree; -} - Path DrawableImage::getOutlineAsPath() const { return {}; // not applicable for images diff --git a/modules/juce_gui_basics/drawables/juce_DrawableImage.h b/modules/juce_gui_basics/drawables/juce_DrawableImage.h index d1277174ab..6558517a76 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableImage.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableImage.h @@ -71,13 +71,16 @@ public: Colour getOverlayColour() const noexcept { return overlayColour; } /** Sets the bounding box within which the image should be displayed. */ - void setBoundingBox (const RelativeParallelogram& newBounds); + void setBoundingBox (Parallelogram newBounds); + + /** Sets the bounding box within which the image should be displayed. */ + void setBoundingBox (Rectangle newBounds); /** Returns the position to which the image's top-left corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } + Parallelogram getBoundingBox() const noexcept { return bounds; } //============================================================================== /** @internal */ @@ -89,49 +92,14 @@ public: /** @internal */ Rectangle getDrawableBounds() const override; /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder&); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider*) const override; - /** @internal */ - static const Identifier valueTreeType; - /** @internal */ Path getOutlineAsPath() const override; - //============================================================================== - /** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - var getImageIdentifier() const; - void setImageIdentifier (const var&, UndoManager*); - Value getImageIdentifierValue (UndoManager*); - - float getOpacity() const; - void setOpacity (float newOpacity, UndoManager*); - Value getOpacityValue (UndoManager*); - - Colour getOverlayColour() const; - void setOverlayColour (Colour newColour, UndoManager*); - Value getOverlayColourValue (UndoManager*); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram&, UndoManager*); - - static const Identifier opacity, overlay, image, topLeft, topRight, bottomLeft; - }; - private: //============================================================================== Image image; - float opacity; - Colour overlayColour; - RelativeParallelogram bounds; - - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); + float opacity = 1.0f; + Colour overlayColour { 0 }; + Parallelogram bounds; DrawableImage& operator= (const DrawableImage&); JUCE_LEAK_DETECTOR (DrawableImage) diff --git a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp index f31813f466..c648f46cf9 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawablePath.cpp @@ -27,21 +27,12 @@ namespace juce { -DrawablePath::DrawablePath() -{ -} - -DrawablePath::DrawablePath (const DrawablePath& other) - : DrawableShape (other) -{ - if (other.relativePath != nullptr) - setPath (*other.relativePath); - else - setPath (other.path); -} +DrawablePath::DrawablePath() {} +DrawablePath::~DrawablePath() {} -DrawablePath::~DrawablePath() +DrawablePath::DrawablePath (const DrawablePath& other) : DrawableShape (other) { + setPath (other.path); } Drawable* DrawablePath::createCopy() const @@ -49,529 +40,19 @@ Drawable* DrawablePath::createCopy() const return new DrawablePath (*this); } -//============================================================================== void DrawablePath::setPath (const Path& newPath) { path = newPath; pathChanged(); } -const Path& DrawablePath::getPath() const -{ - return path; -} - -const Path& DrawablePath::getStrokePath() const -{ - return strokePath; -} - -void DrawablePath::applyRelativePath (const RelativePointPath& newRelativePath, Expression::Scope* scope) -{ - Path newPath; - newRelativePath.createPath (newPath, scope); - - if (path != newPath) - { - path.swapWithPath (newPath); - pathChanged(); - } -} - -//============================================================================== -class DrawablePath::RelativePositioner : public RelativeCoordinatePositionerBase -{ -public: - RelativePositioner (DrawablePath& comp) - : RelativeCoordinatePositionerBase (comp), - owner (comp) - { - } - - bool registerCoordinates() override - { - bool ok = true; - - jassert (owner.relativePath != nullptr); - const RelativePointPath& relPath = *owner.relativePath; - - for (int i = 0; i < relPath.elements.size(); ++i) - { - RelativePointPath::ElementBase* const e = relPath.elements.getUnchecked(i); - - int numPoints; - RelativePoint* const points = e->getControlPoints (numPoints); - - for (int j = numPoints; --j >= 0;) - ok = addPoint (points[j]) && ok; - } - - return ok; - } - - void applyToComponentBounds() override - { - jassert (owner.relativePath != nullptr); - - ComponentScope scope (getComponent()); - owner.applyRelativePath (*owner.relativePath, &scope); - } - - void applyNewBounds (const Rectangle&) override - { - jassertfalse; // drawables can't be resized directly! - } - -private: - DrawablePath& owner; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativePositioner) -}; - -void DrawablePath::setPath (const RelativePointPath& newRelativePath) -{ - if (newRelativePath.containsAnyDynamicPoints()) - { - if (relativePath == nullptr || newRelativePath != *relativePath) - { - relativePath = new RelativePointPath (newRelativePath); - - RelativePositioner* const p = new RelativePositioner (*this); - setPositioner (p); - p->apply(); - } - } - else - { - relativePath.reset(); - applyRelativePath (newRelativePath, nullptr); - } -} - -//============================================================================== -const Identifier DrawablePath::valueTreeType ("Path"); - -const Identifier DrawablePath::ValueTreeWrapper::nonZeroWinding ("nonZeroWinding"); -const Identifier DrawablePath::ValueTreeWrapper::point1 ("p1"); -const Identifier DrawablePath::ValueTreeWrapper::point2 ("p2"); -const Identifier DrawablePath::ValueTreeWrapper::point3 ("p3"); - -//============================================================================== -DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : FillAndStrokeState (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -ValueTree DrawablePath::ValueTreeWrapper::getPathState() +void DrawablePath::setPath (Path&& newPath) { - return state.getOrCreateChildWithName (path, nullptr); -} - -bool DrawablePath::ValueTreeWrapper::usesNonZeroWinding() const -{ - return state [nonZeroWinding]; -} - -void DrawablePath::ValueTreeWrapper::setUsesNonZeroWinding (bool b, UndoManager* undoManager) -{ - state.setProperty (nonZeroWinding, b, undoManager); -} - -void DrawablePath::ValueTreeWrapper::readFrom (const RelativePointPath& p, UndoManager* undoManager) -{ - setUsesNonZeroWinding (p.usesNonZeroWinding, undoManager); - - ValueTree pathTree (getPathState()); - pathTree.removeAllChildren (undoManager); - - for (int i = 0; i < p.elements.size(); ++i) - pathTree.appendChild (p.elements.getUnchecked(i)->createTree(), undoManager); -} - -void DrawablePath::ValueTreeWrapper::writeTo (RelativePointPath& p) const -{ - p.usesNonZeroWinding = usesNonZeroWinding(); - RelativePoint points[3]; - - const ValueTree pathTree (state.getChildWithName (path)); - const int num = pathTree.getNumChildren(); - for (int i = 0; i < num; ++i) - { - const Element e (pathTree.getChild(i)); - - const int numCps = e.getNumControlPoints(); - for (int j = 0; j < numCps; ++j) - points[j] = e.getControlPoint (j); - - RelativePointPath::ElementBase* newElement = nullptr; - const Identifier t (e.getType()); - - if (t == Element::startSubPathElement) newElement = new RelativePointPath::StartSubPath (points[0]); - else if (t == Element::closeSubPathElement) newElement = new RelativePointPath::CloseSubPath(); - else if (t == Element::lineToElement) newElement = new RelativePointPath::LineTo (points[0]); - else if (t == Element::quadraticToElement) newElement = new RelativePointPath::QuadraticTo (points[0], points[1]); - else if (t == Element::cubicToElement) newElement = new RelativePointPath::CubicTo (points[0], points[1], points[2]); - else jassertfalse; - - p.addElement (newElement); - } -} - -//============================================================================== -const Identifier DrawablePath::ValueTreeWrapper::Element::mode ("mode"); -const Identifier DrawablePath::ValueTreeWrapper::Element::startSubPathElement ("Move"); -const Identifier DrawablePath::ValueTreeWrapper::Element::closeSubPathElement ("Close"); -const Identifier DrawablePath::ValueTreeWrapper::Element::lineToElement ("Line"); -const Identifier DrawablePath::ValueTreeWrapper::Element::quadraticToElement ("Quad"); -const Identifier DrawablePath::ValueTreeWrapper::Element::cubicToElement ("Cubic"); - -const char* DrawablePath::ValueTreeWrapper::Element::cornerMode = "corner"; -const char* DrawablePath::ValueTreeWrapper::Element::roundedMode = "round"; -const char* DrawablePath::ValueTreeWrapper::Element::symmetricMode = "symm"; - -DrawablePath::ValueTreeWrapper::Element::Element (const ValueTree& state_) - : state (state_) -{ -} - -DrawablePath::ValueTreeWrapper::Element::~Element() -{ -} - -DrawablePath::ValueTreeWrapper DrawablePath::ValueTreeWrapper::Element::getParent() const -{ - return ValueTreeWrapper (state.getParent().getParent()); -} - -DrawablePath::ValueTreeWrapper::Element DrawablePath::ValueTreeWrapper::Element::getPreviousElement() const -{ - return Element (state.getSibling (-1)); -} - -int DrawablePath::ValueTreeWrapper::Element::getNumControlPoints() const noexcept -{ - const Identifier i (state.getType()); - if (i == startSubPathElement || i == lineToElement) return 1; - if (i == quadraticToElement) return 2; - if (i == cubicToElement) return 3; - return 0; -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getControlPoint (const int index) const -{ - jassert (index >= 0 && index < getNumControlPoints()); - return RelativePoint (state [index == 0 ? point1 : (index == 1 ? point2 : point3)].toString()); -} - -Value DrawablePath::ValueTreeWrapper::Element::getControlPointValue (int index, UndoManager* undoManager) -{ - jassert (index >= 0 && index < getNumControlPoints()); - return state.getPropertyAsValue (index == 0 ? point1 : (index == 1 ? point2 : point3), undoManager); -} - -void DrawablePath::ValueTreeWrapper::Element::setControlPoint (const int index, const RelativePoint& point, UndoManager* undoManager) -{ - jassert (index >= 0 && index < getNumControlPoints()); - state.setProperty (index == 0 ? point1 : (index == 1 ? point2 : point3), point.toString(), undoManager); -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getStartPoint() const -{ - const Identifier i (state.getType()); - - if (i == startSubPathElement) - return getControlPoint (0); - - jassert (i == lineToElement || i == quadraticToElement || i == cubicToElement || i == closeSubPathElement); - - return getPreviousElement().getEndPoint(); -} - -RelativePoint DrawablePath::ValueTreeWrapper::Element::getEndPoint() const -{ - const Identifier i (state.getType()); - if (i == startSubPathElement || i == lineToElement) return getControlPoint (0); - if (i == quadraticToElement) return getControlPoint (1); - if (i == cubicToElement) return getControlPoint (2); - - jassert (i == closeSubPathElement); - return RelativePoint(); -} - -float DrawablePath::ValueTreeWrapper::Element::getLength (Expression::Scope* scope) const -{ - const Identifier i (state.getType()); - - if (i == lineToElement || i == closeSubPathElement) - return getEndPoint().resolve (scope).getDistanceFrom (getStartPoint().resolve (scope)); - - if (i == cubicToElement) - { - Path p; - p.startNewSubPath (getStartPoint().resolve (scope)); - p.cubicTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope), getControlPoint (2).resolve (scope)); - return p.getLength(); - } - - if (i == quadraticToElement) - { - Path p; - p.startNewSubPath (getStartPoint().resolve (scope)); - p.quadraticTo (getControlPoint (0).resolve (scope), getControlPoint (1).resolve (scope)); - return p.getLength(); - } - - jassert (i == startSubPathElement); - return 0; -} - -String DrawablePath::ValueTreeWrapper::Element::getModeOfEndPoint() const -{ - return state [mode].toString(); -} - -void DrawablePath::ValueTreeWrapper::Element::setModeOfEndPoint (const String& newMode, UndoManager* undoManager) -{ - if (state.hasType (cubicToElement)) - state.setProperty (mode, newMode, undoManager); -} - -void DrawablePath::ValueTreeWrapper::Element::convertToLine (UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i == quadraticToElement || i == cubicToElement) - { - ValueTree newState (lineToElement); - Element e (newState); - e.setControlPoint (0, getEndPoint(), undoManager); - state = newState; - } -} - -void DrawablePath::ValueTreeWrapper::Element::convertToCubic (Expression::Scope* scope, UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i == lineToElement || i == quadraticToElement) - { - ValueTree newState (cubicToElement); - Element e (newState); - - const RelativePoint start (getStartPoint()); - const RelativePoint end (getEndPoint()); - const Point startResolved (start.resolve (scope)); - const Point endResolved (end.resolve (scope)); - e.setControlPoint (0, startResolved + (endResolved - startResolved) * 0.3f, undoManager); - e.setControlPoint (1, startResolved + (endResolved - startResolved) * 0.7f, undoManager); - e.setControlPoint (2, end, undoManager); - - state = newState; - } -} - -void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* undoManager) -{ - const Identifier i (state.getType()); - - if (i != startSubPathElement) - { - ValueTree newState (startSubPathElement); - Element e (newState); - e.setControlPoint (0, getEndPoint(), undoManager); - state = newState; - } -} - -namespace DrawablePathHelpers -{ - static Point findCubicSubdivisionPoint (float proportion, const Point points[4]) - { - const Point mid1 (points[0] + (points[1] - points[0]) * proportion), - mid2 (points[1] + (points[2] - points[1]) * proportion), - mid3 (points[2] + (points[3] - points[2]) * proportion); - - const Point newCp1 (mid1 + (mid2 - mid1) * proportion), - newCp2 (mid2 + (mid3 - mid2) * proportion); - - return newCp1 + (newCp2 - newCp1) * proportion; - } - - static Point findQuadraticSubdivisionPoint (float proportion, const Point points[3]) - { - const Point mid1 (points[0] + (points[1] - points[0]) * proportion), - mid2 (points[1] + (points[2] - points[1]) * proportion); - - return mid1 + (mid2 - mid1) * proportion; - } -} - -float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (Point targetPoint, Expression::Scope* scope) const -{ - using namespace DrawablePathHelpers; - const Identifier pointType (state.getType()); - float bestProp = 0; - - if (pointType == cubicToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); - - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; - - float bestDistance = std::numeric_limits::max(); - - for (int i = 110; --i >= 0;) - { - float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); - const Point centre (findCubicSubdivisionPoint (prop, points)); - const float distance = centre.getDistanceFrom (targetPoint); - - if (distance < bestDistance) - { - bestProp = prop; - bestDistance = distance; - } - } - } - else if (pointType == quadraticToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; - - float bestDistance = std::numeric_limits::max(); - - for (int i = 110; --i >= 0;) - { - float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); - const Point centre (findQuadraticSubdivisionPoint ((float) prop, points)); - const float distance = centre.getDistanceFrom (targetPoint); - - if (distance < bestDistance) - { - bestProp = prop; - bestDistance = distance; - } - } - } - else if (pointType == lineToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); - const Line line (rp1.resolve (scope), rp2.resolve (scope)); - bestProp = line.findNearestProportionalPositionTo (targetPoint); - } - - return bestProp; -} - -ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (Point targetPoint, Expression::Scope* scope, UndoManager* undoManager) -{ - ValueTree newTree; - const Identifier pointType (state.getType()); - - if (pointType == cubicToElement) - { - float bestProp = findProportionAlongLine (targetPoint, scope); - - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope), rp4.resolve (scope) }; - - const Point mid1 (points[0] + (points[1] - points[0]) * bestProp), - mid2 (points[1] + (points[2] - points[1]) * bestProp), - mid3 (points[2] + (points[3] - points[2]) * bestProp); - - const Point newCp1 (mid1 + (mid2 - mid1) * bestProp), - newCp2 (mid2 + (mid3 - mid2) * bestProp); - - const Point newCentre (newCp1 + (newCp2 - newCp1) * bestProp); - - setControlPoint (0, mid1, undoManager); - setControlPoint (1, newCp1, undoManager); - setControlPoint (2, newCentre, undoManager); - setModeOfEndPoint (roundedMode, undoManager); - - Element newElement (newTree = ValueTree (cubicToElement)); - newElement.setControlPoint (0, newCp2, nullptr); - newElement.setControlPoint (1, mid3, nullptr); - newElement.setControlPoint (2, rp4, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == quadraticToElement) - { - float bestProp = findProportionAlongLine (targetPoint, scope); - - RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); - const Point points[] = { rp1.resolve (scope), rp2.resolve (scope), rp3.resolve (scope) }; - - const Point mid1 (points[0] + (points[1] - points[0]) * bestProp), - mid2 (points[1] + (points[2] - points[1]) * bestProp); - - const Point newCentre (mid1 + (mid2 - mid1) * bestProp); - - setControlPoint (0, mid1, undoManager); - setControlPoint (1, newCentre, undoManager); - setModeOfEndPoint (roundedMode, undoManager); - - Element newElement (newTree = ValueTree (quadraticToElement)); - newElement.setControlPoint (0, mid2, nullptr); - newElement.setControlPoint (1, rp3, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == lineToElement) - { - RelativePoint rp1 (getStartPoint()), rp2 (getEndPoint()); - const Line line (rp1.resolve (scope), rp2.resolve (scope)); - const Point newPoint (line.findNearestPointTo (targetPoint)); - - setControlPoint (0, newPoint, undoManager); - - Element newElement (newTree = ValueTree (lineToElement)); - newElement.setControlPoint (0, rp2, nullptr); - - state.getParent().addChild (newTree, state.getParent().indexOf (state) + 1, undoManager); - } - else if (pointType == closeSubPathElement) - { - } - - return newTree; -} - -void DrawablePath::ValueTreeWrapper::Element::removePoint (UndoManager* undoManager) -{ - state.getParent().removeChild (state, undoManager); -} - -//============================================================================== -void DrawablePath::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - refreshFillTypes (v, builder.getImageProvider()); - setStrokeType (v.getStrokeType()); - - RelativePointPath newRelativePath; - v.writeTo (newRelativePath); - setPath (newRelativePath); + path = static_cast (newPath); + pathChanged(); } -ValueTree DrawablePath::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - writeTo (v, imageProvider, nullptr); - - if (relativePath != nullptr) - v.readFrom (*relativePath, nullptr); - else - v.readFrom (RelativePointPath (path), nullptr); - - return tree; -} +const Path& DrawablePath::getPath() const { return path; } +const Path& DrawablePath::getStrokePath() const { return strokePath; } } // namespace juce diff --git a/modules/juce_gui_basics/drawables/juce_DrawablePath.h b/modules/juce_gui_basics/drawables/juce_DrawablePath.h index b41daf8bf2..d8b93363d2 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawablePath.h +++ b/modules/juce_gui_basics/drawables/juce_DrawablePath.h @@ -52,11 +52,10 @@ public: */ void setPath (const Path& newPath); - /** Sets the path using a RelativePointPath. - Calling this will set up a Component::Positioner to automatically update the path - if any of the points in the source path are dynamic. + /** Changes the path that will be drawn. + @see setFill, setStrokeType */ - void setPath (const RelativePointPath& newPath); + void setPath (Path&& newPath); /** Returns the current path. */ const Path& getPath() const; @@ -67,77 +66,9 @@ public: //============================================================================== /** @internal */ Drawable* createCopy() const; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const; - /** @internal */ - static const Identifier valueTreeType; - - //============================================================================== - /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ - class ValueTreeWrapper : public DrawableShape::FillAndStrokeState - { - public: - ValueTreeWrapper (const ValueTree& state); - - bool usesNonZeroWinding() const; - void setUsesNonZeroWinding (bool b, UndoManager* undoManager); - - class Element - { - public: - explicit Element (const ValueTree& state); - ~Element(); - - const Identifier getType() const noexcept { return state.getType(); } - int getNumControlPoints() const noexcept; - - RelativePoint getControlPoint (int index) const; - Value getControlPointValue (int index, UndoManager*); - RelativePoint getStartPoint() const; - RelativePoint getEndPoint() const; - void setControlPoint (int index, const RelativePoint& point, UndoManager*); - float getLength (Expression::Scope*) const; - - ValueTreeWrapper getParent() const; - Element getPreviousElement() const; - - String getModeOfEndPoint() const; - void setModeOfEndPoint (const String& newMode, UndoManager*); - - void convertToLine (UndoManager*); - void convertToCubic (Expression::Scope*, UndoManager*); - void convertToPathBreak (UndoManager* undoManager); - ValueTree insertPoint (Point targetPoint, Expression::Scope*, UndoManager*); - void removePoint (UndoManager* undoManager); - float findProportionAlongLine (Point targetPoint, Expression::Scope*) const; - - static const Identifier mode, startSubPathElement, closeSubPathElement, - lineToElement, quadraticToElement, cubicToElement; - static const char* cornerMode; - static const char* roundedMode; - static const char* symmetricMode; - - ValueTree state; - }; - - ValueTree getPathState(); - - void readFrom (const RelativePointPath& relativePath, UndoManager* undoManager); - void writeTo (RelativePointPath& relativePath) const; - - static const Identifier nonZeroWinding, point1, point2, point3; - }; private: //============================================================================== - ScopedPointer relativePath; - - class RelativePositioner; - friend class RelativePositioner; - void applyRelativePath (const RelativePointPath&, Expression::Scope*); - DrawablePath& operator= (const DrawablePath&); JUCE_LEAK_DETECTOR (DrawablePath) }; diff --git a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp index cd61718d43..be093deb41 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.cpp @@ -27,9 +27,8 @@ namespace juce { -DrawableRectangle::DrawableRectangle() -{ -} +DrawableRectangle::DrawableRectangle() {} +DrawableRectangle::~DrawableRectangle() {} DrawableRectangle::DrawableRectangle (const DrawableRectangle& other) : DrawableShape (other), @@ -39,17 +38,13 @@ DrawableRectangle::DrawableRectangle (const DrawableRectangle& other) rebuildPath(); } -DrawableRectangle::~DrawableRectangle() -{ -} - Drawable* DrawableRectangle::createCopy() const { return new DrawableRectangle (*this); } //============================================================================== -void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds) +void DrawableRectangle::setRectangle (Parallelogram newBounds) { if (bounds != newBounds) { @@ -58,7 +53,7 @@ void DrawableRectangle::setRectangle (const RelativeParallelogram& newBounds) } } -void DrawableRectangle::setCornerSize (const RelativePoint& newSize) +void DrawableRectangle::setCornerSize (Point newSize) { if (cornerSize != newSize) { @@ -69,48 +64,19 @@ void DrawableRectangle::setCornerSize (const RelativePoint& newSize) void DrawableRectangle::rebuildPath() { - if (bounds.isDynamic() || cornerSize.isDynamic()) - { - auto p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (nullptr); - recalculateCoordinates (nullptr); - } -} - -bool DrawableRectangle::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - ok = pos.addPoint (bounds.bottomLeft) && ok; - return pos.addPoint (cornerSize) && ok; -} - -void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope) -{ - Point points[3]; - bounds.resolveThreePoints (points, scope); - - auto cornerSizeX = (float) cornerSize.x.resolve (scope); - auto cornerSizeY = (float) cornerSize.y.resolve (scope); - - auto w = Line (points[0], points[1]).getLength(); - auto h = Line (points[0], points[2]).getLength(); + auto w = bounds.getWidth(); + auto h = bounds.getHeight(); Path newPath; - if (cornerSizeX > 0 && cornerSizeY > 0) - newPath.addRoundedRectangle (0, 0, w, h, cornerSizeX, cornerSizeY); + if (cornerSize.x > 0 && cornerSize.y > 0) + newPath.addRoundedRectangle (0, 0, w, h, cornerSize.x, cornerSize.y); else newPath.addRectangle (0, 0, w, h); - newPath.applyTransform (AffineTransform::fromTargetPoints (0, 0, points[0].x, points[0].y, - w, 0, points[1].x, points[1].y, - 0, h, points[2].x, points[2].y)); + newPath.applyTransform (AffineTransform::fromTargetPoints (Point(), bounds.topLeft, + Point (w, 0), bounds.topRight, + Point (0, h), bounds.bottomLeft)); if (path != newPath) { @@ -119,72 +85,4 @@ void DrawableRectangle::recalculateCoordinates (Expression::Scope* scope) } } -//============================================================================== -const Identifier DrawableRectangle::valueTreeType ("Rectangle"); -const Identifier DrawableRectangle::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableRectangle::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableRectangle::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableRectangle::ValueTreeWrapper::cornerSize ("cornerSize"); - -//============================================================================== -DrawableRectangle::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : FillAndStrokeState (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -RelativeParallelogram DrawableRectangle::ValueTreeWrapper::getRectangle() const -{ - return RelativeParallelogram (state.getProperty (topLeft, "0, 0"), - state.getProperty (topRight, "100, 0"), - state.getProperty (bottomLeft, "0, 100")); -} - -void DrawableRectangle::ValueTreeWrapper::setRectangle (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -void DrawableRectangle::ValueTreeWrapper::setCornerSize (const RelativePoint& newSize, UndoManager* undoManager) -{ - state.setProperty (cornerSize, newSize.toString(), undoManager); -} - -RelativePoint DrawableRectangle::ValueTreeWrapper::getCornerSize() const -{ - return RelativePoint (state[cornerSize]); -} - -Value DrawableRectangle::ValueTreeWrapper::getCornerSizeValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (cornerSize, undoManager); -} - -//============================================================================== -void DrawableRectangle::refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - refreshFillTypes (v, builder.getImageProvider()); - setStrokeType (v.getStrokeType()); - setRectangle (v.getRectangle()); - setCornerSize (v.getCornerSize()); -} - -ValueTree DrawableRectangle::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - writeTo (v, imageProvider, nullptr); - v.setRectangle (bounds, nullptr); - v.setCornerSize (cornerSize, nullptr); - - return tree; -} - } // namespace juce diff --git a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h index fbb3f77ccb..ab9fc46bee 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableRectangle.h @@ -47,54 +47,26 @@ public: //============================================================================== /** Sets the rectangle's bounds. */ - void setRectangle (const RelativeParallelogram& newBounds); + void setRectangle (Parallelogram newBounds); /** Returns the rectangle's bounds. */ - const RelativeParallelogram& getRectangle() const noexcept { return bounds; } + Parallelogram getRectangle() const noexcept { return bounds; } /** Returns the corner size to be used. */ - const RelativePoint& getCornerSize() const noexcept { return cornerSize; } + Point getCornerSize() const noexcept { return cornerSize; } /** Sets a new corner size for the rectangle */ - void setCornerSize (const RelativePoint& newSize); + void setCornerSize (Point newSize); //============================================================================== /** @internal */ Drawable* createCopy() const; - /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const; - /** @internal */ - static const Identifier valueTreeType; - - //============================================================================== - /** Internally-used class for wrapping a DrawableRectangle's state into a ValueTree. */ - class ValueTreeWrapper : public DrawableShape::FillAndStrokeState - { - public: - ValueTreeWrapper (const ValueTree& state); - - RelativeParallelogram getRectangle() const; - void setRectangle (const RelativeParallelogram& newBounds, UndoManager*); - - void setCornerSize (const RelativePoint& cornerSize, UndoManager*); - RelativePoint getCornerSize() const; - Value getCornerSizeValue (UndoManager*); - - static const Identifier topLeft, topRight, bottomLeft, cornerSize; - }; - private: - friend class Drawable::Positioner; - - RelativeParallelogram bounds; - RelativePoint cornerSize; + Parallelogram bounds; + Point cornerSize; void rebuildPath(); - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); DrawableRectangle& operator= (const DrawableRectangle&); JUCE_LEAK_DETECTOR (DrawableRectangle) diff --git a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp index 6b1f27d4da..23f82432a7 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableShape.cpp @@ -48,87 +48,24 @@ DrawableShape::~DrawableShape() } //============================================================================== -class DrawableShape::RelativePositioner : public RelativeCoordinatePositionerBase +void DrawableShape::setFill (const FillType& newFill) { -public: - RelativePositioner (DrawableShape& comp, const DrawableShape::RelativeFillType& f, bool isMain) - : RelativeCoordinatePositionerBase (comp), - owner (comp), - fill (f), - isMainFill (isMain) - { - } - - bool registerCoordinates() override + if (mainFill != newFill) { - bool ok = addPoint (fill.gradientPoint1); - ok = addPoint (fill.gradientPoint2) && ok; - return addPoint (fill.gradientPoint3) && ok; - } - - void applyToComponentBounds() override - { - ComponentScope scope (owner); - if (isMainFill ? owner.mainFill.recalculateCoords (&scope) - : owner.strokeFill.recalculateCoords (&scope)) - owner.repaint(); - } - - void applyNewBounds (const Rectangle&) override - { - jassertfalse; // drawables can't be resized directly! + mainFill = newFill; + repaint(); } - -private: - DrawableShape& owner; - const DrawableShape::RelativeFillType fill; - const bool isMainFill; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RelativePositioner) -}; - -void DrawableShape::setFill (const FillType& newFill) -{ - setFill (RelativeFillType (newFill)); } void DrawableShape::setStrokeFill (const FillType& newFill) { - setStrokeFill (RelativeFillType (newFill)); -} - -void DrawableShape::setFillInternal (RelativeFillType& fill, const RelativeFillType& newFill, - ScopedPointer& pos) -{ - if (fill != newFill) + if (strokeFill != newFill) { - fill = newFill; - pos.reset(); - - if (fill.isDynamic()) - { - pos = new RelativePositioner (*this, fill, true); - pos->apply(); - } - else - { - fill.recalculateCoords (nullptr); - } - + strokeFill = newFill; repaint(); } } -void DrawableShape::setFill (const RelativeFillType& newFill) -{ - setFillInternal (mainFill, newFill, mainFillPositioner); -} - -void DrawableShape::setStrokeFill (const RelativeFillType& newFill) -{ - setFillInternal (strokeFill, newFill, strokeFillPositioner); -} - void DrawableShape::setStrokeType (const PathStrokeType& newStrokeType) { if (strokeType != newStrokeType) @@ -154,20 +91,7 @@ void DrawableShape::setStrokeThickness (const float newThickness) bool DrawableShape::isStrokeVisible() const noexcept { - return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.fill.isInvisible(); -} - -void DrawableShape::refreshFillTypes (const FillAndStrokeState& newState, ComponentBuilder::ImageProvider* imageProvider) -{ - setFill (newState.getFill (FillAndStrokeState::fill, imageProvider)); - setStrokeFill (newState.getFill (FillAndStrokeState::stroke, imageProvider)); -} - -void DrawableShape::writeTo (FillAndStrokeState& state, ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) const -{ - state.setFill (FillAndStrokeState::fill, mainFill, imageProvider, undoManager); - state.setFill (FillAndStrokeState::stroke, strokeFill, imageProvider, undoManager); - state.setStrokeType (strokeType, undoManager); + return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); } //============================================================================== @@ -176,12 +100,12 @@ void DrawableShape::paint (Graphics& g) transformContextToCorrectOrigin (g); applyDrawableClipPath (g); - g.setFillType (mainFill.fill); + g.setFillType (mainFill); g.fillPath (path); if (isStrokeVisible()) { - g.setFillType (strokeFill.fill); + g.setFillType (strokeFill); g.fillPath (strokePath); } } @@ -222,262 +146,17 @@ bool DrawableShape::hitTest (int x, int y) if (! allowsClicksOnThisComponent) return false; - const float globalX = (float) (x - originRelativeToComponent.x); - const float globalY = (float) (y - originRelativeToComponent.y); + auto globalX = (float) (x - originRelativeToComponent.x); + auto globalY = (float) (y - originRelativeToComponent.y); return path.contains (globalX, globalY) || (isStrokeVisible() && strokePath.contains (globalX, globalY)); } //============================================================================== -DrawableShape::RelativeFillType::RelativeFillType() -{ -} - -DrawableShape::RelativeFillType::RelativeFillType (const FillType& fill_) - : fill (fill_) -{ - if (fill.isGradient()) - { - const ColourGradient& g = *fill.gradient; - - gradientPoint1 = g.point1.transformedBy (fill.transform); - gradientPoint2 = g.point2.transformedBy (fill.transform); - gradientPoint3 = Point (g.point1.x + g.point2.y - g.point1.y, - g.point1.y + g.point1.x - g.point2.x) - .transformedBy (fill.transform); - fill.transform = AffineTransform(); - } -} - -DrawableShape::RelativeFillType::RelativeFillType (const RelativeFillType& other) - : fill (other.fill), - gradientPoint1 (other.gradientPoint1), - gradientPoint2 (other.gradientPoint2), - gradientPoint3 (other.gradientPoint3) -{ -} - -DrawableShape::RelativeFillType& DrawableShape::RelativeFillType::operator= (const RelativeFillType& other) -{ - fill = other.fill; - gradientPoint1 = other.gradientPoint1; - gradientPoint2 = other.gradientPoint2; - gradientPoint3 = other.gradientPoint3; - return *this; -} - -bool DrawableShape::RelativeFillType::operator== (const RelativeFillType& other) const -{ - return fill == other.fill - && ((! fill.isGradient()) - || (gradientPoint1 == other.gradientPoint1 - && gradientPoint2 == other.gradientPoint2 - && gradientPoint3 == other.gradientPoint3)); -} - -bool DrawableShape::RelativeFillType::operator!= (const RelativeFillType& other) const -{ - return ! operator== (other); -} - -bool DrawableShape::RelativeFillType::recalculateCoords (Expression::Scope* scope) -{ - if (fill.isGradient()) - { - const Point g1 (gradientPoint1.resolve (scope)); - const Point g2 (gradientPoint2.resolve (scope)); - AffineTransform t; - - ColourGradient& g = *fill.gradient; - - if (g.isRadial) - { - const Point g3 (gradientPoint3.resolve (scope)); - const Point g3Source (g1.x + g2.y - g1.y, - g1.y + g1.x - g2.x); - - t = AffineTransform::fromTargetPoints (g1.x, g1.y, g1.x, g1.y, - g2.x, g2.y, g2.x, g2.y, - g3Source.x, g3Source.y, g3.x, g3.y); - } - - if (g.point1 != g1 || g.point2 != g2 || fill.transform != t) - { - g.point1 = g1; - g.point2 = g2; - fill.transform = t; - return true; - } - } - - return false; -} - -bool DrawableShape::RelativeFillType::isDynamic() const -{ - return gradientPoint1.isDynamic() || gradientPoint2.isDynamic() || gradientPoint3.isDynamic(); -} - -void DrawableShape::RelativeFillType::writeTo (ValueTree& v, ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) const -{ - if (fill.isColour()) - { - v.setProperty (FillAndStrokeState::type, "solid", undoManager); - v.setProperty (FillAndStrokeState::colour, String::toHexString ((int) fill.colour.getARGB()), undoManager); - } - else if (fill.isGradient()) - { - v.setProperty (FillAndStrokeState::type, "gradient", undoManager); - v.setProperty (FillAndStrokeState::gradientPoint1, gradientPoint1.toString(), undoManager); - v.setProperty (FillAndStrokeState::gradientPoint2, gradientPoint2.toString(), undoManager); - v.setProperty (FillAndStrokeState::gradientPoint3, gradientPoint3.toString(), undoManager); - - const ColourGradient& cg = *fill.gradient; - v.setProperty (FillAndStrokeState::radial, cg.isRadial, undoManager); - - String s; - for (int i = 0; i < cg.getNumColours(); ++i) - s << ' ' << cg.getColourPosition (i) - << ' ' << String::toHexString ((int) cg.getColour(i).getARGB()); - - v.setProperty (FillAndStrokeState::colours, s.trimStart(), undoManager); - } - else if (fill.isTiledImage()) - { - v.setProperty (FillAndStrokeState::type, "image", undoManager); - - if (imageProvider != nullptr) - v.setProperty (FillAndStrokeState::imageId, imageProvider->getIdentifierForImage (fill.image), undoManager); - - if (fill.getOpacity() < 1.0f) - v.setProperty (FillAndStrokeState::imageOpacity, fill.getOpacity(), undoManager); - else - v.removeProperty (FillAndStrokeState::imageOpacity, undoManager); - } - else - { - jassertfalse; - } -} - -bool DrawableShape::RelativeFillType::readFrom (const ValueTree& v, ComponentBuilder::ImageProvider* imageProvider) -{ - const String newType (v [FillAndStrokeState::type].toString()); - - if (newType == "solid") - { - const String colourString (v [FillAndStrokeState::colour].toString()); - fill.setColour (colourString.isEmpty() ? Colours::black - : Colour::fromString (colourString)); - return true; - } - else if (newType == "gradient") - { - ColourGradient g; - g.isRadial = v [FillAndStrokeState::radial]; - - StringArray colourSteps; - colourSteps.addTokens (v [FillAndStrokeState::colours].toString(), false); - - for (int i = 0; i < colourSteps.size() / 2; ++i) - g.addColour (colourSteps[i * 2].getDoubleValue(), - Colour::fromString (colourSteps[i * 2 + 1])); - - fill.setGradient (g); - - gradientPoint1 = RelativePoint (v [FillAndStrokeState::gradientPoint1]); - gradientPoint2 = RelativePoint (v [FillAndStrokeState::gradientPoint2]); - gradientPoint3 = RelativePoint (v [FillAndStrokeState::gradientPoint3]); - return true; - } - else if (newType == "image") - { - Image im; - if (imageProvider != nullptr) - im = imageProvider->getImageForIdentifier (v [FillAndStrokeState::imageId]); - - fill.setTiledImage (im, AffineTransform()); - fill.setOpacity ((float) v.getProperty (FillAndStrokeState::imageOpacity, 1.0f)); - return true; - } - - jassertfalse; - return false; -} - -//============================================================================== -const Identifier DrawableShape::FillAndStrokeState::type ("type"); -const Identifier DrawableShape::FillAndStrokeState::colour ("colour"); -const Identifier DrawableShape::FillAndStrokeState::colours ("colours"); -const Identifier DrawableShape::FillAndStrokeState::fill ("Fill"); -const Identifier DrawableShape::FillAndStrokeState::stroke ("Stroke"); -const Identifier DrawableShape::FillAndStrokeState::path ("Path"); -const Identifier DrawableShape::FillAndStrokeState::jointStyle ("jointStyle"); -const Identifier DrawableShape::FillAndStrokeState::capStyle ("capStyle"); -const Identifier DrawableShape::FillAndStrokeState::strokeWidth ("strokeWidth"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint1 ("point1"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint2 ("point2"); -const Identifier DrawableShape::FillAndStrokeState::gradientPoint3 ("point3"); -const Identifier DrawableShape::FillAndStrokeState::radial ("radial"); -const Identifier DrawableShape::FillAndStrokeState::imageId ("imageId"); -const Identifier DrawableShape::FillAndStrokeState::imageOpacity ("imageOpacity"); - -DrawableShape::FillAndStrokeState::FillAndStrokeState (const ValueTree& state_) - : Drawable::ValueTreeWrapperBase (state_) -{ -} - -DrawableShape::RelativeFillType DrawableShape::FillAndStrokeState::getFill (const Identifier& fillOrStrokeType, ComponentBuilder::ImageProvider* imageProvider) const -{ - DrawableShape::RelativeFillType f; - f.readFrom (state.getChildWithName (fillOrStrokeType), imageProvider); - return f; -} - -ValueTree DrawableShape::FillAndStrokeState::getFillState (const Identifier& fillOrStrokeType) -{ - ValueTree v (state.getChildWithName (fillOrStrokeType)); - if (v.isValid()) - return v; - - setFill (fillOrStrokeType, FillType (Colours::black), nullptr, nullptr); - return getFillState (fillOrStrokeType); -} - -void DrawableShape::FillAndStrokeState::setFill (const Identifier& fillOrStrokeType, const RelativeFillType& newFill, - ComponentBuilder::ImageProvider* imageProvider, UndoManager* undoManager) -{ - ValueTree v (state.getOrCreateChildWithName (fillOrStrokeType, undoManager)); - newFill.writeTo (v, imageProvider, undoManager); -} - -PathStrokeType DrawableShape::FillAndStrokeState::getStrokeType() const -{ - const String jointStyleString (state [jointStyle].toString()); - const String capStyleString (state [capStyle].toString()); - - return PathStrokeType (state [strokeWidth], - jointStyleString == "curved" ? PathStrokeType::curved - : (jointStyleString == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - capStyleString == "square" ? PathStrokeType::square - : (capStyleString == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); -} - -void DrawableShape::FillAndStrokeState::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) -{ - state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); - state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); - state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); -} - -static bool replaceColourInFill (DrawableShape::RelativeFillType& fill, Colour original, Colour replacement) +static bool replaceColourInFill (FillType& fill, Colour original, Colour replacement) { - if (fill.fill.colour == original && fill.fill.isColour()) + if (fill.colour == original && fill.isColour()) { fill = FillType (replacement); return true; @@ -495,7 +174,7 @@ bool DrawableShape::replaceColour (Colour original, Colour replacement) Path DrawableShape::getOutlineAsPath() const { - Path outline (isStrokeVisible() ? strokePath : path); + auto outline = isStrokeVisible() ? strokePath : path; outline.applyTransform (getTransform()); return outline; } diff --git a/modules/juce_gui_basics/drawables/juce_DrawableShape.h b/modules/juce_gui_basics/drawables/juce_DrawableShape.h index 10a89dd1d9..64ba771bcb 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableShape.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableShape.h @@ -45,31 +45,6 @@ public: /** Destructor. */ ~DrawableShape(); - //============================================================================== - /** A FillType wrapper that allows the gradient coordinates to be implemented using RelativePoint. - */ - class RelativeFillType - { - public: - RelativeFillType(); - RelativeFillType (const FillType& fill); - RelativeFillType (const RelativeFillType&); - RelativeFillType& operator= (const RelativeFillType&); - - bool operator== (const RelativeFillType&) const; - bool operator!= (const RelativeFillType&) const; - - bool isDynamic() const; - bool recalculateCoords (Expression::Scope* scope); - - void writeTo (ValueTree& v, ComponentBuilder::ImageProvider*, UndoManager*) const; - bool readFrom (const ValueTree& v, ComponentBuilder::ImageProvider*); - - //============================================================================== - FillType fill; - RelativePoint gradientPoint1, gradientPoint2, gradientPoint3; - }; - //============================================================================== /** Sets a fill type for the path. This colour is used to fill the path - if you don't want the path to be @@ -80,34 +55,20 @@ public: */ void setFill (const FillType& newFill); - /** Sets a fill type for the path. - This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this to a transparent - colour. - - @see setPath, setStrokeFill - */ - void setFill (const RelativeFillType& newFill); - /** Returns the current fill type. @see setFill */ - const RelativeFillType& getFill() const noexcept { return mainFill; } + const FillType& getFill() const noexcept { return mainFill; } /** Sets the fill type with which the outline will be drawn. @see setFill */ void setStrokeFill (const FillType& newStrokeFill); - /** Sets the fill type with which the outline will be drawn. - @see setFill - */ - void setStrokeFill (const RelativeFillType& newStrokeFill); - /** Returns the current stroke fill. @see setStrokeFill */ - const RelativeFillType& getStrokeFill() const noexcept { return strokeFill; } + const FillType& getStrokeFill() const noexcept { return strokeFill; } /** Changes the properties of the outline that will be drawn around the path. If the stroke has 0 thickness, no stroke will be drawn. @@ -130,24 +91,6 @@ public: const Array& getDashLengths() const noexcept { return dashLengths; } //============================================================================== - /** @internal */ - class FillAndStrokeState : public Drawable::ValueTreeWrapperBase - { - public: - FillAndStrokeState (const ValueTree& state); - - ValueTree getFillState (const Identifier& fillOrStrokeType); - RelativeFillType getFill (const Identifier& fillOrStrokeType, ComponentBuilder::ImageProvider*) const; - void setFill (const Identifier& fillOrStrokeType, const RelativeFillType& newFill, - ComponentBuilder::ImageProvider*, UndoManager*); - - PathStrokeType getStrokeType() const; - void setStrokeType (const PathStrokeType& newStrokeType, UndoManager*); - - static const Identifier type, colour, colours, fill, stroke, path, jointStyle, capStyle, strokeWidth, - gradientPoint1, gradientPoint2, gradientPoint3, radial, imageId, imageOpacity; - }; - /** @internal */ Rectangle getDrawableBounds() const override; /** @internal */ @@ -167,10 +110,6 @@ protected: void strokeChanged(); /** True if there's a stroke with a non-zero thickness and non-transparent colour. */ bool isStrokeVisible() const noexcept; - /** Updates the details from a FillAndStrokeState object, returning true if something changed. */ - void refreshFillTypes (const FillAndStrokeState& newState, ComponentBuilder::ImageProvider*); - /** Writes the stroke and fill details to a FillAndStrokeState object. */ - void writeTo (FillAndStrokeState& state, ComponentBuilder::ImageProvider*, UndoManager*) const; //============================================================================== PathStrokeType strokeType; @@ -178,12 +117,7 @@ protected: Path path, strokePath; private: - class RelativePositioner; - RelativeFillType mainFill, strokeFill; - ScopedPointer mainFillPositioner, strokeFillPositioner; - - void setFillInternal (RelativeFillType& fill, const RelativeFillType& newFill, - ScopedPointer& positioner); + FillType mainFill, strokeFill; DrawableShape& operator= (const DrawableShape&); }; diff --git a/modules/juce_gui_basics/drawables/juce_DrawableText.cpp b/modules/juce_gui_basics/drawables/juce_DrawableText.cpp index c00063cd47..7edab45619 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableText.cpp +++ b/modules/juce_gui_basics/drawables/juce_DrawableText.cpp @@ -31,9 +31,7 @@ DrawableText::DrawableText() : colour (Colours::black), justification (Justification::centredLeft) { - setBoundingBox (RelativeParallelogram (RelativePoint (0.0f, 0.0f), - RelativePoint (50.0f, 0.0f), - RelativePoint (0.0f, 20.0f))); + setBoundingBox (Parallelogram ({ 0.0f, 0.0f, 50.0f, 20.0f })); setFont (Font (15.0f), true); } @@ -54,6 +52,11 @@ DrawableText::~DrawableText() { } +Drawable* DrawableText::createCopy() const +{ + return new DrawableText (*this); +} + //============================================================================== void DrawableText::setText (const String& newText) { @@ -95,7 +98,7 @@ void DrawableText::setJustification (Justification newJustification) repaint(); } -void DrawableText::setBoundingBox (const RelativeParallelogram& newBounds) +void DrawableText::setBoundingBox (Parallelogram newBounds) { if (bounds != newBounds) { @@ -104,7 +107,7 @@ void DrawableText::setBoundingBox (const RelativeParallelogram& newBounds) } } -void DrawableText::setFontHeight (const RelativeCoordinate& newHeight) +void DrawableText::setFontHeight (float newHeight) { if (fontHeight != newHeight) { @@ -113,7 +116,7 @@ void DrawableText::setFontHeight (const RelativeCoordinate& newHeight) } } -void DrawableText::setFontHorizontalScale (const RelativeCoordinate& newScale) +void DrawableText::setFontHorizontalScale (float newScale) { if (fontHScale != newScale) { @@ -124,37 +127,11 @@ void DrawableText::setFontHorizontalScale (const RelativeCoordinate& newScale) void DrawableText::refreshBounds() { - if (bounds.isDynamic() || fontHeight.isDynamic() || fontHScale.isDynamic()) - { - Drawable::Positioner* const p = new Drawable::Positioner (*this); - setPositioner (p); - p->apply(); - } - else - { - setPositioner (0); - recalculateCoordinates (0); - } -} + auto w = bounds.getWidth(); + auto h = bounds.getHeight(); -bool DrawableText::registerCoordinates (RelativeCoordinatePositionerBase& pos) -{ - bool ok = pos.addPoint (bounds.topLeft); - ok = pos.addPoint (bounds.topRight) && ok; - ok = pos.addPoint (bounds.bottomLeft) && ok; - ok = pos.addCoordinate (fontHeight) && ok; - return pos.addCoordinate (fontHScale) && ok; -} - -void DrawableText::recalculateCoordinates (Expression::Scope* scope) -{ - bounds.resolveThreePoints (resolvedPoints, scope); - - const float w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); - const float h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); - - const float height = jlimit (0.01f, jmax (0.01f, h), (float) fontHeight.resolve (scope)); - const float hscale = jlimit (0.01f, jmax (0.01f, w), (float) fontHScale.resolve (scope)); + auto height = jlimit (0.01f, jmax (0.01f, h), fontHeight); + auto hscale = jlimit (0.01f, jmax (0.01f, w), fontHScale); scaledFont = font; scaledFont.setHeight (height); @@ -172,17 +149,17 @@ Rectangle DrawableText::getTextArea (float w, float h) const AffineTransform DrawableText::getTextTransform (float w, float h) const { - return AffineTransform::fromTargetPoints (0, 0, resolvedPoints[0].x, resolvedPoints[0].y, - w, 0, resolvedPoints[1].x, resolvedPoints[1].y, - 0, h, resolvedPoints[2].x, resolvedPoints[2].y); + return AffineTransform::fromTargetPoints (Point(), bounds.topLeft, + Point (w, 0), bounds.topRight, + Point (0, h), bounds.bottomLeft); } void DrawableText::paint (Graphics& g) { transformContextToCorrectOrigin (g); - const float w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); - const float h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); + auto w = bounds.getWidth(); + auto h = bounds.getHeight(); g.addTransform (getTextTransform (w, h)); g.setFont (scaledFont); @@ -193,166 +170,14 @@ void DrawableText::paint (Graphics& g) Rectangle DrawableText::getDrawableBounds() const { - return RelativeParallelogram::getBoundingBox (resolvedPoints); -} - -Drawable* DrawableText::createCopy() const -{ - return new DrawableText (*this); -} - -//============================================================================== -const Identifier DrawableText::valueTreeType ("Text"); - -const Identifier DrawableText::ValueTreeWrapper::text ("text"); -const Identifier DrawableText::ValueTreeWrapper::colour ("colour"); -const Identifier DrawableText::ValueTreeWrapper::font ("font"); -const Identifier DrawableText::ValueTreeWrapper::justification ("justification"); -const Identifier DrawableText::ValueTreeWrapper::topLeft ("topLeft"); -const Identifier DrawableText::ValueTreeWrapper::topRight ("topRight"); -const Identifier DrawableText::ValueTreeWrapper::bottomLeft ("bottomLeft"); -const Identifier DrawableText::ValueTreeWrapper::fontHeight ("fontHeight"); -const Identifier DrawableText::ValueTreeWrapper::fontHScale ("fontHScale"); - -//============================================================================== -DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) - : ValueTreeWrapperBase (state_) -{ - jassert (state.hasType (valueTreeType)); -} - -String DrawableText::ValueTreeWrapper::getText() const -{ - return state [text].toString(); -} - -void DrawableText::ValueTreeWrapper::setText (const String& newText, UndoManager* undoManager) -{ - state.setProperty (text, newText, undoManager); -} - -Value DrawableText::ValueTreeWrapper::getTextValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (text, undoManager); -} - -Colour DrawableText::ValueTreeWrapper::getColour() const -{ - return Colour::fromString (state [colour].toString()); -} - -void DrawableText::ValueTreeWrapper::setColour (Colour newColour, UndoManager* undoManager) -{ - state.setProperty (colour, newColour.toString(), undoManager); -} - -Justification DrawableText::ValueTreeWrapper::getJustification() const -{ - return Justification ((int) state [justification]); -} - -void DrawableText::ValueTreeWrapper::setJustification (Justification newJustification, UndoManager* undoManager) -{ - state.setProperty (justification, newJustification.getFlags(), undoManager); -} - -Font DrawableText::ValueTreeWrapper::getFont() const -{ - return Font::fromString (state [font]); -} - -void DrawableText::ValueTreeWrapper::setFont (const Font& newFont, UndoManager* undoManager) -{ - state.setProperty (font, newFont.toString(), undoManager); -} - -Value DrawableText::ValueTreeWrapper::getFontValue (UndoManager* undoManager) -{ - return state.getPropertyAsValue (font, undoManager); -} - -RelativeParallelogram DrawableText::ValueTreeWrapper::getBoundingBox() const -{ - return RelativeParallelogram (state [topLeft].toString(), state [topRight].toString(), state [bottomLeft].toString()); -} - -void DrawableText::ValueTreeWrapper::setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager) -{ - state.setProperty (topLeft, newBounds.topLeft.toString(), undoManager); - state.setProperty (topRight, newBounds.topRight.toString(), undoManager); - state.setProperty (bottomLeft, newBounds.bottomLeft.toString(), undoManager); -} - -RelativeCoordinate DrawableText::ValueTreeWrapper::getFontHeight() const -{ - return state [fontHeight].toString(); -} - -void DrawableText::ValueTreeWrapper::setFontHeight (const RelativeCoordinate& coord, UndoManager* undoManager) -{ - state.setProperty (fontHeight, coord.toString(), undoManager); -} - -RelativeCoordinate DrawableText::ValueTreeWrapper::getFontHorizontalScale() const -{ - return state [fontHScale].toString(); -} - -void DrawableText::ValueTreeWrapper::setFontHorizontalScale (const RelativeCoordinate& coord, UndoManager* undoManager) -{ - state.setProperty (fontHScale, coord.toString(), undoManager); -} - -//============================================================================== -void DrawableText::refreshFromValueTree (const ValueTree& tree, ComponentBuilder&) -{ - ValueTreeWrapper v (tree); - setComponentID (v.getID()); - - const RelativeParallelogram newBounds (v.getBoundingBox()); - const RelativeCoordinate newFontHeight (v.getFontHeight()); - const RelativeCoordinate newFontHScale (v.getFontHorizontalScale()); - const Colour newColour (v.getColour()); - const Justification newJustification (v.getJustification()); - const String newText (v.getText()); - const Font newFont (v.getFont()); - - if (text != newText || font != newFont || justification != newJustification - || colour != newColour || bounds != newBounds - || newFontHeight != fontHeight || newFontHScale != fontHScale) - { - setBoundingBox (newBounds); - setFontHeight (newFontHeight); - setFontHorizontalScale (newFontHScale); - setColour (newColour); - setFont (newFont, false); - setJustification (newJustification); - setText (newText); - } -} - -ValueTree DrawableText::createValueTree (ComponentBuilder::ImageProvider*) const -{ - ValueTree tree (valueTreeType); - ValueTreeWrapper v (tree); - - v.setID (getComponentID()); - v.setText (text, nullptr); - v.setFont (font, nullptr); - v.setJustification (justification, nullptr); - v.setColour (colour, nullptr); - v.setBoundingBox (bounds, nullptr); - v.setFontHeight (fontHeight, nullptr); - v.setFontHorizontalScale (fontHScale, nullptr); - - return tree; + return bounds.getBoundingBox(); } Path DrawableText::getOutlineAsPath() const { - auto w = Line (resolvedPoints[0], resolvedPoints[1]).getLength(); - auto h = Line (resolvedPoints[0], resolvedPoints[2]).getLength(); - const auto area = getTextArea (w, h).toFloat(); + auto w = bounds.getWidth(); + auto h = bounds.getHeight(); + auto area = getTextArea (w, h).toFloat(); GlyphArrangement arr; arr.addFittedText (scaledFont, text, diff --git a/modules/juce_gui_basics/drawables/juce_DrawableText.h b/modules/juce_gui_basics/drawables/juce_DrawableText.h index 637659ed8d..801462efb2 100644 --- a/modules/juce_gui_basics/drawables/juce_DrawableText.h +++ b/modules/juce_gui_basics/drawables/juce_DrawableText.h @@ -58,8 +58,8 @@ public: Colour getColour() const noexcept { return colour; } /** Sets the font to use. - Note that the font height and horizontal scale are set as RelativeCoordinates using - setFontHeight and setFontHorizontalScale. If applySizeAndScale is true, then these height + Note that the font height and horizontal scale are set using setFontHeight() and + setFontHorizontalScale(). If applySizeAndScale is true, then these height and scale values will be changed to match the dimensions of the font supplied; if it is false, then the new font object's height and scale are ignored. */ @@ -75,16 +75,16 @@ public: Justification getJustification() const noexcept { return justification; } /** Returns the parallelogram that defines the text bounding box. */ - const RelativeParallelogram& getBoundingBox() const noexcept { return bounds; } + Parallelogram getBoundingBox() const noexcept { return bounds; } /** Sets the bounding box that contains the text. */ - void setBoundingBox (const RelativeParallelogram& newBounds); + void setBoundingBox (Parallelogram newBounds); - const RelativeCoordinate& getFontHeight() const { return fontHeight; } - void setFontHeight (const RelativeCoordinate& newHeight); + float getFontHeight() const noexcept { return fontHeight; } + void setFontHeight (float newHeight); - const RelativeCoordinate& getFontHorizontalScale() const { return fontHScale; } - void setFontHorizontalScale (const RelativeCoordinate& newScale); + float getFontHorizontalScale() const noexcept { return fontHScale; } + void setFontHorizontalScale (float newScale); //============================================================================== /** @internal */ @@ -92,62 +92,19 @@ public: /** @internal */ Drawable* createCopy() const override; /** @internal */ - void refreshFromValueTree (const ValueTree& tree, ComponentBuilder& builder); - /** @internal */ - ValueTree createValueTree (ComponentBuilder::ImageProvider* imageProvider) const override; - /** @internal */ - static const Identifier valueTreeType; - /** @internal */ Rectangle getDrawableBounds() const override; /** @internal */ Path getOutlineAsPath() const override; - //============================================================================== - /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ - class ValueTreeWrapper : public Drawable::ValueTreeWrapperBase - { - public: - ValueTreeWrapper (const ValueTree& state); - - String getText() const; - void setText (const String& newText, UndoManager* undoManager); - Value getTextValue (UndoManager* undoManager); - - Colour getColour() const; - void setColour (Colour newColour, UndoManager* undoManager); - - Justification getJustification() const; - void setJustification (Justification newJustification, UndoManager* undoManager); - - Font getFont() const; - void setFont (const Font& newFont, UndoManager* undoManager); - Value getFontValue (UndoManager* undoManager); - - RelativeParallelogram getBoundingBox() const; - void setBoundingBox (const RelativeParallelogram& newBounds, UndoManager* undoManager); - - RelativeCoordinate getFontHeight() const; - void setFontHeight (const RelativeCoordinate& newHeight, UndoManager* undoManager); - - RelativeCoordinate getFontHorizontalScale() const; - void setFontHorizontalScale (const RelativeCoordinate& newScale, UndoManager* undoManager); - - static const Identifier text, colour, font, justification, topLeft, topRight, bottomLeft, fontHeight, fontHScale; - }; - private: //============================================================================== - RelativeParallelogram bounds; - RelativeCoordinate fontHeight, fontHScale; - Point resolvedPoints[3]; + Parallelogram bounds; + float fontHeight, fontHScale; Font font, scaledFont; String text; Colour colour; Justification justification; - friend class Drawable::Positioner; - bool registerCoordinates (RelativeCoordinatePositionerBase&); - void recalculateCoordinates (Expression::Scope*); void refreshBounds(); Rectangle getTextArea (float width, float height) const; AffineTransform getTextTransform (float width, float height) const; diff --git a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index eb4909a081..a4162b7da4 100644 --- a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -196,10 +196,7 @@ public: newState.parseSubElements (xml, *drawable); - drawable->setContentArea (RelativeRectangle (RelativeCoordinate (viewboxXY.x), - RelativeCoordinate (viewboxXY.x + newState.viewBoxW), - RelativeCoordinate (viewboxXY.y), - RelativeCoordinate (viewboxXY.y + newState.viewBoxH))); + drawable->setContentArea ({ viewboxXY.x, viewboxXY.y, newState.viewBoxW, newState.viewBoxH }); drawable->resetBoundingBoxToContentArea(); return drawable; diff --git a/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp b/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp index f735f35efa..b5206f8608 100644 --- a/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp +++ b/modules/juce_gui_basics/layout/juce_ComponentBuilder.cpp @@ -182,7 +182,6 @@ ComponentBuilder::TypeHandler* ComponentBuilder::getHandler (const int index) co void ComponentBuilder::registerStandardComponentTypes() { - Drawable::registerDrawableTypeHandlers (*this); } void ComponentBuilder::setImageProvider (ImageProvider* newImageProvider) noexcept diff --git a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp index 3d9f6ed919..0f48090bd7 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp @@ -95,9 +95,9 @@ AffineTransform RelativeParallelogram::resetToPerpendicular (Expression::Scope* topRight.moveToAbsolute (newTopRight, scope); bottomLeft.moveToAbsolute (newBottomLeft, scope); - return AffineTransform::fromTargetPoints (corners[0].x, corners[0].y, corners[0].x, corners[0].y, - corners[1].x, corners[1].y, newTopRight.x, newTopRight.y, - corners[2].x, corners[2].y, newBottomLeft.x, newBottomLeft.y); + return AffineTransform::fromTargetPoints (corners[0], corners[0], + corners[1], newTopRight, + corners[2], newBottomLeft); } bool RelativeParallelogram::isDynamic() const diff --git a/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp b/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp index ee57e48895..ce08c876ea 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp +++ b/modules/juce_gui_basics/positioning/juce_RelativePointPath.cpp @@ -147,13 +147,6 @@ RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos) { } -ValueTree RelativePointPath::StartSubPath::createTree() const -{ - ValueTree v (DrawablePath::ValueTreeWrapper::Element::startSubPathElement); - v.setProperty (DrawablePath::ValueTreeWrapper::point1, startPos.toString(), nullptr); - return v; -} - void RelativePointPath::StartSubPath::addToPath (Path& path, Expression::Scope* scope) const { path.startNewSubPath (startPos.resolve (scope)); @@ -176,11 +169,6 @@ RelativePointPath::CloseSubPath::CloseSubPath() { } -ValueTree RelativePointPath::CloseSubPath::createTree() const -{ - return ValueTree (DrawablePath::ValueTreeWrapper::Element::closeSubPathElement); -} - void RelativePointPath::CloseSubPath::addToPath (Path& path, Expression::Scope*) const { path.closeSubPath(); @@ -203,13 +191,6 @@ RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_) { } -ValueTree RelativePointPath::LineTo::createTree() const -{ - ValueTree v (DrawablePath::ValueTreeWrapper::Element::lineToElement); - v.setProperty (DrawablePath::ValueTreeWrapper::point1, endPoint.toString(), nullptr); - return v; -} - void RelativePointPath::LineTo::addToPath (Path& path, Expression::Scope* scope) const { path.lineTo (endPoint.resolve (scope)); @@ -234,14 +215,6 @@ RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint, controlPoints[1] = endPoint; } -ValueTree RelativePointPath::QuadraticTo::createTree() const -{ - ValueTree v (DrawablePath::ValueTreeWrapper::Element::quadraticToElement); - v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr); - v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr); - return v; -} - void RelativePointPath::QuadraticTo::addToPath (Path& path, Expression::Scope* scope) const { path.quadraticTo (controlPoints[0].resolve (scope), @@ -269,15 +242,6 @@ RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1, const R controlPoints[2] = endPoint; } -ValueTree RelativePointPath::CubicTo::createTree() const -{ - ValueTree v (DrawablePath::ValueTreeWrapper::Element::cubicToElement); - v.setProperty (DrawablePath::ValueTreeWrapper::point1, controlPoints[0].toString(), nullptr); - v.setProperty (DrawablePath::ValueTreeWrapper::point2, controlPoints[1].toString(), nullptr); - v.setProperty (DrawablePath::ValueTreeWrapper::point3, controlPoints[2].toString(), nullptr); - return v; -} - void RelativePointPath::CubicTo::addToPath (Path& path, Expression::Scope* scope) const { path.cubicTo (controlPoints[0].resolve (scope), diff --git a/modules/juce_gui_basics/positioning/juce_RelativePointPath.h b/modules/juce_gui_basics/positioning/juce_RelativePointPath.h index d0c719dbe3..95e605879d 100644 --- a/modules/juce_gui_basics/positioning/juce_RelativePointPath.h +++ b/modules/juce_gui_basics/positioning/juce_RelativePointPath.h @@ -80,7 +80,6 @@ public: public: ElementBase (ElementType type); virtual ~ElementBase() {} - virtual ValueTree createTree() const = 0; virtual void addToPath (Path& path, Expression::Scope*) const = 0; virtual RelativePoint* getControlPoints (int& numPoints) = 0; virtual ElementBase* clone() const = 0; @@ -97,7 +96,6 @@ public: { public: StartSubPath (const RelativePoint& pos); - ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; @@ -113,7 +111,6 @@ public: { public: CloseSubPath(); - ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const; @@ -127,7 +124,6 @@ public: { public: LineTo (const RelativePoint& endPoint); - ValueTree createTree() const; void addToPath (Path& path, Expression::Scope*) const; RelativePoint* getControlPoints (int& numPoints); ElementBase* clone() const;