File indexing completed on 2025-02-09 05:13:15
0001 /* 0002 * SPDX-FileCopyrightText: 1999 Matthias Elter <me@kde.org> 0003 * SPDX-FileCopyrightText: 1999 Michael Koch <koch@kde.org> 0004 * SPDX-FileCopyrightText: 2003 Patrick Julien <freak@codepimps.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KIS_TOOL_MOVE_H_ 0010 #define KIS_TOOL_MOVE_H_ 0011 0012 #include <KisToolPaintFactoryBase.h> 0013 #include <kis_types.h> 0014 #include <kis_tool.h> 0015 #include <flake/kis_node_shape.h> 0016 #include <kis_icon.h> 0017 #include <QKeySequence> 0018 #include <QWidget> 0019 #include <QGroupBox> 0020 #include <QRadioButton> 0021 #include "KisToolChangesTracker.h" 0022 #include "kis_signal_compressor.h" 0023 #include "kis_signal_auto_connection.h" 0024 #include "KisAsynchronousStrokeUpdateHelper.h" 0025 0026 #include "kis_canvas2.h" 0027 0028 0029 class KoCanvasBase; 0030 class MoveToolOptionsWidget; 0031 class KisDocument; 0032 0033 class KisToolMove : public KisTool 0034 { 0035 Q_OBJECT 0036 Q_ENUMS(MoveToolMode); 0037 public: 0038 KisToolMove(KoCanvasBase * canvas); 0039 ~KisToolMove() override; 0040 0041 /** 0042 * @brief wantsAutoScroll 0043 * reimplemented from KoToolBase 0044 * there's an issue where autoscrolling with this tool never makes the 0045 * stroke end, so we return false here so that users don't get stuck with 0046 * the tool. See bug 362659 0047 * @return false 0048 */ 0049 bool wantsAutoScroll() const override { 0050 return false; 0051 } 0052 0053 public Q_SLOTS: 0054 void activate(const QSet<KoShape*> &shapes) override; 0055 void deactivate() override; 0056 0057 public Q_SLOTS: 0058 void requestStrokeEnd() override; 0059 void requestStrokeCancellation() override; 0060 void requestUndoDuringStroke() override; 0061 void requestRedoDuringStroke() override; 0062 0063 protected Q_SLOTS: 0064 void resetCursorStyle() override; 0065 0066 public: 0067 enum MoveToolMode { 0068 MoveSelectedLayer, 0069 MoveFirstLayer, 0070 MoveGroup 0071 }; 0072 0073 enum MoveDirection { 0074 Up, 0075 Down, 0076 Left, 0077 Right 0078 }; 0079 0080 void beginPrimaryAction(KoPointerEvent *event) override; 0081 void continuePrimaryAction(KoPointerEvent *event) override; 0082 void endPrimaryAction(KoPointerEvent *event) override; 0083 0084 void beginAlternateAction(KoPointerEvent *event, AlternateAction action) override; 0085 void continueAlternateAction(KoPointerEvent *event, AlternateAction action) override; 0086 void endAlternateAction(KoPointerEvent *event, AlternateAction action) override; 0087 0088 void mouseMoveEvent(KoPointerEvent *event) override; 0089 0090 void startAction(KoPointerEvent *event, MoveToolMode mode); 0091 void continueAction(KoPointerEvent *event); 0092 void endAction(KoPointerEvent *event); 0093 0094 void paint(QPainter& gc, const KoViewConverter &converter) override; 0095 0096 QWidget *createOptionWidget() override; 0097 void updateUIUnit(int newUnit); 0098 0099 MoveToolMode moveToolMode() const; 0100 0101 void setShowCoordinates(bool value); 0102 0103 public Q_SLOTS: 0104 void moveDiscrete(MoveDirection direction, bool big); 0105 0106 void moveBySpinX(int newX); 0107 void moveBySpinY(int newY); 0108 0109 void slotNodeChanged(const KisNodeList &nodes); 0110 void slotSelectionChanged(); 0111 void commitChanges(); 0112 0113 void slotHandlesRectCalculated(const QRect &handlesRect); 0114 void slotStrokeStartedEmpty(); 0115 void slotStrokePickedLayers(const KisNodeList &nodes); 0116 0117 Q_SIGNALS: 0118 void moveToolModeChanged(); 0119 void moveInNewPosition(QPoint); 0120 0121 private: 0122 void drag(const QPoint& newPos); 0123 void cancelStroke(); 0124 QPoint applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos); 0125 0126 bool startStrokeImpl(MoveToolMode mode, const QPoint *pos); 0127 0128 QPoint currentOffset() const; 0129 void notifyGuiAfterMove(bool showFloatingMessage = true); 0130 bool tryEndPreviousStroke(const KisNodeList &nodes); 0131 void requestHandlesRectUpdate(); 0132 0133 0134 private Q_SLOTS: 0135 void endStroke(); 0136 void slotTrackerChangedConfig(KisToolChangesTrackerDataSP state); 0137 0138 void slotMoveDiscreteLeft(); 0139 void slotMoveDiscreteRight(); 0140 void slotMoveDiscreteUp(); 0141 void slotMoveDiscreteDown(); 0142 void slotMoveDiscreteLeftMore(); 0143 void slotMoveDiscreteRightMore(); 0144 void slotMoveDiscreteUpMore(); 0145 void slotMoveDiscreteDownMore(); 0146 0147 private: 0148 0149 MoveToolOptionsWidget* m_optionsWidget {0}; 0150 QPoint m_dragStart; ///< Point where current cursor dragging began 0151 QPoint m_accumulatedOffset; ///< Total offset including multiple clicks, up/down/left/right keys, etc. added together 0152 0153 KisStrokeId m_strokeId; 0154 0155 KisNodeList m_currentlyProcessingNodes; 0156 bool m_currentlyUsingSelection {false}; 0157 MoveToolMode m_currentMode {MoveSelectedLayer}; 0158 0159 int m_resolution {0}; 0160 0161 QAction *m_showCoordinatesAction {0}; 0162 0163 QPoint m_dragPos; 0164 QRect m_handlesRect; 0165 0166 KisToolChangesTracker m_changesTracker; 0167 0168 QPoint m_lastCursorPos; 0169 KisSignalCompressor m_updateCursorCompressor; 0170 KisSignalAutoConnectionsStore m_actionConnections; 0171 KisSignalAutoConnectionsStore m_canvasConnections; 0172 0173 KisAsynchronousStrokeUpdateHelper m_asyncUpdateHelper; 0174 }; 0175 0176 0177 class KisToolMoveFactory : public KisToolPaintFactoryBase 0178 { 0179 0180 public: 0181 KisToolMoveFactory() 0182 : KisToolPaintFactoryBase("KritaTransform/KisToolMove") { 0183 setToolTip(i18n("Move Tool")); 0184 setSection(ToolBoxSection::Transform); 0185 setActivationShapeId(KRITA_TOOL_ACTIVATION_ID); 0186 setPriority(3); 0187 setIconName(koIconNameCStr("krita_tool_move")); 0188 setShortcut(QKeySequence(Qt::Key_T)); 0189 } 0190 0191 ~KisToolMoveFactory() override {} 0192 0193 KoToolBase * createTool(KoCanvasBase *canvas) override { 0194 return new KisToolMove(canvas); 0195 } 0196 0197 QList<QAction *> createActionsImpl() override; 0198 }; 0199 0200 #endif // KIS_TOOL_MOVE_H_ 0201