Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tool_select_path.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <KoPathShape.h>
10
11#include "kis_canvas2.h"
13#include "kis_cursor.h"
14#include "kis_image.h"
15#include "kis_painter.h"
16#include "kis_pixel_selection.h"
19#include <KisView.h>
20#include <kis_command_utils.h>
23#include <kis_default_bounds.h>
24
27 KisCursor::load("tool_polygonal_selection_cursor.png", 6, 6),
28 i18n("Select path"),
29 new __KisToolSelectPathLocalTool(canvas, this))
30{}
31
33{
34 localTool()->endPathWithoutLastPoint();
35}
36
41
42// Install an event filter to catch right-click events.
43// This code is duplicated in kis_tool_path.cc
44bool KisToolSelectPath::eventFilter(QObject *obj, QEvent *event)
45{
46 Q_UNUSED(obj);
47 if (!localTool()->pathStarted()) {
48 return false;
49 }
50 if (event->type() == QEvent::MouseButtonPress ||
51 event->type() == QEvent::MouseButtonDblClick) {
52 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
53 if (mouseEvent->button() == Qt::RightButton && isSelecting()) {
54 localTool()->removeLastPoint();
55 return true;
56 }
57 } else if (event->type() == QEvent::TabletPress) {
58 QTabletEvent *tabletEvent = static_cast<QTabletEvent*>(event);
59 if (tabletEvent->button() == Qt::RightButton && isSelecting()) {
60 localTool()->removeLastPoint();
61 return true;
62 }
63 }
64 return false;
65}
66
68{
69 QList<QPointer<QWidget> > widgetsList =
71 QList<QPointer<QWidget> > filteredWidgets;
72 Q_FOREACH (QWidget* widget, widgetsList) {
73 if (widget->objectName() != "Stroke widget") {
74 filteredWidgets.push_back(widget);
75 }
76 }
77 return filteredWidgets;
78}
79
83
87
91
96
98{
99 // this event will be forwarded using beginPrimaryAction
100 Q_UNUSED(event);
101}
102
104{
106
107 // WARNING: the code is duplicated from KisToolPaint::requestUpdateOutline
108 KisCanvas2 *kiscanvas = qobject_cast<KisCanvas2*>(canvas());
110 if (decoration && decoration->visible() && decoration->hasPaintableAssistants()) {
111 kiscanvas->updateCanvasDecorations();
112 }
113}
114
116{
117 // this event will be forwarded using continuePrimaryAction
118 Q_UNUSED(event);
119}
120
122{
123 // this event will be forwarded using endPrimaryAction
124 Q_UNUSED(event);
125}
126
128 : KoCreatePathTool(canvas), m_selectionTool(parentTool)
129{
131}
132
133void __KisToolSelectPathLocalTool::paintPath(KoPathShape &pathShape, QPainter &painter, const KoViewConverter &converter)
134{
135 Q_UNUSED(converter);
136 KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
137 if (!kisCanvas)
138 return;
139
140 QTransform matrix;
141 matrix.scale(kisCanvas->image()->xRes(), kisCanvas->image()->yRes());
142 matrix.translate(pathShape.position().x(), pathShape.position().y());
143 m_selectionTool->paintToolOutline(&painter, m_selectionTool->pixelToView(matrix.map(pathShape.outline())));
144}
145
147{
148 pathShape->normalize();
149 pathShape->close();
150
151 KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
152 if (!kisCanvas)
153 return;
154
155 KisImageWSP image = kisCanvas->image();
156
157 KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select by Bezier Curve"));
158
159 const SelectionMode mode =
160 helper.tryOverrideSelectionMode(kisCanvas->viewManager()->selection(),
163
164 if (mode == PIXEL_SELECTION) {
165 KisProcessingApplicator applicator(
166 m_selectionTool->currentImage(),
167 m_selectionTool->currentNode(),
170 kundo2_i18n("Select by Bezier Curve"));
171
173 new KisDefaultBounds(m_selectionTool->currentImage()));
174
175 const bool antiAlias = m_selectionTool->antiAliasSelection();
176 const int grow = m_selectionTool->growSelection();
177 const int feather = m_selectionTool->featherSelection();
178
179 QTransform matrix;
180 matrix.scale(image->xRes(), image->yRes());
181 matrix.translate(pathShape->position().x(), pathShape->position().y());
182
183 QPainterPath path = matrix.map(pathShape->outline());
184
186 [tmpSel, antiAlias, grow, feather, path]() mutable
187 -> KUndo2Command * {
188 KisPainter painter(tmpSel);
189 painter.setPaintColor(KoColor(Qt::black, tmpSel->colorSpace()));
190 // Since the feathering already smooths the selection, the
191 // antiAlias is not applied if we must feather
192 painter.setAntiAliasPolygonFill(antiAlias && feather == 0);
195
196 painter.fillPainterPath(path);
197
198 if (grow > 0) {
199 KisGrowSelectionFilter biggy(grow, grow);
200 biggy.process(tmpSel,
201 tmpSel->selectedRect().adjusted(-grow,
202 -grow,
203 grow,
204 grow));
205 } else if (grow < 0) {
206 KisShrinkSelectionFilter tiny(-grow, -grow, false);
207 tiny.process(tmpSel, tmpSel->selectedRect());
208 }
209 if (feather > 0) {
210 KisFeatherSelectionFilter feathery(feather);
211 feathery.process(tmpSel,
212 tmpSel->selectedRect().adjusted(-feather,
213 -feather,
214 feather,
215 feather));
216 }
217
218 if (grow == 0 && feather == 0) {
219 tmpSel->setOutlineCache(path);
220 } else {
221 tmpSel->invalidateOutlineCache();
222 }
223
224 return 0;
225 });
226
228 helper.selectPixelSelection(applicator,
229 tmpSel,
231 applicator.end();
232
233 delete pathShape;
234
235 } else {
237 }
238}
239
241{
242 KisToolSelectPath* selectPathTool = dynamic_cast<KisToolSelectPath*>(m_selectionTool);
243 KIS_ASSERT(selectPathTool);
244 selectPathTool->beginSelectInteraction();
245}
246
248{
249 KisToolSelectPath* selectPathTool = dynamic_cast<KisToolSelectPath*>(m_selectionTool);
250 KIS_ASSERT(selectPathTool);
251 selectPathTool->endSelectInteraction();
252}
253
255{
257 useCursor(KisCursor::load("tool_polygonal_selection_cursor_add.png", 6, 6));
258 } else if (selectionAction() == SELECTION_SUBTRACT) {
259 useCursor(KisCursor::load("tool_polygonal_selection_cursor_sub.png", 6, 6));
260 } else if (selectionAction() == SELECTION_INTERSECT) {
261 useCursor(KisCursor::load("tool_polygonal_selection_cursor_inter.png", 6, 6));
263 useCursor(KisCursor::load("tool_polygonal_selection_cursor_symdiff.png", 6, 6));
264 } else {
266 }
267}
268
269
SelectionMode
@ PIXEL_SELECTION
@ SELECTION_INTERSECT
@ SELECTION_SYMMETRICDIFFERENCE
@ SELECTION_SUBTRACT
@ SELECTION_ADD
KisImageWSP image() const
KisViewManager * viewManager() const
KisPaintingAssistantsDecorationSP paintingAssistantsDecoration() const
void updateCanvasDecorations()
static QCursor load(const QString &cursorName, int hotspotX=-1, int hotspotY=-1)
void mouseMoveEvent(KoPointerEvent *event) override
QList< QPointer< QWidget > > createOptionWidgets() override
void mousePressEvent(KoPointerEvent *event) override
void mouseReleaseEvent(KoPointerEvent *event) override
void mouseDoubleClickEvent(KoPointerEvent *event) override
DelegateTool * localTool() const
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
double xRes() const
double yRes() const
const KoColorSpace * colorSpace() const
@ FillStyleForegroundColor
void setStrokeStyle(StrokeStyle strokeStyle)
Set the current brush stroke style.
void setFillStyle(FillStyle fillStyle)
Set the current style with which to fill.
void fillPainterPath(const QPainterPath &path)
void setPaintColor(const KoColor &color)
void setAntiAliasPolygonFill(bool antiAliasPolygonFill)
Set whether a polygon's filled area should be anti-aliased or not. The default is true.
void applyCommand(KUndo2Command *command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
void addSelectionShape(KoShape *shape, SelectionAction action=SELECTION_DEFAULT)
void selectPixelSelection(KisProcessingApplicator &applicator, KisPixelSelectionSP selection, SelectionAction action)
SelectionMode tryOverrideSelectionMode(KisSelectionSP activeSelection, SelectionMode currentMode, SelectionAction currentAction) const
void process(KisPixelSelectionSP pixelSelection, const QRect &rect) override
SelectionAction selectionAction() const
SelectionMode selectionMode() const
bool antiAliasSelection() const
QList< QPointer< QWidget > > createOptionWidgets() override
void requestStrokeEnd() override
void requestStrokeCancellation() override
void resetCursorStyle() override
KisToolSelectPath(KoCanvasBase *canvas)
bool eventFilter(QObject *obj, QEvent *event) override
KisSelectionSP selection()
void setEnableClosePathShortcut(bool value)
The position of a path point within a path shape.
Definition KoPathShape.h:63
virtual QPointF normalize()
Normalizes the path data.
void close()
Closes the current subpath.
QPainterPath outline() const override
reimplemented
QPointF position() const
Get the position of the shape in pt.
Definition KoShape.cpp:825
KoCanvasBase * canvas() const
Returns the canvas the tool is working on.
KisToolSelectPath *const m_selectionTool
void addPathShape(KoPathShape *pathShape) override
__KisToolSelectPathLocalTool(KoCanvasBase *canvas, KisToolSelectPath *parentTool)
void paintPath(KoPathShape &path, QPainter &painter, const KoViewConverter &converter) override
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
KUndo2MagicString kundo2_i18n(const char *text)
The LambdaCommand struct is a shorthand for creation of AggregateCommand commands using C++ lambda fe...
void mousePressEvent(KoPointerEvent *event) override
void beginPrimaryAction(KoPointerEvent *event) override
void endPrimaryAction(KoPointerEvent *event) override
void continuePrimaryAction(KoPointerEvent *event) override
void mouseReleaseEvent(KoPointerEvent *event) override
void mouseDoubleClickEvent(KoPointerEvent *event) override
void beginPrimaryDoubleClickAction(KoPointerEvent *event) override
void mouseMoveEvent(KoPointerEvent *event) override
void setOutlineCache(const QPainterPath &cache)