[calligra] krita: [FEATURE] Fixed painting and color picking on global selections

Dmitry Kazakov dimula73 at gmail.com
Thu Jun 19 15:01:59 UTC 2014


Git commit d6554e82ff3534f5986c5785edcb5663731ad2cb by Dmitry Kazakov.
Committed on 19/06/2014 at 14:46.
Pushed by dkazakov into branch 'master'.

[FEATURE] Fixed painting and color picking on global selections

This patch fixes three problems:

1) Painting on a global selection now is not recursively limited to
   the selected area of the selection itself. If current node and active
   selection mask are the same entity, KisResourcesSnapshot will report
   no selection active.

2) Color Picker can now pick from selection masks. Yes, it converts the
   color into compositionSourceColorSpace() to make it paintable.

3) The Color Picker's option widget now shows alpha value correctly,
   although the resource server gets opaque color.

CCMAIL:kimageshop at kde.org
BUG:336115

M  +9    -5    krita/plugins/tools/defaulttools/kis_tool_colorpicker.cc
M  +1    -1    krita/plugins/tools/defaulttools/kis_tool_fill.cc
M  +9    -9    krita/plugins/tools/defaulttools/kis_tool_gradient.cc
M  +6    -2    krita/plugins/tools/defaulttools/kis_tool_move.cc
M  +7    -2    krita/plugins/tools/tool_crop/kis_tool_crop.cc
M  +11   -4    krita/plugins/tools/tool_transform2/kis_tool_transform.cc
M  +20   -0    krita/ui/tool/kis_resources_snapshot.cpp
M  +8    -0    krita/ui/tool/kis_resources_snapshot.h
M  +7    -14   krita/ui/tool/kis_tool.cc
M  +0    -3    krita/ui/tool/kis_tool.h
M  +1    -1    krita/ui/tool/kis_tool_paint.cc
M  +1    -0    krita/ui/tool/kis_tool_utils.cpp
M  +1    -7    krita/ui/tool/strokes/kis_painter_based_stroke_strategy.cpp

http://commits.kde.org/calligra/d6554e82ff3534f5986c5785edcb5663731ad2cb

diff --git a/krita/plugins/tools/defaulttools/kis_tool_colorpicker.cc b/krita/plugins/tools/defaulttools/kis_tool_colorpicker.cc
index 23a9c68..37e964b 100644
--- a/krita/plugins/tools/defaulttools/kis_tool_colorpicker.cc
+++ b/krita/plugins/tools/defaulttools/kis_tool_colorpicker.cc
@@ -227,12 +227,16 @@ void KisToolColorPicker::pickColor(const QPointF& pos)
             delete[] data;
         }
 
-        m_pickedColor.setOpacity(OPACITY_OPAQUE_U8);
+        m_pickedColor.convertTo(dev->compositionSourceColorSpace());
         if (m_config.updateColor) {
-            if (m_config.toForegroundColor)
-                canvas()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, m_pickedColor);
-            else
-                canvas()->resourceManager()->setResource(KoCanvasResourceManager::BackgroundColor, m_pickedColor);
+            KoColor publicColor = m_pickedColor;
+            publicColor.setOpacity(OPACITY_OPAQUE_U8);
+
+            if (m_config.toForegroundColor) {
+                canvas()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, publicColor);
+            } else {
+                canvas()->resourceManager()->setResource(KoCanvasResourceManager::BackgroundColor, publicColor);
+            }
         }
 
         if (m_optionsWidget->cmbSources->currentIndex() == SAMPLE_MERGED) {
diff --git a/krita/plugins/tools/defaulttools/kis_tool_fill.cc b/krita/plugins/tools/defaulttools/kis_tool_fill.cc
index 36efa0d..af7d508 100644
--- a/krita/plugins/tools/defaulttools/kis_tool_fill.cc
+++ b/krita/plugins/tools/defaulttools/kis_tool_fill.cc
@@ -132,7 +132,7 @@ void KisToolFill::endPrimaryAction(KoPointerEvent *event)
 
     KisProcessingVisitorSP visitor =
         new FillProcessingVisitor(m_startPos,
-                                  currentSelection(),
+                                  resources->activeSelection(),
                                   resources,
                                   useFastMode,
                                   m_usePattern,
diff --git a/krita/plugins/tools/defaulttools/kis_tool_gradient.cc b/krita/plugins/tools/defaulttools/kis_tool_gradient.cc
index 6bed70b..13f26b4 100644
--- a/krita/plugins/tools/defaulttools/kis_tool_gradient.cc
+++ b/krita/plugins/tools/defaulttools/kis_tool_gradient.cc
@@ -57,9 +57,9 @@
 #include <widgets/kis_slider_spin_box.h>
 #include <kis_cursor.h>
 #include <kis_config.h>
-
 #include "kis_resources_snapshot.h"
 
+
 KisToolGradient::KisToolGradient(KoCanvasBase * canvas)
         : KisToolPaint(canvas, KisCursor::load("tool_gradient_cursor.png", 6, 6))
 {
@@ -143,19 +143,19 @@ void KisToolGradient::endPrimaryAction(KoPointerEvent *event)
     KisSystemLocker locker(currentNode());
 
     KisPaintDeviceSP device;
+    KisImageSP image = this->image();
 
-    if (currentImage() && (device = currentNode()->paintDevice())) {
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image, 0, this->canvas()->resourceManager());
+
+    if (image && (device = resources->currentNode()->paintDevice())) {
         qApp->setOverrideCursor(Qt::BusyCursor);
 
         KUndo2MagicString actionName = kundo2_i18n("Gradient");
-        KisUndoAdapter *undoAdapter = image()->undoAdapter();
+        KisUndoAdapter *undoAdapter = image->undoAdapter();
         undoAdapter->beginMacro(actionName);
 
-        KisGradientPainter painter(device, currentSelection());
-
-        KisResourcesSnapshotSP resources =
-            new KisResourcesSnapshot(image(), 0,
-                                     canvas()->resourceManager());
+        KisGradientPainter painter(device, resources->activeSelection());
         resources->setupPainter(&painter);
 
         painter.beginTransaction();
@@ -166,7 +166,7 @@ void KisToolGradient::endPrimaryAction(KoPointerEvent *event)
         updater->start(100, i18nc("@info:progress", "Gradient..."));
         painter.setProgress(updater->startSubtask());
 
-        painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, currentImage()->width(), currentImage()->height());
+        painter.paintGradient(m_startPos, m_endPos, m_shape, m_repeat, m_antiAliasThreshold, m_reverse, 0, 0, image->width(), image->height());
         painter.endTransaction(undoAdapter);
         undoAdapter->endMacro();
 
diff --git a/krita/plugins/tools/defaulttools/kis_tool_move.cc b/krita/plugins/tools/defaulttools/kis_tool_move.cc
index cdd3689..d3d67e9 100644
--- a/krita/plugins/tools/defaulttools/kis_tool_move.cc
+++ b/krita/plugins/tools/defaulttools/kis_tool_move.cc
@@ -34,6 +34,8 @@
 #include "strokes/move_stroke_strategy.h"
 #include "kis_tool_movetooloptionswidget.h"
 #include "strokes/move_selection_stroke_strategy.h"
+#include "kis_resources_snapshot.h"
+
 
 KisToolMove::KisToolMove(KoCanvasBase * canvas)
         :  KisTool(canvas, KisCursor::moveCursor())
@@ -134,14 +136,16 @@ void KisToolMove::startAction(KoPointerEvent *event, MoveToolMode mode)
     KisNodeSP node;
     KisImageSP image = this->image();
 
-    KisSelectionSP selection = currentSelection();
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image, 0, this->canvas()->resourceManager());
+    KisSelectionSP selection = resources->activeSelection();
 
     if (mode != MoveSelectedLayer) {
         bool wholeGroup = !selection &&  mode == MoveGroup;
         node = KisToolUtils::findNode(image->root(), pos, wholeGroup);
     }
 
-    if ((!node && !(node = currentNode())) || !node->isEditable()) {
+    if ((!node && !(node = resources->currentNode())) || !node->isEditable()) {
         event->ignore();
         return;
     }
diff --git a/krita/plugins/tools/tool_crop/kis_tool_crop.cc b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
index b4eabfb..8752a58 100644
--- a/krita/plugins/tools/tool_crop/kis_tool_crop.cc
+++ b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
@@ -51,6 +51,8 @@
 #include <kis_view2.h>
 #include <kis_floating_message.h>
 #include <kis_group_layer.h>
+#include <kis_resources_snapshot.h>
+
 
 struct DecorationLine
 {
@@ -134,7 +136,10 @@ void KisToolCrop::activate(ToolActivation toolActivation, const QSet<KoShape*> &
 {
     KisTool::activate(toolActivation, shapes);
 
-    KisSelectionSP sel = currentSelection();
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image(), 0, this->canvas()->resourceManager());
+
+    KisSelectionSP sel = resources->activeSelection();
     if (sel) {
         sel->updateProjection();
         m_rectCrop = sel->selectedExactRect();
@@ -145,7 +150,7 @@ void KisToolCrop::activate(ToolActivation toolActivation, const QSet<KoShape*> &
     updateCanvasPixelRect(image()->bounds());
 
     //pixel layer
-    if(currentNode() && currentNode()->paintDevice()) {
+    if(resources->currentNode() && resources->currentNode()->paintDevice()) {
         setCropTypeSelectable(true);
     }
     //vector layer
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
index b799842..49706f0 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
@@ -72,6 +72,7 @@
 #include <kis_selection_manager.h>
 #include <kis_system_locker.h>
 #include <krita_utils.h>
+#include <kis_resources_snapshot.h>
 
 #include <KoShapeTransformCommand.h>
 
@@ -2182,8 +2183,11 @@ void KisToolTransform::updateSelectionPath()
 {
     m_selectionPath = QPainterPath();
 
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image(), 0, this->canvas()->resourceManager());
+
     QPainterPath selectionOutline;
-    KisSelectionSP selection = currentSelection();
+    KisSelectionSP selection = resources->activeSelection();
 
     if (selection && selection->outlineCacheValid()) {
         selectionOutline = selection->outlineCache();
@@ -2280,7 +2284,10 @@ void KisToolTransform::startStroke(ToolTransformArgs::TransformMode mode)
 
     KisPaintDeviceSP dev;
 
-    KisNodeSP currentNode = this->currentNode();
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image(), 0, this->canvas()->resourceManager());
+
+    KisNodeSP currentNode = resources->currentNode();
 
     if (!currentNode || !currentNode->isEditable()) {
         return;
@@ -2306,10 +2313,10 @@ void KisToolTransform::startStroke(ToolTransformArgs::TransformMode mode)
             !currentNode->paintDevice();
     }
 
-    TransformStrokeStrategy *strategy = new TransformStrokeStrategy(currentNode, currentSelection(), image()->postExecutionUndoAdapter());
+    TransformStrokeStrategy *strategy = new TransformStrokeStrategy(currentNode, resources->activeSelection(), image()->postExecutionUndoAdapter());
     KisPaintDeviceSP previewDevice = strategy->previewDevice();
 
-    KisSelectionSP selection = currentSelection();
+    KisSelectionSP selection = resources->activeSelection();
     QRect srcRect = selection ? selection->selectedExactRect() : previewDevice->exactBounds();
 
     m_transaction = TransformTransactionProperties(srcRect, &m_currentArgs, currentNode);
diff --git a/krita/ui/tool/kis_resources_snapshot.cpp b/krita/ui/tool/kis_resources_snapshot.cpp
index a50cf94..3dbeebf 100644
--- a/krita/ui/tool/kis_resources_snapshot.cpp
+++ b/krita/ui/tool/kis_resources_snapshot.cpp
@@ -33,6 +33,9 @@
 #include "kis_paint_layer.h"
 #include "recorder/kis_recorded_paint_action.h"
 #include "kis_default_bounds.h"
+#include "kis_selection.h"
+#include "kis_selection_mask.h"
+
 
 struct KisResourcesSnapshot::Private {
     Private()
@@ -220,6 +223,23 @@ QString KisResourcesSnapshot::indirectPaintingCompositeOp() const
     return m_d->currentPaintOpPreset->settings()->indirectPaintingCompositeOp();
 }
 
+KisSelectionSP KisResourcesSnapshot::activeSelection() const
+{
+    KisSelectionSP selection = m_d->image->globalSelection();
+
+    KisLayerSP layer = dynamic_cast<KisLayer*>(m_d->currentNode.data());
+    KisSelectionMaskSP mask;
+    if((layer = dynamic_cast<KisLayer*>(m_d->currentNode.data()))) {
+        selection = layer->selection();
+    } else if ((mask = dynamic_cast<KisSelectionMask*>(m_d->currentNode.data())) &&
+               mask->selection() == selection) {
+
+        selection = 0;
+    }
+
+    return selection;
+}
+
 bool KisResourcesSnapshot::needsAirbrushing() const
 {
     return m_d->currentPaintOpPreset->settings()->isAirbrushing();
diff --git a/krita/ui/tool/kis_resources_snapshot.h b/krita/ui/tool/kis_resources_snapshot.h
index ea08f6d..95fd8a4 100644
--- a/krita/ui/tool/kis_resources_snapshot.h
+++ b/krita/ui/tool/kis_resources_snapshot.h
@@ -54,6 +54,14 @@ public:
     bool needsIndirectPainting() const;
     QString indirectPaintingCompositeOp() const;
 
+    /**
+     * \return currently active selection. Note that it will return
+     *         null if current node *is* the current selection. This
+     *         is done to avoid recursive selection application when
+     *         painting on selectgion masks.
+     */
+    KisSelectionSP activeSelection() const;
+
     bool needsAirbrushing() const;
     int airbrushingRate() const;
 
diff --git a/krita/ui/tool/kis_tool.cc b/krita/ui/tool/kis_tool.cc
index ac411a1..93539bf 100644
--- a/krita/ui/tool/kis_tool.cc
+++ b/krita/ui/tool/kis_tool.cc
@@ -70,6 +70,8 @@
 #include "kis_cursor.h"
 #include <recorder/kis_recorded_paint_action.h>
 #include <kis_selection_mask.h>
+#include "kis_resources_snapshot.h"
+
 
 struct KisTool::Private {
     Private()
@@ -370,18 +372,6 @@ QCursor KisTool::cursor() const
     return d->cursor;
 }
 
-KisSelectionSP KisTool::currentSelection() const
-{
-    KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
-    if (kisCanvas) {
-        KisView2 * view = kisCanvas->view();
-        if (view) return view->selection();
-    }
-
-    return 0;
-
-}
-
 void KisTool::notifyModified() const
 {
     if (image()) {
@@ -535,8 +525,11 @@ void KisTool::mouseMoveEvent(KoPointerEvent *event)
 
 void KisTool::deleteSelection()
 {
-    KisSelectionSP selection = currentSelection();
-    KisNodeSP node = currentNode();
+    KisResourcesSnapshotSP resources =
+        new KisResourcesSnapshot(image(), 0, this->canvas()->resourceManager());
+
+    KisSelectionSP selection = resources->activeSelection();
+    KisNodeSP node = resources->currentNode();
 
     if(node && node->hasEditablePaintDevice()) {
         KisPaintDeviceSP device = node->paintDevice();
diff --git a/krita/ui/tool/kis_tool.h b/krita/ui/tool/kis_tool.h
index f7bb57d..558fdc3 100644
--- a/krita/ui/tool/kis_tool.h
+++ b/krita/ui/tool/kis_tool.h
@@ -257,9 +257,6 @@ protected:
     KisImageWSP image() const;
     QCursor cursor() const;
 
-    /// @return the currently active selection
-    KisSelectionSP currentSelection() const;
-
     /// Call this to set the document modified
     void notifyModified() const;
 
diff --git a/krita/ui/tool/kis_tool_paint.cc b/krita/ui/tool/kis_tool_paint.cc
index c97f566..c209507 100644
--- a/krita/ui/tool/kis_tool_paint.cc
+++ b/krita/ui/tool/kis_tool_paint.cc
@@ -301,7 +301,7 @@ bool KisToolPaint::pickColor(const QPointF &documentPixel,
 
     KisPaintDeviceSP device;
     if (fromCurrentNode) {
-        device = currentNode()->projection();
+        device = currentNode()->paintDevice();
         if (!device) {
             device = currentNode()->projection();
         }
diff --git a/krita/ui/tool/kis_tool_utils.cpp b/krita/ui/tool/kis_tool_utils.cpp
index 82d5cfd..042ff9a 100644
--- a/krita/ui/tool/kis_tool_utils.cpp
+++ b/krita/ui/tool/kis_tool_utils.cpp
@@ -28,6 +28,7 @@ namespace KisToolUtils {
         KIS_ASSERT(dev);
         KoColor pickedColor;
         dev->pixel(pos.x(), pos.y(), &pickedColor);
+        pickedColor.convertTo(dev->compositionSourceColorSpace());
         pickedColor.setOpacity(OPACITY_OPAQUE_U8);
         return pickedColor;
     }
diff --git a/krita/ui/tool/strokes/kis_painter_based_stroke_strategy.cpp b/krita/ui/tool/strokes/kis_painter_based_stroke_strategy.cpp
index 7b7cecb..76de587 100644
--- a/krita/ui/tool/strokes/kis_painter_based_stroke_strategy.cpp
+++ b/krita/ui/tool/strokes/kis_painter_based_stroke_strategy.cpp
@@ -116,13 +116,7 @@ void KisPainterBasedStrokeStrategy::initStrokeCallback()
     KisPaintDeviceSP targetDevice = paintDevice;
     bool hasIndirectPainting = needsIndirectPainting();
 
-    KisSelectionSP selection;
-    KisLayerSP layer = dynamic_cast<KisLayer*>(node.data());
-    if(layer) {
-        selection = layer->selection();
-    } else {
-        selection = m_resources->image()->globalSelection();
-    }
+    KisSelectionSP selection = m_resources->activeSelection();
 
     if (hasIndirectPainting) {
         KisIndirectPaintingSupport *indirect =


More information about the kimageshop mailing list