[krita] /: FEATURE: move selection with any selection tool

Dmitry Kazakov null at kde.org
Tue Sep 4 10:40:36 BST 2018


Git commit 31519cf0d868a039e87a2d79e5c2969643498891 by Dmitry Kazakov.
Committed on 03/09/2018 at 19:11.
Pushed by dkazakov into branch 'master'.

FEATURE: move selection with any selection tool

Now any selection tool can move just created selection on
the canvas. Just hover the cursor over the selection until
you see a move cursor and click :)

CC:kimageshop at kde.org
Ref T9486

M  +2    -2    libs/image/KisSelectionTags.h
M  +3    -1    libs/image/kis_selection.h
M  +1    -1    libs/image/kis_selection_mask.cpp
M  +1    -0    libs/ui/CMakeLists.txt
M  +11   -7    libs/ui/flake/kis_shape_selection.cpp
M  +10   -1    libs/ui/flake/kis_shape_selection.h
M  +1    -3    libs/ui/tool/kis_selection_tool_config_widget_helper.cpp
M  +67   -0    libs/ui/tool/kis_tool_select_base.h
R  +7    -0    libs/ui/tool/strokes/move_stroke_strategy.cpp [from: plugins/tools/basictools/strokes/move_stroke_strategy.cpp - 096% similarity]
R  +2    -1    libs/ui/tool/strokes/move_stroke_strategy.h [from: plugins/tools/basictools/strokes/move_stroke_strategy.h - 096% similarity]
M  +6    -4    libs/ui/widgets/kis_selection_options.cc
M  +0    -1    plugins/tools/basictools/CMakeLists.txt
M  +1    -1    plugins/tools/basictools/strokes/move_selection_stroke_strategy.cpp
M  +1    -1    plugins/tools/basictools/tests/CMakeLists.txt

https://commits.kde.org/krita/31519cf0d868a039e87a2d79e5c2969643498891

diff --git a/libs/image/KisSelectionTags.h b/libs/image/KisSelectionTags.h
index 12f0e67859b..eab45119d2b 100644
--- a/libs/image/KisSelectionTags.h
+++ b/libs/image/KisSelectionTags.h
@@ -21,12 +21,12 @@
 
 
 enum SelectionMode {
-    PIXEL_SELECTION,
+    PIXEL_SELECTION = 0,
     SHAPE_PROTECTION
 };
 
 enum SelectionAction {
-    SELECTION_REPLACE,
+    SELECTION_REPLACE = 0,
     SELECTION_ADD,
     SELECTION_SUBTRACT,
     SELECTION_INTERSECT,
diff --git a/libs/image/kis_selection.h b/libs/image/kis_selection.h
index 97ce6f2c25b..b2dc7a73748 100644
--- a/libs/image/kis_selection.h
+++ b/libs/image/kis_selection.h
@@ -198,6 +198,8 @@ public:
     /// replace it with. Undeprecate, therefore.
     quint8 selected(qint32 x, qint32 y) const;
 
+    KisNodeWSP parentNode() const;
+
 private:
     friend class KisSelectionTest;
     friend class KisMaskTest;
@@ -205,7 +207,7 @@ private:
     friend class KisUpdateSelectionJob;
     friend class KisSelectionUpdateCompressor;
     friend class KisDeselectActiveSelectionCommand;
-    KisNodeWSP parentNode() const;
+
 
     void copyFrom(const KisSelection &rhs);
 
diff --git a/libs/image/kis_selection_mask.cpp b/libs/image/kis_selection_mask.cpp
index 786c3d4b0ca..7f2a51dac1a 100644
--- a/libs/image/kis_selection_mask.cpp
+++ b/libs/image/kis_selection_mask.cpp
@@ -70,7 +70,7 @@ KisSelectionMask::KisSelectionMask(KisImageWSP image)
     m_d->image = image;
 
     m_d->updatesCompressor =
-            new KisThreadSafeSignalCompressor(300, KisSignalCompressor::POSTPONE);
+            new KisThreadSafeSignalCompressor(50, KisSignalCompressor::FIRST_ACTIVE);
 
     connect(m_d->updatesCompressor, SIGNAL(timeout()), SLOT(slotSelectionChangedCompressed()));
     this->moveToThread(image->thread());
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index 2f2e4279206..8fc647779c5 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -201,6 +201,7 @@ set(kritaui_LIB_SRCS
     tool/strokes/KisMaskedFreehandStrokePainter.cpp
     tool/strokes/KisMaskingBrushRenderer.cpp
     tool/strokes/KisMaskingBrushCompositeOpFactory.cpp
+    tool/strokes/move_stroke_strategy.cpp
 
     widgets/kis_cmb_composite.cc
     widgets/kis_cmb_contour.cpp
diff --git a/libs/ui/flake/kis_shape_selection.cpp b/libs/ui/flake/kis_shape_selection.cpp
index d0d4b65c295..18e3676f42a 100644
--- a/libs/ui/flake/kis_shape_selection.cpp
+++ b/libs/ui/flake/kis_shape_selection.cpp
@@ -82,6 +82,8 @@ KisShapeSelection::KisShapeSelection(KoShapeControllerBase *shapeControllerBase,
     m_model->moveToThread(image->thread());
     m_canvas->setObjectName("KisShapeSelectionCanvas");
     m_canvas->moveToThread(image->thread());
+
+    connect(this, SIGNAL(sigMoveShapes(QPointF)), SLOT(slotMoveShapes(QPointF)));
 }
 
 KisShapeSelection::~KisShapeSelection()
@@ -341,20 +343,22 @@ KisShapeSelectionFactory::KisShapeSelectionFactory()
 
 void KisShapeSelection::moveX(qint32 x)
 {
-    Q_FOREACH (KoShape* shape, shapeManager()->shapes()) {
-        if (shape != this) {
-            QPointF pos = shape->position();
-            shape->setPosition(QPointF(pos.x() + x/m_image->xRes(), pos.y()));
-        }
-    }
+    const QPointF diff(x / m_image->xRes(), 0);
+    emit sigMoveShapes(diff);
 }
 
 void KisShapeSelection::moveY(qint32 y)
+{
+    const QPointF diff(0, y / m_image->yRes());
+    emit sigMoveShapes(diff);
+}
+
+void KisShapeSelection::slotMoveShapes(const QPointF &diff)
 {
     Q_FOREACH (KoShape* shape, shapeManager()->shapes()) {
         if (shape != this) {
             QPointF pos = shape->position();
-            shape->setPosition(QPointF(pos.x(), pos.y() + y/m_image->yRes()));
+            shape->setPosition(pos + diff);
         }
     }
 }
diff --git a/libs/ui/flake/kis_shape_selection.h b/libs/ui/flake/kis_shape_selection.h
index b036024de4f..6e4a696db8f 100644
--- a/libs/ui/flake/kis_shape_selection.h
+++ b/libs/ui/flake/kis_shape_selection.h
@@ -48,8 +48,10 @@ class KisShapeSelectionMarker : public KoShapeUserData
 };
 
 
-class KRITAUI_EXPORT KisShapeSelection : public KoShapeLayer, public KisSelectionComponent
+class KRITAUI_EXPORT KisShapeSelection : public QObject, public KoShapeLayer, public KisSelectionComponent
 {
+    Q_OBJECT
+
     KisShapeSelection(const KisShapeSelection& rhs);
 public:
 
@@ -86,6 +88,13 @@ public:
     void moveY(qint32 y) override;
 
     KUndo2Command* transform(const QTransform &transform) override;
+
+Q_SIGNALS:
+    void sigMoveShapes(const QPointF &diff);
+
+private Q_SLOTS:
+    void slotMoveShapes(const QPointF &diff);
+
 protected:
 
     void paintComponent(QPainter& painter, const KoViewConverter& converter, KoShapePaintingContext &paintcontext) override;
diff --git a/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp b/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp
index 87bff8a910f..91ebe4171ad 100644
--- a/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp
+++ b/libs/ui/tool/kis_selection_tool_config_widget_helper.cpp
@@ -41,8 +41,7 @@ void KisSelectionToolConfigWidgetHelper::createOptionWidget(KisCanvas2 *canvas,
 
     m_optionsWidget->setObjectName(toolId + "option widget");
     m_optionsWidget->setWindowTitle(m_windowTitle);
-    m_optionsWidget->setAction(selectionAction());
-    m_optionsWidget->setMode(selectionMode());
+    slotToolActivatedChanged(true);
 
     // See https://bugs.kde.org/show_bug.cgi?id=316896
     QWidget *specialSpacer = new QWidget(m_optionsWidget);
@@ -58,7 +57,6 @@ void KisSelectionToolConfigWidgetHelper::createOptionWidget(KisCanvas2 *canvas,
 
     m_optionsWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
     m_optionsWidget->adjustSize();
-    slotToolActivatedChanged(true);
 }
 
 KisSelectionOptions* KisSelectionToolConfigWidgetHelper::optionWidget() const
diff --git a/libs/ui/tool/kis_tool_select_base.h b/libs/ui/tool/kis_tool_select_base.h
index 1e76c673eb4..afab5b5957e 100644
--- a/libs/ui/tool/kis_tool_select_base.h
+++ b/libs/ui/tool/kis_tool_select_base.h
@@ -30,6 +30,9 @@
 #include "KisViewManager.h"
 #include "kis_selection_manager.h"
 #include "kis_selection_modifier_mapper.h"
+#include "strokes/move_stroke_strategy.h"
+#include "kis_image.h"
+#include "kis_cursor.h"
 
 /**
  * This is a basic template to create selection tools from basic path based drawing tools.
@@ -170,8 +173,53 @@ public:
         endPrimaryAction(event);
     }
 
+    KisNodeSP locateSelectionMaskUnderCursor(const QPointF &pos) {
+        KisCanvas2* canvas = dynamic_cast<KisCanvas2*>(this->canvas());
+        KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(canvas, 0);
+
+        KisSelectionSP selection = canvas->viewManager()->selection();
+        if (selection &&
+            selection->outlineCacheValid() &&
+            selection->outlineCache().contains(pos)) {
+
+            KisNodeSP parent = selection->parentNode();
+            if (parent && parent->isEditable()) {
+                return parent;
+            }
+        }
+
+        return 0;
+    }
+
+    void mouseMoveEvent(KoPointerEvent *event) {
+        const QPointF pos = this->convertToPixelCoord(event->point);
+        KisNodeSP selectionMask = locateSelectionMaskUnderCursor(pos);
+        if (selectionMask) {
+            this->useCursor(KisCursor::moveCursor());
+        } else {
+            this->resetCursorStyle();
+        }
+
+        BaseClass::mouseMoveEvent(event);
+    }
+
+
     virtual void beginPrimaryAction(KoPointerEvent *event)
     {
+        const QPointF pos = this->convertToPixelCoord(event->point);
+        KisCanvas2* canvas = dynamic_cast<KisCanvas2*>(this->canvas());
+        KIS_SAFE_ASSERT_RECOVER_RETURN(canvas);
+
+        KisNodeSP selectionMask = locateSelectionMaskUnderCursor(pos);
+        if (selectionMask) {
+            KisStrokeStrategy *strategy = new MoveStrokeStrategy({selectionMask}, this->image().data(), this->image().data());
+            m_moveStrokeId = this->image()->startStroke(strategy);
+            m_dragStartPos = pos;
+
+            return;
+        }
+
+
         keysAtStart = event->modifiers();
 
         setAlternateSelectionAction(KisSelectionModifierMapper::map(keysAtStart));
@@ -183,6 +231,15 @@ public:
 
     virtual void continuePrimaryAction(KoPointerEvent *event)
     {
+        if (m_moveStrokeId) {
+            const QPointF pos = this->convertToPixelCoord(event->point);
+            const QPoint offset((pos - m_dragStartPos).toPoint());
+
+            this->image()->addJob(m_moveStrokeId, new MoveStrokeStrategy::Data(offset));
+            return;
+        }
+
+
         //If modifier keys have changed, tell the base tool it can start capturing modifiers
         if ((keysAtStart != event->modifiers()) && !BaseClass::listeningToModifiers()) {
             BaseClass::listenToModifiers(true);
@@ -198,6 +255,14 @@ public:
 
     void endPrimaryAction(KoPointerEvent *event)
     {
+        if (m_moveStrokeId) {
+            this->image()->endStroke(m_moveStrokeId);
+
+            m_moveStrokeId.clear();
+            return;
+        }
+
+
         keysAtStart = Qt::NoModifier; //reset this with each action
         BaseClass::endPrimaryAction(event);
     }
@@ -222,6 +287,8 @@ protected:
 private:
     Qt::KeyboardModifiers keysAtStart;
 
+    QPointF m_dragStartPos;
+    KisStrokeId m_moveStrokeId;
 };
 
 
diff --git a/plugins/tools/basictools/strokes/move_stroke_strategy.cpp b/libs/ui/tool/strokes/move_stroke_strategy.cpp
similarity index 96%
rename from plugins/tools/basictools/strokes/move_stroke_strategy.cpp
rename to libs/ui/tool/strokes/move_stroke_strategy.cpp
index 8cb4958ed4d..e8085a8e434 100644
--- a/plugins/tools/basictools/strokes/move_stroke_strategy.cpp
+++ b/libs/ui/tool/strokes/move_stroke_strategy.cpp
@@ -145,6 +145,9 @@ void MoveStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
     }
 }
 
+#include "kis_selection_mask.h"
+#include "kis_selection.h"
+
 void MoveStrokeStrategy::moveAndUpdate(QPoint offset)
 {
     Q_FOREACH (KisNodeSP node, m_nodes) {
@@ -154,6 +157,10 @@ void MoveStrokeStrategy::moveAndUpdate(QPoint offset)
         if (m_updatesEnabled) {
             m_updatesFacade->refreshGraphAsync(node, dirtyRect);
         }
+
+        if (KisSelectionMask *mask = dynamic_cast<KisSelectionMask*>(node.data())) {
+            //mask->selection()->notifySelectionChanged();
+        }
     }
 }
 
diff --git a/plugins/tools/basictools/strokes/move_stroke_strategy.h b/libs/ui/tool/strokes/move_stroke_strategy.h
similarity index 96%
rename from plugins/tools/basictools/strokes/move_stroke_strategy.h
rename to libs/ui/tool/strokes/move_stroke_strategy.h
index e7f31d3fe15..0ae3bc643ab 100644
--- a/plugins/tools/basictools/strokes/move_stroke_strategy.h
+++ b/libs/ui/tool/strokes/move_stroke_strategy.h
@@ -21,6 +21,7 @@
 
 #include <QHash>
 
+#include "kritaui_export.h"
 #include "kis_stroke_strategy_undo_command_based.h"
 #include "kis_types.h"
 #include "kis_lod_transform.h"
@@ -30,7 +31,7 @@ class KisUpdatesFacade;
 class KisPostExecutionUndoAdapter;
 
 
-class MoveStrokeStrategy : public KisStrokeStrategyUndoCommandBased
+class KRITAUI_EXPORT MoveStrokeStrategy : public KisStrokeStrategyUndoCommandBased
 {
 public:
     class Data : public KisStrokeJobData {
diff --git a/libs/ui/widgets/kis_selection_options.cc b/libs/ui/widgets/kis_selection_options.cc
index 995c15ef568..6f86500d28d 100644
--- a/libs/ui/widgets/kis_selection_options.cc
+++ b/libs/ui/widgets/kis_selection_options.cc
@@ -85,14 +85,16 @@ int KisSelectionOptions::action()
 
 void KisSelectionOptions::setAction(int action) {
     QAbstractButton* button = m_action->button(action);
-    Q_ASSERT(button);
-    if(button) button->setChecked(true);
+    KIS_SAFE_ASSERT_RECOVER_RETURN(button);
+
+    button->setChecked(true);
 }
 
 void KisSelectionOptions::setMode(int mode) {
     QAbstractButton* button = m_mode->button(mode);
-    Q_ASSERT(button);
-    if(button) button->setChecked(true);
+    KIS_SAFE_ASSERT_RECOVER_RETURN(button);
+
+    button->setChecked(true);
     hideActionsForSelectionMode(mode);
 }
 
diff --git a/plugins/tools/basictools/CMakeLists.txt b/plugins/tools/basictools/CMakeLists.txt
index effd5e654be..c0771eafd5f 100644
--- a/plugins/tools/basictools/CMakeLists.txt
+++ b/plugins/tools/basictools/CMakeLists.txt
@@ -16,7 +16,6 @@ set(kritadefaulttools_SOURCES
     kis_tool_path.cc
     kis_tool_move.cc
     kis_tool_movetooloptionswidget.cpp
-    strokes/move_stroke_strategy.cpp
     strokes/move_selection_stroke_strategy.cpp
     kis_tool_multihand.cpp
     kis_tool_multihand_config.cpp
diff --git a/plugins/tools/basictools/strokes/move_selection_stroke_strategy.cpp b/plugins/tools/basictools/strokes/move_selection_stroke_strategy.cpp
index 2fd6584a0c6..cc953cdb988 100644
--- a/plugins/tools/basictools/strokes/move_selection_stroke_strategy.cpp
+++ b/plugins/tools/basictools/strokes/move_selection_stroke_strategy.cpp
@@ -135,7 +135,7 @@ void MoveSelectionStrokeStrategy::cancelStrokeCallback()
     KisStrokeStrategyUndoCommandBased::cancelStrokeCallback();
 }
 
-#include "move_stroke_strategy.h"
+#include "tool/strokes/move_stroke_strategy.h"
 
 void MoveSelectionStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
 {
diff --git a/plugins/tools/basictools/tests/CMakeLists.txt b/plugins/tools/basictools/tests/CMakeLists.txt
index f859770067f..a682d73387a 100644
--- a/plugins/tools/basictools/tests/CMakeLists.txt
+++ b/plugins/tools/basictools/tests/CMakeLists.txt
@@ -9,7 +9,7 @@ macro_add_unittest_definitions()
 
 ########### next target ###############
 
-krita_add_broken_unit_test(move_stroke_test.cpp ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp ../strokes/move_stroke_strategy.cpp
+krita_add_broken_unit_test(move_stroke_test.cpp ${CMAKE_SOURCE_DIR}/sdk/tests/stroke_testing_utils.cpp
     TEST_NAME MoveStrokeTest
     LINK_LIBRARIES kritabasicflakes kritaui Qt5::Test
     NAME_PREFIX "plugins-tools-basictools-")



More information about the kimageshop mailing list