[krita/krita/4.1] /: FEATURE: Undo for Move Tool
Boudewijn Rempt
null at kde.org
Thu Sep 13 12:59:27 BST 2018
Git commit 0857f999ae86b1a403cee9141877da5c10c58db9 by Boudewijn Rempt, on behalf of Dmitry Kazakov.
Committed on 13/09/2018 at 11:59.
Pushed by rempt into branch 'krita/4.1'.
FEATURE: Undo for Move Tool
Now move tool also supports undo for intermediate actions
BUG:392014
CC:kimageshop at kde.org
M +2 -0 libs/ui/CMakeLists.txt
A +46 -0 libs/ui/tool/KisToolChangesTracker.cpp [License: UNKNOWN] *
A +31 -0 libs/ui/tool/KisToolChangesTracker.h [License: UNKNOWN] *
A +18 -0 libs/ui/tool/KisToolChangesTrackerData.cpp [License: UNKNOWN] *
A +19 -0 libs/ui/tool/KisToolChangesTrackerData.h [License: UNKNOWN] *
M +140 -116 plugins/tools/basictools/kis_tool_move.cc
M +11 -7 plugins/tools/basictools/kis_tool_move.h
M +3 -0 plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp
M +2 -0 plugins/tools/basictools/kis_tool_movetooloptionswidget.h
M +0 -1 plugins/tools/tool_transform2/CMakeLists.txt
M +9 -5 plugins/tools/tool_transform2/kis_tool_transform.cc
M +3 -3 plugins/tools/tool_transform2/kis_tool_transform.h
M +5 -0 plugins/tools/tool_transform2/tool_transform_args.cc
M +4 -2 plugins/tools/tool_transform2/tool_transform_args.h
D +0 -49 plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp
D +0 -54 plugins/tools/tool_transform2/tool_transform_changes_tracker.h
The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.
https://commits.kde.org/krita/0857f999ae86b1a403cee9141877da5c10c58db9
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index 1e8feaa7a43..a231cb8ced1 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -168,6 +168,8 @@ set(kritaui_LIB_SRCS
opengl/kis_texture_tile_info_pool.cpp
opengl/KisOpenGLUpdateInfoBuilder.cpp
kis_fps_decoration.cpp
+ tool/KisToolChangesTracker.cpp
+ tool/KisToolChangesTrackerData.cpp
tool/kis_selection_tool_helper.cpp
tool/kis_selection_tool_config_widget_helper.cpp
tool/kis_rectangle_constraint_widget.cpp
diff --git a/libs/ui/tool/KisToolChangesTracker.cpp b/libs/ui/tool/KisToolChangesTracker.cpp
new file mode 100644
index 00000000000..b740644148c
--- /dev/null
+++ b/libs/ui/tool/KisToolChangesTracker.cpp
@@ -0,0 +1,46 @@
+#include "KisToolChangesTracker.h"
+
+#include "kis_global.h"
+#include <QSharedPointer>
+
+struct KisToolChangesTracker::Private {
+ QList<KisToolChangesTrackerDataSP> undoStack;
+};
+
+
+KisToolChangesTracker::KisToolChangesTracker()
+ : m_d(new Private)
+{
+}
+
+KisToolChangesTracker::~KisToolChangesTracker()
+{
+}
+
+void KisToolChangesTracker::commitConfig(KisToolChangesTrackerDataSP state)
+{
+ m_d->undoStack.append(state);
+}
+
+void KisToolChangesTracker::requestUndo()
+{
+ if (m_d->undoStack.size() > 1) {
+ m_d->undoStack.removeLast();
+ emit sigConfigChanged(m_d->undoStack.last());
+ }
+}
+
+KisToolChangesTrackerDataSP KisToolChangesTracker::lastState() const
+{
+ return !m_d->undoStack.isEmpty() ? m_d->undoStack.last() : 0;
+}
+
+void KisToolChangesTracker::reset()
+{
+ m_d->undoStack.clear();
+}
+
+bool KisToolChangesTracker::isEmpty() const
+{
+ return m_d->undoStack.isEmpty();
+}
diff --git a/libs/ui/tool/KisToolChangesTracker.h b/libs/ui/tool/KisToolChangesTracker.h
new file mode 100644
index 00000000000..e81c5685126
--- /dev/null
+++ b/libs/ui/tool/KisToolChangesTracker.h
@@ -0,0 +1,31 @@
+#ifndef KISTOOLCHANGESTRACKER_H
+#define KISTOOLCHANGESTRACKER_H
+
+#include "kritaui_export.h"
+#include <QScopedPointer>
+#include "KisToolChangesTrackerData.h"
+
+class KRITAUI_EXPORT KisToolChangesTracker :public QObject
+{
+ Q_OBJECT
+
+public:
+ KisToolChangesTracker();
+ ~KisToolChangesTracker();
+
+ void commitConfig(KisToolChangesTrackerDataSP state);
+ void requestUndo();
+ KisToolChangesTrackerDataSP lastState() const;
+ void reset();
+
+ bool isEmpty() const;
+
+Q_SIGNALS:
+ void sigConfigChanged(KisToolChangesTrackerDataSP state);
+
+private:
+ struct Private;
+ const QScopedPointer<Private> m_d;
+};
+
+#endif // KISTOOLCHANGESTRACKER_H
diff --git a/libs/ui/tool/KisToolChangesTrackerData.cpp b/libs/ui/tool/KisToolChangesTrackerData.cpp
new file mode 100644
index 00000000000..3cce59c497c
--- /dev/null
+++ b/libs/ui/tool/KisToolChangesTrackerData.cpp
@@ -0,0 +1,18 @@
+#include "KisToolChangesTrackerData.h"
+
+struct KisToolChangesTrackerDataSPRegistrar {
+ KisToolChangesTrackerDataSPRegistrar() {
+ qRegisterMetaType<KisToolChangesTrackerDataSP>("KisToolChangesTrackerDataSP");
+ }
+};
+static KisToolChangesTrackerDataSPRegistrar __registrar;
+
+
+KisToolChangesTrackerData::~KisToolChangesTrackerData()
+{
+}
+
+KisToolChangesTrackerData *KisToolChangesTrackerData::clone() const
+{
+ return new KisToolChangesTrackerData(*this);
+}
diff --git a/libs/ui/tool/KisToolChangesTrackerData.h b/libs/ui/tool/KisToolChangesTrackerData.h
new file mode 100644
index 00000000000..6f879a91b53
--- /dev/null
+++ b/libs/ui/tool/KisToolChangesTrackerData.h
@@ -0,0 +1,19 @@
+#ifndef KISTOOLCHANGESTRACKERDATA_H
+#define KISTOOLCHANGESTRACKERDATA_H
+
+#include <QObject>
+#include "kritaui_export.h"
+#include <QSharedPointer>
+
+class KRITAUI_EXPORT KisToolChangesTrackerData
+{
+public:
+ virtual ~KisToolChangesTrackerData();
+ virtual KisToolChangesTrackerData* clone() const;
+};
+
+typedef QSharedPointer<KisToolChangesTrackerData> KisToolChangesTrackerDataSP;
+
+Q_DECLARE_METATYPE(KisToolChangesTrackerDataSP)
+
+#endif // KISTOOLCHANGESTRACKERDATA_H
diff --git a/plugins/tools/basictools/kis_tool_move.cc b/plugins/tools/basictools/kis_tool_move.cc
index 1472fc8ef23..c1d3a815547 100644
--- a/plugins/tools/basictools/kis_tool_move.cc
+++ b/plugins/tools/basictools/kis_tool_move.cc
@@ -44,6 +44,20 @@
#include "kis_node_manager.h"
#include "kis_signals_blocker.h"
+#include <boost/operators.hpp>
+
+struct KisToolMoveState : KisToolChangesTrackerData, boost::equality_comparable<KisToolMoveState>
+{
+ KisToolMoveState(QPoint _accumulatedOffset) : accumulatedOffset(_accumulatedOffset) {}
+ KisToolChangesTrackerData* clone() const { return new KisToolMoveState(*this); }
+
+ bool operator ==(const KisToolMoveState &rhs) {
+ return accumulatedOffset == rhs.accumulatedOffset;
+ }
+
+ QPoint accumulatedOffset;
+};
+
KisToolMove::KisToolMove(KoCanvasBase * canvas)
: KisTool(canvas, KisCursor::moveCursor())
@@ -52,7 +66,6 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas)
setObjectName("tool_move");
m_optionsWidget = 0;
- m_moveInProgress = false;
QAction *a;
KisActionRegistry *actionRegistry = KisActionRegistry::instance();
@@ -90,6 +103,10 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas)
m_showCoordinatesAction = actionRegistry->makeQAction("movetool-show-coordinates", this);
addAction("movetool-show-coordinates", m_showCoordinatesAction);
+
+ connect(&m_changesTracker,
+ SIGNAL(sigConfigChanged(KisToolChangesTrackerDataSP)),
+ SLOT(slotTrackerChangedConfig(KisToolChangesTrackerDataSP)));
}
KisToolMove::~KisToolMove()
@@ -141,20 +158,16 @@ bool KisToolMove::startStrokeImpl(MoveToolMode mode, const QPoint *pos)
return false;
}
- initHandles(nodes);
-
/**
* If the target node has changed, the stroke should be
* restarted. Otherwise just continue processing current node.
*/
- if (m_strokeId) {
- if (KritaUtils::compareListsUnordered(nodes, m_currentlyProcessingNodes)) {
- return true;
- } else {
- endStroke();
- }
+ if (m_strokeId && !tryEndPreviousStroke(nodes)) {
+ return true;
}
+ initHandles(nodes);
+
KisStrokeStrategy *strategy;
KisPaintLayerSP paintLayer = node ?
@@ -177,50 +190,92 @@ bool KisToolMove::startStrokeImpl(MoveToolMode mode, const QPoint *pos)
m_currentlyProcessingNodes = nodes;
m_accumulatedOffset = QPoint();
+ KIS_SAFE_ASSERT_RECOVER(m_changesTracker.isEmpty()) {
+ m_changesTracker.reset();
+ }
+ commitChanges();
+
return true;
}
-void KisToolMove::moveDiscrete(MoveDirection direction, bool big)
+QPoint KisToolMove::currentOffset() const
{
- if (mode() == KisTool::PAINT_MODE) return; // Don't interact with dragging
- if (!currentNode()->isEditable()) return; // Don't move invisible nodes
+ return m_accumulatedOffset + m_dragPos - m_dragStart;
+}
- if (startStrokeImpl(MoveSelectedLayer, 0)) {
- setMode(KisTool::PAINT_MODE);
- }
+void KisToolMove::notifyGuiAfterMove(bool showFloatingMessage)
+{
+ if (!m_optionsWidget) return;
- // Larger movement if "shift" key is pressed.
- qreal scale = big ? m_optionsWidget->moveScale() : 1.0;
- qreal moveStep = m_optionsWidget->moveStep() * scale;
+ const QPoint currentTopLeft = m_handlesRect.topLeft() + currentOffset();
- QPoint offset = direction == Up ? QPoint( 0, -moveStep) :
- direction == Down ? QPoint( 0, moveStep) :
- direction == Left ? QPoint(-moveStep, 0) :
- QPoint( moveStep, 0) ;
+ KisSignalsBlocker b(m_optionsWidget);
+ emit moveInNewPosition(currentTopLeft);
+ // TODO: fetch this info not from options widget, but from config
const bool showCoordinates = m_optionsWidget->showCoordinates();
- if (showCoordinates) {
+ if (showCoordinates && showFloatingMessage) {
KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
kisCanvas->viewManager()->
showFloatingMessage(
i18nc("floating message in move tool",
"X: %1 px, Y: %2 px",
- (m_startPosition + offset).x(),
- (m_startPosition + offset).y()),
+ currentTopLeft.x(),
+ currentTopLeft.y()),
QIcon(), 1000, KisFloatingMessage::High);
}
+}
- KisSignalsBlocker b(m_optionsWidget);
- emit moveInNewPosition(m_startPosition + offset);
+bool KisToolMove::tryEndPreviousStroke(KisNodeList nodes)
+{
+ if (!m_strokeId) return false;
+
+ bool strokeEnded = false;
+
+ if (!KritaUtils::compareListsUnordered(nodes, m_currentlyProcessingNodes)) {
+ endStroke();
+ strokeEnded = true;
+ }
+
+ return strokeEnded;
+}
+
+void KisToolMove::commitChanges()
+{
+ KIS_SAFE_ASSERT_RECOVER_RETURN(m_strokeId);
+
+ QSharedPointer<KisToolMoveState> newState(new KisToolMoveState(m_accumulatedOffset));
+ KisToolMoveState *lastState = dynamic_cast<KisToolMoveState*>(m_changesTracker.lastState().data());
+ if (lastState && *lastState == *newState) return;
+
+ m_changesTracker.commitConfig(newState);
+}
+
+void KisToolMove::moveDiscrete(MoveDirection direction, bool big)
+{
+ if (mode() == KisTool::PAINT_MODE) return; // Don't interact with dragging
+ if (!currentNode()->isEditable()) return; // Don't move invisible nodes
+
+ if (startStrokeImpl(MoveSelectedLayer, 0)) {
+ setMode(KisTool::PAINT_MODE);
+ }
+
+ // Larger movement if "shift" key is pressed.
+ qreal scale = big ? m_optionsWidget->moveScale() : 1.0;
+ qreal moveStep = m_optionsWidget->moveStep() * scale;
- m_startPosition += offset;
+ const QPoint offset =
+ direction == Up ? QPoint( 0, -moveStep) :
+ direction == Down ? QPoint( 0, moveStep) :
+ direction == Left ? QPoint(-moveStep, 0) :
+ QPoint( moveStep, 0) ;
- image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset + offset));
m_accumulatedOffset += offset;
+ image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset));
- m_moveInProgress = false;
- emit moveInProgressChanged();
+ notifyGuiAfterMove();
+ commitChanges();
setMode(KisTool::HOVER_MODE);
}
@@ -240,7 +295,7 @@ void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
if (m_dragInProgress) {
QPainterPath handles;
- handles.addRect(m_handlesRect.translated(m_pos));
+ handles.addRect(m_handlesRect.translated(currentOffset()));
QPainterPath path = pixelToView(handles);
paintToolOutline(&gc, path);
@@ -249,6 +304,12 @@ void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
void KisToolMove::initHandles(const KisNodeList &nodes)
{
+ /**
+ * The handles should be initialized only once, **before** the start of
+ * the stroke. If the nodes change, we should restart the stroke.
+ */
+ KIS_SAFE_ASSERT_RECOVER_NOOP(!m_strokeId);
+
m_handlesRect = QRect();
for (KisNodeSP node : nodes) {
node->exactBounds();
@@ -257,9 +318,6 @@ void KisToolMove::initHandles(const KisNodeList &nodes)
if (image()->globalSelection()) {
m_handlesRect &= image()->globalSelection()->selectedRect();
}
- if (m_handlesRect.topLeft() != m_startPosition) {
- m_handlesRect.moveTopLeft(m_startPosition);
- }
}
void KisToolMove::deactivate()
@@ -280,9 +338,8 @@ void KisToolMove::requestStrokeCancellation()
void KisToolMove::requestUndoDuringStroke()
{
- // we shouldn't cancel the stroke on Ctrl+Z, because it will not only
- // cancel the stroke, but also undo the previous command, which we haven't
- // yet pushed to the stack
+ if (!m_strokeId) return;
+ m_changesTracker.requestUndo();
}
void KisToolMove::beginPrimaryAction(KoPointerEvent *event)
@@ -334,15 +391,16 @@ void KisToolMove::startAction(KoPointerEvent *event, MoveToolMode mode)
{
QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
m_dragStart = pos;
- m_pos = QPoint();
- m_moveInProgress = true;
+ m_dragPos = pos;
m_dragInProgress = true;
- emit moveInProgressChanged();
if (startStrokeImpl(mode, &pos)) {
setMode(KisTool::PAINT_MODE);
} else {
event->ignore();
+ m_dragPos = QPoint();
+ m_dragStart = QPoint();
+ m_dragInProgress = false;
}
m_canvas->updateCanvas();
}
@@ -354,27 +412,12 @@ void KisToolMove::continueAction(KoPointerEvent *event)
if (!m_strokeId) return;
QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
-
- const bool showCoordinates =
- m_optionsWidget ? m_optionsWidget->showCoordinates() : true;
-
- if (showCoordinates) {
- KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
- kisCanvas->viewManager()->
- showFloatingMessage(
- i18nc("floating message in move tool",
- "X: %1 px, Y: %2 px",
- (m_startPosition + (pos - m_dragStart)).x(),
- (m_startPosition + (pos - m_dragStart)).y()),
- QIcon(), 1000, KisFloatingMessage::High);
- }
-
- KisSignalsBlocker b(m_optionsWidget);
- emit moveInNewPosition(m_startPosition + (pos - m_dragStart));
-
pos = applyModifiers(event->modifiers(), pos);
+ m_dragPos = pos;
+
drag(pos);
- m_pos = pos - m_dragStart;
+ notifyGuiAfterMove();
+
m_canvas->updateCanvas();
}
@@ -387,11 +430,15 @@ void KisToolMove::endAction(KoPointerEvent *event)
QPoint pos = convertToPixelCoordAndSnap(event).toPoint();
pos = applyModifiers(event->modifiers(), pos);
drag(pos);
- m_pos = pos - m_dragStart;
+ m_accumulatedOffset += m_dragPos - m_dragStart;
+ m_dragStart = QPoint();
+ m_dragPos = QPoint();
m_dragInProgress = false;
- m_startPosition += pos - m_dragStart;
- m_accumulatedOffset += pos - m_dragStart;
+ commitChanges();
+
+ notifyGuiAfterMove();
+
m_canvas->updateCanvas();
}
@@ -412,9 +459,22 @@ void KisToolMove::endStroke()
KisImageSP image = currentImage();
image->endStroke(m_strokeId);
m_strokeId.clear();
+ m_changesTracker.reset();
m_currentlyProcessingNodes.clear();
- m_moveInProgress = false;
- emit moveInProgressChanged();
+ m_accumulatedOffset = QPoint();
+}
+
+void KisToolMove::slotTrackerChangedConfig(KisToolChangesTrackerDataSP state)
+{
+ KIS_SAFE_ASSERT_RECOVER_RETURN(m_strokeId);
+
+ KisToolMoveState *newState = dynamic_cast<KisToolMoveState*>(state.data());
+ KIS_SAFE_ASSERT_RECOVER_RETURN(newState);
+
+ if (mode() == KisTool::PAINT_MODE) return; // Don't interact with dragging
+ m_accumulatedOffset = newState->accumulatedOffset;
+ image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset));
+ notifyGuiAfterMove();
}
void KisToolMove::cancelStroke()
@@ -424,15 +484,10 @@ void KisToolMove::cancelStroke()
KisImageSP image = currentImage();
image->cancelStroke(m_strokeId);
m_strokeId.clear();
+ m_changesTracker.reset();
m_currentlyProcessingNodes.clear();
- m_moveInProgress = false;
- emit moveInProgressChanged();
-
- // we should reset m_startPosition into the original value when
- // the stroke is cancelled
- KisCanvas2 *canvas = dynamic_cast<KisCanvas2*>(this->canvas());
- canvas->viewManager()->blockUntilOperationsFinishedForced(image);
- slotNodeChanged(this->selectedNodes());
+ m_accumulatedOffset = QPoint();
+ notifyGuiAfterMove();
}
QWidget* KisToolMove::createOptionWidget()
@@ -454,10 +509,11 @@ QWidget* KisToolMove::createOptionWidget()
m_showCoordinatesAction->setChecked(m_optionsWidget->showCoordinates());
- m_optionsWidget->slotSetTranslate(m_startPosition);
+ m_optionsWidget->slotSetTranslate(m_handlesRect.topLeft() + currentOffset());
connect(m_optionsWidget, SIGNAL(sigSetTranslateX(int)), SLOT(moveBySpinX(int)));
connect(m_optionsWidget, SIGNAL(sigSetTranslateY(int)), SLOT(moveBySpinY(int)));
+ connect(m_optionsWidget, SIGNAL(sigRequestCommitOffsetChanges()), this, SLOT(commitChanges()));
connect(this, SIGNAL(moveInNewPosition(QPoint)), m_optionsWidget, SLOT(slotSetTranslate(QPoint)));
@@ -476,11 +532,6 @@ KisToolMove::MoveToolMode KisToolMove::moveToolMode() const
return MoveSelectedLayer;
}
-bool KisToolMove::moveInProgress() const
-{
- return m_moveInProgress;
-}
-
QPoint KisToolMove::applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos)
{
QPoint move = pos - m_dragStart;
@@ -508,18 +559,11 @@ void KisToolMove::moveBySpinX(int newX)
setMode(KisTool::PAINT_MODE);
}
- int offsetX = newX - m_startPosition.x();
- QPoint offset = QPoint(offsetX, 0);
-
- KisSignalsBlocker b(m_optionsWidget);
- emit moveInNewPosition(m_startPosition + offset);
+ m_accumulatedOffset.rx() = newX - m_handlesRect.x();
- image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset + offset));
- m_accumulatedOffset += offset;
- m_startPosition += offset;
+ image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset));
- m_moveInProgress = false;
- emit moveInProgressChanged();
+ notifyGuiAfterMove(false);
setMode(KisTool::HOVER_MODE);
}
@@ -532,40 +576,20 @@ void KisToolMove::moveBySpinY(int newY)
setMode(KisTool::PAINT_MODE);
}
- int offsetY = newY - m_startPosition.y();
- QPoint offset = QPoint(0, offsetY);
-
- KisSignalsBlocker b(m_optionsWidget);
- emit moveInNewPosition(m_startPosition + offset);
+ m_accumulatedOffset.ry() = newY - m_handlesRect.y();
- image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset + offset));
- m_accumulatedOffset += offset;
- m_startPosition += offset;
+ image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulatedOffset));
- m_moveInProgress = false;
- emit moveInProgressChanged();
+ notifyGuiAfterMove(false);
setMode(KisTool::HOVER_MODE);
}
void KisToolMove::slotNodeChanged(KisNodeList nodes)
{
- QRect totalBounds;
-
- Q_FOREACH (KisNodeSP node, nodes) {
- if (node && node->projection()) {
- totalBounds |= node->projection()->nonDefaultPixelArea();
- }
- }
-
- if (image()->globalSelection()) {
- totalBounds &= image()->globalSelection()->selectedRect();
+ if (m_strokeId && !tryEndPreviousStroke(nodes)) {
+ return;
}
- m_startPosition = totalBounds.topLeft();
-
- if (m_optionsWidget)
- {
- KisSignalsBlocker b(m_optionsWidget);
- m_optionsWidget->slotSetTranslate(m_startPosition);
- }
+ initHandles(nodes);
+ notifyGuiAfterMove(false);
}
diff --git a/plugins/tools/basictools/kis_tool_move.h b/plugins/tools/basictools/kis_tool_move.h
index d2dfa55727c..8ed06499663 100644
--- a/plugins/tools/basictools/kis_tool_move.h
+++ b/plugins/tools/basictools/kis_tool_move.h
@@ -30,6 +30,7 @@
#include <QWidget>
#include <QGroupBox>
#include <QRadioButton>
+#include "KisToolChangesTracker.h"
#include "kis_canvas2.h"
@@ -42,7 +43,6 @@ class KisToolMove : public KisTool
{
Q_OBJECT
Q_ENUMS(MoveToolMode);
- Q_PROPERTY(bool moveInProgress READ moveInProgress NOTIFY moveInProgressChanged);
public:
KisToolMove(KoCanvasBase * canvas);
~KisToolMove() override;
@@ -104,7 +104,6 @@ public:
void updateUIUnit(int newUnit);
MoveToolMode moveToolMode() const;
- bool moveInProgress() const;
void setShowCoordinates(bool value);
@@ -115,10 +114,10 @@ public Q_SLOTS:
void moveBySpinY(int newY);
void slotNodeChanged(KisNodeList nodes);
+ void commitChanges();
Q_SIGNALS:
void moveToolModeChanged();
- void moveInProgressChanged();
void moveInNewPosition(QPoint);
private:
@@ -128,8 +127,14 @@ private:
bool startStrokeImpl(MoveToolMode mode, const QPoint *pos);
+ QPoint currentOffset() const;
+ void notifyGuiAfterMove(bool showFloatingMessage = true);
+ bool tryEndPreviousStroke(KisNodeList nodes);
+
+
private Q_SLOTS:
void endStroke();
+ void slotTrackerChangedConfig(KisToolChangesTrackerDataSP state);
private:
@@ -137,11 +142,8 @@ private:
QPoint m_dragStart; ///< Point where current cursor dragging began
QPoint m_accumulatedOffset; ///< Total offset including multiple clicks, up/down/left/right keys, etc. added together
- QPoint m_startPosition;
-
KisStrokeId m_strokeId;
- bool m_moveInProgress;
KisNodeList m_currentlyProcessingNodes;
int m_resolution;
@@ -150,9 +152,11 @@ private:
KisCanvas2* m_canvas;
- QPoint m_pos;
+ QPoint m_dragPos;
QRect m_handlesRect;
bool m_dragInProgress = false;
+
+ KisToolChangesTracker m_changesTracker;
};
diff --git a/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp b/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp
index c0c0dddfadf..2aa47948efa 100644
--- a/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp
+++ b/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp
@@ -85,6 +85,9 @@ void MoveToolOptionsWidget::updateUIUnit(int newUnit)
spinMoveStep->blockSignals(true);
spinMoveStep->setValue(valueForUI);
spinMoveStep->blockSignals(false);
+
+ connect(translateXBox, SIGNAL(editingFinished()), SIGNAL(sigRequestCommitOffsetChanges()));
+ connect(translateYBox, SIGNAL(editingFinished()), SIGNAL(sigRequestCommitOffsetChanges()));
}
void MoveToolOptionsWidget::on_spinMoveStep_valueChanged(double UIMoveStep)
diff --git a/plugins/tools/basictools/kis_tool_movetooloptionswidget.h b/plugins/tools/basictools/kis_tool_movetooloptionswidget.h
index f1434bfd208..7749f0e0541 100644
--- a/plugins/tools/basictools/kis_tool_movetooloptionswidget.h
+++ b/plugins/tools/basictools/kis_tool_movetooloptionswidget.h
@@ -64,6 +64,8 @@ Q_SIGNALS:
void sigSetTranslateX(int value);
void sigSetTranslateY(int value);
+ void sigRequestCommitOffsetChanges();
+
private:
void updateUIUnit(int newUnit);
void setMoveToolMode(KisToolMove::MoveToolMode newMode);
diff --git a/plugins/tools/tool_transform2/CMakeLists.txt b/plugins/tools/tool_transform2/CMakeLists.txt
index ce61896b4fa..e90230c48e6 100644
--- a/plugins/tools/tool_transform2/CMakeLists.txt
+++ b/plugins/tools/tool_transform2/CMakeLists.txt
@@ -7,7 +7,6 @@ set(kritatooltransform_SOURCES
tool_transform_args.cc
kis_transform_mask_adapter.cpp
kis_animated_transform_parameters.cpp
- tool_transform_changes_tracker.cpp
kis_tool_transform.cc
kis_tool_transform_config_widget.cpp
kis_transform_strategy_base.cpp
diff --git a/plugins/tools/tool_transform2/kis_tool_transform.cc b/plugins/tools/tool_transform2/kis_tool_transform.cc
index 5bbaec35b60..09878a6da93 100644
--- a/plugins/tools/tool_transform2/kis_tool_transform.cc
+++ b/plugins/tools/tool_transform2/kis_tool_transform.cc
@@ -91,7 +91,6 @@
KisToolTransform::KisToolTransform(KoCanvasBase * canvas)
: KisTool(canvas, KisCursor::rotateCursor())
, m_workRecursively(true)
- , m_changesTracker(&m_transaction)
, m_warpStrategy(
new KisWarpTransformStrategy(
dynamic_cast<KisCanvas2*>(canvas)->coordinatesConverter(),
@@ -150,8 +149,8 @@ KisToolTransform::KisToolTransform(KoCanvasBase * canvas)
connect(m_perspectiveStrategy.data(), SIGNAL(requestCanvasUpdate()), SLOT(canvasUpdateRequested()));
connect(m_perspectiveStrategy.data(), SIGNAL(requestShowImageTooBig(bool)), SLOT(imageTooBigRequested(bool)));
- connect(&m_changesTracker, SIGNAL(sigConfigChanged()),
- this, SLOT(slotTrackerChangedConfig()));
+ connect(&m_changesTracker, SIGNAL(sigConfigChanged(KisToolChangesTrackerDataSP)),
+ this, SLOT(slotTrackerChangedConfig(KisToolChangesTrackerDataSP)));
}
KisToolTransform::~KisToolTransform()
@@ -996,11 +995,16 @@ void KisToolTransform::commitChanges()
{
if (!m_strokeData.strokeId()) return;
- m_changesTracker.commitConfig(m_currentArgs);
+ m_changesTracker.commitConfig(toQShared(m_currentArgs.clone()));
}
-void KisToolTransform::slotTrackerChangedConfig()
+void KisToolTransform::slotTrackerChangedConfig(KisToolChangesTrackerDataSP status)
{
+ const ToolTransformArgs *newArgs = dynamic_cast<const ToolTransformArgs*>(status.data());
+ KIS_SAFE_ASSERT_RECOVER_RETURN(newArgs);
+
+ *m_transaction.currentConfig() = *newArgs;
+
slotUiChangedConfig();
updateOptionWidget();
}
diff --git a/plugins/tools/tool_transform2/kis_tool_transform.h b/plugins/tools/tool_transform2/kis_tool_transform.h
index 15e034c5330..e03b2f0dec6 100644
--- a/plugins/tools/tool_transform2/kis_tool_transform.h
+++ b/plugins/tools/tool_transform2/kis_tool_transform.h
@@ -46,7 +46,7 @@
#include "tool_transform_args.h"
-#include "tool_transform_changes_tracker.h"
+#include "KisToolChangesTracker.h"
#include "kis_tool_transform_config_widget.h"
#include "transform_transaction_properties.h"
@@ -295,7 +295,7 @@ private:
QPointer<KisCanvas2> m_canvas;
TransformTransactionProperties m_transaction;
- TransformChangesTracker m_changesTracker;
+ KisToolChangesTracker m_changesTracker;
/// actions for the context click menu
@@ -333,7 +333,7 @@ private:
QPainterPath m_cursorOutline;
private Q_SLOTS:
- void slotTrackerChangedConfig();
+ void slotTrackerChangedConfig(KisToolChangesTrackerDataSP status);
void slotUiChangedConfig();
void slotApplyTransform();
void slotResetTransform();
diff --git a/plugins/tools/tool_transform2/tool_transform_args.cc b/plugins/tools/tool_transform2/tool_transform_args.cc
index 1a2612d47e7..7453961e8e3 100644
--- a/plugins/tools/tool_transform2/tool_transform_args.cc
+++ b/plugins/tools/tool_transform2/tool_transform_args.cc
@@ -121,6 +121,11 @@ ToolTransformArgs::ToolTransformArgs(const ToolTransformArgs& args)
init(args);
}
+KisToolChangesTrackerData *ToolTransformArgs::clone() const
+{
+ return new ToolTransformArgs(*this);
+}
+
ToolTransformArgs& ToolTransformArgs::operator=(const ToolTransformArgs& args)
{
clear();
diff --git a/plugins/tools/tool_transform2/tool_transform_args.h b/plugins/tools/tool_transform2/tool_transform_args.h
index b04e2ec3639..073e15f8eb9 100644
--- a/plugins/tools/tool_transform2/tool_transform_args.h
+++ b/plugins/tools/tool_transform2/tool_transform_args.h
@@ -28,7 +28,7 @@
#include "kis_liquify_properties.h"
#include "kritatooltransform_export.h"
#include "kis_global.h"
-
+#include "KisToolChangesTrackerData.h"
#include <QScopedPointer>
class KisLiquifyTransformWorker;
@@ -41,7 +41,7 @@ class QDomElement;
* memory.
*/
-class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs
+class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs : public KisToolChangesTrackerData
{
public:
enum TransformMode {FREE_TRANSFORM = 0,
@@ -62,6 +62,8 @@ public:
*/
ToolTransformArgs(const ToolTransformArgs& args);
+ KisToolChangesTrackerData *clone() const;
+
/**
* If mode is warp, original and transformed vector points will be of size 0.
* Use setPoints method to set those vectors.
diff --git a/plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp b/plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp
deleted file mode 100644
index 68a81950027..00000000000
--- a/plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013 Dmitry Kazakov <dimula73 at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "tool_transform_changes_tracker.h"
-
-
-TransformChangesTracker::TransformChangesTracker(TransformTransactionProperties *transaction)
- : m_transaction(transaction)
-{
-}
-
-void TransformChangesTracker::commitConfig(const ToolTransformArgs &config)
-{
- m_config.append(config);
-}
-
-void TransformChangesTracker::requestUndo()
-{
- if (m_config.size() > 1) {
- m_config.removeLast();
- *m_transaction->currentConfig() = m_config.last();
- emit sigConfigChanged();
- }
-}
-
-void TransformChangesTracker::reset()
-{
- m_config.clear();
-}
-
-bool TransformChangesTracker::isEmpty() const
-{
- return m_config.isEmpty();
-}
diff --git a/plugins/tools/tool_transform2/tool_transform_changes_tracker.h b/plugins/tools/tool_transform2/tool_transform_changes_tracker.h
deleted file mode 100644
index c5bf20a1473..00000000000
--- a/plugins/tools/tool_transform2/tool_transform_changes_tracker.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2013 Dmitry Kazakov <dimula73 at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef __TOOL_TRANSFORM_CHANGES_TRACKER_H
-#define __TOOL_TRANSFORM_CHANGES_TRACKER_H
-
-#include <QObject>
-
-#include "tool_transform_args.h"
-#include "transform_transaction_properties.h"
-
-
-/**
- * This class is supposed to support undo operations for the Transform
- * Tool. Note, that the transform tool is not going to support redo()
- * operations, so we do not use QUndoStack here to not complicate the
- * structure of classes.
- */
-class TransformChangesTracker : public QObject
-{
- Q_OBJECT
-public:
- TransformChangesTracker(TransformTransactionProperties *transaction);
-
- void commitConfig(const ToolTransformArgs &config);
- void requestUndo();
- void reset();
-
- bool isEmpty() const;
-
-Q_SIGNALS:
- void sigConfigChanged();
-
-private:
- QList<ToolTransformArgs> m_config;
- TransformTransactionProperties *m_transaction;
-};
-
-#endif /* __TOOL_TRANSFORM_CHANGES_TRACKER_H */
More information about the kimageshop
mailing list