File indexing completed on 2024-06-23 04:28:10

0001 /* This file is part of the KDE project
0002 
0003    SPDX-FileCopyrightText: 2006-2008 Thorsten Zachmann <zachmann@kde.org>
0004    SPDX-FileCopyrightText: 2006-2008 Thomas Zander <zander@kde.org>
0005 
0006    SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef DEFAULTTOOL_H
0010 #define DEFAULTTOOL_H
0011 
0012 #include <KoInteractionTool.h>
0013 #include <KoFlake.h>
0014 #include <commands/KoShapeAlignCommand.h>
0015 #include <commands/KoShapeReorderCommand.h>
0016 #include "SelectionDecorator.h"
0017 #include "KoShapeMeshGradientHandles.h"
0018 
0019 #include <QPolygonF>
0020 #include <QTime>
0021 
0022 class KisSignalMapper;
0023 class KoInteractionStrategy;
0024 class KoShapeMoveCommand;
0025 class KoSelection;
0026 class DefaultToolTabbedWidget;
0027 class KisViewManager;
0028 
0029 /**
0030  * The default tool (associated with the arrow icon) implements the default
0031  * interactions you have with flake objects.<br>
0032  * The tool provides scaling, moving, selecting, rotation and soon skewing of
0033  * any number of shapes.
0034  * <p>Note that the implementation of those different strategies are delegated
0035  * to the InteractionStrategy class and its subclasses.
0036  */
0037 class DefaultTool : public KoInteractionTool
0038 {
0039     Q_OBJECT
0040 public:
0041     /**
0042      * Constructor for basic interaction tool where user actions are translated
0043      * and handled by interaction strategies of type KoInteractionStrategy.
0044      * @param canvas the canvas this tool will be working for.
0045      */
0046     explicit DefaultTool(KoCanvasBase *canvas, bool connectToSelectedShapesProxy = false);
0047     ~DefaultTool() override;
0048 
0049     enum CanvasResource {
0050         HotPosition = 1410100299
0051     };
0052 
0053 public:
0054 
0055     bool wantsAutoScroll() const override;
0056     void paint(QPainter &painter, const KoViewConverter &converter) override;
0057 
0058     QRectF decorationsRect() const override;
0059 
0060     ///reimplemented
0061     void copy() const override;
0062 
0063     ///reimplemented
0064     void deleteSelection() override;
0065 
0066     ///reimplemented
0067     bool paste() override;
0068 
0069     ///reimplemented
0070     bool selectAll() override;
0071 
0072     ///reimplemented
0073     void deselect() override;
0074 
0075     ///reimplemented
0076     KoToolSelection *selection() override;
0077 
0078     QMenu *popupActionsMenu() override;
0079 
0080     /**
0081      * Returns which selection handle is at params point (or NoHandle if none).
0082      * @return which selection handle is at params point (or NoHandle if none).
0083      * @param point the location (in pt) where we should look for a handle
0084      * @param innerHandleMeaning this boolean is altered to true if the point
0085      *   is inside the selection rectangle and false if it is just outside.
0086      *   The value of innerHandleMeaning is undefined if the handle location is NoHandle
0087      */
0088     KoFlake::SelectionHandle handleAt(const QPointF &point, bool *innerHandleMeaning = 0);
0089 
0090 
0091 public Q_SLOTS:
0092     void activate(const QSet<KoShape *> &shapes) override;
0093     void deactivate() override;
0094 
0095 Q_SIGNALS:
0096     void meshgradientHandleSelected(KoShapeMeshGradientHandles::Handle);
0097 
0098 private Q_SLOTS:
0099     void selectionAlign(int _align);
0100     void selectionDistribute(int _distribute);
0101 
0102     void selectionBringToFront();
0103     void selectionSendToBack();
0104     void selectionMoveUp();
0105     void selectionMoveDown();
0106 
0107     void selectionGroup();
0108     void selectionUngroup();
0109 
0110     void selectionTransform(int transformAction);
0111     void selectionBooleanOp(int booleanOp);
0112     void selectionSplitShapes();
0113 
0114     void slotActivateEditFillGradient(bool value);
0115     void slotActivateEditStrokeGradient(bool value);
0116 
0117     void slotActivateEditFillMeshGradient(bool value);
0118     void slotResetMeshGradientState();
0119 
0120 protected Q_SLOTS:
0121     /// Update actions on selection change
0122     void updateActions();
0123 
0124 public: // Events
0125 
0126     void mousePressEvent(KoPointerEvent *event) override;
0127     void mouseMoveEvent(KoPointerEvent *event) override;
0128     void mouseReleaseEvent(KoPointerEvent *event) override;
0129     void mouseDoubleClickEvent(KoPointerEvent *event) override;
0130 
0131     void keyPressEvent(QKeyEvent *event) override;
0132 
0133     void explicitUserStrokeEndRequest() override;
0134 protected:
0135     QList<QPointer<QWidget> > createOptionWidgets() override;
0136 
0137     KoInteractionStrategy *createStrategy(KoPointerEvent *event) override;
0138 
0139 protected:
0140     friend class SelectionInteractionStrategy;
0141     virtual bool isValidForCurrentLayer() const;
0142     virtual KoShapeManager *shapeManager() const;
0143     virtual KoSelection *koSelection() const;
0144 
0145     /**
0146      * Enable/disable actions specific to the tool (vector vs. reference images)
0147      */
0148     virtual void updateDistinctiveActions(const QList<KoShape*> &editableShapes);
0149 
0150     void addTransformActions(QMenu *menu) const;
0151     QScopedPointer<QMenu> m_contextMenu;
0152 
0153 private:
0154     class MoveGradientHandleInteractionFactory;
0155     class MoveMeshGradientHandleInteractionFactory;
0156 
0157 private:
0158     void setupActions();
0159     void recalcSelectionBox(KoSelection *selection);
0160     void updateCursor();
0161     /// Returns rotation angle of given handle of the current selection
0162     qreal rotationOfHandle(KoFlake::SelectionHandle handle, bool useEdgeRotation);
0163 
0164     void addMappedAction(KisSignalMapper *mapper, const QString &actionId, int type);
0165 
0166     void selectionReorder(KoShapeReorderCommand::MoveShapeType order);
0167     bool moveSelection(int direction, Qt::KeyboardModifiers modifiers);
0168 
0169     /// Returns selection rectangle adjusted by handle proximity threshold
0170     QRectF handlesSize();
0171 
0172 
0173     void canvasResourceChanged(int key, const QVariant &res) override;
0174 
0175     KoFlake::SelectionHandle m_lastHandle;
0176     KoFlake::AnchorPosition m_hotPosition;
0177     bool m_mouseWasInsideHandles;
0178     QPointF m_selectionBox[8];
0179     QPolygonF m_selectionOutline;
0180     QPointF m_lastPoint;
0181 
0182     QScopedPointer<SelectionDecorator> m_decorator;
0183 
0184     KoShapeMeshGradientHandles::Handle m_selectedMeshHandle;
0185     KoShapeMeshGradientHandles::Handle m_hoveredMeshHandle;
0186 
0187     // TODO alter these 3 arrays to be static const instead
0188     QCursor m_sizeCursors[8];
0189     QCursor m_rotateCursors[8];
0190     QCursor m_shearCursors[8];
0191     qreal m_angle;
0192     KoToolSelection *m_selectionHandler;
0193     friend class SelectionHandler;
0194 
0195     DefaultToolTabbedWidget *m_tabbedOptionWidget;
0196 
0197     KisSignalMapper *m_alignSignalsMapper {0};
0198     KisSignalMapper *m_distributeSignalsMapper {0};
0199     KisSignalMapper *m_transformSignalsMapper {0};
0200     KisSignalMapper *m_booleanSignalsMapper {0};
0201 };
0202 
0203 
0204 #endif