/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2022 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. By using JUCE, you agree to the terms of both the JUCE 7 End-User License Agreement and JUCE Privacy Policy. End User License Agreement: www.juce.com/juce-7-licence Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE DISCLAIMED. ============================================================================== */ #pragma once #include "../jucer_GeneratedCode.h" #include "../UI/jucer_RelativePositionedRectangle.h" class FillType; class PaintRoutine; class JucerDocument; class ElementSiblingComponent; //============================================================================== /** Base class for objects that can be used in a PaintRoutine. */ class PaintElement : public Component, public ComponentBoundsConstrainer, private ChangeListener { public: //============================================================================== PaintElement (PaintRoutine* owner, const String& typeName); ~PaintElement() override; //============================================================================== virtual void setInitialBounds (int parentWidth, int parentHeight); virtual Rectangle getCurrentBounds (const Rectangle& activeArea) const; virtual void setCurrentBounds (const Rectangle& newBounds, const Rectangle& activeArea, bool undoable); const RelativePositionedRectangle& getPosition() const; void setPosition (const RelativePositionedRectangle& newPosition, bool undoable); void setPaintElementBounds (const Rectangle& newBounds, bool undoable); void setPaintElementBoundsAndProperties (PaintElement* elementToPosition, const Rectangle& newBounds, PaintElement* referenceElement, bool undoable); void updateBounds (const Rectangle& activeArea); const String& getTypeName() const noexcept { return typeName; } PaintRoutine* getOwner() const noexcept { return owner; } //============================================================================== virtual void draw (Graphics& g, const ComponentLayout* layout, const Rectangle& parentArea) = 0; virtual void drawExtraEditorGraphics (Graphics& g, const Rectangle& relativeTo); virtual void getEditableProperties (Array& props, bool multipleSelected); virtual void showPopupMenu(); //============================================================================== virtual XmlElement* createXml() const = 0; virtual bool loadFromXml (const XmlElement& xml) = 0; //============================================================================== virtual void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode) = 0; JucerDocument* getDocument() const; virtual void changed(); bool perform (UndoableAction* action, const String& actionName); //============================================================================== void paint (Graphics&) override; void resized() override; void mouseDown (const MouseEvent&) override; void mouseDrag (const MouseEvent&) override; void mouseUp (const MouseEvent&) override; void changeListenerCallback (ChangeBroadcaster*) override; void parentHierarchyChanged() override; virtual void applyCustomPaintSnippets (StringArray&) {} int borderThickness; protected: PaintRoutine* const owner; RelativePositionedRectangle position; void resizeStart() override; void resizeEnd() override; void checkBounds (Rectangle& bounds, const Rectangle& previousBounds, const Rectangle& limits, bool isStretchingTop, bool isStretchingLeft, bool isStretchingBottom, bool isStretchingRight) override; void applyBoundsToComponent (Component&, Rectangle) override; Rectangle getCurrentAbsoluteBounds() const; void getCurrentAbsoluteBoundsDouble (double& x, double& y, double& w, double& h) const; virtual void selectionChanged (bool isSelected); virtual void createSiblingComponents(); void siblingComponentsChanged(); OwnedArray siblingComponents; void updateSiblingComps(); private: std::unique_ptr border; String typeName; bool selected, dragging, mouseDownSelectStatus; double originalAspectRatio; ChangeBroadcaster selfChangeListenerList; }; //============================================================================== template class ElementListener : private ChangeListener { public: ElementListener (ElementType* e) : owner (e), broadcaster (*owner->getDocument()), propToRefresh (nullptr) { broadcaster.addChangeListener (this); } ~ElementListener() override { jassert (propToRefresh != nullptr); broadcaster.removeChangeListener (this); } void setPropertyToRefresh (PropertyComponent& pc) { propToRefresh = &pc; } mutable Component::SafePointer owner; ChangeBroadcaster& broadcaster; PropertyComponent* propToRefresh; private: void changeListenerCallback (ChangeBroadcaster*) override { jassert (propToRefresh != nullptr); if (propToRefresh != nullptr && owner != nullptr) propToRefresh->refresh(); } JUCE_DECLARE_NON_COPYABLE (ElementListener) };