[krita/krita/3.1] /: [FEATURE] Allow deselection by clicking with a selection tool

Dmitry Kazakov null at kde.org
Wed Jan 4 10:10:30 UTC 2017


Git commit 5913c435be223cd89cdeebd9334f365c3cb2cee8 by Dmitry Kazakov.
Committed on 04/01/2017 at 10:10.
Pushed by dkazakov into branch 'krita/3.1'.

[FEATURE] Allow deselection by clicking with a selection tool

1) Now you can deselect with *any* selection tool:
   rectangular, elliptical, outline.

2) Now you can also deselect with your tablet stylus,
   because there is a small tolerance level for
   considering your new selection as a click. If you made
   a selection that is smaller than 5 (view) pixels, then
   it is considered as a click and the tool deselects
   everything.

3) One can configure the click-tolerance level with a
   config option 'SelectionViewSizeMinimum'

CC:kimageshop at kde.org

# Conflicts:
#	libs/image/kis_algebra_2d.h

M  +29   -1    libs/image/kis_algebra_2d.h
M  +10   -0    libs/ui/kis_config.cc
M  +3    -0    libs/ui/kis_config.h
M  +18   -0    libs/ui/tool/kis_selection_tool_helper.cpp
M  +3    -1    libs/ui/tool/kis_selection_tool_helper.h
M  +3    -6    plugins/tools/selectiontools/kis_tool_select_elliptical.cc
M  +12   -2    plugins/tools/selectiontools/kis_tool_select_outline.cc
M  +1    -4    plugins/tools/selectiontools/kis_tool_select_rectangular.cc

https://commits.kde.org/krita/5913c435be223cd89cdeebd9334f365c3cb2cee8

diff --git a/libs/image/kis_algebra_2d.h b/libs/image/kis_algebra_2d.h
index 4e48e8e3c24..ffdb84a62f1 100644
--- a/libs/image/kis_algebra_2d.h
+++ b/libs/image/kis_algebra_2d.h
@@ -41,6 +41,7 @@ struct PointTypeTraits<QPoint>
 {
     typedef int value_type;
     typedef qreal calculation_type;
+    typedef QRect rect_type;
 };
 
 template <>
@@ -48,6 +49,7 @@ struct PointTypeTraits<QPointF>
 {
     typedef qreal value_type;
     typedef qreal calculation_type;
+    typedef QRectF rect_type;
 };
 
 
@@ -201,6 +203,27 @@ inline void accumulateBounds(const Point &pt, Rect *bounds)
     }
 }
 
+template <template <class T> class Container, class Point, class Rect>
+inline void accumulateBounds(const Container<Point> &points, Rect *bounds)
+{
+    Q_FOREACH (const Point &pt, points) {
+        accumulateBounds(pt, bounds);
+    }
+}
+
+template <template <class T> class Container, class Point>
+inline typename PointTypeTraits<Point>::rect_type
+accumulateBounds(const Container<Point> &points)
+{
+    typename PointTypeTraits<Point>::rect_type result;
+
+    Q_FOREACH (const Point &pt, points) {
+        accumulateBounds(pt, &result);
+    }
+
+    return result;
+}
+
 template <class Point, class Rect>
 inline Point clampPoint(Point pt, const Rect &bounds)
 {
@@ -223,7 +246,12 @@ inline Point clampPoint(Point pt, const Rect &bounds)
     return pt;
 }
 
-QPainterPath KRITAIMAGE_EXPORT smallArrow();
+template <class Size>
+auto maxDimension(Size size) -> decltype(size.width()) {
+    return qMax(size.width(), size.height());
+}
+
+QPainterPath KRITAGLOBAL_EXPORT smallArrow();
 
 /**
  * Multiply width and height of \p rect by \p coeff keeping the
diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc
index a65a3722874..252791b5217 100644
--- a/libs/ui/kis_config.cc
+++ b/libs/ui/kis_config.cc
@@ -918,6 +918,16 @@ void KisConfig::setOutlineSizeMinimum(qreal outlineSizeMinimum) const
     m_cfg.writeEntry("OutlineSizeMinimum", outlineSizeMinimum);
 }
 
+qreal KisConfig::selectionViewSizeMinimum(bool defaultValue) const
+{
+    return (defaultValue ? 5.0 : m_cfg.readEntry("SelectionViewSizeMinimum", 5.0));
+}
+
+void KisConfig::setSelectionViewSizeMinimum(qreal outlineSizeMinimum) const
+{
+    m_cfg.writeEntry("SelectionViewSizeMinimum", outlineSizeMinimum);
+}
+
 int KisConfig::autoSaveInterval(bool defaultValue)  const
 {
     return (defaultValue ? KisDocument::defaultAutoSave() : m_cfg.readEntry("AutoSaveInterval", KisDocument::defaultAutoSave()));
diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h
index fff75bfee0c..7736fe101d7 100644
--- a/libs/ui/kis_config.h
+++ b/libs/ui/kis_config.h
@@ -239,6 +239,9 @@ public:
     qreal outlineSizeMinimum(bool defaultValue = false) const;
     void setOutlineSizeMinimum(qreal outlineSizeMinimum) const;
 
+    qreal selectionViewSizeMinimum(bool defaultValue = false) const;
+    void setSelectionViewSizeMinimum(qreal outlineSizeMinimum) const;
+
     int autoSaveInterval(bool defaultValue = false) const;
     void setAutoSaveInterval(int seconds) const;
 
diff --git a/libs/ui/tool/kis_selection_tool_helper.cpp b/libs/ui/tool/kis_selection_tool_helper.cpp
index 85f33853e19..db14dc4223d 100644
--- a/libs/ui/tool/kis_selection_tool_helper.cpp
+++ b/libs/ui/tool/kis_selection_tool_helper.cpp
@@ -41,6 +41,9 @@
 #include "kis_command_utils.h"
 #include "commands/kis_deselect_global_selection_command.h"
 
+#include "kis_algebra_2d.h"
+#include "kis_config.h"
+
 
 KisSelectionToolHelper::KisSelectionToolHelper(KisCanvas2* canvas, const KUndo2MagicString& name)
         : m_canvas(canvas)
@@ -243,3 +246,18 @@ void KisSelectionToolHelper::cropPathIfNeeded(QPainterPath *path)
         *path &= cropPath;
     }
 }
+
+bool KisSelectionToolHelper::tryDeselectCurrentSelection(const QRectF selectionViewRect, SelectionAction action)
+{
+    bool result = false;
+
+    if (KisAlgebra2D::maxDimension(selectionViewRect) < KisConfig().selectionViewSizeMinimum() &&
+        (action == SELECTION_INTERSECT || action == SELECTION_REPLACE)) {
+
+        // Queueing this action to ensure we avoid a race condition when unlocking the node system
+        QTimer::singleShot(0, m_canvas->viewManager()->selectionManager(), SLOT(deselect()));
+        result = true;
+    }
+
+    return result;
+}
diff --git a/libs/ui/tool/kis_selection_tool_helper.h b/libs/ui/tool/kis_selection_tool_helper.h
index 326e9ad147f..a469699fa7f 100644
--- a/libs/ui/tool/kis_selection_tool_helper.h
+++ b/libs/ui/tool/kis_selection_tool_helper.h
@@ -46,9 +46,11 @@ public:
     bool canShortcutToNoop(const QRect &rect, SelectionAction action);
     void cropPathIfNeeded(QPainterPath *path);
 
+    bool tryDeselectCurrentSelection(const QRectF selectionViewRect, SelectionAction action);
+
 private:
     KisCanvas2* m_canvas;
-    KisImageWSP m_image;
+    KisImageSP m_image;
     KisLayerSP m_layer;
     KUndo2MagicString m_name;
 };
diff --git a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
index 1d03b474068..f61b8a0db09 100644
--- a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
@@ -48,15 +48,12 @@ void __KisToolSelectEllipticalLocal::finishRect(const QRectF &rect)
     KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
     Q_ASSERT(kisCanvas);
 
-    // If the user just clicks on the canvas deselect
-    if (rect.isEmpty()) {
-        // Queueing this action to ensure we avoid a race condition when unlocking the node system
-        QTimer::singleShot(0, kisCanvas->viewManager()->selectionManager(), SLOT(deselect()));
+    KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select Ellipse"));
+
+    if (helper.tryDeselectCurrentSelection(pixelToView(rect), selectionAction())) {
         return;
     }
 
-    KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select Ellipse"));
-
     if (selectionMode() == PIXEL_SELECTION) {
         KisPixelSelectionSP tmpSel = new KisPixelSelection();
 
diff --git a/plugins/tools/selectiontools/kis_tool_select_outline.cc b/plugins/tools/selectiontools/kis_tool_select_outline.cc
index e938325bace..2dce8835b28 100644
--- a/plugins/tools/selectiontools/kis_tool_select_outline.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_outline.cc
@@ -52,6 +52,9 @@
 #include "kis_pixel_selection.h"
 #include "kis_selection_tool_helper.h"
 
+#include "kis_algebra_2d.h"
+
+
 #define FEEDBACK_LINE_WIDTH 2
 
 
@@ -151,10 +154,17 @@ void KisToolSelectOutline::finishSelectionAction()
     KIS_ASSERT_RECOVER_RETURN(kisCanvas);
     kisCanvas->updateCanvas();
 
-    if (m_points.count() > 2) {
+    QRectF boundingViewRect =
+        pixelToView(KisAlgebra2D::accumulateBounds(m_points));
+
+    KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select by Outline"));
+
+    if (m_points.count() > 2 &&
+        !helper.tryDeselectCurrentSelection(boundingViewRect, selectionAction())) {
+
         QApplication::setOverrideCursor(KisCursor::waitCursor());
 
-        KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select by Outline"));
+
 
         if (selectionMode() == PIXEL_SELECTION) {
 
diff --git a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
index 38fb73c9b19..5e77277ca69 100644
--- a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
@@ -55,10 +55,7 @@ void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect)
     QRect rc(rect.normalized().toRect());
     helper.cropRectIfNeeded(&rc, selectionAction());
 
-    // If the user just clicks on the canvas deselect
-    if (helper.canShortcutToDeselect(rc, selectionAction())) {
-        // Queueing this action to ensure we avoid a race condition when unlocking the node system
-        QTimer::singleShot(0, kisCanvas->viewManager()->selectionManager(), SLOT(deselect()));
+    if (helper.tryDeselectCurrentSelection(pixelToView(rc), selectionAction())) {
         return;
     }
 



More information about the kimageshop mailing list