1 /*
2  *  Copyright (c) 2019 Kuntal Majumder <hellozee@disroot.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #ifndef KIS_TOOL_SELECT_MAGNETIC_H_
20 #define KIS_TOOL_SELECT_MAGNETIC_H_
21 
22 #include <QPoint>
23 #include "KisSelectionToolFactoryBase.h"
24 #include <kis_tool_select_base.h>
25 #include <kis_signal_compressor.h>
26 #include <kis_icon.h>
27 #include "KisMagneticWorker.h"
28 
29 class QPainterPath;
30 
31 class KisToolSelectMagnetic : public KisToolSelect
32 {
33     Q_OBJECT
34 
35 public:
36     KisToolSelectMagnetic(KoCanvasBase *canvas);
37     ~KisToolSelectMagnetic() override = default;
38     void beginPrimaryAction(KoPointerEvent *event) override;
39     void continuePrimaryAction(KoPointerEvent *event) override;
40     void endPrimaryAction(KoPointerEvent *event) override;
41     void paint(QPainter& gc, const KoViewConverter &converter) override;
42 
43     //void beginPrimaryDoubleClickAction(KoPointerEvent *event) override;
44 
45     void keyPressEvent(QKeyEvent *event) override;
46     void keyReleaseEvent(QKeyEvent *event) override;
47 
48     void mouseMoveEvent(KoPointerEvent *event) override;
49 
50     void resetCursorStyle() override;
51     void requestStrokeEnd() override;
52     void requestStrokeCancellation() override;
53     QWidget *createOptionWidget() override;
54 
55 Q_SIGNALS:
56     void setButtonsEnabled(bool);
57 
58 public Q_SLOTS:
59     void deactivate() override;
60     void activate(KoToolBase::ToolActivation activation, const QSet<KoShape *> &shapes) override;
61     void undoPoints();
62     void slotSetFilterRadius(qreal);
63     void slotSetThreshold(int);
64     void slotSetSearchRadius(int);
65     void slotSetAnchorGap(int);
66     void slotCalculateEdge();
67 
68 protected:
69     using KisToolSelectBase::m_widgetHelper;
70 
71 private:
72     void finishSelectionAction();
73     void updateFeedback();
74     void updateContinuedMode();
75     void updateCanvas();
76     void updatePaintPath();
77     void resetVariables();
78     void drawAnchors(QPainter &gc);
79     void checkIfAnchorIsSelected(QPointF pt);
80     vQPointF computeEdgeWrapper(QPoint a, QPoint b);
81     void reEvaluatePoints();
82     void calculateCheckPoints(vQPointF points);
83     void deleteSelectedAnchor();
84     void updateSelectedAnchor();
85     int updateInitialAnchorBounds(QPoint pt);
86 
87     QPainterPath m_paintPath;
88     QVector<QPointF> m_points;
89     QVector<QPoint> m_anchorPoints;
90     bool m_continuedMode;
91     QPointF m_lastCursorPos, m_cursorOnPress;
92     QPoint m_lastAnchor;
93     bool m_complete, m_selected, m_finished;
94     KisMagneticWorker m_worker;
95     int m_threshold, m_searchRadius, m_selectedAnchor, m_anchorGap;
96     qreal m_filterRadius;
97     QRectF m_snapBound;
98     KConfigGroup m_configGroup;
99     QVector<vQPointF> m_pointCollection;
100     KisSignalCompressor m_mouseHoverCompressor;
101 };
102 
103 class KisToolSelectMagneticFactory : public KisSelectionToolFactoryBase
104 {
105 public:
KisToolSelectMagneticFactory()106     KisToolSelectMagneticFactory()
107         : KisSelectionToolFactoryBase("KisToolSelectMagnetic")
108     {
109         setToolTip(i18n("Magnetic Selection Tool"));
110         setSection(TOOL_TYPE_SELECTION);
111         setIconName(koIconNameCStr("tool_magnetic_selection"));
112         setPriority(8);
113         setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
114     }
115 
~KisToolSelectMagneticFactory()116     ~KisToolSelectMagneticFactory() override { }
117 
createTool(KoCanvasBase * canvas)118     KoToolBase * createTool(KoCanvasBase *canvas) override
119     {
120         return new KisToolSelectMagnetic(canvas);
121     }
122 
createActionsImpl()123     QList<QAction *> createActionsImpl() override
124     {
125         KisActionRegistry *actionRegistry = KisActionRegistry::instance();
126         QList<QAction *> actions = KisSelectionToolFactoryBase::createActionsImpl();
127 
128         actions << actionRegistry->makeQAction("undo_polygon_selection");
129 
130         return actions;
131     }
132 };
133 
134 
135 #endif // __selecttoolmagnetic_h__
136