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