[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