diff --git a/plugins/tools/selectiontools/CMakeLists.txt b/plugins/tools/selectiontools/CMakeLists.txt
index c81049076c..9a2601c2b9 100644
--- a/plugins/tools/selectiontools/CMakeLists.txt
+++ b/plugins/tools/selectiontools/CMakeLists.txt
@@ -1,30 +1,32 @@
set(kritaselectiontools_SOURCES
selection_tools.cc
kis_tool_select_rectangular.cc
kis_tool_select_polygonal.cc
kis_tool_select_elliptical.cc
kis_tool_select_contiguous.cc
kis_tool_select_outline.cc
kis_tool_select_path.cc
kis_tool_select_similar.cc
+ kis_tool_select_magnetic.cc
kis_selection_modifier_mapper.cc
)
qt5_add_resources(kritaselectiontools_SOURCES selectiontools.qrc)
add_library(kritaselectiontools MODULE ${kritaselectiontools_SOURCES})
target_link_libraries(kritaselectiontools kritaui kritabasicflakes)
install(TARGETS kritaselectiontools DESTINATION ${KRITA_PLUGIN_INSTALL_DIR})
install( FILES
KisToolSelectPolygonal.action
KisToolSelectElliptical.action
KisToolSelectSimilar.action
KisToolSelectContiguous.action
KisToolSelectRectangular.action
KisToolSelectOutline.action
KisToolSelectPath.action
+ KisToolSelectMagnetic.action
DESTINATION ${DATA_INSTALL_DIR}/krita/actions
)
diff --git a/plugins/tools/selectiontools/KisToolSelectMagnetic.action b/plugins/tools/selectiontools/KisToolSelectMagnetic.action
new file mode 100644
index 0000000000..fe0fbb9f7c
--- /dev/null
+++ b/plugins/tools/selectiontools/KisToolSelectMagnetic.action
@@ -0,0 +1,6 @@
+
+
+
+ Magnetic Selection Tool
+
+
diff --git a/plugins/tools/selectiontools/kis_tool_select_magnetic.cc b/plugins/tools/selectiontools/kis_tool_select_magnetic.cc
new file mode 100644
index 0000000000..6c5910ff45
--- /dev/null
+++ b/plugins/tools/selectiontools/kis_tool_select_magnetic.cc
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2007 Sven Langkamp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_tool_select_magnetic.h"
+
+#include
+
+#include "kis_cursor.h"
+#include "kis_image.h"
+#include "kis_painter.h"
+#include "kis_selection_options.h"
+#include "kis_canvas_resource_provider.h"
+#include "kis_canvas2.h"
+#include "kis_pixel_selection.h"
+#include "kis_selection_tool_helper.h"
+#include
+
+
+KisToolSelectMagnetic::KisToolSelectMagnetic(KoCanvasBase * canvas)
+ : KisToolSelectBase(canvas,
+ KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6),
+ i18n("Select path"),
+ dynamic_cast (new __KisToolSelectMagneticLocalTool(canvas, this)))
+{
+}
+
+void KisToolSelectMagnetic::requestStrokeEnd()
+{
+ localTool()->endPathWithoutLastPoint();
+}
+
+void KisToolSelectMagnetic::requestStrokeCancellation()
+{
+ localTool()->cancelPath();
+}
+
+void KisToolSelectMagnetic::mousePressEvent(KoPointerEvent* event)
+{
+ if (!selectionEditable()) return;
+ DelegatedSelectMagneticTool::mousePressEvent(event);
+}
+
+// Install an event filter to catch right-click events.
+// This code is duplicated in kis_tool_path.cc
+bool KisToolSelectMagnetic::eventFilter(QObject *obj, QEvent *event)
+{
+ Q_UNUSED(obj);
+ if (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::MouseButtonDblClick) {
+ QMouseEvent *mouseEvent = static_cast(event);
+ if (mouseEvent->button() == Qt::RightButton) {
+ localTool()->removeLastPoint();
+ return true;
+ }
+ } else if (event->type() == QEvent::TabletPress) {
+ QTabletEvent *tabletEvent = static_cast(event);
+ if (tabletEvent->button() == Qt::RightButton) {
+ localTool()->removeLastPoint();
+ return true;
+ }
+ }
+ return false;
+}
+
+QList > KisToolSelectMagnetic::createOptionWidgets()
+{
+ QList > widgetsList =
+ DelegatedSelectMagneticTool::createOptionWidgets();
+ QList > filteredWidgets;
+ Q_FOREACH (QWidget* widget, widgetsList) {
+ if (widget->objectName() != "Stroke widget") {
+ filteredWidgets.push_back(widget);
+ }
+ }
+ return filteredWidgets;
+}
+
+void KisDelegatedSelectMagneticWrapper::beginPrimaryAction(KoPointerEvent *event) {
+ mousePressEvent(event);
+}
+
+void KisDelegatedSelectMagneticWrapper::continuePrimaryAction(KoPointerEvent *event){
+ mouseMoveEvent(event);
+}
+
+void KisDelegatedSelectMagneticWrapper::endPrimaryAction(KoPointerEvent *event) {
+ mouseReleaseEvent(event);
+}
+
+bool KisDelegatedSelectMagneticWrapper::hasUserInteractionRunning() const
+{
+ /**
+ * KoCreatePathTool doesn't support moving interventions from KisToolselectBase,
+ * because it doesn't use begin/continue/endPrimaryAction and uses direct event
+ * handling instead.
+ *
+ * TODO: refactor KoCreatePathTool and port it to action infrastructure
+ */
+ return true;
+}
+
+
+__KisToolSelectMagneticLocalTool::__KisToolSelectMagneticLocalTool(KoCanvasBase * canvas, KisToolSelectMagnetic* parentTool)
+ : KoCreatePathTool(canvas), m_selectionTool(parentTool)
+{
+ setEnableClosePathShortcut(false);
+}
+
+void __KisToolSelectMagneticLocalTool::paintPath(KoPathShape &pathShape, QPainter &painter, const KoViewConverter &converter)
+{
+ Q_UNUSED(converter);
+ KisCanvas2 * kisCanvas = dynamic_cast(canvas());
+ if (!kisCanvas)
+ return;
+
+ QTransform matrix;
+ matrix.scale(kisCanvas->image()->xRes(), kisCanvas->image()->yRes());
+ matrix.translate(pathShape.position().x(), pathShape.position().y());
+
+ qreal zoomX, zoomY;
+ kisCanvas->viewConverter()->zoom(&zoomX, &zoomY);
+ Q_ASSERT(qFuzzyCompare(zoomX, zoomY));
+
+ qreal width = 25*2;
+ width *= zoomX/(kisCanvas->image()->xRes());
+
+ paintOutline(&painter, m_selectionTool->pixelToView(matrix.map(pathShape.outline())), width);
+}
+
+void __KisToolSelectMagneticLocalTool::addPathShape(KoPathShape* pathShape)
+{
+ pathShape->normalize();
+ pathShape->close();
+
+ KisCanvas2 * kisCanvas = dynamic_cast(canvas());
+ if (!kisCanvas)
+ return;
+
+ KisImageWSP image = kisCanvas->image();
+
+ KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select by Bezier Curve"));
+
+ const SelectionMode mode =
+ helper.tryOverrideSelectionMode(kisCanvas->viewManager()->selection(),
+ m_selectionTool->selectionMode(),
+ m_selectionTool->selectionAction());
+
+ if (mode == PIXEL_SELECTION) {
+
+ KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection());
+
+ KisPainter painter(tmpSel);
+ painter.setPaintColor(KoColor(Qt::black, tmpSel->colorSpace()));
+ painter.setFillStyle(KisPainter::FillStyleForegroundColor);
+ painter.setAntiAliasPolygonFill(m_selectionTool->antiAliasSelection());
+ painter.setStrokeStyle(KisPainter::StrokeStyleNone);
+
+ QTransform matrix;
+ matrix.scale(image->xRes(), image->yRes());
+ matrix.translate(pathShape->position().x(), pathShape->position().y());
+
+ QPainterPath path = matrix.map(pathShape->outline());
+ painter.fillPainterPath(path);
+ tmpSel->setOutlineCache(path);
+
+ helper.selectPixelSelection(tmpSel, m_selectionTool->selectionAction());
+
+ delete pathShape;
+ } else {
+ helper.addSelectionShape(pathShape, m_selectionTool->selectionAction());
+ }
+}
+
+void __KisToolSelectMagneticLocalTool::paintOutline(QPainter *painter, const QPainterPath &path, qreal width)
+{
+ painter->save();
+ painter->setOpacity(.3);
+ painter->setPen(QPen(QColor(128, 128, 128), width));
+ painter->drawPath(path);
+ m_selectionTool->updateCanvasViewRect(path.controlPointRect().adjusted(-width, -width, width, width));
+ painter->restore();
+}
+
+void KisToolSelectMagnetic::resetCursorStyle()
+{
+ if (selectionAction() == SELECTION_ADD) {
+ useCursor(KisCursor::load("tool_polygonal_selection_cursor_add.png", 6, 6));
+ } else if (selectionAction() == SELECTION_SUBTRACT) {
+ useCursor(KisCursor::load("tool_polygonal_selection_cursor_sub.png", 6, 6));
+ } else {
+ KisToolSelectBase::resetCursorStyle();
+ }
+}
diff --git a/plugins/tools/selectiontools/kis_tool_select_magnetic.h b/plugins/tools/selectiontools/kis_tool_select_magnetic.h
new file mode 100644
index 0000000000..78ecc603c1
--- /dev/null
+++ b/plugins/tools/selectiontools/kis_tool_select_magnetic.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2007 Sven Langkamp
+ * Copyright (c) 2015 Michael Abrahams
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KIS_TOOL_SELECT_MAGNETIC_H_
+#define KIS_TOOL_SELECT_MAGNETIC_H_
+
+#include
+#include
+#include "kis_tool_select_base.h"
+#include "kis_delegated_tool.h"
+
+#include
+
+class KoCanvasBase;
+class KisToolSelectMagnetic;
+
+
+class __KisToolSelectMagneticLocalTool : public KoCreatePathTool {
+public:
+ __KisToolSelectMagneticLocalTool(KoCanvasBase * canvas, KisToolSelectMagnetic* parentTool);
+ void paintPath(KoPathShape &path, QPainter &painter, const KoViewConverter &converter) override;
+ void addPathShape(KoPathShape* pathShape) override;
+
+ using KoCreatePathTool::createOptionWidgets;
+ using KoCreatePathTool::endPathWithoutLastPoint;
+ using KoCreatePathTool::endPath;
+ using KoCreatePathTool::cancelPath;
+ using KoCreatePathTool::removeLastPoint;
+
+protected:
+ void paintOutline(QPainter *painter, const QPainterPath &path, qreal width);
+
+private:
+ KisToolSelectMagnetic* const m_selectionTool;
+};
+
+typedef KisDelegatedTool DelegatedSelectMagneticTool;
+
+struct KisDelegatedSelectMagneticWrapper : public DelegatedSelectMagneticTool {
+ KisDelegatedSelectMagneticWrapper(KoCanvasBase *canvas,
+ const QCursor &cursor,
+ KisTool* delegateTool)
+ : DelegatedSelectMagneticTool(canvas, cursor, dynamic_cast<__KisToolSelectMagneticLocalTool*>(delegateTool))
+ {
+ }
+
+ // If an event is explicitly forwarded only as an action (e.g. shift-click is captured by "change size")
+ // we will receive a primary action but no mousePressEvent. Thus these events must be explicitly forwarded.
+ void beginPrimaryAction(KoPointerEvent *event) override;
+ void continuePrimaryAction(KoPointerEvent *event) override;
+ void endPrimaryAction(KoPointerEvent *event) override;
+
+ bool hasUserInteractionRunning() const;
+};
+
+
+class KisToolSelectMagnetic : public KisToolSelectBase
+{
+ Q_OBJECT
+public:
+ KisToolSelectMagnetic(KoCanvasBase * canvas);
+ void mousePressEvent(KoPointerEvent* event) override;
+ bool eventFilter(QObject *obj, QEvent *event) override;
+ void resetCursorStyle() override;
+
+protected:
+ void requestStrokeCancellation() override;
+ void requestStrokeEnd() override;
+ friend class __KisToolSelectMagneticLocalTool;
+ QList > createOptionWidgets() override;
+};
+
+class KisToolSelectMagneticFactory : public KisSelectionToolFactoryBase
+{
+public:
+ KisToolSelectMagneticFactory()
+ : KisSelectionToolFactoryBase("KisToolSelectMagnetic") {
+ setToolTip(i18n("Magnetic Selection Tool"));
+ setSection(TOOL_TYPE_SELECTION);
+ setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
+ setIconName(koIconNameCStr("tool_path_selection"));
+ setPriority(6);
+ }
+
+ ~KisToolSelectMagneticFactory() override {}
+
+ KoToolBase * createTool(KoCanvasBase *canvas) override {
+ return new KisToolSelectMagnetic(canvas);
+ }
+
+
+};
+
+
+
+#endif // KIS_TOOL_SELECT_MAGNETIC_H_
diff --git a/plugins/tools/selectiontools/selection_tools.cc b/plugins/tools/selectiontools/selection_tools.cc
index e0e44fbe60..2411b8f045 100644
--- a/plugins/tools/selectiontools/selection_tools.cc
+++ b/plugins/tools/selectiontools/selection_tools.cc
@@ -1,59 +1,61 @@
/*
* selection_tools.cc -- Part of Krita
*
* Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "selection_tools.h"
#include
#include
#include
#include "KoToolRegistry.h"
#include "kis_global.h"
#include "kis_types.h"
#include "kis_tool_select_outline.h"
#include "kis_tool_select_polygonal.h"
#include "kis_tool_select_rectangular.h"
#include "kis_tool_select_contiguous.h"
#include "kis_tool_select_elliptical.h"
#include "kis_tool_select_path.h"
#include "kis_tool_select_similar.h"
+#include "kis_tool_select_magnetic.h"
K_PLUGIN_FACTORY_WITH_JSON(SelectionToolsFactory, "kritaselectiontools.json", registerPlugin();)
SelectionTools::SelectionTools(QObject *parent, const QVariantList &)
: QObject(parent)
{
KoToolRegistry::instance()->add(new KisToolSelectOutlineFactory());
KoToolRegistry::instance()->add(new KisToolSelectPolygonalFactory());
KoToolRegistry::instance()->add(new KisToolSelectRectangularFactory());
KoToolRegistry::instance()->add(new KisToolSelectEllipticalFactory());
KoToolRegistry::instance()->add(new KisToolSelectContiguousFactory());
KoToolRegistry::instance()->add(new KisToolSelectPathFactory());
KoToolRegistry::instance()->add(new KisToolSelectSimilarFactory());
+ KoToolRegistry::instance()->add(new KisToolSelectMagneticFactory());
}
SelectionTools::~SelectionTools()
{
}
#include "selection_tools.moc"