Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_tool_paint.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2003-2009 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2015 Moritz Molch <kde@moritzmolch.de>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include "kis_tool_paint.h"
9
10#include <algorithm>
11
12#include <QWidget>
13#include <QRect>
14#include <QLayout>
15#include <QPushButton>
16#include <QWhatsThis>
17#include <QCheckBox>
18#include <QVBoxLayout>
19#include <QHBoxLayout>
20#include <QGridLayout>
21#include <QEvent>
22#include <QVariant>
23#include <QAction>
24#include <kis_debug.h>
25#include <QPoint>
26
27#include <klocalizedstring.h>
28#include <kactioncollection.h>
29
30#include <kis_algebra_2d.h>
31#include <kis_icon.h>
32#include <KoShape.h>
34#include <KoColorSpace.h>
35#include <KoPointerEvent.h>
36#include <KoColor.h>
37#include <KoCanvasBase.h>
38#include <KoCanvasController.h>
39
40#include <kis_types.h>
41#include <kis_global.h>
42#include <kis_image.h>
43#include <kis_paint_device.h>
44#include <kis_layer.h>
45#include <KisViewManager.h>
46#include <kis_canvas2.h>
47#include <kis_cubic_curve.h>
49#include <KisDocument.h>
51
52#include "kis_config.h"
53#include "kis_config_notifier.h"
54#include "kis_cursor.h"
55#include "kis_image_config.h"
57#include "kis_slider_spin_box.h"
59#include "kis_tool_utils.h"
63#include <kis_action_manager.h>
64#include <kis_action.h>
66#include "kis_popup_palette.h"
67#include "kis_paintop_utils.h"
68
69
71{
72 // Keeps track of past cursor positions. This is used to determine the drawing angle when
73 // drawing the brush outline or starting a stroke.
75};
76
77
78KisToolPaint::KisToolPaint(KoCanvasBase *canvas, const QCursor &cursor)
79 : KisTool(canvas, cursor),
80 m_isOutlineEnabled(true),
81 m_isOutlineVisible(true),
82 m_standardBrushSizes(1, KisImageConfig(true).maxBrushSize()),
83 m_colorSamplerHelper(dynamic_cast<KisCanvas2*>(canvas)),
84 m_d(new Private())
85{
86 KisCanvas2 *kiscanvas = dynamic_cast<KisCanvas2*>(canvas);
87 KIS_ASSERT(kiscanvas);
88 connect(this, SIGNAL(sigPaintingFinished()), kiscanvas->viewManager()->canvasResourceProvider(), SLOT(slotPainting()));
89
90 connect(&m_colorSamplerHelper, SIGNAL(sigRequestCursor(QCursor)), this, SLOT(slotColorPickerRequestedCursor(QCursor)));
91 connect(&m_colorSamplerHelper, SIGNAL(sigRequestCursorReset()), this, SLOT(slotColorPickerRequestedCursorReset()));
92 connect(&m_colorSamplerHelper, SIGNAL(sigRequestUpdateOutline()), this, SLOT(slotColorPickerRequestedOutlineUpdate()));
93}
94
95
99
104
105void KisToolPaint::canvasResourceChanged(int key, const QVariant& v)
106{
108
109 switch(key) {
111 break;
113 if (isActive()) {
115 }
116 break;
117 }
119 if (isActive()) {
120 const QString formattedBrushName = v.toString().replace("_", " ");
121 Q_EMIT statusTextChanged(formattedBrushName);
122 }
123 break;
124 }
125 default: //nothing
126 break;
127 }
128
129 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(resetCursorStyle()), Qt::UniqueConnection);
130
131}
132
134{
146 KisCanvasResourceProvider *provider = qobject_cast<KisCanvas2*>(canvas())->viewManager()->canvasResourceProvider();
147
148 KisPaintOpPresetSP newPreset = provider->currentPreset();
149
150 if (newPreset) {
151 m_oldPreset = newPreset;
152 m_oldPresetIsDirty = newPreset->isDirty();
153 m_oldPresetVersion = newPreset->version();
154 }
155}
156
157
158void KisToolPaint::activate(const QSet<KoShape*> &shapes)
159{
160 if (currentPaintOpPreset()) {
161 const QString formattedBrushName = currentPaintOpPreset() ? currentPaintOpPreset()->name().replace("_", " ") : QString();
162 Q_EMIT statusTextChanged(formattedBrushName);
163 }
164
165 KisTool::activate(shapes);
167 connect(action("increase_brush_size"), SIGNAL(triggered()), SLOT(increaseBrushSize()), Qt::UniqueConnection);
168 connect(action("decrease_brush_size"), SIGNAL(triggered()), SLOT(decreaseBrushSize()), Qt::UniqueConnection);
169 connect(action("increase_brush_size"), SIGNAL(triggered()), this, SLOT(showBrushSize()));
170 connect(action("decrease_brush_size"), SIGNAL(triggered()), this, SLOT(showBrushSize()));
171
172 }
173
174 connect(action("rotate_brush_tip_clockwise"), SIGNAL(triggered()), SLOT(rotateBrushTipClockwise()), Qt::UniqueConnection);
175 connect(action("rotate_brush_tip_clockwise_precise"), SIGNAL(triggered()), SLOT(rotateBrushTipClockwisePrecise()), Qt::UniqueConnection);
176 connect(action("rotate_brush_tip_counter_clockwise"), SIGNAL(triggered()), SLOT(rotateBrushTipCounterClockwise()), Qt::UniqueConnection);
177 connect(action("rotate_brush_tip_counter_clockwise_precise"), SIGNAL(triggered()), SLOT(rotateBrushTipCounterClockwisePrecise()), Qt::UniqueConnection);
178
180}
181
183{
185 disconnect(action("increase_brush_size"), 0, this, 0);
186 disconnect(action("decrease_brush_size"), 0, this, 0);
187 }
188
189 disconnect(action("rotate_brush_tip_clockwise"), 0, this, 0);
190 disconnect(action("rotate_brush_tip_clockwise_precise"), 0, this, 0);
191 disconnect(action("rotate_brush_tip_counter_clockwise"), 0, this, 0);
192 disconnect(action("rotate_brush_tip_counter_clockwise_precise"), 0, this, 0);
193
195 Q_EMIT statusTextChanged(QString());
196
198}
199
201{
203}
204
209
214
216{
217 KisConfig cfg(true);
218
219 bool useSeparateEraserCursor = cfg.separateEraserCursor() && isEraser();
220
221 const OutlineStyle currentOutlineStyle = !useSeparateEraserCursor ? cfg.newOutlineStyle() : cfg.eraserOutlineStyle();
222 if (currentOutlineStyle == OUTLINE_NONE) return originalOutline;
223
224 const qreal minThresholdSize = cfg.outlineSizeMinimum();
225
232 QSize widgetSize = canvas()->canvasWidget()->size();
233 const int maxThresholdSum = widgetSize.width() + widgetSize.height();
234
235 KisOptimizedBrushOutline outline = originalOutline;
236 QRectF boundingRect = outline.boundingRect();
237 const qreal sum = boundingRect.width() + boundingRect.height();
238
239 QPointF center = boundingRect.center();
240
241 if (sum > maxThresholdSum) {
242 const int hairOffset = 7;
243
244 QPainterPath crossIcon;
245
246 crossIcon.moveTo(center.x(), center.y() - hairOffset);
247 crossIcon.lineTo(center.x(), center.y() + hairOffset);
248
249 crossIcon.moveTo(center.x() - hairOffset, center.y());
250 crossIcon.lineTo(center.x() + hairOffset, center.y());
251
252 outline.addPath(crossIcon);
253
254 } else if (sum < minThresholdSize && !outline.isEmpty()) {
255 outline = QPainterPath();
256 outline.addEllipse(center, 0.5 * minThresholdSize, 0.5 * minThresholdSize);
257 }
258
259 return outline;
260}
261
262void KisToolPaint::paint(QPainter &gc, const KoViewConverter &converter)
263{
264 Q_UNUSED(converter);
265
267 paintToolOutline(&gc, path);
268
269 m_colorSamplerHelper.paint(gc, converter);
270}
271
273{
274 if(this->mode() == KisTool::PAINT_MODE &&
275 mode != KisTool::PAINT_MODE) {
276
277 // Let's add history information about recently used colors
278 Q_EMIT sigPaintingFinished();
279 }
280
282}
283
285{
286 if (!isSamplingAction(action)) {
288 return;
289 }
290
291 const bool sampleCurrentLayer = action == SampleFgNode || action == SampleBgNode;
292 const bool sampleFgColor = action == SampleFgNode || action == SampleFgImage;
293 m_colorSamplerHelper.activate(sampleCurrentLayer, sampleFgColor);
294}
295
305
312
314{
317
319 config.load();
320
321 m_colorSamplerHelper.startAction(event->point, config.radius, config.blend);
322 requestUpdateOutline(event->point, event);
323 } else {
325 }
326}
327
337
348
350{
352 if (mode() == KisTool::HOVER_MODE) {
353 requestUpdateOutline(event->point, event);
354 }
355}
356
358{
360 if (mode() == KisTool::HOVER_MODE) {
361 requestUpdateOutline(event->point, event);
362 }
363}
364
366{
367 KisCanvas2 *kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
368
369 if (!kisCanvas) {
370 return nullptr;
371 }
372
374 return popupWidget;
375}
376
378{
380 if (mode() == KisTool::HOVER_MODE) {
381 requestUpdateOutline(event->point, event);
382 }
383}
384
386{
387 QWidget *optionWidget = new QWidget();
388 optionWidget->setObjectName(toolId());
389
390 QVBoxLayout *verticalLayout = new QVBoxLayout(optionWidget);
391 verticalLayout->setObjectName("KisToolPaint::OptionWidget::VerticalLayout");
392 verticalLayout->setContentsMargins(0,0,0,0);
393 verticalLayout->setSpacing(5);
394
395 // See https://bugs.kde.org/show_bug.cgi?id=316896
396 QWidget *specialSpacer = new QWidget(optionWidget);
397 specialSpacer->setObjectName("SpecialSpacer");
398 specialSpacer->setFixedSize(0, 0);
399 verticalLayout->addWidget(specialSpacer);
400 verticalLayout->addWidget(specialSpacer);
401
402 m_optionsWidgetLayout = new QGridLayout();
403 m_optionsWidgetLayout->setColumnStretch(1, 1);
404 verticalLayout->addLayout(m_optionsWidgetLayout);
405 m_optionsWidgetLayout->setContentsMargins(0,0,0,0);
406 m_optionsWidgetLayout->setSpacing(5);
407
408 if (!quickHelp().isEmpty()) {
409 QPushButton *push = new QPushButton(KisIconUtils::loadIcon("help-contents"), QString(), optionWidget);
410 connect(push, SIGNAL(clicked()), this, SLOT(slotPopupQuickHelp()));
411 QHBoxLayout *hLayout = new QHBoxLayout();
412 hLayout->addWidget(push);
413 hLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
414 verticalLayout->addLayout(hLayout);
415 }
416
417 return optionWidget;
418}
419
420QWidget* findLabelWidget(QGridLayout *layout, QWidget *control)
421{
422 QWidget *result = 0;
423
424 int index = layout->indexOf(control);
425
426 int row, col, rowSpan, colSpan;
427 layout->getItemPosition(index, &row, &col, &rowSpan, &colSpan);
428
429 if (col > 0) {
430 QLayoutItem *item = layout->itemAtPosition(row, col - 1);
431
432 if (item) {
433 result = item->widget();
434 }
435 } else {
436 QLayoutItem *item = layout->itemAtPosition(row, col + 1);
437 if (item) {
438 result = item->widget();
439 }
440 }
441
442 return result;
443}
444
445void KisToolPaint::showControl(QWidget *control, bool value)
446{
447 control->setVisible(value);
448 QWidget *label = findLabelWidget(m_optionsWidgetLayout, control);
449 if (label) {
450 label->setVisible(value);
451 }
452}
453
454void KisToolPaint::enableControl(QWidget *control, bool value)
455{
456 control->setEnabled(value);
457 QWidget *label = findLabelWidget(m_optionsWidgetLayout, control);
458 if (label) {
459 label->setEnabled(value);
460 }
461}
462
464{
465 Q_ASSERT(m_optionsWidgetLayout != 0);
466 int rowCount = m_optionsWidgetLayout->rowCount();
467 m_optionsWidgetLayout->addLayout(layout, rowCount, 0, 1, 2);
468}
469
470
471void KisToolPaint::addOptionWidgetOption(QWidget *control, QWidget *label)
472{
473 Q_ASSERT(m_optionsWidgetLayout != 0);
474 if (label) {
475 m_optionsWidgetLayout->addWidget(label, m_optionsWidgetLayout->rowCount(), 0);
476 m_optionsWidgetLayout->addWidget(control, m_optionsWidgetLayout->rowCount() - 1, 1);
477 }
478 else {
479 m_optionsWidgetLayout->addWidget(control, m_optionsWidgetLayout->rowCount(), 0, 1, 2);
480 }
481}
482
483
485{
486 QWhatsThis::showText(QCursor::pos(), quickHelp());
487}
488
494
500
502{
503 return m_isOutlineEnabled;
504}
505
511
513{
514 return m_isOutlineVisible;
515}
516
522
524{
525 qreal paintopSize = currentPaintOpPreset()->settings()->paintOpSize();
526 int newValue = m_standardBrushSizes.increaseBrushSize(paintopSize);
527 currentPaintOpPreset()->settings()->setPaintOpSize(newValue);
529}
530
532{
533 qreal paintopSize = currentPaintOpPreset()->settings()->paintOpSize();
534 int newValue = m_standardBrushSizes.decreaseBrushSize(paintopSize);
535 currentPaintOpPreset()->settings()->setPaintOpSize(newValue);
537}
538
543
545{
546 const qreal angle = currentPaintOpPreset()->settings()->paintOpAngle();
547 currentPaintOpPreset()->settings()->setPaintOpAngle(angle - 15);
549}
550
552{
553 const qreal angle = currentPaintOpPreset()->settings()->paintOpAngle();
554 currentPaintOpPreset()->settings()->setPaintOpAngle(angle - 1);
556}
557
559{
560 const qreal angle = currentPaintOpPreset()->settings()->paintOpAngle();
561 currentPaintOpPreset()->settings()->setPaintOpAngle(angle + 15);
563}
564
566{
567 const qreal angle = currentPaintOpPreset()->settings()->paintOpAngle();
568 currentPaintOpPreset()->settings()->setPaintOpAngle(angle + 1);
570}
571
572void KisToolPaint::requestUpdateOutline(const QPointF &outlineDocPoint, const KoPointerEvent *event)
573{
574 QRectF outlinePixelRect;
575 QRectF outlineDocRect;
576
577 QRectF colorPreviewDocUpdateRect;
578
579 QPointF outlineMoveVector;
580
581 if (m_supportOutline) {
582 KisConfig cfg(true);
584
585 bool useSeparateEraserCursor = cfg.separateEraserCursor() && isEraser();
586
587 const OutlineStyle currentOutlineStyle = !useSeparateEraserCursor ? cfg.newOutlineStyle() : cfg.eraserOutlineStyle();
588 const auto outlineStyleIsVisible = [&]() {
589 return currentOutlineStyle == OUTLINE_FULL ||
590 currentOutlineStyle == OUTLINE_CIRCLE ||
591 currentOutlineStyle == OUTLINE_TILT;
592 };
593 const auto shouldShowOutlineWhilePainting = [&]() {
594 return !useSeparateEraserCursor ? cfg.showOutlineWhilePainting() : cfg.showEraserOutlineWhilePainting();
595 };
598 (outlineStyleIsVisible() &&
599 (mode() == HOVER_MODE ||
600 (mode() == PAINT_MODE && shouldShowOutlineWhilePainting()))))) { // lisp forever!
601
602 outlineMode.isVisible = true;
603
604 switch (!useSeparateEraserCursor ? cfg.newOutlineStyle() : cfg.eraserOutlineStyle()) {
605 case OUTLINE_CIRCLE:
606 outlineMode.forceCircle = true;
607 break;
608 case OUTLINE_TILT:
609 outlineMode.forceCircle = true;
610 outlineMode.showTiltDecoration = true;
611 break;
612 default:
613 break;
614 }
615 }
616
617 outlineMode.forceFullSize = !useSeparateEraserCursor ? cfg.forceAlwaysFullSizedOutline() : cfg.forceAlwaysFullSizedEraserOutline();
618
619 outlineMoveVector = outlineDocPoint - m_outlineDocPoint;
620
621 m_outlineDocPoint = outlineDocPoint;
623
625 outlineDocRect = currentImage()->pixelToDocument(outlinePixelRect);
626
627 // This adjusted call is needed as we paint with a 3 pixel wide brush and the pen is outside the bounds of the path
628 // Pen uses view coordinates so we have to zoom the document value to match 2 pixel in view coordinates
629 // See BUG 275829
630 qreal zoomX;
631 qreal zoomY;
632 canvas()->viewConverter()->zoom(&zoomX, &zoomY);
633 qreal xoffset = 2.0/zoomX;
634 qreal yoffset = 2.0/zoomY;
635
636 if (!outlineDocRect.isEmpty()) {
637 outlineDocRect.adjust(-xoffset,-yoffset,xoffset,yoffset);
638 }
639
641
642 if (!colorPreviewDocUpdateRect.isEmpty()) {
643 colorPreviewDocUpdateRect = colorPreviewDocUpdateRect.adjusted(-xoffset,-yoffset,xoffset,yoffset);
644 }
645
646 }
647
648 // DIRTY HACK ALERT: we should fetch the assistant's dirty rect when requesting
649 // the update, instead of just dumbly update the entire canvas!
650
651 // WARNING: assistants code is also duplicated in KisDelegatedSelectPathWrapper::mouseMoveEvent
652
653 KisCanvas2 *kiscanvas = qobject_cast<KisCanvas2*>(canvas());
655 if (decoration && decoration->visible() && decoration->hasPaintableAssistants()) {
656 kiscanvas->updateCanvasDecorations();
657 }
658
659 if (!m_oldColorPreviewUpdateRect.isEmpty()) {
661 }
662
663 if (!m_oldOutlineRect.isEmpty()) {
665 }
666
667 if (!outlineDocRect.isEmpty()) {
691 const qreal maxUpdateAheadOutlinePortion = 0.5;
692
694 const qreal offsetFuzzyExtension = 0.1;
695
696 const qreal moveDistance = KisAlgebra2D::norm(outlineMoveVector);
697
698 QRectF offsetRect;
699
700 if (moveDistance < maxUpdateAheadOutlinePortion * KisAlgebra2D::maxDimension(outlineDocRect)) {
701 offsetRect = outlineDocRect.translated((1.0 + offsetFuzzyExtension) * outlineMoveVector);
702 }
703
704 kiscanvas->updateCanvasToolOutlineDoc(outlineDocRect | offsetRect);
705 }
706
707 if (!colorPreviewDocUpdateRect.isEmpty()) {
708 kiscanvas->updateCanvasToolOutlineDoc(colorPreviewDocUpdateRect);
709 }
710
711 m_oldOutlineRect = outlineDocRect;
712 m_oldColorPreviewUpdateRect = colorPreviewDocUpdateRect;
713}
714
718
720 const KoPointerEvent *event,
722{
723 KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
724 KIS_ASSERT(canvas2);
725 const KisCoordinatesConverter *converter = canvas2->coordinatesConverter();
726
727 const QPointF pixelPos = convertToPixelCoord(documentPos);
728 // When touch drawing, a "hover" event means the finger was just pressed
729 // down. The last cursor position is invalid with regards to distance and
730 // speed, since it isn't updated while the finger isn't down, so reset it.
731 if (event && event->isTouchEvent() && mode() == HOVER_MODE) {
732 m_d->lastCursorPos.reset(pixelPos);
733 }
734
735 KisPaintInformation info(pixelPos);
741
742 const qreal currentZoom = canvas2->resourceManager() ? canvas2->resourceManager()->resource(KoCanvasResource::EffectiveZoom).toReal() : 1.0;
743
744 QPointF prevPoint = m_d->lastCursorPos.pushThroughHistory(pixelPos, currentZoom);
745 qreal startAngle = KisAlgebra2D::directionBetweenPoints(prevPoint, pixelPos, 0);
746 KisDistanceInformation distanceInfo(prevPoint, startAngle);
747
749 info.registerDistanceInformation(&distanceInfo);
750
752 brushOutline(info,
753 outlineMode, converter->effectivePhysicalZoom());
754
755 return path;
756}
757
float value(const T *src, size_t ch)
qreal v
const QString COMPOSITE_ERASE
void activate(bool sampleCurrentLayer, bool pickFgColor)
void paint(QPainter &gc, const KoViewConverter &converter)
void continueAction(const QPointF &docPoint)
void startAction(const QPointF &docPoint, int radius, int blend)
QRectF colorPreviewDocRect(const QPointF &docPoint)
KisPopupPalette * popupPalette
void updateCanvasToolOutlineDoc(const QRectF &docRect)
KisCoordinatesConverter * coordinatesConverter
KisViewManager * viewManager() const
KisAbstractCanvasWidget * canvasWidget
KisPaintingAssistantsDecorationSP paintingAssistantsDecoration() const
void updateCanvasDecorations()
const KoViewConverter * viewConverter() const override
KisPaintOpPresetSP currentPreset() const
static KisConfigNotifier * instance()
qreal outlineSizeMinimum(bool defaultValue=false) const
OutlineStyle newOutlineStyle(bool defaultValue=false) const
bool forceAlwaysFullSizedOutline(bool defaultValue=false) const
OutlineStyle eraserOutlineStyle(bool defaultValue=false) const
bool forceAlwaysFullSizedEraserOutline(bool defaultValue=false) const
bool showOutlineWhilePainting(bool defaultValue=false) const
bool separateEraserCursor(bool defaultValue=false) const
bool showEraserOutlineWhilePainting(bool defaultValue=false) const
QPointF pixelToDocument(const QPointF &pixelCoord) const
void addPath(const QPainterPath &path)
void addEllipse(const QPointF &center, qreal rx, qreal ry)
void setRandomSource(KisRandomSourceSP value)
void setCanvasMirroredV(bool value)
void setCanvasMirroredH(bool value)
DistanceInformationRegistrar registerDistanceInformation(KisDistanceInformation *distance)
void setCanvasRotation(qreal rotation)
void setPerStrokeRandomSource(KisPerStrokeRandomSourceSP value)
The PopupWidgetInterface abstract class defines the basic interface that will be used by all popup wi...
QRectF m_oldColorPreviewUpdateRect
void enableControl(QWidget *control, bool value)
void slotColorPickerRequestedOutlineUpdate()
virtual KisOptimizedBrushOutline getOutlinePath(const QPointF &documentPos, const KoPointerEvent *event, KisPaintOpSettings::OutlineMode outlineMode)
QPointF m_outlineDocPoint
virtual void requestUpdateOutline(const QPointF &outlineDocPoint, const KoPointerEvent *event)
void deactivate() override
int flags() const override
void mouseReleaseEvent(KoPointerEvent *event) override
QWidget * createOptionWidget() override
QRectF m_oldOutlineRect
void activate(const QSet< KoShape * > &shapes) override
void deactivateAlternateAction(AlternateAction action) override
void setOutlineVisible(bool visible)
void addOptionWidgetLayout(QLayout *layout)
Add the tool-specific layout to the default option widget layout.
void increaseBrushSize()
void paint(QPainter &gc, const KoViewConverter &converter) override
KisPaintOpPresetSP m_oldPreset
void deactivatePrimaryAction() override
void sigPaintingFinished()
void setMode(ToolMode mode) override
bool isSamplingAction(AlternateAction action)
void rotateBrushTipCounterClockwisePrecise()
void mousePressEvent(KoPointerEvent *event) override
void rotateBrushTipClockwise()
bool isOutlineEnabled() const
bool isOutlineVisible() const
virtual void addOptionWidgetOption(QWidget *control, QWidget *label=nullptr)
Add a widget and a label to the current option widget layout.
bool isEraser() const
void rotateBrushTipClockwisePrecise()
KisToolPaint(KoCanvasBase *canvas, const QCursor &cursor)
QScopedPointer< Private > m_d
void slotColorPickerRequestedCursor(const QCursor &cursor)
void decreaseBrushSize()
KisOptimizedBrushOutline m_currentOutline
void showControl(QWidget *control, bool value)
void slotPopupQuickHelp()
void canvasResourceChanged(int key, const QVariant &v) override
KisPopupWidgetInterface * popupWidget() override
void endAlternateAction(KoPointerEvent *event, AlternateAction action) override
void activatePrimaryAction() override
QGridLayout * m_optionsWidgetLayout
void continueAlternateAction(KoPointerEvent *event, AlternateAction action) override
void rotateBrushTipCounterClockwise()
void activateAlternateAction(AlternateAction action) override
void mouseMoveEvent(KoPointerEvent *event) override
KisAsyncColorSamplerHelper m_colorSamplerHelper
virtual QString quickHelp() const
void beginAlternateAction(KoPointerEvent *event, AlternateAction action) override
~KisToolPaint() override
KisToolUtils::StandardBrushSizes m_standardBrushSizes
void slotColorPickerRequestedCursorReset()
KisOptimizedBrushOutline tryFixBrushOutline(const KisOptimizedBrushOutline &originalOutline)
void setOutlineEnabled(bool enabled)
void tryRestoreOpacitySnapshot()
KisCanvasResourceProvider * canvasResourceProvider()
QPointer< KoCanvasResourceProvider > resourceManager
bool isTouchEvent() const
QPointF point
The point in document coordinates.
Q_INVOKABLE QString toolId() const
void statusTextChanged(const QString &statusText)
void useCursor(const QCursor &cursor)
QAction * action(const QString &name) const
KoPointerEvent * lastDeliveredPointerEvent() const
virtual void zoom(qreal *zoomX, qreal *zoomY) const
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
OutlineStyle
Definition kis_global.h:53
@ OUTLINE_CIRCLE
Definition kis_global.h:55
@ OUTLINE_FULL
Definition kis_global.h:56
@ OUTLINE_TILT
Definition kis_global.h:57
@ OUTLINE_NONE
Definition kis_global.h:54
QWidget * findLabelWidget(QGridLayout *layout, QWidget *control)
auto maxDimension(Size size) -> decltype(size.width())
qreal directionBetweenPoints(const QPointF &p1, const QPointF &p2, qreal defaultAngle)
qreal norm(const T &a)
QIcon loadIcon(const QString &name)
void KRITAUI_EXPORT showBrushSizeFloatingMessage(KoCanvasBase *canvas, qreal size)
@ EffectiveZoom
-Used only by painting tools for non-displaying purposes
KisPaintOpUtils::PositionHistory lastCursorPos
QPointF convertToPixelCoord(KoPointerEvent *e)
Definition kis_tool.cc:189
virtual ToolMode mode() const
Definition kis_tool.cc:407
virtual void activatePrimaryAction()
Definition kis_tool.cc:421
KisImageWSP currentImage()
Definition kis_tool.cc:393
void mouseReleaseEvent(KoPointerEvent *event) override
Definition kis_tool.cc:515
virtual void resetCursorStyle()
Definition kis_tool.cc:613
virtual void continueAlternateAction(KoPointerEvent *event, AlternateAction action)
Definition kis_tool.cc:477
QWidget * optionWidget
Definition kis_tool.cc:73
KisPaintOpPresetSP currentPaintOpPreset()
Definition kis_tool.cc:359
QPointF pixelToView(const QPoint &pixelCoord) const
Definition kis_tool.cc:269
virtual void activateAlternateAction(AlternateAction action)
Definition kis_tool.cc:456
virtual void deactivateAlternateAction(AlternateAction action)
Definition kis_tool.cc:461
bool isActive
Definition kis_tool.h:44
virtual void endAlternateAction(KoPointerEvent *event, AlternateAction action)
Definition kis_tool.cc:483
void mousePressEvent(KoPointerEvent *event) override
Definition kis_tool.cc:510
void canvasResourceChanged(int key, const QVariant &res) override
Definition kis_tool.cc:139
@ FLAG_USES_CUSTOM_SIZE
Definition kis_tool.h:47
@ FLAG_USES_CUSTOM_COMPOSITEOP
Definition kis_tool.h:47
void mouseMoveEvent(KoPointerEvent *event) override
Definition kis_tool.cc:520
void activate(const QSet< KoShape * > &shapes) override
Definition kis_tool.cc:93
void paintToolOutline(QPainter *painter, const KisOptimizedBrushOutline &path)
Definition kis_tool.cc:589
void deactivate() override
Definition kis_tool.cc:131
@ SECONDARY_PAINT_MODE
Definition kis_tool.h:301
@ GESTURE_MODE
Definition kis_tool.h:303
@ PAINT_MODE
Definition kis_tool.h:300
@ HOVER_MODE
Definition kis_tool.h:299
QCursor cursor
Definition kis_tool.cc:64
virtual void beginAlternateAction(KoPointerEvent *event, AlternateAction action)
Definition kis_tool.cc:466
virtual void deactivatePrimaryAction()
Definition kis_tool.cc:426
AlternateAction
Definition kis_tool.h:134
@ SampleFgImage
Definition kis_tool.h:139
@ SampleFgNode
Definition kis_tool.h:137
@ SampleBgImage
Definition kis_tool.h:140
@ SampleBgNode
Definition kis_tool.h:138
virtual void setMode(ToolMode mode)
Definition kis_tool.cc:403
KisCanvas2 * canvas