[calligra/krita-chili-kazakov] krita: Ported the Transform Tool onto primary/secondary actions framework

Dmitry Kazakov dimula73 at gmail.com
Fri Oct 17 11:29:41 UTC 2014


Git commit 06ad9821962658e199900e9085c0912ccbcd2113 by Dmitry Kazakov.
Committed on 17/10/2014 at 11:22.
Pushed by dkazakov into branch 'krita-chili-kazakov'.

Ported the Transform Tool onto primary/secondary actions framework

Transform tool was the last tool not ported and filtering events directly.
Now it also uses the predefined actions. The resulting architecture doesn't
seem to be ideal, and looks a bit complicated with lots of methods calling
each other and forwarding 9 methods for every strategy. Probably, we should
use some boost::function-based action assignment here. Then we will be able
to map/remaps actions quite easily.

This patch implements shift-gesture action and ctrl-base inversion for the
transformation tool. Right not it is almost ready for usage. The only thing
left is "build-up vs wash mode" switch (if needed) and better UI.

CCMAIL:kimageshop at kde.org

M  +9    -0    krita/image/kis_algebra_2d.h
M  +1    -0    krita/plugins/tools/tool_transform2/CMakeLists.txt
M  +1    -1    krita/plugins/tools/tool_transform2/kis_free_transform_strategy.cpp
M  +2    -2    krita/plugins/tools/tool_transform2/kis_free_transform_strategy.h
M  +8    -0    krita/plugins/tools/tool_transform2/kis_liquify_properties.h
M  +90   -7    krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.cpp
M  +12   -8    krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.h
M  +1    -1    krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.cpp
M  +2    -2    krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.h
A  +120  -0    krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.cpp     [License: GPL (v2+)]
C  +23   -35   krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.h [from: krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h - 052% similarity]
M  +126  -62   krita/plugins/tools/tool_transform2/kis_tool_transform.cc
M  +19   -3    krita/plugins/tools/tool_transform2/kis_tool_transform.h
M  +2    -1    krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
M  +14   -35   krita/plugins/tools/tool_transform2/kis_transform_strategy_base.cpp
M  +13   -12   krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
M  +1    -1    krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
M  +2    -2    krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h

http://commits.kde.org/calligra/06ad9821962658e199900e9085c0912ccbcd2113

diff --git a/krita/image/kis_algebra_2d.h b/krita/image/kis_algebra_2d.h
index 9f0a439..c6e0465 100644
--- a/krita/image/kis_algebra_2d.h
+++ b/krita/image/kis_algebra_2d.h
@@ -76,6 +76,15 @@ Point normalize(const Point &a)
     return (1.0 / length) * a;
 }
 
+/**
+ * Usual sign() function with positive zero
+ */
+template <typename T>
+T signPZ(T x) {
+    const T zeroValue(0);
+    return x >= T(0) ? T(1) : T(-1);
+}
+
 template <class T>
 T leftUnitNormal(const T &a)
 {
diff --git a/krita/plugins/tools/tool_transform2/CMakeLists.txt b/krita/plugins/tools/tool_transform2/CMakeLists.txt
index 075f606..14d3d7e 100644
--- a/krita/plugins/tools/tool_transform2/CMakeLists.txt
+++ b/krita/plugins/tools/tool_transform2/CMakeLists.txt
@@ -7,6 +7,7 @@ set(kritatooltransform_PART_SRCS
     kis_transform_strategy_base.cpp
     kis_warp_transform_strategy.cpp
     kis_cage_transform_strategy.cpp
+    kis_simplified_action_policy_strategy.cpp
     kis_liquify_transform_strategy.cpp
     kis_liquify_paint_helper.cpp
     kis_liquify_paintop.cpp
diff --git a/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.cpp b/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.cpp
index 6066a6d..4166647 100644
--- a/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.cpp
@@ -135,7 +135,7 @@ struct KisFreeTransformStrategy::Private
 KisFreeTransformStrategy::KisFreeTransformStrategy(const KisCoordinatesConverter *converter,
                                                    ToolTransformArgs &currentArgs,
                                                    TransformTransactionProperties &transaction)
-    : KisTransformStrategyBase(converter),
+    : KisSimplifiedActionPolicyStrategy(converter),
       m_d(new Private(this, converter, currentArgs, transaction))
 {
 }
diff --git a/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.h b/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.h
index 0ced30c..1551aa4 100644
--- a/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_free_transform_strategy.h
@@ -22,7 +22,7 @@
 #include <QObject>
 #include <QScopedPointer>
 
-#include "kis_transform_strategy_base.h"
+#include "kis_simplified_action_policy_strategy.h"
 
 class QPointF;
 class QPainter;
@@ -33,7 +33,7 @@ class TransformTransactionProperties;
 class QCursor;
 class QImage;
 
-class KisFreeTransformStrategy : public KisTransformStrategyBase
+class KisFreeTransformStrategy : public KisSimplifiedActionPolicyStrategy
 {
     Q_OBJECT
 public:
diff --git a/krita/plugins/tools/tool_transform2/kis_liquify_properties.h b/krita/plugins/tools/tool_transform2/kis_liquify_properties.h
index 0eea8f1..ab888aa 100644
--- a/krita/plugins/tools/tool_transform2/kis_liquify_properties.h
+++ b/krita/plugins/tools/tool_transform2/kis_liquify_properties.h
@@ -57,6 +57,14 @@ public:
         m_size = value;
     }
 
+    static qreal minSize() {
+        return 5.0;
+    }
+
+    static qreal maxSize() {
+        return 1000.0;
+    }
+
     qreal amount() const {
         return m_amount;
     }
diff --git a/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.cpp b/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.cpp
index a3ecc20..cf2aefe 100644
--- a/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.cpp
@@ -23,6 +23,8 @@
 #include <QPointF>
 #include <QPainter>
 
+#include "KoPointerEvent.h"
+
 #include "kis_coordinates_converter.h"
 #include "tool_transform_args.h"
 #include "transform_transaction_properties.h"
@@ -30,6 +32,7 @@
 #include "kis_cursor.h"
 #include "kis_transform_utils.h"
 #include "kis_algebra_2d.h"
+#include "kis_transform_utils.h"
 #include "kis_liquify_paint_helper.h"
 #include "kis_liquify_transform_worker.h"
 
@@ -67,7 +70,12 @@ struct KisLiquifyTransformStrategy::Private
     /// custom members ///
 
     QImage transformedImage;
-    QPointF lastMousePos;
+
+    // size-gesture-related
+    QPointF lastMouseWidgetPos;
+    QPointF startResizeImagePos;
+    QPoint startResizeGlobalCursorPos;
+
     KisLiquifyPaintHelper helper;
 
     void recalculateTransformations();
@@ -78,8 +86,7 @@ KisLiquifyTransformStrategy::KisLiquifyTransformStrategy(const KisCoordinatesCon
                                                          ToolTransformArgs &currentArgs,
                                                          TransformTransactionProperties &transaction)
 
-    : KisTransformStrategyBase(converter),
-      m_d(new Private(this, converter, currentArgs, transaction))
+    : m_d(new Private(this, converter, currentArgs, transaction))
 {
 }
 
@@ -136,10 +143,8 @@ bool KisLiquifyTransformStrategy::beginPrimaryAction(KoPointerEvent *event)
     return true;
 }
 
-void KisLiquifyTransformStrategy::continuePrimaryAction(KoPointerEvent *event, bool specialModifierActve)
+void KisLiquifyTransformStrategy::continuePrimaryAction(KoPointerEvent *event)
 {
-    Q_UNUSED(specialModifierActve);
-
     m_d->helper.continuePaint(event);
 
     m_d->recalculateTransformations();
@@ -156,11 +161,89 @@ bool KisLiquifyTransformStrategy::endPrimaryAction(KoPointerEvent *event)
     return true;
 }
 
-void KisLiquifyTransformStrategy::hoverPrimaryAction(KoPointerEvent *event)
+void KisLiquifyTransformStrategy::hoverActionCommon(KoPointerEvent *event)
 {
     m_d->helper.hoverPaint(event);
 }
 
+void KisLiquifyTransformStrategy::activateAlternateAction(KisTool::AlternateAction action)
+{
+    if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+        action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        KisLiquifyProperties *props = m_d->currentArgs.liquifyProperties();
+        props->setReverseDirection(!props->reverseDirection());
+        emit requestUpdateOptionWidget();
+    }
+}
+
+void KisLiquifyTransformStrategy::deactivateAlternateAction(KisTool::AlternateAction action)
+{
+    if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+        action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        KisLiquifyProperties *props = m_d->currentArgs.liquifyProperties();
+        props->setReverseDirection(!props->reverseDirection());
+        emit requestUpdateOptionWidget();
+    }
+}
+
+bool KisLiquifyTransformStrategy::beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    if (action == KisTool::ChangeSize) {
+        QPointF widgetPoint = m_d->converter->documentToWidget(event->point);
+        m_d->lastMouseWidgetPos = widgetPoint;
+        m_d->startResizeImagePos = m_d->converter->documentToImage(event->point);
+        m_d->startResizeGlobalCursorPos = QCursor::pos();
+        return true;
+    } else if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+               action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        return beginPrimaryAction(event);
+    }
+
+
+    return false;
+}
+
+void KisLiquifyTransformStrategy::continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    if (action == KisTool::ChangeSize) {
+        QPointF widgetPoint = m_d->converter->documentToWidget(event->point);
+
+        QPointF diff = widgetPoint - m_d->lastMouseWidgetPos;
+
+        KisLiquifyProperties *props = m_d->currentArgs.liquifyProperties();
+        const qreal linearizedOffset = diff.x() / KisTransformUtils::scaleFromAffineMatrix(m_d->converter->imageToWidgetTransform());
+        const qreal newSize = qBound(props->minSize(), props->size() + linearizedOffset, props->maxSize());
+        props->setSize(newSize);
+        m_d->currentArgs.saveLiquifyTransformMode();
+
+        m_d->lastMouseWidgetPos = widgetPoint;
+
+        emit requestCursorOutlineUpdate(m_d->startResizeImagePos);
+    } else if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+               action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        return continuePrimaryAction(event);
+    }
+}
+
+bool KisLiquifyTransformStrategy::endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    Q_UNUSED(event);
+
+    if (action == KisTool::ChangeSize) {
+        QCursor::setPos(m_d->startResizeGlobalCursorPos);
+        return true;
+    } else if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+               action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+        return endPrimaryAction(event);
+    }
+
+    return false;
+}
+
 inline QPointF KisLiquifyTransformStrategy::Private::imageToThumb(const QPointF &pt, bool useFlakeOptimization)
 {
     return useFlakeOptimization ? converter->imageToDocument(converter->documentToFlake((pt))) : q->thumbToImageTransform().inverted().map(pt);
diff --git a/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.h b/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.h
index 4dff135..6ef9677 100644
--- a/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_liquify_transform_strategy.h
@@ -48,22 +48,26 @@ public:
     QCursor getCurrentCursor() const;
     QPainterPath getCursorOutline() const;
 
-    void externalConfigChanged();
+    bool acceptsClicks() const;
 
-    using KisTransformStrategyBase::beginPrimaryAction;
-    using KisTransformStrategyBase::continuePrimaryAction;
-    using KisTransformStrategyBase::endPrimaryAction;
-    using KisTransformStrategyBase::hoverPrimaryAction;
+    void externalConfigChanged();
 
     bool beginPrimaryAction(KoPointerEvent *event);
-    void continuePrimaryAction(KoPointerEvent *event, bool specialModifierActve);
+    void continuePrimaryAction(KoPointerEvent *event);
     bool endPrimaryAction(KoPointerEvent *event);
-    void hoverPrimaryAction(KoPointerEvent *event);
+    void hoverActionCommon(KoPointerEvent *event);
 
-    bool acceptsClicks() const;
+    void activateAlternateAction(KisTool::AlternateAction action);
+    void deactivateAlternateAction(KisTool::AlternateAction action);
+
+    bool beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    void continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    bool endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
 
 signals:
     void requestCanvasUpdate();
+    void requestUpdateOptionWidget();
+    void requestCursorOutlineUpdate(const QPointF &imagePoint);
 
 private:
     class Private;
diff --git a/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.cpp b/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.cpp
index 085c47e..2c67d3b 100644
--- a/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.cpp
@@ -114,7 +114,7 @@ struct KisPerspectiveTransformStrategy::Private
 KisPerspectiveTransformStrategy::KisPerspectiveTransformStrategy(const KisCoordinatesConverter *converter,
                                                    ToolTransformArgs &currentArgs,
                                                    TransformTransactionProperties &transaction)
-    : KisTransformStrategyBase(converter),
+    : KisSimplifiedActionPolicyStrategy(converter),
       m_d(new Private(this, converter, currentArgs, transaction))
 {
 }
diff --git a/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.h b/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.h
index 6a704e5..4e7bf02 100644
--- a/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_perspective_transform_strategy.h
@@ -22,7 +22,7 @@
 #include <QObject>
 #include <QScopedPointer>
 
-#include "kis_transform_strategy_base.h"
+#include "kis_simplified_action_policy_strategy.h"
 
 class QPointF;
 class QPainter;
@@ -33,7 +33,7 @@ class TransformTransactionProperties;
 class QCursor;
 class QImage;
 
-class KisPerspectiveTransformStrategy : public KisTransformStrategyBase
+class KisPerspectiveTransformStrategy : public KisSimplifiedActionPolicyStrategy
 {
     Q_OBJECT
 public:
diff --git a/krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.cpp b/krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.cpp
new file mode 100644
index 0000000..56b2568
--- /dev/null
+++ b/krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.cpp
@@ -0,0 +1,120 @@
+/*
+ *  Copyright (c) 2014 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 "kis_simplified_action_policy_strategy.h"
+
+#include "KoPointerEvent.h"
+#include "kis_coordinates_converter.h"
+
+
+struct KisSimplifiedActionPolicyStrategy::Private
+{
+    Private(const KisCoordinatesConverter *_converter)
+        : converter(_converter) {}
+
+    const KisCoordinatesConverter *converter;
+
+    bool changeSizeModifierActive;
+    bool anyPickerModifierActive;
+};
+
+
+KisSimplifiedActionPolicyStrategy::KisSimplifiedActionPolicyStrategy(const KisCoordinatesConverter *_converter)
+    : m_d(new Private(_converter))
+{
+}
+
+KisSimplifiedActionPolicyStrategy::~KisSimplifiedActionPolicyStrategy()
+{
+}
+
+bool KisSimplifiedActionPolicyStrategy::beginPrimaryAction(KoPointerEvent *event)
+{
+    return beginPrimaryAction(m_d->converter->documentToImage(event->point));
+}
+
+void KisSimplifiedActionPolicyStrategy::continuePrimaryAction(KoPointerEvent *event)
+{
+    continuePrimaryAction(m_d->converter->documentToImage(event->point), false);
+}
+
+void KisSimplifiedActionPolicyStrategy::hoverActionCommon(KoPointerEvent *event)
+{
+    hoverActionCommon(m_d->converter->documentToImage(event->point));
+}
+
+bool KisSimplifiedActionPolicyStrategy::endPrimaryAction(KoPointerEvent *event)
+{
+    Q_UNUSED(event);
+    return endPrimaryAction();
+}
+
+void KisSimplifiedActionPolicyStrategy::activateAlternateAction(KisTool::AlternateAction action)
+{
+    if (action == KisTool::ChangeSize) {
+        m_d->changeSizeModifierActive = true;
+    } else if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+               action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        m_d->anyPickerModifierActive = true;
+    }
+}
+
+void KisSimplifiedActionPolicyStrategy::deactivateAlternateAction(KisTool::AlternateAction action)
+{
+    if (action == KisTool::ChangeSize) {
+        m_d->changeSizeModifierActive = false;
+    } else if (action == KisTool::PickFgNode || action == KisTool::PickBgNode ||
+               action == KisTool::PickFgImage || action == KisTool::PickBgImage) {
+
+        m_d->anyPickerModifierActive = false;
+    }
+}
+
+bool KisSimplifiedActionPolicyStrategy::beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    Q_UNUSED(action);
+
+    if (!m_d->changeSizeModifierActive && !m_d->anyPickerModifierActive) return false;
+
+    return beginPrimaryAction(m_d->converter->documentToImage(event->point));
+}
+
+void KisSimplifiedActionPolicyStrategy::continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    Q_UNUSED(action);
+
+    if (!m_d->changeSizeModifierActive && !m_d->anyPickerModifierActive) return;
+
+    continuePrimaryAction(m_d->converter->documentToImage(event->point), m_d->changeSizeModifierActive);
+}
+
+bool KisSimplifiedActionPolicyStrategy::endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
+{
+    Q_UNUSED(action);
+
+    if (!m_d->changeSizeModifierActive && !m_d->anyPickerModifierActive) return false;
+
+    return endPrimaryAction();
+}
+
+void KisSimplifiedActionPolicyStrategy::hoverActionCommon(const QPointF &pt)
+{
+    setTransformFunction(pt, m_d->anyPickerModifierActive);
+}
+
diff --git a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h b/krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.h
similarity index 52%
copy from krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
copy to krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.h
index fa92b31..eb375c0 100644
--- a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
+++ b/krita/plugins/tools/tool_transform2/kis_simplified_action_policy_strategy.h
@@ -16,59 +16,47 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
-#ifndef __KIS_TRANSFORM_STRATEGY_BASE_H
-#define __KIS_TRANSFORM_STRATEGY_BASE_H
+#ifndef __KIS_SIMPLIFIED_ACTION_POLICY_STRATEGY_H
+#define __KIS_SIMPLIFIED_ACTION_POLICY_STRATEGY_H
 
-#include <QObject>
 #include <QScopedPointer>
 
-class QImage;
-class QPointF;
-class QTransform;
-class QPainter;
-class QCursor;
+#include "kis_transform_strategy_base.h"
+
+
 class KoPointerEvent;
 class KisCoordinatesConverter;
-class QPainterPath;
 
-
-class KisTransformStrategyBase : public QObject
+class KisSimplifiedActionPolicyStrategy : public KisTransformStrategyBase
 {
 public:
-    KisTransformStrategyBase(const KisCoordinatesConverter *_converter);
-    ~KisTransformStrategyBase();
+    KisSimplifiedActionPolicyStrategy(const KisCoordinatesConverter *_converter);
+    ~KisSimplifiedActionPolicyStrategy();
 
-    QImage originalImage() const;
-    QTransform thumbToImageTransform() const;
+    virtual bool beginPrimaryAction(KoPointerEvent *event);
+    virtual void continuePrimaryAction(KoPointerEvent *event);
+    virtual bool endPrimaryAction(KoPointerEvent *event);
+    virtual void hoverActionCommon(KoPointerEvent *event);
 
-    void setThumbnailImage(const QImage &image, QTransform thumbToImageTransform);
+    virtual void activateAlternateAction(KisTool::AlternateAction action);
+    virtual void deactivateAlternateAction(KisTool::AlternateAction action);
 
-public:
+    virtual bool beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    virtual void continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    virtual bool endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
 
-    virtual bool acceptsClicks() const;
+protected:
 
     virtual void setTransformFunction(const QPointF &mousePos, bool perspectiveModifierActive) = 0;
-    virtual void paint(QPainter &gc) = 0;
-    virtual QCursor getCurrentCursor() const = 0;
-    virtual QPainterPath getCursorOutline() const;
-
-    virtual void externalConfigChanged() = 0;
-
-    virtual bool beginPrimaryAction(KoPointerEvent *event);
-    virtual void continuePrimaryAction(KoPointerEvent *event, bool specialModifierActve);
-    virtual bool endPrimaryAction(KoPointerEvent *event);
-    virtual void hoverPrimaryAction(KoPointerEvent *event);
-
-protected:
 
-    virtual bool beginPrimaryAction(const QPointF &pt);
-    virtual void continuePrimaryAction(const QPointF &pt, bool specialModifierActve);
-    virtual bool endPrimaryAction();
-    virtual void hoverPrimaryAction(const QPointF &pt);
+    virtual bool beginPrimaryAction(const QPointF &pt) = 0;
+    virtual void continuePrimaryAction(const QPointF &pt, bool specialModifierActve) = 0;
+    virtual bool endPrimaryAction() = 0;
+    virtual void hoverActionCommon(const QPointF &pt);
 
 private:
     struct Private;
     const QScopedPointer<Private> m_d;
 };
 
-#endif /* __KIS_TRANSFORM_STRATEGY_BASE_H */
+#endif /* __KIS_SIMPLIFIED_ACTION_POLICY_STRATEGY_H */
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
index 9a0f930..c3ceda2 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
@@ -123,6 +123,8 @@ KisToolTransform::KisToolTransform(KoCanvasBase * canvas)
     connect(m_warpStrategy.data(), SIGNAL(requestCanvasUpdate()), SLOT(canvasUpdateRequested()));
     connect(m_cageStrategy.data(), SIGNAL(requestCanvasUpdate()), SLOT(canvasUpdateRequested()));
     connect(m_liquifyStrategy.data(), SIGNAL(requestCanvasUpdate()), SLOT(canvasUpdateRequested()));
+    connect(m_liquifyStrategy.data(), SIGNAL(requestCursorOutlineUpdate(const QPointF&)), SLOT(cursorOutlineUpdateRequested(const QPointF&)));
+    connect(m_liquifyStrategy.data(), SIGNAL(requestUpdateOptionWidget()), SLOT(updateOptionWidget()));
     connect(m_freeStrategy.data(), SIGNAL(requestCanvasUpdate()), SLOT(canvasUpdateRequested()));
     connect(m_freeStrategy.data(), SIGNAL(requestResetRotationCenterButtons()), SLOT(resetRotationCenterButtonsRequested()));
     connect(m_freeStrategy.data(), SIGNAL(requestShowImageTooBig(bool)), SLOT(imageTooBigRequested(bool)));
@@ -215,7 +217,7 @@ void KisToolTransform::setFunctionalCursor()
     }
 }
 
-void KisToolTransform::updateCursorOutline(const QPointF &imagePos)
+void KisToolTransform::cursorOutlineUpdateRequested(const QPointF &imagePos)
 {
     QRect canvasUpdateRect;
 
@@ -240,36 +242,142 @@ void KisToolTransform::updateCursorOutline(const QPointF &imagePos)
     }
 }
 
-void KisToolTransform::mousePressEvent(KoPointerEvent *event)
+void KisToolTransform::beginActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action)
 {
-    if (!PRESS_CONDITION_OM(event, KisTool::HOVER_MODE, Qt::LeftButton, Qt::ControlModifier | Qt::ShiftModifier)) {
-
-        KisTool::mousePressEvent(event);
+    if (!nodeEditable()) {
+        event->ignore();
         return;
     }
 
-    KisImageWSP kisimage = image();
-
-    if (!currentNode())
-        return;
+    if (!m_strokeData.strokeId()) {
+        startStroke(m_currentArgs.mode());
+    } else {
+        bool result = false;
 
-    setMode(KisTool::PAINT_MODE);
-    if (kisimage && event->button() == Qt::LeftButton) {
-        if (!m_strokeData.strokeId()) {
-            startStroke(m_currentArgs.mode());
-            setMode(KisTool::HOVER_MODE);
+        if (usePrimaryAction) {
+            result = currentStrategy()->beginPrimaryAction(event);
         } else {
-            if (!currentStrategy()->beginPrimaryAction(event)) {
-                setMode(KisTool::HOVER_MODE);
-            }
+            result = currentStrategy()->beginAlternateAction(event, action);
         }
 
-        m_actuallyMoveWhileSelected = false;
+        if (result) {
+            setMode(KisTool::PAINT_MODE);
+        }
     }
 
+    m_actuallyMoveWhileSelected = false;
+
     outlineChanged();
 }
 
+void KisToolTransform::continueActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action)
+{
+    if (mode() != KisTool::PAINT_MODE) return;
+
+    m_actuallyMoveWhileSelected = true;
+
+    if (usePrimaryAction) {
+        currentStrategy()->continuePrimaryAction(event);
+    } else {
+        currentStrategy()->continueAlternateAction(event, action);
+    }
+
+    updateOptionWidget();
+    outlineChanged();
+}
+
+void KisToolTransform::endActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action)
+{
+    if (mode() != KisTool::PAINT_MODE) return;
+
+    setMode(KisTool::HOVER_MODE);
+
+    if (m_actuallyMoveWhileSelected ||
+        currentStrategy()->acceptsClicks()) {
+
+        bool result = false;
+
+        if (usePrimaryAction) {
+            result = currentStrategy()->endPrimaryAction(event);
+        } else {
+            result = currentStrategy()->endAlternateAction(event, action);
+        }
+
+        if (result) {
+            commitChanges();
+        }
+
+        outlineChanged();
+    }
+
+    updateOptionWidget();
+    updateApplyResetAvailability();
+}
+
+void KisToolTransform::beginPrimaryAction(KoPointerEvent *event)
+{
+    beginActionImpl(event, true, KisTool::NONE);
+}
+
+void KisToolTransform::continuePrimaryAction(KoPointerEvent *event)
+{
+    continueActionImpl(event, true, KisTool::NONE);
+}
+
+void KisToolTransform::endPrimaryAction(KoPointerEvent *event)
+{
+    endActionImpl(event, true, KisTool::NONE);
+}
+
+void KisToolTransform::activateAlternateAction(AlternateAction action)
+{
+    currentStrategy()->activateAlternateAction(action);
+}
+
+void KisToolTransform::deactivateAlternateAction(AlternateAction action)
+{
+    currentStrategy()->deactivateAlternateAction(action);
+}
+
+void KisToolTransform::beginAlternateAction(KoPointerEvent *event, AlternateAction action)
+{
+    beginActionImpl(event, false, action);
+}
+
+void KisToolTransform::continueAlternateAction(KoPointerEvent *event, AlternateAction action)
+{
+    continueActionImpl(event, false, action);
+}
+
+void KisToolTransform::endAlternateAction(KoPointerEvent *event, AlternateAction action)
+{
+    endActionImpl(event, false, action);
+}
+
+void KisToolTransform::mousePressEvent(KoPointerEvent *event)
+{
+    KisTool::mousePressEvent(event);
+}
+
+void KisToolTransform::mouseMoveEvent(KoPointerEvent *event)
+{
+    QPointF mousePos = m_canvas->coordinatesConverter()->documentToImage(event->point);
+
+    cursorOutlineUpdateRequested(mousePos);
+
+    if (!MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        currentStrategy()->hoverActionCommon(event);
+        setFunctionalCursor();
+        KisTool::mouseMoveEvent(event);
+        return;
+    }
+}
+
+void KisToolTransform::mouseReleaseEvent(KoPointerEvent *event)
+{
+    KisTool::mouseReleaseEvent(event);
+}
+
 void KisToolTransform::touchEvent( QTouchEvent* event )
 {
     //Count all moving touch points
@@ -525,50 +633,6 @@ void KisToolTransform::setWarpPointDensity( int density )
     m_optionsWidget->slotSetWarpDensity(density);
 }
 
-void KisToolTransform::mouseMoveEvent(KoPointerEvent *event)
-{
-    QPointF mousePos = m_canvas->coordinatesConverter()->documentToImage(event->point);
-
-    updateCursorOutline(mousePos);
-
-    if (!MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
-        currentStrategy()->setTransformFunction(mousePos, event->modifiers() & Qt::ControlModifier);
-        setFunctionalCursor();
-        currentStrategy()->hoverPrimaryAction(event);
-        KisTool::mouseMoveEvent(event);
-        return;
-    }
-
-    m_actuallyMoveWhileSelected = true;
-
-    currentStrategy()->continuePrimaryAction(event, event->modifiers() & Qt::ShiftModifier);
-    updateOptionWidget();
-    outlineChanged();
-}
-
-void KisToolTransform::mouseReleaseEvent(KoPointerEvent *event)
-{
-    if (!RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
-        KisTool::mouseReleaseEvent(event);
-        return;
-    }
-
-    setMode(KisTool::HOVER_MODE);
-
-    if (m_actuallyMoveWhileSelected ||
-        currentStrategy()->acceptsClicks()) {
-
-        if (currentStrategy()->endPrimaryAction(event)) {
-            commitChanges();
-        }
-
-        outlineChanged();
-    }
-
-    updateOptionWidget();
-    updateApplyResetAvailability();
-}
-
 void KisToolTransform::initTransformMode(ToolTransformArgs::TransformMode mode)
 {
     // NOTE: we are requesting an old value of m_currentArgs variable
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform.h b/krita/plugins/tools/tool_transform2/kis_tool_transform.h
index 3cb59ac..f84b27a 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform.h
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform.h
@@ -133,6 +133,20 @@ public:
     virtual void mouseReleaseEvent(KoPointerEvent *e);
     virtual void touchEvent(QTouchEvent *event);
 
+    void beginActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action);
+    void continueActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action);
+    void endActionImpl(KoPointerEvent *event, bool usePrimaryAction, KisTool::AlternateAction action);
+
+    void beginPrimaryAction(KoPointerEvent *event);
+    void continuePrimaryAction(KoPointerEvent *event);
+    void endPrimaryAction(KoPointerEvent *event);
+
+    void activateAlternateAction(AlternateAction action);
+    void deactivateAlternateAction(AlternateAction action);
+    void beginAlternateAction(KoPointerEvent *event, AlternateAction action);
+    void continueAlternateAction(KoPointerEvent *event, AlternateAction action);
+    void endAlternateAction(KoPointerEvent *event, AlternateAction action);
+
     void paint(QPainter& gc, const KoViewConverter &converter);
 
     bool isActive() const;
@@ -193,6 +207,11 @@ public Q_SLOTS:
     void requestStrokeEnd();
     void requestStrokeCancellation();
     void canvasUpdateRequested();
+    void cursorOutlineUpdateRequested(const QPointF &imagePos);
+
+    // Update the widget according to m_currentArgs
+    void updateOptionWidget();
+
     void resetRotationCenterButtonsRequested();
     void imageTooBigRequested(bool value);
 
@@ -208,14 +227,11 @@ private:
     void outlineChanged();
     // Sets the cursor according to mouse position (doesn't take shearing into account well yet)
     void setFunctionalCursor();
-    void updateCursorOutline(const QPointF &imagePos);
     // Sets m_function according to mouse position and modifier
     void setTransformFunction(QPointF mousePos, Qt::KeyboardModifiers modifiers);
 
     void commitChanges();
 
-    // Updated the widget according to m_currentArgs
-    void updateOptionWidget();
 
     void initTransformMode(ToolTransformArgs::TransformMode mode);
 
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
index eada719..ca1623f 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
@@ -132,7 +132,8 @@ KisToolTransformConfigWidget::KisToolTransformConfigWidget(TransformTransactionP
     connect(chkEditCage, SIGNAL(clicked(bool)), this, SLOT(slotEditCagePoints(bool)));
 
     // Init Liquify Transform Values
-    liquifySizeSlider->setRange(0.0, 1000.0, 2);
+    liquifySizeSlider->setRange(KisLiquifyProperties::minSize(),
+                                KisLiquifyProperties::maxSize(), 2);
     liquifySizeSlider->setExponentRatio(4);
     liquifySizeSlider->setValue(50.0);
     connect(liquifySizeSlider, SIGNAL(valueChanged(qreal)), this, SLOT(liquifySizeChanged(qreal)));
diff --git a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.cpp b/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.cpp
index 80e1367..aab7b55 100644
--- a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.cpp
@@ -21,22 +21,17 @@
 #include <QImage>
 #include <QTransform>
 #include "KoPointerEvent.h"
-#include "kis_coordinates_converter.h"
 
 
 struct KisTransformStrategyBase::Private
 {
-    Private(const KisCoordinatesConverter *_converter)
-        : converter(_converter) {}
-
     QTransform thumbToImageTransform;
     QImage originalImage;
-    const KisCoordinatesConverter *converter;
 };
 
 
-KisTransformStrategyBase::KisTransformStrategyBase(const KisCoordinatesConverter *_converter)
-    : m_d(new Private(_converter))
+KisTransformStrategyBase::KisTransformStrategyBase()
+    : m_d(new Private())
 {
 }
 
@@ -70,48 +65,32 @@ bool KisTransformStrategyBase::acceptsClicks() const
     return false;
 }
 
-bool KisTransformStrategyBase::beginPrimaryAction(KoPointerEvent *event)
-{
-    return beginPrimaryAction(m_d->converter->documentToImage(event->point));
-}
-
-void KisTransformStrategyBase::continuePrimaryAction(KoPointerEvent *event, bool specialModifierActve)
+void KisTransformStrategyBase::activateAlternateAction(KisTool::AlternateAction action)
 {
-    continuePrimaryAction(m_d->converter->documentToImage(event->point), specialModifierActve);
+    Q_UNUSED(action);
 }
 
-void KisTransformStrategyBase::hoverPrimaryAction(KoPointerEvent *event)
+void KisTransformStrategyBase::deactivateAlternateAction(KisTool::AlternateAction action)
 {
-    hoverPrimaryAction(m_d->converter->documentToImage(event->point));
+    Q_UNUSED(action);
 }
 
-bool KisTransformStrategyBase::endPrimaryAction(KoPointerEvent *event)
+bool KisTransformStrategyBase::beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
 {
     Q_UNUSED(event);
-    return endPrimaryAction();
-}
-
-bool KisTransformStrategyBase::beginPrimaryAction(const QPointF &pt)
-{
-    Q_UNUSED(pt);
-    qFatal("Not implemented");
+    Q_UNUSED(action);
     return false;
 }
 
-void KisTransformStrategyBase::continuePrimaryAction(const QPointF &pt, bool specialModifierActve)
+void KisTransformStrategyBase::continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
 {
-    Q_UNUSED(pt);
-    Q_UNUSED(specialModifierActve);
-    qFatal("Not implemented");
+    Q_UNUSED(event);
+    Q_UNUSED(action);
 }
 
-bool KisTransformStrategyBase::endPrimaryAction()
+bool KisTransformStrategyBase::endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action)
 {
-    qFatal("Not implemented");
+    Q_UNUSED(event);
+    Q_UNUSED(action);
     return false;
 }
-
-void KisTransformStrategyBase::hoverPrimaryAction(const QPointF &pt)
-{
-    Q_UNUSED(pt);
-}
diff --git a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h b/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
index fa92b31..828dc75 100644
--- a/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
+++ b/krita/plugins/tools/tool_transform2/kis_transform_strategy_base.h
@@ -22,20 +22,22 @@
 #include <QObject>
 #include <QScopedPointer>
 
+#include "kis_tool.h"
+
+
 class QImage;
 class QPointF;
 class QTransform;
 class QPainter;
 class QCursor;
 class KoPointerEvent;
-class KisCoordinatesConverter;
 class QPainterPath;
 
 
 class KisTransformStrategyBase : public QObject
 {
 public:
-    KisTransformStrategyBase(const KisCoordinatesConverter *_converter);
+    KisTransformStrategyBase();
     ~KisTransformStrategyBase();
 
     QImage originalImage() const;
@@ -47,24 +49,23 @@ public:
 
     virtual bool acceptsClicks() const;
 
-    virtual void setTransformFunction(const QPointF &mousePos, bool perspectiveModifierActive) = 0;
     virtual void paint(QPainter &gc) = 0;
     virtual QCursor getCurrentCursor() const = 0;
     virtual QPainterPath getCursorOutline() const;
 
     virtual void externalConfigChanged() = 0;
 
-    virtual bool beginPrimaryAction(KoPointerEvent *event);
-    virtual void continuePrimaryAction(KoPointerEvent *event, bool specialModifierActve);
-    virtual bool endPrimaryAction(KoPointerEvent *event);
-    virtual void hoverPrimaryAction(KoPointerEvent *event);
+    virtual bool beginPrimaryAction(KoPointerEvent *event) = 0;
+    virtual void continuePrimaryAction(KoPointerEvent *event) = 0;
+    virtual bool endPrimaryAction(KoPointerEvent *event) = 0;
+    virtual void hoverActionCommon(KoPointerEvent *event) = 0;
 
-protected:
+    virtual void activateAlternateAction(KisTool::AlternateAction action);
+    virtual void deactivateAlternateAction(KisTool::AlternateAction action);
 
-    virtual bool beginPrimaryAction(const QPointF &pt);
-    virtual void continuePrimaryAction(const QPointF &pt, bool specialModifierActve);
-    virtual bool endPrimaryAction();
-    virtual void hoverPrimaryAction(const QPointF &pt);
+    virtual bool beginAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    virtual void continueAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
+    virtual bool endAlternateAction(KoPointerEvent *event, KisTool::AlternateAction action);
 
 private:
     struct Private;
diff --git a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
index 549fd49..bb3dbbb 100644
--- a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.cpp
@@ -107,7 +107,7 @@ struct KisWarpTransformStrategy::Private
 KisWarpTransformStrategy::KisWarpTransformStrategy(const KisCoordinatesConverter *converter,
                                                    ToolTransformArgs &currentArgs,
                                                    TransformTransactionProperties &transaction)
-    : KisTransformStrategyBase(converter),
+    : KisSimplifiedActionPolicyStrategy(converter),
       m_d(new Private(this, converter, currentArgs, transaction))
 {
 }
diff --git a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
index 9fe18c2..1f8f219 100644
--- a/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
+++ b/krita/plugins/tools/tool_transform2/kis_warp_transform_strategy.h
@@ -22,7 +22,7 @@
 #include <QObject>
 #include <QScopedPointer>
 
-#include "kis_transform_strategy_base.h"
+#include "kis_simplified_action_policy_strategy.h"
 
 class QPointF;
 class QPainter;
@@ -34,7 +34,7 @@ class QCursor;
 class QImage;
 
 
-class KisWarpTransformStrategy : public KisTransformStrategyBase
+class KisWarpTransformStrategy : public KisSimplifiedActionPolicyStrategy
 {
     Q_OBJECT
 public:



More information about the kimageshop mailing list