Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tool_move.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 1999 Matthias Elter <me@kde.org>
3 * SPDX-FileCopyrightText: 1999 Michael Koch <koch@kde.org>
4 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org>
5 * SPDX-FileCopyrightText: 2004 Boudewijn Rempt <boud@valdyas.org>
6 * SPDX-FileCopyrightText: 2016 Michael Abrahams <miabraha@gmail.com>
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "kis_tool_move.h"
12
13#include <QPoint>
14
15
16#include "kis_cursor.h"
17#include "kis_selection.h"
18#include "kis_canvas2.h"
19#include "kis_image.h"
20
21#include "kis_tool_utils.h"
22#include "kis_paint_layer.h"
27#include "kis_action_registry.h"
28#include "krita_utils.h"
29
30#include <KisViewManager.h>
31#include <KisDocument.h>
32
33#include "kis_node_manager.h"
35#include "kis_signals_blocker.h"
36#include "KisAnimAutoKey.h"
37#include <boost/operators.hpp>
40
41
42struct KisToolMoveState : KisToolChangesTrackerData, boost::equality_comparable<KisToolMoveState>
43{
44 KisToolMoveState(QPoint _accumulatedOffset) : accumulatedOffset(_accumulatedOffset) {}
45 KisToolChangesTrackerData* clone() const override { return new KisToolMoveState(*this); }
46
47 bool operator ==(const KisToolMoveState &rhs) {
49 }
50
52};
53
54
56 : KisTool(canvas, KisCursor::moveCursor())
57 , m_updateCursorCompressor(100, KisSignalCompressor::FIRST_ACTIVE)
58{
59 setObjectName("tool_move");
60
61 m_showCoordinatesAction = action("movetool-show-coordinates");
62 m_showCoordinatesAction = action("movetool-show-coordinates");
63 connect(&m_updateCursorCompressor, SIGNAL(timeout()), this, SLOT(resetCursorStyle()));
64
65 m_optionsWidget = new MoveToolOptionsWidget(nullptr, currentImage()->xRes(), toolId());
66
67 // See https://bugs.kde.org/show_bug.cgi?id=316896
68 QWidget *specialSpacer = new QWidget(m_optionsWidget);
69 specialSpacer->setObjectName("SpecialSpacer");
70 specialSpacer->setFixedSize(0, 0);
71 m_optionsWidget->layout()->addWidget(specialSpacer);
72
73 m_optionsWidget->setFixedHeight(m_optionsWidget->sizeHint().height());
74
76
78
79 connect(this, SIGNAL(moveInNewPosition(QPoint)), m_optionsWidget, SLOT(slotSetTranslate(QPoint)), Qt::UniqueConnection);
80}
81
87
89{
90 if (!isActive()) return;
91
92 bool canMove = true;
93
103 (m_handlesRect.isEmpty() ||
104 !m_handlesRect.translated(currentOffset()).contains(m_lastCursorPos))) {
105
107 return;
108 }
109 } else {
110 KisResourcesSnapshotSP resources =
111 new KisResourcesSnapshot(this->image(), currentNode(), canvas()->resourceManager());
113
114 KisPaintLayerSP paintLayer =
115 dynamic_cast<KisPaintLayer*>(this->currentNode().data());
116
117 const bool canUseSelectionMode =
118 paintLayer && selection &&
119 !selection->selectedRect().isEmpty() &&
120 !selection->selectedExactRect().isEmpty();
121
122 if (canUseSelectionMode) {
123 canMove = (m_currentMode == MoveSelectedLayer ? paintLayer->isEditable() : true);
124 } else {
125 KisNodeSelectionRecipe nodeSelection =
127 this->selectedNodes(),
130
131 if (nodeSelection.selectNodesToProcess().isEmpty()) {
132 canMove = false;
133 }
134 }
135 }
136
137 if (canMove) {
139 } else {
140 useCursor(Qt::ForbiddenCursor);
141 }
142}
143
144bool KisToolMove::startStrokeImpl(MoveToolMode mode, const QPoint *pos)
145{
146 KisNodeSP node;
147 KisImageSP image = this->image();
148
149 KisResourcesSnapshotSP resources =
150 new KisResourcesSnapshot(image, currentNode(), canvas()->resourceManager());
152
153 KisPaintLayerSP paintLayer =
154 dynamic_cast<KisPaintLayer*>(this->currentNode().data());
155
156
157
158 const bool canUseSelectionMode =
159 paintLayer && selection &&
160 !selection->selectedRect().isEmpty() &&
161 !selection->selectedExactRect().isEmpty();
162
163 if (pos) {
164 // finish stroke by clicking outside image bounds
165 if (m_strokeId && !image->bounds().contains(*pos)) {
166 endStroke();
167 return false;
168 }
169
170 // restart stroke when the mode has changed or the user tried to
171 // pick another layer in "layer under cursor" mode.
172 if (m_strokeId &&
173 (m_currentMode != mode ||
174 m_currentlyUsingSelection != canUseSelectionMode ||
177 !m_handlesRect.translated(currentOffset()).contains(*pos)))) {
178
179 endStroke();
180 }
181 }
182
183 if (m_strokeId) return true;
184
185
186 if (canUseSelectionMode && !nodeEditable()) {
187 // if there is a selection, it would only use the current layer anyway
188 // if the current layer is not editable, don't continue
189 return false;
190 }
191
192 KisNodeList nodes;
193
194 KisStrokeStrategy *strategy;
195
196 bool isMoveSelection = false;
197 if (canUseSelectionMode) {
199
200 MoveSelectionStrokeStrategy *moveStrategy =
201 new MoveSelectionStrokeStrategy(paintLayer,
202 selection,
203 image.data(),
204 image.data());
205
206 connect(moveStrategy,
207 SIGNAL(sigHandlesRectCalculated(const QRect&)),
208 SLOT(slotHandlesRectCalculated(const QRect&)));
209 connect(moveStrategy,
210 SIGNAL(sigStrokeStartedEmpty()),
211 SLOT(slotStrokeStartedEmpty()));
212
213 strategy = moveStrategy;
214 isMoveSelection = true;
215 nodes = {paintLayer};
216
217 } else {
218 KisNodeSelectionRecipe nodeSelection =
219 pos ?
221 this->selectedNodes(),
223 *pos) :
225
226
227 MoveStrokeStrategy *moveStrategy =
228 new MoveStrokeStrategy(nodeSelection, image.data(), image.data());
229 connect(moveStrategy,
230 SIGNAL(sigHandlesRectCalculated(const QRect&)),
231 SLOT(slotHandlesRectCalculated(const QRect&)));
232 connect(moveStrategy,
233 SIGNAL(sigStrokeStartedEmpty()),
234 SLOT(slotStrokeStartedEmpty()));
235 connect(moveStrategy,
236 SIGNAL(sigLayersPicked(const KisNodeList&)),
237 SLOT(slotStrokePickedLayers(const KisNodeList&)));
238
239 strategy = moveStrategy;
240 nodes = nodeSelection.selectedNodes;
241 }
242
243 {
244 KConfigGroup group = KSharedConfig::openConfig()->group(toolId());
245 const bool forceLodMode = group.readEntry("forceLodMode", false);
246 strategy->setForceLodModeIfPossible(forceLodMode);
247 }
248
249 // disable outline feedback until the stroke calculates
250 // correct bounding rect
251 m_handlesRect = QRect();
252 m_strokeId = image->startStroke(strategy);
254 m_currentlyUsingSelection = isMoveSelection;
256 m_accumulatedOffset = QPoint();
257
258 if (!isMoveSelection) {
260 }
261
264 }
266
267 return true;
268}
269
274
275void KisToolMove::notifyGuiAfterMove(bool showFloatingMessage)
276{
277 if (!m_optionsWidget) return;
278 if (m_handlesRect.isEmpty()) return;
279
280 const QPoint currentTopLeft = m_handlesRect.topLeft() + currentOffset();
281
283 Q_EMIT moveInNewPosition(currentTopLeft);
284
285 const bool showCoordinates = m_optionsWidget->showCoordinates();
286
287 if (showCoordinates && showFloatingMessage) {
288 KisCanvas2 *kisCanvas = static_cast<KisCanvas2*>(canvas());
289 kisCanvas->viewManager()->
290 showFloatingMessage(
291 i18nc("floating message in move tool",
292 "X: %1 px, Y: %2 px",
293 QLocale().toString(currentTopLeft.x()),
294 QLocale().toString(currentTopLeft.y())),
295 QIcon(), 1000, KisFloatingMessage::High);
296 }
297}
298
300{
301 if (!m_strokeId) return false;
302
303 bool strokeEnded = false;
304
306 endStroke();
307 strokeEnded = true;
308 }
309
310 return strokeEnded;
311}
312
314{
316
318 KisToolMoveState *lastState = dynamic_cast<KisToolMoveState*>(m_changesTracker.lastState().data());
319 if (lastState && *lastState == *newState) return;
320
322}
323
324void KisToolMove::slotHandlesRectCalculated(const QRect &handlesRect)
325{
326 m_handlesRect = handlesRect;
327 notifyGuiAfterMove(false);
328}
329
331{
336 KisCanvas2 *kisCanvas = static_cast<KisCanvas2*>(canvas());
337 kisCanvas->viewManager()->
338 showFloatingMessage(
339 i18nc("floating message in move tool",
340 "Selected area has no pixels"),
341 QIcon(), 1000, KisFloatingMessage::High);
342 }
343
349 cancelStroke();
350}
351
353{
354 if (nodes.isEmpty()) {
355 useCursor(Qt::ForbiddenCursor);
356 } else {
358 }
359}
360
362{
363 if (mode() == KisTool::PAINT_MODE) return; // Don't interact with dragging
364 if (!currentNode()) return;
365 if (!image()) return;
366 if (!currentNode()->isEditable()) return; // Don't move invisible nodes
367
368 if (startStrokeImpl(MoveSelectedLayer, nullptr)) {
370 }
371
372 // Larger movement if "shift" key is pressed.
373 qreal scale = big ? m_optionsWidget->moveScale() : 1.0;
374 qreal moveStep = m_optionsWidget->moveStep() * scale;
375
376 const QPoint offset =
377 direction == Up ? QPoint( 0, -moveStep) :
378 direction == Down ? QPoint( 0, moveStep) :
379 direction == Left ? QPoint(-moveStep, 0) :
380 QPoint( moveStep, 0) ;
381
382 m_accumulatedOffset += offset;
384
388}
389
390void KisToolMove::activate(const QSet<KoShape*> &shapes)
391{
392 KisTool::activate(shapes);
393
394 m_actionConnections.addConnection(action("movetool-move-up"), SIGNAL(triggered(bool)),
395 this, SLOT(slotMoveDiscreteUp()));
396 m_actionConnections.addConnection(action("movetool-move-down"), SIGNAL(triggered(bool)),
397 this, SLOT(slotMoveDiscreteDown()));
398 m_actionConnections.addConnection(action("movetool-move-left"), SIGNAL(triggered(bool)),
399 this, SLOT(slotMoveDiscreteLeft()));
400 m_actionConnections.addConnection(action("movetool-move-right"), SIGNAL(triggered(bool)),
401 this, SLOT(slotMoveDiscreteRight()));
402
403 m_actionConnections.addConnection(action("movetool-move-up-more"), SIGNAL(triggered(bool)),
404 this, SLOT(slotMoveDiscreteUpMore()));
405 m_actionConnections.addConnection(action("movetool-move-down-more"), SIGNAL(triggered(bool)),
406 this, SLOT(slotMoveDiscreteDownMore()));
407 m_actionConnections.addConnection(action("movetool-move-left-more"), SIGNAL(triggered(bool)),
408 this, SLOT(slotMoveDiscreteLeftMore()));
409 m_actionConnections.addConnection(action("movetool-move-right-more"), SIGNAL(triggered(bool)),
410 this, SLOT(slotMoveDiscreteRightMore()));
411
412 m_canvasConnections.addUniqueConnection(qobject_cast<KisCanvas2*>(canvas())->viewManager()->nodeManager(), SIGNAL(sigUiNeedChangeSelectedNodes(KisNodeList)), this, SLOT(slotNodeChanged(KisNodeList)));
413 m_canvasConnections.addUniqueConnection(qobject_cast<KisCanvas2*>(canvas())->viewManager()->selectionManager(), SIGNAL(currentSelectionChanged()), this, SLOT(slotSelectionChanged()));
414
415 connect(m_showCoordinatesAction, SIGNAL(triggered(bool)), m_optionsWidget, SLOT(setShowCoordinates(bool)), Qt::UniqueConnection);
416 connect(m_optionsWidget, SIGNAL(showCoordinatesChanged(bool)), m_showCoordinatesAction, SLOT(setChecked(bool)), Qt::UniqueConnection);
417 connect(m_optionsWidget, SIGNAL(sigSetTranslateX(int)), SLOT(moveBySpinX(int)), Qt::UniqueConnection);
418 connect(m_optionsWidget, SIGNAL(sigSetTranslateY(int)), SLOT(moveBySpinY(int)), Qt::UniqueConnection);
419 connect(m_optionsWidget, SIGNAL(sigRequestCommitOffsetChanges()), this, SLOT(commitChanges()), Qt::UniqueConnection);
420
421 connect(&m_changesTracker,
422 SIGNAL(sigConfigChanged(KisToolChangesTrackerDataSP)),
424
425
427}
428
429
430
431void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
432{
433 Q_UNUSED(converter);
434
435 if (m_strokeId && !m_handlesRect.isEmpty() && !m_currentlyUsingSelection) {
436 QPainterPath handles;
437 handles.addRect(m_handlesRect.translated(currentOffset()));
438
439 QPainterPath path = pixelToView(handles);
440 paintToolOutline(&gc, path);
441 }
442}
443
445{
448
449 disconnect(m_showCoordinatesAction, 0, this, 0);
450 disconnect(m_optionsWidget, 0, this, 0);
451
452 endStroke();
454}
455
460
465
467{
468 if (!m_strokeId) return;
469
470 if (!m_changesTracker.canUndo()) {
471 cancelStroke();
472 } else {
474 }
475}
476
478{
479 if (!m_strokeId) return;
480
483 }
484}
485
490
495
497{
498 endAction(event);
499}
500
502{
503 // Ctrl+Right click toggles between moving current layer and moving layer w/ content
506
507 if (mode == MoveSelectedLayer) {
509 } else if (mode == MoveFirstLayer) {
511 }
512
513 startAction(event, mode);
514 } else {
515 startAction(event, MoveGroup);
516 }
517}
518
520{
521 Q_UNUSED(action);
522 continueAction(event);
523}
524
526{
527 Q_UNUSED(action);
528 endAction(event);
529}
530
542
544{
545 QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
546 m_dragStart = pos;
547 m_dragPos = pos;
548
549 if (startStrokeImpl(mode, &pos)) {
551
556 }
557
558 } else {
559 event->ignore();
560 m_dragPos = QPoint();
561 m_dragStart = QPoint();
562 }
563 qobject_cast<KisCanvas2*>(canvas())->updateCanvas();
564}
565
567{
569
570 if (!m_strokeId) return;
571
572 QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
573 pos = applyModifiers(event->modifiers(), pos);
574 m_dragPos = pos;
575
576 drag(pos);
578
579 qobject_cast<KisCanvas2*>(canvas())->updateCanvas();
580}
581
583{
586 if (!m_strokeId) return;
587
588 QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
589 pos = applyModifiers(event->modifiers(), pos);
590 drag(pos);
591
593 m_dragStart = QPoint();
594 m_dragPos = QPoint();
596
601 }
602
604
605 qobject_cast<KisCanvas2*>(canvas())->updateCanvas();
606}
607
608void KisToolMove::drag(const QPoint& newPos)
609{
611
612 QPoint offset = m_accumulatedOffset + newPos - m_dragStart;
613
615 new MoveStrokeStrategy::Data(offset));
616}
617
619{
620 if (!m_strokeId) return;
621
624 }
625
628 m_strokeId.clear();
633 m_accumulatedOffset = QPoint();
634 qobject_cast<KisCanvas2*>(canvas())->updateCanvas();
635}
636
649
654
659
664
669
674
679
684
689
691{
692 if (!m_strokeId) return;
693
696 }
697
700 m_strokeId.clear();
705 m_accumulatedOffset = QPoint();
707 qobject_cast<KisCanvas2*>(canvas())->updateCanvas();
708}
709
711{
712 return m_optionsWidget;
713}
714
721
722QPoint KisToolMove::applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos)
723{
724 QPoint move = pos - m_dragStart;
725
726 // Snap to axis
727 if (modifiers & Qt::ShiftModifier) {
728 move = snapToClosestAxis(move);
729 }
730
731 // "Precision mode" - scale down movement by 1/5
732 if (modifiers & Qt::AltModifier) {
733 const qreal SCALE_FACTOR = .2;
734 move = SCALE_FACTOR * move;
735 }
736
737 return m_dragStart + move;
738}
739
741{
742 if (mode() == KisTool::PAINT_MODE || // Don't interact with dragging
743 !currentNode()->isEditable() || // Don't move invisible nodes
744 m_handlesRect.isEmpty()) {
745 return;
746 }
747
748 // starting a new stroke resets m_handlesRect and it gets updated asynchronously,
749 // but in this case no change is expected
750 int handlesRectX = m_handlesRect.x();
751
752 if (startStrokeImpl(MoveSelectedLayer, nullptr)) {
754 }
755
756 m_accumulatedOffset.rx() = newX - handlesRectX;
757
759
760 notifyGuiAfterMove(false);
762}
763
765{
766 if (mode() == KisTool::PAINT_MODE || // Don't interact with dragging
767 !currentNode()->isEditable() || // Don't move invisible nodes
768 m_handlesRect.isEmpty()) {
769 return;
770 }
771
772 // starting a new stroke resets m_handlesRect and it gets updated asynchronously,
773 // but in this case no change is expected
774 int handlesRectY = m_handlesRect.y();
775
776 if (startStrokeImpl(MoveSelectedLayer, nullptr)) {
778 }
779
780 m_accumulatedOffset.ry() = newY - handlesRectY;
781
783
784 notifyGuiAfterMove(false);
786}
787
789{
790 KisResourcesSnapshotSP resources =
791 new KisResourcesSnapshot(image(), currentNode(), canvas()->resourceManager());
793
795 selection, this);
796 connect(job,
797 SIGNAL(sigCalculationFinished(const QRect&)),
798 SLOT(slotHandlesRectCalculated(const QRect &)));
799
800 KisImageSP image = this->image();
801 image->addSpontaneousJob(job);
802
803 notifyGuiAfterMove(false);
804}
805
807{
808 if (m_strokeId && !tryEndPreviousStroke(nodes)) {
809 return;
810 }
812}
813
819
821{
824
825 actions << actionRegistry->makeQAction("movetool-move-up", this);
826 actions << actionRegistry->makeQAction("movetool-move-down", this);
827 actions << actionRegistry->makeQAction("movetool-move-left", this);
828 actions << actionRegistry->makeQAction("movetool-move-right", this);
829 actions << actionRegistry->makeQAction("movetool-move-up-more", this);
830 actions << actionRegistry->makeQAction("movetool-move-down-more", this);
831 actions << actionRegistry->makeQAction("movetool-move-left-more", this);
832 actions << actionRegistry->makeQAction("movetool-move-right-more", this);
833 actions << actionRegistry->makeQAction("movetool-show-coordinates", this);
834
835 return actions;
836
837}
QAction * makeQAction(const QString &name, QObject *parent=0)
static KisActionRegistry * instance()
void startUpdateStream(KisStrokesFacade *strokesFacade, KisStrokeId strokeId)
KisViewManager * viewManager() const
bool cancelStroke(KisStrokeId id) override
void addJob(KisStrokeId id, KisStrokeJobData *data) override
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
QRect bounds() const override
void addSpontaneousJob(KisSpontaneousJob *spontaneousJob)
void endStroke(KisStrokeId id) override
KisNodeList selectNodesToProcess() const
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
KisSelectionSP activeSelection() const
void addUniqueConnection(Sender sender, Signal signal, Receiver receiver, Method method)
void addConnection(Sender sender, Signal signal, Receiver receiver, Method method, Qt::ConnectionType type=Qt::AutoConnection)
void setForceLodModeIfPossible(bool forceLodModeIfPossible)
void commitConfig(KisToolChangesTrackerDataSP state)
KisToolChangesTrackerDataSP lastState() const
QList< QAction * > createActionsImpl() override
createActionsImpl should be reimplemented if the tool needs any actions. The actions should have a va...
QPoint applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos)
void setShowCoordinates(bool value)
void continuePrimaryAction(KoPointerEvent *event) override
void slotMoveDiscreteLeftMore()
void requestUndoDuringStroke() override
void activate(const QSet< KoShape * > &shapes) override
KisAsynchronousStrokeUpdateHelper m_asyncUpdateHelper
MoveToolMode moveToolMode() const
~KisToolMove() override
void moveBySpinX(int newX)
void moveInNewPosition(QPoint)
bool tryEndPreviousStroke(const KisNodeList &nodes)
void notifyGuiAfterMove(bool showFloatingMessage=true)
void slotMoveDiscreteRight()
void paint(QPainter &gc, const KoViewConverter &converter) override
void deactivate() override
void slotMoveDiscreteUp()
void moveDiscrete(MoveDirection direction, bool big)
void drag(const QPoint &newPos)
void slotHandlesRectCalculated(const QRect &handlesRect)
KisSignalAutoConnectionsStore m_canvasConnections
void slotMoveDiscreteLeft()
void moveBySpinY(int newY)
void slotStrokeStartedEmpty()
KisSignalCompressor m_updateCursorCompressor
QPoint currentOffset() const
bool m_currentlyUsingSelection
void slotMoveDiscreteRightMore()
QWidget * createOptionWidget() override
void endPrimaryAction(KoPointerEvent *event) override
void continueAction(KoPointerEvent *event)
void cancelStroke()
void slotTrackerChangedConfig(KisToolChangesTrackerDataSP state)
void mouseMoveEvent(KoPointerEvent *event) override
MoveToolMode m_currentMode
KisToolMove(KoCanvasBase *canvas)
void requestStrokeCancellation() override
QPoint m_accumulatedOffset
Total offset including multiple clicks, up/down/left/right keys, etc. added together.
void beginPrimaryAction(KoPointerEvent *event) override
void resetCursorStyle() override
void requestStrokeEnd() override
void startAction(KoPointerEvent *event, MoveToolMode mode)
QPoint m_dragStart
Point where current cursor dragging began.
void continueAlternateAction(KoPointerEvent *event, AlternateAction action) override
KisNodeList m_currentlyProcessingNodes
QAction * m_showCoordinatesAction
KisSignalAutoConnectionsStore m_actionConnections
void endAction(KoPointerEvent *event)
void slotMoveDiscreteDownMore()
void slotNodeChanged(const KisNodeList &nodes)
void requestRedoDuringStroke() override
void slotMoveDiscreteUpMore()
QRect m_handlesRect
KisToolChangesTracker m_changesTracker
void requestHandlesRectUpdate()
void endAlternateAction(KoPointerEvent *event, AlternateAction action) override
MoveToolOptionsWidget * m_optionsWidget
void beginAlternateAction(KoPointerEvent *event, AlternateAction action) override
bool startStrokeImpl(MoveToolMode mode, const QPoint *pos)
void slotStrokePickedLayers(const KisNodeList &nodes)
QPoint m_lastCursorPos
KisStrokeId m_strokeId
void commitChanges()
void slotMoveDiscreteDown()
void slotSelectionChanged()
QList< QAction * > createActionsImpl() override
createActionsImpl should be reimplemented if the tool needs any actions. The actions should have a va...
Qt::KeyboardModifiers modifiers() const
Q_INVOKABLE QString toolId() const
virtual KoToolSelection * selection()
void useCursor(const QCursor &cursor)
QAction * action(const QString &name) const
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
PointType snapToClosestAxis(PointType P)
Definition kis_global.h:199
#define CHECK_MODE_SANITY_OR_RETURN(_mode)
Definition kis_tool.h:27
bool compareListsUnordered(const QList< T > &a, const QList< T > &b)
bool isEditable(bool checkVisibility=true) const
KisToolMoveState(QPoint _accumulatedOffset)
KisToolChangesTrackerData * clone() const override
bool operator==(const KisToolMoveState &rhs)
QPointF convertToPixelCoord(KoPointerEvent *e)
Definition kis_tool.cc:189
KisNodeList selectedNodes() const
Definition kis_tool.cc:376
virtual ToolMode mode() const
Definition kis_tool.cc:407
KisImageWSP currentImage()
Definition kis_tool.cc:393
virtual void resetCursorStyle()
Definition kis_tool.cc:613
bool nodeEditable()
Checks checks if the current node is editable.
Definition kis_tool.cc:651
QPointF pixelToView(const QPoint &pixelCoord) const
Definition kis_tool.cc:269
bool isActive
Definition kis_tool.h:44
KisNodeSP currentNode() const
Definition kis_tool.cc:370
void mouseMoveEvent(KoPointerEvent *event) override
Definition kis_tool.cc:520
void activate(const QSet< KoShape * > &shapes) override
Definition kis_tool.cc:93
void paintToolOutline(QPainter *painter, const KisOptimizedBrushOutline &path)
Definition kis_tool.cc:589
void deactivate() override
Definition kis_tool.cc:131
KisImageWSP image() const
Definition kis_tool.cc:332
@ PAINT_MODE
Definition kis_tool.h:300
@ HOVER_MODE
Definition kis_tool.h:299
QPointF convertToPixelCoordAndSnap(KoPointerEvent *e, const QPointF &offset=QPointF(), bool useModifiers=true)
Definition kis_tool.cc:214
AlternateAction
Definition kis_tool.h:134
@ SampleFgNode
Definition kis_tool.h:137
@ SampleBgImage
Definition kis_tool.h:140
virtual void setMode(ToolMode mode)
Definition kis_tool.cc:403
KisCanvas2 * canvas