1 /* This file is part of the KDE project
2 
3    Copyright (C) 2006-2008 Thorsten Zachmann <zachmann@kde.org>
4    Copyright (C) 2006-2008 Thomas Zander <zander@kde.org>
5 
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public
8    License as published by the Free Software Foundation; either
9    version 2 of the License, or (at your option) any later version.
10 
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public License
17    along with this library; see the file COPYING.LIB.  If not, write to
18    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20 */
21 
22 #ifndef DEFAULTTOOL_H
23 #define DEFAULTTOOL_H
24 
25 #include <KoInteractionTool.h>
26 #include <KoFlake.h>
27 #include <commands/KoShapeAlignCommand.h>
28 #include <commands/KoShapeReorderCommand.h>
29 #include "SelectionDecorator.h"
30 #include "KoShapeMeshGradientHandles.h"
31 
32 #include <QPolygonF>
33 #include <QTime>
34 
35 class KisSignalMapper;
36 class KoInteractionStrategy;
37 class KoShapeMoveCommand;
38 class KoSelection;
39 class DefaultToolTabbedWidget;
40 class KisViewManager;
41 
42 /**
43  * The default tool (associated with the arrow icon) implements the default
44  * interactions you have with flake objects.<br>
45  * The tool provides scaling, moving, selecting, rotation and soon skewing of
46  * any number of shapes.
47  * <p>Note that the implementation of those different strategies are delegated
48  * to the InteractionStrategy class and its subclasses.
49  */
50 class DefaultTool : public KoInteractionTool
51 {
52     Q_OBJECT
53 public:
54     /**
55      * Constructor for basic interaction tool where user actions are translated
56      * and handled by interaction strategies of type KoInteractionStrategy.
57      * @param canvas the canvas this tool will be working for.
58      */
59     explicit DefaultTool(KoCanvasBase *canvas, bool connectToSelectedShapesProxy = false);
60     ~DefaultTool() override;
61 
62     enum CanvasResource {
63         HotPosition = 1410100299
64     };
65 
66 public:
67 
68     bool wantsAutoScroll() const override;
69     void paint(QPainter &painter, const KoViewConverter &converter) override;
70 
71     QRectF decorationsRect() const override;
72 
73     ///reimplemented
74     void copy() const override;
75 
76     ///reimplemented
77     void deleteSelection() override;
78 
79     ///reimplemented
80     bool paste() override;
81     ///reimplemented
82     KoToolSelection *selection() override;
83 
84     QMenu* popupActionsMenu() override;
85 
86     /**
87      * Returns which selection handle is at params point (or NoHandle if none).
88      * @return which selection handle is at params point (or NoHandle if none).
89      * @param point the location (in pt) where we should look for a handle
90      * @param innerHandleMeaning this boolean is altered to true if the point
91      *   is inside the selection rectangle and false if it is just outside.
92      *   The value of innerHandleMeaning is undefined if the handle location is NoHandle
93      */
94     KoFlake::SelectionHandle handleAt(const QPointF &point, bool *innerHandleMeaning = 0);
95 
96 
97 public Q_SLOTS:
98     void activate(ToolActivation activation, const QSet<KoShape *> &shapes) override;
99     void deactivate() override;
100 
101 Q_SIGNALS:
102     void meshgradientHandleSelected(KoShapeMeshGradientHandles::Handle);
103 
104 private Q_SLOTS:
105     void selectionAlign(int _align);
106     void selectionDistribute(int _distribute);
107 
108     void selectionBringToFront();
109     void selectionSendToBack();
110     void selectionMoveUp();
111     void selectionMoveDown();
112 
113     void selectionGroup();
114     void selectionUngroup();
115 
116     void selectionTransform(int transformAction);
117     void selectionBooleanOp(int booleanOp);
118     void selectionSplitShapes();
119 
120     void slotActivateEditFillGradient(bool value);
121     void slotActivateEditStrokeGradient(bool value);
122 
123     void slotActivateEditFillMeshGradient(bool value);
124     void slotResetMeshGradientState();
125 
126 protected Q_SLOTS:
127     /// Update actions on selection change
128     void updateActions();
129 
130 public: // Events
131 
132     void mousePressEvent(KoPointerEvent *event) override;
133     void mouseMoveEvent(KoPointerEvent *event) override;
134     void mouseReleaseEvent(KoPointerEvent *event) override;
135     void mouseDoubleClickEvent(KoPointerEvent *event) override;
136 
137     void keyPressEvent(QKeyEvent *event) override;
138 
139     void explicitUserStrokeEndRequest() override;
140 protected:
141     QList<QPointer<QWidget> > createOptionWidgets() override;
142 
143     KoInteractionStrategy *createStrategy(KoPointerEvent *event) override;
144 
145 protected:
146     friend class SelectionInteractionStrategy;
147     virtual bool isValidForCurrentLayer() const;
148     virtual KoShapeManager *shapeManager() const;
149     virtual KoSelection *koSelection() const;
150 
151     /**
152      * Enable/disable actions specific to the tool (vector vs. reference images)
153      */
154     virtual void updateDistinctiveActions(const QList<KoShape*> &editableShapes);
155 
156     void addTransformActions(QMenu *menu) const;
157     QScopedPointer<QMenu> m_contextMenu;
158 
159 private:
160     class MoveGradientHandleInteractionFactory;
161     class MoveMeshGradientHandleInteractionFactory;
162 
163 private:
164     void setupActions();
165     void recalcSelectionBox(KoSelection *selection);
166     void updateCursor();
167     /// Returns rotation angle of given handle of the current selection
168     qreal rotationOfHandle(KoFlake::SelectionHandle handle, bool useEdgeRotation);
169 
170     void addMappedAction(KisSignalMapper *mapper, const QString &actionId, int type);
171 
172     void selectionReorder(KoShapeReorderCommand::MoveShapeType order);
173     bool moveSelection(int direction, Qt::KeyboardModifiers modifiers);
174 
175     /// Returns selection rectangle adjusted by handle proximity threshold
176     QRectF handlesSize();
177 
178 
179     void canvasResourceChanged(int key, const QVariant &res) override;
180 
181     KoFlake::SelectionHandle m_lastHandle;
182     KoFlake::AnchorPosition m_hotPosition;
183     bool m_mouseWasInsideHandles;
184     QPointF m_selectionBox[8];
185     QPolygonF m_selectionOutline;
186     QPointF m_lastPoint;
187 
188     QScopedPointer<SelectionDecorator> m_decorator;
189 
190     KoShapeMeshGradientHandles::Handle m_selectedMeshHandle;
191     KoShapeMeshGradientHandles::Handle m_hoveredMeshHandle;
192 
193     // TODO alter these 3 arrays to be static const instead
194     QCursor m_sizeCursors[8];
195     QCursor m_rotateCursors[8];
196     QCursor m_shearCursors[8];
197     qreal m_angle;
198     KoToolSelection *m_selectionHandler;
199     friend class SelectionHandler;
200 
201     DefaultToolTabbedWidget *m_tabbedOptionWidget;
202 
203     KisSignalMapper *m_alignSignalsMapper {0};
204     KisSignalMapper *m_distributeSignalsMapper {0};
205     KisSignalMapper *m_transformSignalsMapper {0};
206     KisSignalMapper *m_booleanSignalsMapper {0};
207 };
208 
209 
210 #endif
211