[krita/kazakov/svg-loading] /: Implement correct selection and toggling of shapes according to the requirements

Dmitry Kazakov null at kde.org
Tue Dec 27 13:28:09 UTC 2016


Git commit 206cc497e452aa89afdd1e9a56a7d0c617a091b1 by Dmitry Kazakov.
Committed on 27/12/2016 at 13:26.
Pushed by dkazakov into branch 'kazakov/svg-loading'.

Implement correct selection and toggling of shapes according to the requirements

1) Shift + click --- toggles multiple shapes
2) Shift + drag --- *adds* shapes to the selection
3) Ctrl+drag --- toggles overlapping shapes
4) Alt+drag --- lets you start a rubber band on a shapes
                (disabled click-selection)

CC:kimageshop at kde.org

M  +3    -45   libs/flake/KoToolProxy.cpp
M  +1    -1    libs/flake/tools/KoShapeRubberSelectStrategy.cpp
M  +1    -1    libs/ui/input/kis_change_primary_setting_action.cpp
M  +45   -24   plugins/tools/defaulttool/defaulttool/DefaultTool.cpp

https://commits.kde.org/krita/206cc497e452aa89afdd1e9a56a7d0c617a091b1

diff --git a/libs/flake/KoToolProxy.cpp b/libs/flake/KoToolProxy.cpp
index 6426416712d..aae732b1096 100644
--- a/libs/flake/KoToolProxy.cpp
+++ b/libs/flake/KoToolProxy.cpp
@@ -327,21 +327,8 @@ void KoToolProxy::mouseDoubleClickEvent(KoPointerEvent *event)
 
 void KoToolProxy::mouseMoveEvent(QMouseEvent *event, const QPointF &point)
 {
-    if (d->mouseLeaveWorkaround) {
-        d->mouseLeaveWorkaround = false;
-        return;
-    }
-    KoInputDevice id;
-    KoToolManager::instance()->priv()->switchInputDevice(id);
-    if (d->activeTool == 0) {
-        event->ignore();
-        return;
-    }
-
     KoPointerEvent ev(event, point);
-    d->activeTool->mouseMoveEvent(&ev);
-
-    d->checkAutoScroll(ev);
+    mouseMoveEvent(&ev);
 }
 
 void KoToolProxy::mouseMoveEvent(KoPointerEvent *event)
@@ -364,38 +351,8 @@ void KoToolProxy::mouseMoveEvent(KoPointerEvent *event)
 
 void KoToolProxy::mouseReleaseEvent(QMouseEvent *event, const QPointF &point)
 {
-    d->mouseLeaveWorkaround = false;
-    KoInputDevice id;
-    KoToolManager::instance()->priv()->switchInputDevice(id);
-    d->scrollTimer.stop();
-
     KoPointerEvent ev(event, point);
-    if (d->activeTool) {
-        d->activeTool->mouseReleaseEvent(&ev);
-
-        if (! event->isAccepted() && event->button() == Qt::LeftButton && event->modifiers() == 0
-                && qAbs(d->mouseDownPoint.x() - event->x()) < 5
-                && qAbs(d->mouseDownPoint.y() - event->y()) < 5) {
-            // we potentially will change the selection
-            Q_ASSERT(d->activeTool->canvas());
-            KoShapeManager *manager = d->activeTool->canvas()->shapeManager();
-            Q_ASSERT(manager);
-            // only change the selection if that will not lead to losing a complex selection
-            if (manager->selection()->count() <= 1) {
-                KoShape *shape = manager->shapeAt(point);
-                if (shape && !manager->selection()->isSelected(shape)) { // make the clicked shape the active one
-                    manager->selection()->deselectAll();
-                    manager->selection()->select(shape);
-                    QList<KoShape*> shapes;
-                    shapes << shape;
-                    QString tool = KoToolManager::instance()->preferredToolForSelection(shapes);
-                    KoToolManager::instance()->switchToolRequested(tool);
-                }
-            }
-        }
-    } else {
-        event->ignore();
-    }
+    mouseReleaseEvent(&ev);
 }
 
 void KoToolProxy::mouseReleaseEvent(KoPointerEvent* event)
@@ -408,6 +365,7 @@ void KoToolProxy::mouseReleaseEvent(KoPointerEvent* event)
     if (d->activeTool) {
         d->activeTool->mouseReleaseEvent(event);
 
+        // FIXME: What happens here??!!!!
         if (!event->isAccepted() && event->button() == Qt::LeftButton && event->modifiers() == 0
                 && qAbs(d->mouseDownPoint.x() - event->x()) < 5
                 && qAbs(d->mouseDownPoint.y() - event->y()) < 5) {
diff --git a/libs/flake/tools/KoShapeRubberSelectStrategy.cpp b/libs/flake/tools/KoShapeRubberSelectStrategy.cpp
index 727c5d5d6c0..458c3b90d9f 100644
--- a/libs/flake/tools/KoShapeRubberSelectStrategy.cpp
+++ b/libs/flake/tools/KoShapeRubberSelectStrategy.cpp
@@ -69,7 +69,7 @@ void KoShapeRubberSelectStrategy::handleMouseMove(const QPointF &p, Qt::Keyboard
 {
     Q_D(KoShapeRubberSelectStrategy);
     QPointF point = d->snapGuide->snap(p, modifiers);
-    if (modifiers & Qt::AltModifier || modifiers & Qt::ControlModifier) {
+    if (modifiers & Qt::ControlModifier) {
         d->tool->canvas()->updateCanvas(d->selectedRect());
         d->selectRect.moveTopLeft(d->selectRect.topLeft() - (d->lastPos - point));
         d->lastPos = point;
diff --git a/libs/ui/input/kis_change_primary_setting_action.cpp b/libs/ui/input/kis_change_primary_setting_action.cpp
index 98b5d9552d7..95bf5c16ab4 100644
--- a/libs/ui/input/kis_change_primary_setting_action.cpp
+++ b/libs/ui/input/kis_change_primary_setting_action.cpp
@@ -81,7 +81,7 @@ void KisChangePrimarySettingAction::end(QEvent *event)
 void KisChangePrimarySettingAction::inputEvent(QEvent* event)
 {
     if (event && (event->type() == QEvent::MouseMove || event->type() == QEvent::TabletMove)) {
-        QMouseEvent targetEvent(QEvent::MouseButtonRelease, eventPos(event), Qt::NoButton, Qt::LeftButton, Qt::ShiftModifier);
+        QMouseEvent targetEvent(QEvent::MouseMove, eventPos(event), Qt::NoButton, Qt::LeftButton, Qt::ShiftModifier);
         inputManager()->toolProxy()->forwardEvent(KisToolProxy::CONTINUE, KisTool::AlternateChangeSize, &targetEvent, event);
     }
 }
diff --git a/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp b/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
index 5ff793506d7..b3b2b406dfa 100644
--- a/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
+++ b/plugins/tools/defaulttool/defaulttool/DefaultTool.cpp
@@ -115,8 +115,34 @@ public:
 
     void handleMouseMove(const QPointF & /*mouseLocation*/, Qt::KeyboardModifiers /*modifiers*/) override {}
     void finishInteraction(Qt::KeyboardModifiers /*modifiers*/) override {}
+
+    void paint(QPainter &painter, const KoViewConverter &converter) {
+        SelectionDecorator decorator(KoFlake::NoHandle, false, false);
+        decorator.setSelection(tool()->canvas()->shapeManager()->selection());
+        decorator.setHandleRadius(handleRadius());
+        decorator.paint(painter, converter);
+    }
+};
+
+class SelectionInteractionStrategy : public KoShapeRubberSelectStrategy
+{
+public:
+    explicit SelectionInteractionStrategy(KoToolBase *parent, const QPointF &clicked, bool useSnapToGrid)
+        : KoShapeRubberSelectStrategy(parent, clicked, useSnapToGrid)
+    {
+    }
+
+    void paint(QPainter &painter, const KoViewConverter &converter) {
+        SelectionDecorator decorator(KoFlake::NoHandle, false, false);
+        decorator.setSelection(tool()->canvas()->shapeManager()->selection());
+        decorator.setHandleRadius(handleRadius());
+        decorator.paint(painter, converter);
+
+        KoShapeRubberSelectStrategy::paint(painter, converter);
+    }
 };
 
+
 class SelectionHandler : public KoToolSelection
 {
 public:
@@ -1023,7 +1049,9 @@ QList<QPointer<QWidget> > DefaultTool::createOptionWidgets()
 void DefaultTool::canvasResourceChanged(int key, const QVariant &res)
 {
     if (key == HotPosition) {
+
         m_hotPosition = static_cast<KoFlake::Position>(res.toInt());
+        ENTER_FUNCTION() << ppVar(m_hotPosition);
         repaintDecorations();
     }
 }
@@ -1042,8 +1070,11 @@ KoInteractionStrategy *DefaultTool::createStrategy(KoPointerEvent *event)
 
     bool editableShape = editableShapesCount(selection->selectedShapes());
 
-    // TODO: use modifiers instead
-    if (event->buttons() & Qt::MidButton) {
+    const bool selectMultiple = event->modifiers() & Qt::ShiftModifier;
+    const bool selectNextInStack = event->modifiers() & Qt::ControlModifier;
+    const bool avoidSelection = event->modifiers() & Qt::AltModifier;
+
+    if (selectNextInStack) {
         // change the hot selection position when middle clicking on a handle
         KoFlake::Position newHotPosition = m_hotPosition;
         switch (handle) {
@@ -1075,28 +1106,22 @@ KoInteractionStrategy *DefaultTool::createStrategy(KoPointerEvent *event)
         }
         if (m_hotPosition != newHotPosition) {
             canvas()->resourceManager()->setResource(HotPosition, newHotPosition);
+            return new NopInteractionStrategy(this);
         }
-        return 0;
     }
 
-    bool selectMultiple = event->modifiers() & Qt::ControlModifier;
-    bool selectNextInStack = event->modifiers() & Qt::ShiftModifier;
-
-    if (editableShape) {
-
+    if (!avoidSelection && editableShape) {
         // manipulation of selected shapes goes first
         if (handle != KoFlake::NoHandle) {
-            if (event->buttons() == Qt::LeftButton) {
-                // resizing or shearing only with left mouse button
-                if (insideSelection) {
-                    return new ShapeResizeStrategy(this, event->point, handle);
-                }
+            // resizing or shearing only with left mouse button
+            if (insideSelection) {
+                return new ShapeResizeStrategy(this, event->point, handle);
+            }
 
-                if (handle == KoFlake::TopMiddleHandle || handle == KoFlake::RightMiddleHandle ||
-                        handle == KoFlake::BottomMiddleHandle || handle == KoFlake::LeftMiddleHandle) {
+            if (handle == KoFlake::TopMiddleHandle || handle == KoFlake::RightMiddleHandle ||
+                handle == KoFlake::BottomMiddleHandle || handle == KoFlake::LeftMiddleHandle) {
 
-                    return new ShapeShearStrategy(this, event->point, handle);
-                }
+                return new ShapeShearStrategy(this, event->point, handle);
             }
 
             // rotating is allowed for rigth mouse button too
@@ -1107,25 +1132,21 @@ KoInteractionStrategy *DefaultTool::createStrategy(KoPointerEvent *event)
             }
         }
 
-        if (!(selectMultiple || selectNextInStack) && event->buttons() == Qt::LeftButton) {
+        if (!selectMultiple && !selectNextInStack) {
             if (insideSelection) {
                 return new ShapeMoveStrategy(this, event->point);
             }
         }
     }
 
-    if ((event->buttons() & Qt::LeftButton) == 0) {
-        return 0;    // Nothing to do for middle/right mouse button
-    }
-
     KoShape *shape = shapeManager->shapeAt(event->point, selectNextInStack ? KoFlake::NextUnselected : KoFlake::ShapeOnTop);
 
-    if (!shape && handle == KoFlake::NoHandle) {
+    if (avoidSelection || (!shape && handle == KoFlake::NoHandle)) {
         if (!selectMultiple) {
             repaintDecorations();
             selection->deselectAll();
         }
-        return new KoShapeRubberSelectStrategy(this, event->point);
+        return new SelectionInteractionStrategy(this, event->point, false);
     }
 
     if (selection->isSelected(shape)) {


More information about the kimageshop mailing list