[krita] /: Implement Ctrl+click shortcuts for selecting opaque pixels on a layer

Git commit 09ce1d040f3ad9f3dc1a2d7185639b06d4c50fb3 by Dmitry Kazakov. Committed on 22/08/2018 at 11:19. Pushed by dkazakov into branch 'master'. Implement Ctrl+click shortcuts for selecting opaque pixels on a layer Now one can click on a layer's thumbnail in the Layers docker to have all the opaque pixels selected. * ctrl+click --- replace selection * ctrl+shift+click --- add selection * ctrl+alt+click --- subtract selection * ctrl+shift+alt+click --- intersect selection CC:kimageshop at kde.org CCBUG:346892 A +18 -0 libs/image/KisSelectionTags.h [License: UNKNOWN] * M +1 -12 libs/image/kis_selection.h M +12 -2 libs/libqml/plugins/kritasketchplugin/models/LayerModel.cpp M +1 -0 libs/ui/CMakeLists.txt M +40 -2 libs/ui/KisNodeDelegate.cpp M +1 -1 libs/ui/KisNodeDelegate.h A +15 -0 libs/ui/KisSelectionActionsAdapter.cpp [License: UNKNOWN] * A +21 -0 libs/ui/KisSelectionActionsAdapter.h [License: UNKNOWN] * M +1 -1 libs/ui/kis_node_filter_proxy_model.cpp M +18 -2 libs/ui/kis_node_model.cpp M +15 -3 libs/ui/kis_node_model.h M +71 -0 libs/ui/kis_selection_manager.cc M +3 -0 libs/ui/kis_selection_manager.h M +2 -2 libs/ui/tests/kis_model_index_converter_test.cpp M +5 -5 libs/ui/tests/kis_node_model_test.cpp M +1 -1 libs/ui/tests/kis_node_view_test.cpp M +12 -2 plugins/dockers/defaultdockers/kis_layer_box.cpp M +2 -0 plugins/dockers/defaultdockers/kis_layer_box.h M +4 -58 plugins/extensions/colorrange/colorrange.cc M +0 -6 plugins/extensions/colorrange/colorrange.h The files marked with a * at the end have a non valid license. Please read: https://community.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page. https://commits.kde.org/krita/09ce1d040f3ad9f3dc1a2d7185639b06d4c50fb3 diff --git a/libs/image/KisSelectionTags.h b/libs/image/KisSelectionTags.h new file mode 100644 index 00000000000..8558af5f00f --- /dev/null +++ b/libs/image/KisSelectionTags.h @@ -0,0 +1,18 @@ +#ifndef KISSELECTIONTAGS_H +#define KISSELECTIONTAGS_H + + +enum SelectionMode { + PIXEL_SELECTION, + SHAPE_PROTECTION +}; + +enum SelectionAction { + SELECTION_REPLACE, + SELECTION_ADD, + SELECTION_SUBTRACT, + SELECTION_INTERSECT, + SELECTION_DEFAULT +}; + +#endif // KISSELECTIONTAGS_H diff --git a/libs/image/kis_selection.h b/libs/image/kis_selection.h index e72a7f028a1..48930d815e3 100644 --- a/libs/image/kis_selection.h +++ b/libs/image/kis_selection.h @@ -25,18 +25,7 @@ #include "kis_default_bounds.h" #include "kis_image.h" -enum SelectionMode { - PIXEL_SELECTION, - SHAPE_PROTECTION -}; - -enum SelectionAction { - SELECTION_REPLACE, - SELECTION_ADD, - SELECTION_SUBTRACT, - SELECTION_INTERSECT, - SELECTION_DEFAULT -}; +#include "KisSelectionTags.h" #include "kis_pixel_selection.h" diff --git a/libs/libqml/plugins/kritasketchplugin/models/LayerModel.cpp b/libs/libqml/plugins/kritasketchplugin/models/LayerModel.cpp index 2c13f720b19..6ce5a76e8bf 100644 --- a/libs/libqml/plugins/kritasketchplugin/models/LayerModel.cpp +++ b/libs/libqml/plugins/kritasketchplugin/models/LayerModel.cpp @@ -42,6 +42,7 @@ #include <KoProperties.h> #include <QQmlEngine> #include <kis_base_node.h> +#include "KisSelectionActionsAdapter.h" struct LayerModelMetaInfo { LayerModelMetaInfo() @@ -94,6 +95,7 @@ public: bool aboutToRemoveRoots; KisViewManager* view; KisCanvas2* canvas; + QScopedPointer<KisSelectionActionsAdapter> selectionActionsAdapter; QPointer<KisNodeManager> nodeManager; KisImageWSP image; KisNodeSP activeNode; @@ -266,7 +268,8 @@ void LayerModel::setView(QObject *newView) d->layers.clear(); d->activeNode.clear(); d->canvas = 0; - d->nodeModel->setDummiesFacade(0, 0, 0, 0, 0); + d->nodeModel->setDummiesFacade(0, 0, 0, 0, 0, 0); + d->selectionActionsAdapter.reset(); } @@ -288,7 +291,14 @@ void LayerModel::setView(QObject *newView) KisDummiesFacadeBase *kritaDummiesFacade = dynamic_cast<KisDummiesFacadeBase*>(d->canvas->imageView()->document()->shapeController()); KisShapeController *shapeController = dynamic_cast<KisShapeController*>(d->canvas->imageView()->document()->shapeController()); - d->nodeModel->setDummiesFacade(kritaDummiesFacade, d->image, shapeController, d->nodeManager->nodeSelectionAdapter(), d->nodeManager->nodeInsertionAdapter()); + + d->selectionActionsAdapter.reset(new KisSelectionActionsAdapter(d->canvas->viewManager()->selectionManager())); + d->nodeModel->setDummiesFacade(kritaDummiesFacade, + d->image, + shapeController, + d->nodeManager->nodeSelectionAdapter(), + d->nodeManager->nodeInsertionAdapter(), + d->selectionActionsAdapter.data()); connect(d->image, SIGNAL(sigAboutToBeDeleted()), SLOT(notifyImageDeleted())); connect(d->image, SIGNAL(sigNodeChanged(KisNodeSP)), SLOT(nodeChanged(KisNodeSP))); diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index e09778b4073..d829b68381c 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -140,6 +140,7 @@ set(kritaui_LIB_SRCS KisSelectedShapesProxy.cpp kis_selection_decoration.cc kis_selection_manager.cc + KisSelectionActionsAdapter.cpp kis_statusbar.cc kis_zoom_manager.cc kis_favorite_resource_manager.cpp diff --git a/libs/ui/KisNodeDelegate.cpp b/libs/ui/KisNodeDelegate.cpp index 328e38abc49..0e73f9ba793 100644 --- a/libs/ui/KisNodeDelegate.cpp +++ b/libs/ui/KisNodeDelegate.cpp @@ -264,11 +264,24 @@ void KisNodeDelegate::drawFrame(QPainter *p, const QStyleOptionViewItem &option, p->setPen(oldPen); } -void KisNodeDelegate::drawThumbnail(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const +QRect KisNodeDelegate::thumbnailClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const { - KisNodeViewColorScheme scm; + Q_UNUSED(index); + const int steps = 0; + KisNodeViewColorScheme scm; + return QRect(scm.border() + + 2 * scm.visibilityMargin() + scm.visibilitySize() + + scm.border() + steps * scm.indentation(), + scm.border() + option.rect.top(), + 2 * scm.thumbnailMargin() + scm.thumbnailSize(), + scm.rowHeight() - scm.border()); +} + +void KisNodeDelegate::drawThumbnail(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + KisNodeViewColorScheme scm; const int thumbSize = scm.thumbnailSize(); const qreal oldOpacity = p->opacity(); // remember previous opacity @@ -686,6 +699,9 @@ bool KisNodeDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, cons const bool leftButton = mouseEvent->buttons() & Qt::LeftButton; + const QRect thumbnailRect = thumbnailClickRect(option, index); + const bool thumbnailClicked = thumbnailRect.contains(mouseEvent->pos()); + if (leftButton && iconsClicked) { KisBaseNode::PropertyList props = index.data(KisNodeModel::PropertiesRole).value<KisBaseNode::PropertyList>(); QList<OptionalProperty> realProps = d->rightmostProperties(props); @@ -717,6 +733,28 @@ bool KisNodeDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, cons if (isExpandable) { bool isExpanded = d->view->isExpanded(index); d->view->setExpanded(index, !isExpanded); + } + return true; + } else if (leftButton && thumbnailClicked) { + bool hasCorrectModifier = false; + SelectionAction action = SELECTION_REPLACE; + + if (mouseEvent->modifiers() == Qt::ControlModifier) { + action = SELECTION_REPLACE; + hasCorrectModifier = true; + } else if (mouseEvent->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) { + action = SELECTION_ADD; + hasCorrectModifier = true; + } else if (mouseEvent->modifiers() == (Qt::ControlModifier | Qt::AltModifier)) { + action = SELECTION_SUBTRACT; + hasCorrectModifier = true; + } else if (mouseEvent->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier | Qt::AltModifier)) { + action = SELECTION_INTERSECT; + hasCorrectModifier = true; + } + + if (hasCorrectModifier) { + model->setData(index, QVariant(int(action)), KisNodeModel::SelectOpaqueRole); return true; } } diff --git a/libs/ui/KisNodeDelegate.h b/libs/ui/KisNodeDelegate.h index cdf6c5e73c1..ad53f443e19 100644 --- a/libs/ui/KisNodeDelegate.h +++ b/libs/ui/KisNodeDelegate.h @@ -54,7 +54,6 @@ public: protected: bool eventFilter(QObject *object, QEvent *event) override; - private: typedef KisNodeModel Model; typedef KisNodeView View; @@ -74,6 +73,7 @@ private: void drawIcons(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; QRect visibilityClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; QRect decorationClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; + QRect thumbnailClickRect(const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawVisibilityIconHijack(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawDecoration(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; void drawExpandButton(QPainter *p, const QStyleOptionViewItem &option, const QModelIndex &index) const; diff --git a/libs/ui/KisSelectionActionsAdapter.cpp b/libs/ui/KisSelectionActionsAdapter.cpp new file mode 100644 index 00000000000..63834378969 --- /dev/null +++ b/libs/ui/KisSelectionActionsAdapter.cpp @@ -0,0 +1,15 @@ +#include "KisSelectionActionsAdapter.h" + +#include "kis_selection_manager.h" + + +KisSelectionActionsAdapter::KisSelectionActionsAdapter(KisSelectionManager *selectionManager) + : m_selectionManager(selectionManager) +{ +} + +void KisSelectionActionsAdapter::selectOpaqueOnNode(KisNodeSP node, SelectionAction action) +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_selectionManager); + m_selectionManager->selectOpaqueOnNode(node, action); +} diff --git a/libs/ui/KisSelectionActionsAdapter.h b/libs/ui/KisSelectionActionsAdapter.h new file mode 100644 index 00000000000..ae70736d392 --- /dev/null +++ b/libs/ui/KisSelectionActionsAdapter.h @@ -0,0 +1,21 @@ +#ifndef KISSELECTIONACTIONSADAPTER_H +#define KISSELECTIONACTIONSADAPTER_H + +#include "kritaui_export.h" +#include "kis_types.h" +#include "KisSelectionTags.h" + +class KisSelectionManager; + + +class KRITAUI_EXPORT KisSelectionActionsAdapter +{ +public: + KisSelectionActionsAdapter(KisSelectionManager *selectionManager); + void selectOpaqueOnNode(KisNodeSP node, SelectionAction action); + +private: + KisSelectionManager *m_selectionManager; +}; + +#endif // KISSELECTIONACTIONSADAPTER_H diff --git a/libs/ui/kis_node_filter_proxy_model.cpp b/libs/ui/kis_node_filter_proxy_model.cpp index 083741e1af1..8686863b7a8 100644 --- a/libs/ui/kis_node_filter_proxy_model.cpp +++ b/libs/ui/kis_node_filter_proxy_model.cpp @@ -163,7 +163,7 @@ void KisNodeFilterProxyModel::slotUpdateCurrentNodeFilter() void KisNodeFilterProxyModel::unsetDummiesFacade() { - m_d->nodeModel->setDummiesFacade(0, 0, 0, 0, 0); + m_d->nodeModel->setDummiesFacade(0, 0, 0, 0, 0, 0); m_d->pendingActiveNode = 0; m_d->activeNode = 0; } diff --git a/libs/ui/kis_node_model.cpp b/libs/ui/kis_node_model.cpp index 916d3f9ed30..4938070cdb0 100644 --- a/libs/ui/kis_node_model.cpp +++ b/libs/ui/kis_node_model.cpp @@ -48,6 +48,7 @@ #include "kis_model_index_converter_show_all.h" #include "kis_node_selection_adapter.h" #include "kis_node_insertion_adapter.h" +#include <KisSelectionActionsAdapter.h> #include "kis_config.h" #include "kis_config_notifier.h" @@ -60,6 +61,7 @@ struct KisNodeModel::Private KisShapeController *shapeController = 0; KisNodeSelectionAdapter *nodeSelectionAdapter = 0; KisNodeInsertionAdapter *nodeInsertionAdapter = 0; + KisSelectionActionsAdapter *selectionActionsAdapter = 0; QList<KisNodeDummy*> updateQueue; QTimer updateTimer; @@ -252,7 +254,12 @@ void KisNodeModel::connectDummies(KisNodeDummy *dummy, bool needConnect) } } -void KisNodeModel::setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, KisImageWSP image, KisShapeController *shapeController, KisNodeSelectionAdapter *nodeSelectionAdapter, KisNodeInsertionAdapter *nodeInsertionAdapter) +void KisNodeModel::setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, + KisImageWSP image, + KisShapeController *shapeController, + KisNodeSelectionAdapter *nodeSelectionAdapter, + KisNodeInsertionAdapter *nodeInsertionAdapter, + KisSelectionActionsAdapter *selectionActionsAdapter) { QPointer<KisDummiesFacadeBase> oldDummiesFacade(m_d->dummiesFacade); KisShapeController *oldShapeController = m_d->shapeController; @@ -260,6 +267,7 @@ void KisNodeModel::setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, KisImag m_d->shapeController = shapeController; m_d->nodeSelectionAdapter = nodeSelectionAdapter; m_d->nodeInsertionAdapter = nodeInsertionAdapter; + m_d->selectionActionsAdapter = selectionActionsAdapter; if (oldDummiesFacade && m_d->image) { m_d->image->disconnect(this); @@ -558,6 +566,7 @@ bool KisNodeModel::setData(const QModelIndex &index, const QVariant &value, int if(!m_d->dummiesFacade || !index.isValid()) return false; bool result = true; + bool shouldUpdate = true; bool shouldUpdateRecursively = false; KisNodeSP node = nodeFromIndex(index); @@ -575,11 +584,18 @@ bool KisNodeModel::setData(const QModelIndex &index, const QVariant &value, int break; } + case KisNodeModel::SelectOpaqueRole: + if (node && m_d->selectionActionsAdapter) { + SelectionAction action = SelectionAction(value.toInt()); + m_d->selectionActionsAdapter->selectOpaqueOnNode(node, action); + } + shouldUpdate = false; + break; default: result = false; } - if(result) { + if (result && shouldUpdate) { if (shouldUpdateRecursively) { QSet<QModelIndex> indexes; addChangedIndex(index, &indexes); diff --git a/libs/ui/kis_node_model.h b/libs/ui/kis_node_model.h index 7d737af260f..52e4e3146cb 100644 --- a/libs/ui/kis_node_model.h +++ b/libs/ui/kis_node_model.h @@ -26,12 +26,15 @@ #include <QString> #include <QVariant> +#include <KisSelectionTags.h> + class KisDummiesFacadeBase; class KisNodeDummy; class KisShapeController; class KisModelIndexConverterBase; class KisNodeSelectionAdapter; class KisNodeInsertionAdapter; +class KisSelectionActionsAdapter; /** * KisNodeModel offers a Qt model-view compatible view of the node @@ -84,8 +87,13 @@ public: // reflect if the item allows an "onto" drop of the given QMimeData*. DropEnabled, + // Instructs the model to activate "select opaque" action, + // the selection action (of type SelectionAction) value + // is passed via QVariant as integer + SelectOpaqueRole, + /// This is to ensure that we can extend the data role in the future, since it's not possible to add a role after BeginThumbnailRole (due to "Hack") - ReservedRole = 99, + ReservedRole = Qt::UserRole + 99, /** * For values of BeginThumbnailRole or higher, a thumbnail of the layer of which neither dimension @@ -101,12 +109,16 @@ public: // from QAbstractItemModel KisNodeModel(QObject * parent); ~KisNodeModel() override; - void setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, KisImageWSP image, KisShapeController *shapeController, KisNodeSelectionAdapter *nodeSelectionAdapter, KisNodeInsertionAdapter *nodeInsertionAdapter); + void setDummiesFacade(KisDummiesFacadeBase *dummiesFacade, + KisImageWSP image, + KisShapeController *shapeController, + KisNodeSelectionAdapter *nodeSelectionAdapter, + KisNodeInsertionAdapter *nodeInsertionAdapter, + KisSelectionActionsAdapter *selectionActionsAdapter); KisNodeSP nodeFromIndex(const QModelIndex &index) const; QModelIndex indexFromNode(KisNodeSP node) const; bool showGlobalSelection() const; - public Q_SLOTS: void setShowGlobalSelection(bool value); diff --git a/libs/ui/kis_selection_manager.cc b/libs/ui/kis_selection_manager.cc index ebdb5628923..b7ff5766631 100644 --- a/libs/ui/kis_selection_manager.cc +++ b/libs/ui/kis_selection_manager.cc @@ -605,3 +605,74 @@ void KisSelectionManager::slotStrokeSelection() } + +#include "kis_image_barrier_locker.h" +#include "kis_selection_tool_helper.h" + +void KisSelectionManager::selectOpaqueOnNode(KisNodeSP node, SelectionAction action) +{ + KisImageSP image = m_view->image(); + + if (!m_view->blockUntilOperationsFinished(image)) { + return; + } + + KUndo2MagicString actionName; + KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection()); + KisCanvas2 *canvas = m_view->canvasBase(); + + + { + KisImageBarrierLocker locker(image); + + KisPaintDeviceSP device = node->projection(); + if (!device) device = node->paintDevice(); + if (!device) device = node->original(); + KIS_ASSERT_RECOVER_RETURN(canvas && device); + + QRect rc = device->exactBounds(); + if (rc.isEmpty()) return; + + /** + * If there is nothing selected, just create a new selection + */ + if (!canvas->imageView()->selection()) { + action = SELECTION_REPLACE; + } + + switch (action) { + case SELECTION_ADD: + actionName = kundo2_i18n("Select Opaque (Add)"); + break; + case SELECTION_SUBTRACT: + actionName = kundo2_i18n("Select Opaque (Subtract)"); + break; + case SELECTION_INTERSECT: + actionName = kundo2_i18n("Select Opaque (Intersect)"); + break; + default: + actionName = kundo2_i18n("Select Opaque"); + break; + } + + qint32 x, y, w, h; + rc.getRect(&x, &y, &w, &h); + + const KoColorSpace * cs = device->colorSpace(); + + KisHLineConstIteratorSP deviter = device->createHLineConstIteratorNG(x, y, w); + KisHLineIteratorSP selIter = tmpSel ->createHLineIteratorNG(x, y, w); + + for (int row = y; row < h + y; ++row) { + do { + *selIter->rawData() = cs->opacityU8(deviter->oldRawData()); + } while (deviter->nextPixel() && selIter->nextPixel()); + deviter->nextRow(); + selIter->nextRow(); + } + } + + KisSelectionToolHelper helper(canvas, actionName); + tmpSel->invalidateOutlineCache(); + helper.selectPixelSelection(tmpSel, action); +} diff --git a/libs/ui/kis_selection_manager.h b/libs/ui/kis_selection_manager.h index 5b8046030ed..bd165eb9522 100644 --- a/libs/ui/kis_selection_manager.h +++ b/libs/ui/kis_selection_manager.h @@ -24,6 +24,7 @@ #include <kis_image.h> #include "KisView.h" +#include <KisSelectionTags.h> #include <kritaui_export.h> @@ -111,6 +112,8 @@ public Q_SLOTS: void slotStrokeSelection(); + void selectOpaqueOnNode(KisNodeSP node, SelectionAction action); + Q_SIGNALS: void currentSelectionChanged(); void signalUpdateGUI(); diff --git a/libs/ui/tests/kis_model_index_converter_test.cpp b/libs/ui/tests/kis_model_index_converter_test.cpp index 795217d45d4..e2cd6e2660a 100644 --- a/libs/ui/tests/kis_model_index_converter_test.cpp +++ b/libs/ui/tests/kis_model_index_converter_test.cpp @@ -36,12 +36,12 @@ void KisModelIndexConverterTest::init() addSelectionMasks(); m_dummiesFacade->setImage(m_image); - m_nodeModel->setDummiesFacade(m_dummiesFacade, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_dummiesFacade, m_image, 0, 0, 0, 0); } void KisModelIndexConverterTest::cleanup() { - m_nodeModel->setDummiesFacade(0, 0, 0, 0, 0); + m_nodeModel->setDummiesFacade(0, 0, 0, 0, 0, 0); m_dummiesFacade->setImage(0); cleanupBase(); diff --git a/libs/ui/tests/kis_node_model_test.cpp b/libs/ui/tests/kis_node_model_test.cpp index 2e6e55cd5b8..db97778d7c4 100644 --- a/libs/ui/tests/kis_node_model_test.cpp +++ b/libs/ui/tests/kis_node_model_test.cpp @@ -57,14 +57,14 @@ void KisNodeModelTest::testSetImage() { constructImage(); m_shapeController->setImage(m_image); - m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0, 0); new ModelTest(m_nodeModel, this); } void KisNodeModelTest::testAddNode() { m_shapeController->setImage(m_image); - m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0, 0); new ModelTest(m_nodeModel, this); constructImage(); @@ -75,7 +75,7 @@ void KisNodeModelTest::testRemoveAllNodes() { constructImage(); m_shapeController->setImage(m_image); - m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0, 0); new ModelTest(m_nodeModel, this); m_image->removeNode(m_layer4); @@ -88,7 +88,7 @@ void KisNodeModelTest::testRemoveIncludingRoot() { constructImage(); m_shapeController->setImage(m_image); - m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0, 0); new ModelTest(m_nodeModel, this); m_image->removeNode(m_layer4); @@ -104,7 +104,7 @@ void KisNodeModelTest::testSubstituteRootNode() { constructImage(); m_shapeController->setImage(m_image); - m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0); + m_nodeModel->setDummiesFacade(m_shapeController, m_image, 0, 0, 0, 0); new ModelTest(m_nodeModel, this); m_image->flatten(); diff --git a/libs/ui/tests/kis_node_view_test.cpp b/libs/ui/tests/kis_node_view_test.cpp index bb40cd6e626..923a6013033 100644 --- a/libs/ui/tests/kis_node_view_test.cpp +++ b/libs/ui/tests/kis_node_view_test.cpp @@ -80,7 +80,7 @@ void KisNodeViewTest::testLayers() addSelectionMasks(); m_shapeController->setImage(m_image); - model->setDummiesFacade(m_shapeController, m_image, m_shapeController, 0, 0); + model->setDummiesFacade(m_shapeController, m_image, m_shapeController, 0, 0, 0); QVBoxLayout *layout = new QVBoxLayout(&dlg); KisColorFilterCombo *cb = new KisColorFilterCombo(&dlg); diff --git a/plugins/dockers/defaultdockers/kis_layer_box.cpp b/plugins/dockers/defaultdockers/kis_layer_box.cpp index 5c7f23c00c9..006cccba708 100644 --- a/plugins/dockers/defaultdockers/kis_layer_box.cpp +++ b/plugins/dockers/defaultdockers/kis_layer_box.cpp @@ -90,6 +90,7 @@ #include "kis_selection.h" #include "kis_processing_applicator.h" #include "commands/kis_set_global_selection_command.h" +#include "KisSelectionActionsAdapter.h" #include "kis_layer_utils.h" @@ -379,7 +380,8 @@ void KisLayerBox::setCanvas(KoCanvasBase *canvas) if (m_canvas) { m_canvas->disconnectCanvasObserver(this); - m_nodeModel->setDummiesFacade(0, 0, 0, 0, 0); + m_nodeModel->setDummiesFacade(0, 0, 0, 0, 0, 0); + m_selectionActionsAdapter.reset(); if (m_image) { KisImageAnimationInterface *animation = m_image->animationInterface(); @@ -403,7 +405,15 @@ void KisLayerBox::setCanvas(KoCanvasBase *canvas) dynamic_cast<KisShapeController*>(doc->shapeController()); KisDummiesFacadeBase *kritaDummiesFacade = static_cast<KisDummiesFacadeBase*>(kritaShapeController); - m_nodeModel->setDummiesFacade(kritaDummiesFacade, m_image, kritaShapeController, m_nodeManager->nodeSelectionAdapter(), m_nodeManager->nodeInsertionAdapter()); + + + m_selectionActionsAdapter.reset(new KisSelectionActionsAdapter(m_canvas->viewManager()->selectionManager())); + m_nodeModel->setDummiesFacade(kritaDummiesFacade, + m_image, + kritaShapeController, + m_nodeManager->nodeSelectionAdapter(), + m_nodeManager->nodeInsertionAdapter(), + m_selectionActionsAdapter.data()); connect(m_image, SIGNAL(sigAboutToBeDeleted()), SLOT(notifyImageDeleted())); connect(m_image, SIGNAL(sigNodeCollapsedChanged()), SLOT(slotNodeCollapsedChanged())); diff --git a/plugins/dockers/defaultdockers/kis_layer_box.h b/plugins/dockers/defaultdockers/kis_layer_box.h index 9cd1e51048d..e392cf09337 100644 --- a/plugins/dockers/defaultdockers/kis_layer_box.h +++ b/plugins/dockers/defaultdockers/kis_layer_box.h @@ -57,6 +57,7 @@ class KisNodeJugglerCompressed; class KisColorLabelSelectorWidget; class QWidgetAction; class KisKeyframeChannel; +class KisSelectionActionsAdapter; /** * A widget that shows a visualization of the layer structure. @@ -146,6 +147,7 @@ private: private: QPointer<KisCanvas2> m_canvas; + QScopedPointer<KisSelectionActionsAdapter> m_selectionActionsAdapter; QMenu *m_newLayerMenu; KisImageWSP m_image; QPointer<KisNodeModel> m_nodeModel; diff --git a/plugins/extensions/colorrange/colorrange.cc b/plugins/extensions/colorrange/colorrange.cc index cbec33f7259..72161a6bf0c 100644 --- a/plugins/extensions/colorrange/colorrange.cc +++ b/plugins/extensions/colorrange/colorrange.cc @@ -85,65 +85,11 @@ void ColorRange::slotActivated() void ColorRange::selectOpaque(int id) { - selectOpaqueImpl(SelectionAction(id)); -} + KisNodeSP node = viewManager()->activeNode(); + if (!node) return; -void ColorRange::selectOpaqueImpl(SelectionAction action) -{ - KisCanvas2 *canvas = viewManager()->canvasBase(); - KisPaintDeviceSP device = viewManager()->activeNode()->projection(); - if (!device) device = viewManager()->activeNode()->paintDevice(); - if (!device) device = viewManager()->activeNode()->original(); - KIS_ASSERT_RECOVER_RETURN(canvas && device); - - QRect rc = device->exactBounds(); - if (rc.isEmpty()) return; - - /** - * If there is nothing selected, just create a new selection - */ - if (!canvas->imageView()->selection()) { - action = SELECTION_REPLACE; - } - - KUndo2MagicString actionName; - - switch (action) { - case SELECTION_ADD: - actionName = kundo2_i18n("Select Opaque (Add)"); - break; - case SELECTION_SUBTRACT: - actionName = kundo2_i18n("Select Opaque (Subtract)"); - break; - case SELECTION_INTERSECT: - actionName = kundo2_i18n("Select Opaque (Intersect)"); - break; - default: - actionName = kundo2_i18n("Select Opaque"); - break; - } - - KisSelectionToolHelper helper(canvas, actionName); - - qint32 x, y, w, h; - rc.getRect(&x, &y, &w, &h); - - const KoColorSpace * cs = device->colorSpace(); - KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection()); - - KisHLineConstIteratorSP deviter = device->createHLineConstIteratorNG(x, y, w); - KisHLineIteratorSP selIter = tmpSel ->createHLineIteratorNG(x, y, w); - - for (int row = y; row < h + y; ++row) { - do { - *selIter->rawData() = cs->opacityU8(deviter->oldRawData()); - } while (deviter->nextPixel() && selIter->nextPixel()); - deviter->nextRow(); - selIter->nextRow(); - } - - tmpSel->invalidateOutlineCache(); - helper.selectPixelSelection(tmpSel, action); + viewManager()->selectionManager()-> + selectOpaqueOnNode(node, SelectionAction(id)); } #include "colorrange.moc" diff --git a/plugins/extensions/colorrange/colorrange.h b/plugins/extensions/colorrange/colorrange.h index e373ef0fa0e..ef5c197be91 100644 --- a/plugins/extensions/colorrange/colorrange.h +++ b/plugins/extensions/colorrange/colorrange.h @@ -25,9 +25,6 @@ #include <KisActionPlugin.h> -#include "kis_selection.h" - - class ColorRange : public KisActionPlugin { Q_OBJECT @@ -38,9 +35,6 @@ public: private Q_SLOTS: void slotActivated(); void selectOpaque(int id); - -private: - void selectOpaqueImpl(SelectionAction action); }; #endif // COLORRANGE_H