File indexing completed on 2024-05-12 04:04:35

0001 /***************************************************************************
0002  *   Copyright 2008, 2009, 2010 Stefan Majewsky <majewsky@gmx.net>
0003  *
0004  *   This program is free software; you can redistribute it and/or
0005  *   modify it under the terms of the GNU General Public
0006  *   License as published by the Free Software Foundation; either
0007  *   version 2 of the License, or (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details.
0013  *
0014  *   You should have received a copy of the GNU General Public License
0015  *   along with this program; if not, write to the Free Software
0016  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0017  ***************************************************************************/
0018 
0019 #ifndef KOLF_OVERLAY_H
0020 #define KOLF_OVERLAY_H
0021 
0022 #include <QGraphicsItem>
0023 
0024 namespace Utils
0025 {
0026     class AnimatedItem;
0027 }
0028 
0029 class CanvasItem;
0030 
0031 namespace Kolf
0032 {
0033     //This can be used by Kolf::Overlay subclasses for modifying the physical appearance of an object.
0034     class OverlayHandle : public QObject, public QGraphicsPathItem
0035     {
0036         Q_OBJECT
0037         public:
0038             enum Shape
0039             {
0040                 SquareShape,
0041                 CircleShape,
0042                 TriangleShape
0043             };
0044 
0045             OverlayHandle(Shape shape, QGraphicsItem* parent);
0046         Q_SIGNALS:
0047             void moveStarted();
0048             void moveRequest(const QPointF& targetScenePos);
0049             void moveEnded();
0050         protected:
0051             void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
0052             void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
0053             void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
0054             void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
0055             void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
0056     };
0057 
0058     //This is used by Kolf::Overlay to paint the various outlines of an item.
0059     class OverlayAreaItem : public QObject, public QGraphicsPathItem
0060     {
0061         Q_OBJECT
0062         public:
0063             enum Feature
0064             {
0065                 Draggable = 1 << 0,
0066                 Clickable = 1 << 1,
0067                 Hoverable = 1 << 2
0068             };
0069             Q_DECLARE_FLAGS(Features, Feature)
0070 
0071             OverlayAreaItem(Features features, QGraphicsItem* parent);
0072         Q_SIGNALS:
0073             void clicked(int button);
0074             void dragged(const QPointF& distance);
0075             void hoverEntered();
0076             void hoverLeft();
0077         protected:
0078             void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
0079             void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
0080             void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
0081             void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
0082             void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
0083         private:
0084             Features m_features;
0085     };
0086 
0087     /**
0088      * \class Overlay
0089      * \since 2.0
0090      *
0091      * Overlays are used by the editor to provide the on-screen editing interface. The most wellknown overlay is probably the rectangle with grips at every corner and edge. Overlays react on changes in the property set of their object and change specific properties through user interaction.
0092      *
0093      * By default, the Overlay renders interaction and activation outlines and allows to change the object's position; subclasses have to add handles to manipulate geometrical properties of the object. (This class may become pure virtual in the future, we therefore recommend to not instance this class. If you want an overlay without handles, use Kolf::EmptyOverlay instead.)
0094      *
0095      * \warning Do not add any handles or additional interface items through setParentItem() et al. Use the addHandle() method to ensure that handles are correctly shown and hidden.
0096      * \sa Kolf::Object
0097      */
0098     class Overlay : public QObject, public QGraphicsItem
0099     {
0100         Q_OBJECT
0101         Q_INTERFACES(QGraphicsItem)
0102         public:
0103             ///This enum specifies states that an overlay can occupy.
0104             enum State
0105             {
0106                 Passive = 0, ///< The overlay is invisible (not as in isVisible() == false, but all components are transparent or invisible).
0107                 Hovered = 1, ///< The overlay's activation area has been hovered, and the interactor area is shown (though very translucent).
0108                 Active = 2   ///< The interaction area is shown at a high opacity, and the overlay's handles are visible.
0109             };
0110 
0111             Overlay(CanvasItem* citem, QGraphicsItem* qitem, bool hack_addQitemShapeToOutlines = false);
0112             ///Returns a reference to the CanvasItem that this overlay is associated with.
0113             CanvasItem* citem() const;
0114             ///Returns a reference to the QGraphicsItem that is the CanvasItem that this overlay is associated with.
0115             QGraphicsItem* qitem() const;
0116 
0117             ///Returns the current state of this overlay.
0118             State state() const;
0119             ///Performs a state transition from the current towards the given \a state.
0120             void setState(State state);
0121             ///Lets the overlay initialize its properties or react on property changes in the base object. Subclasses of Kolf::Overlay need to reimplement this to read all important properties of their object (aside from calling the base class implementation!).
0122             virtual void update();
0123 
0124             ///Overlays should not allow to decrease an object's dimensions below this level, for the sake of usability.
0125             static const qreal MinimumObjectDimension;
0126 
0127             QRectF boundingRect() const override;
0128             void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) override;
0129         Q_SIGNALS:
0130             ///This signal is emitted if the overlay's state changes.
0131             void stateChanged();
0132         protected:
0133             ///Adds a handle to the overlay interface. Handles are only shown if the overlay is visible and activated.
0134             void addHandle(QGraphicsItem* handle);
0135         private Q_SLOTS:
0136             void activatorEntered();
0137             void activatorLeft();
0138             void activatorClicked(int button);
0139             void interactorDragged(const QPointF& distance);
0140         private:
0141             CanvasItem* m_citem;
0142             QGraphicsItem* m_qitem;
0143             Kolf::Overlay::State m_state;
0144             bool m_addQitemShapeToOutlines;
0145             //pre-defined handles and area items
0146             Kolf::OverlayAreaItem* m_activatorItem;
0147             Utils::AnimatedItem* m_interactorAnimator;
0148             Kolf::OverlayAreaItem* m_interactorItem;
0149             Utils::AnimatedItem* m_handleAnimator;
0150     };
0151 }
0152 
0153 Q_DECLARE_OPERATORS_FOR_FLAGS(Kolf::OverlayAreaItem::Features)
0154 
0155 #endif // KOLF_OVERLAY_H