[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    [krita] /: FEATURE: move selection with any selection tool
From:       Dmitry Kazakov <null () kde ! org>
Date:       2018-09-04 9:40:36
Message-ID: E1fx7p6-00060I-9t () code ! kde ! org
[Download RAW message or body]

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@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-")


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic