Krita Source Code Documentation
Loading...
Searching...
No Matches
KisToolEncloseAndFill.cpp
Go to the documentation of this file.
1/*
2 * KDE. Krita Project.
3 *
4 * SPDX-FileCopyrightText: 2022 Deif Lou <ginoba@gmail.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include <kis_debug.h>
10#include <klocalizedstring.h>
11
12#include <QCheckBox>
13#include <QPushButton>
14
17#include <KoGroupButton.h>
18
19#include <ksharedconfig.h>
20
21#include <KoCanvasBase.h>
22#include <KoPointerEvent.h>
23
24#include <kis_layer.h>
25#include <kis_painter.h>
26#include <resources/KoPattern.h>
27#include <kis_selection.h>
28
29#include <KisViewManager.h>
30#include <canvas/kis_canvas2.h>
32#include <kis_slider_spin_box.h>
33#include <kis_cursor.h>
36#include <KisAngleSelector.h>
37#include <KoGroupButton.h>
38#include <kis_color_button.h>
40#include <kis_cmb_composite.h>
42
46#include <kis_command_utils.h>
47#include <functional>
48#include <kis_group_layer.h>
49#include <kis_layer_utils.h>
50
52#include <KisPart.h>
53#include <KisDocument.h>
54#include <kis_dummies_facade.h>
58
60
62
69
71 : KisDynamicDelegatedTool<KisToolShape>(canvas, QCursor())
72{
73 setObjectName("tool_enclose_and_fill");
74}
75
78
84
85void KisToolEncloseAndFill::activate(const QSet<KoShape*> &shapes)
86{
88 m_configGroup = KSharedConfig::openConfig()->group(toolId());
89 KisCanvas2 *kisCanvas = static_cast<KisCanvas2*>(canvas());
90 KisCanvasResourceProvider *resourceProvider = kisCanvas->viewManager()->canvasResourceProvider();
91 if (resourceProvider) {
92 connect(resourceProvider,
93 SIGNAL(sigNodeChanged(const KisNodeSP)),
94 this,
97 }
98}
99
101{
102 m_referencePaintDevice = nullptr;
103 m_referenceNodeList = nullptr;
104 KisCanvas2 *kisCanvas = static_cast<KisCanvas2*>(canvas());
105 KisCanvasResourceProvider *resourceProvider = kisCanvas->viewManager()->canvasResourceProvider();
106 if (resourceProvider) {
107 disconnect(resourceProvider,
108 SIGNAL(sigNodeChanged(const KisNodeSP)),
109 this,
111 }
114}
115
117{
118 if (delegateTool()) {
119 delegateTool()->deactivate();
120 }
121
122 if (m_enclosingMethod == Ellipse) {
124 setDelegateTool(reinterpret_cast<KisDynamicDelegateTool<KisToolShape>*>(newDelegateTool));
125 setCursor(newDelegateTool->cursor());
126 } else if (m_enclosingMethod == Path) {
128 setDelegateTool(reinterpret_cast<KisDynamicDelegateTool<KisToolShape>*>(newDelegateTool));
129 setCursor(newDelegateTool->cursor());
130 } else if (m_enclosingMethod == Lasso) {
132 setDelegateTool(reinterpret_cast<KisDynamicDelegateTool<KisToolShape>*>(newDelegateTool));
133 setCursor(newDelegateTool->cursor());
134 } else if (m_enclosingMethod == Brush) {
136 setDelegateTool(reinterpret_cast<KisDynamicDelegateTool<KisToolShape>*>(newDelegateTool));
137 setCursor(newDelegateTool->cursor());
138 } else {
140 setDelegateTool(reinterpret_cast<KisDynamicDelegateTool<KisToolShape>*>(newDelegateTool));
141 setCursor(newDelegateTool->cursor());
142 }
143
145
146 if (isActivated()) {
147 delegateTool()->activate(QSet<KoShape*>());
148 }
149}
150
152{
153 if (!delegateTool()) {
154 return false;
155 }
156
158 return reinterpret_cast<KisRectangleEnclosingProducer*>(delegateTool())->hasUserInteractionRunning();
159 } else if (m_enclosingMethod == Ellipse) {
160 return reinterpret_cast<KisEllipseEnclosingProducer*>(delegateTool())->hasUserInteractionRunning();
161 } else if (m_enclosingMethod == Path) {
162 return reinterpret_cast<KisPathEnclosingProducer*>(delegateTool())->hasUserInteractionRunning();
163 } else if (m_enclosingMethod == Lasso) {
164 return reinterpret_cast<KisLassoEnclosingProducer*>(delegateTool())->hasUserInteractionRunning();
165 } else if (m_enclosingMethod == Brush) {
166 return reinterpret_cast<KisBrushEnclosingProducer*>(delegateTool())->hasUserInteractionRunning();
167 }
168 return false;
169}
170
172{
173 // cannot use enclose and fill tool on non-painting layers.
174 // this logic triggers with multiple layer types like vector layer, clone layer, file layer, group layer
175 if (currentNode().isNull() || currentNode()->inherits("KisShapeLayer") || nodePaintAbility() != NodePaintAbility::PAINT) {
176 KisCanvas2 * kiscanvas = static_cast<KisCanvas2*>(canvas());
177 kiscanvas->viewManager()->
178 showFloatingMessage(
179 i18n("You cannot use this tool with the selected layer type"),
180 QIcon(), 2000, KisFloatingMessage::Medium, Qt::AlignCenter);
181 event->ignore();
182 return;
183 }
184
185 if (!nodeEditable()) {
186 event->ignore();
187 return;
188 }
189
191}
192
194{
196 if (delegateTool()) {
197 delegateTool()->activatePrimaryAction();
198 }
199 return;
200 }
202}
203
211
213{
215 if (delegateTool()) {
216 delegateTool()->beginPrimaryAction(event);
217 }
218 return;
219 }
222}
223
225{
227 if (delegateTool()) {
228 delegateTool()->continuePrimaryAction(event);
229 }
230 return;
231 }
233 return;
234 }
236}
237
239{
241 if (delegateTool()) {
242 delegateTool()->endPrimaryAction(event);
243 }
244 return;
245 }
247 return;
248 }
251}
252
254{
256 if (delegateTool()) {
257 delegateTool()->beginPrimaryDoubleClickAction(event);
258 }
259 return;
260 }
262}
263
265{
267 new KisStrokeStrategyUndoCommandBased(kundo2_i18n("Enclose and Fill"), false, image().data());
268 strategy->setSupportsWrapAroundMode(true);
269 m_fillStrokeId = image()->startStroke(strategy);
271
272 m_dirtyRect.reset(new QRect);
273
274 KisResourcesSnapshotSP resources =
275 new KisResourcesSnapshot(image(), currentNode(), this->canvas()->resourceManager());
276
277 if (m_reference == CurrentLayer) {
279 } else if (m_reference == AllLayers) {
281 } else if (m_reference == ColorLabeledLayers) {
282 if (!m_referenceNodeList) {
283 m_referencePaintDevice = KisMergeLabeledLayersCommand::createRefPaintDevice(image(), "Enclose and Fill Tool Reference Result Paint Device");
285 }
286 KisPaintDeviceSP newReferencePaintDevice = KisMergeLabeledLayersCommand::createRefPaintDevice(image(), "Enclose and Fill Tool Reference Result Paint Device");
288 const int currentTime = image()->animationInterface()->currentTime();
289 image()->addJob(
293 image(),
295 newReferenceNodeList,
297 newReferencePaintDevice,
300 m_previousTime != currentTime,
301 m_useActiveLayer ? currentNode() : nullptr
302 )),
303 false,
306 )
307 );
308 m_referencePaintDevice = newReferencePaintDevice;
309 m_referenceNodeList = newReferenceNodeList;
310 m_previousTime = currentTime;
311 }
312
314 // Reset this so that the device from color labeled layers gets
315 // regenerated when that mode is selected again
316 m_referenceNodeList.reset();
317 }
318
319 QTransform transform;
320 transform.rotate(m_patternRotation);
321 const qreal normalizedScale = m_patternScale * 0.01;
322 transform.scale(normalizedScale, normalizedScale);
323 resources->setFillTransform(transform);
324
325 KisProcessingVisitorSP visitor =
327 enclosingMask,
328 resources->activeSelection(),
329 resources,
334 false,
339 m_expand,
341 m_feather,
344 false,
347 m_customOpacity / 100.0,
350
351 image()->addJob(
355 false,
358 )
359 );
360
361 image()->addJob(
365 false,
368 )
369 );
370
372
373 m_fillStrokeId = nullptr;
374 m_dirtyRect = nullptr;
375}
376
378{
379 return KisDynamicDelegatedTool::flags() | KisTool::FLAG_USES_CUSTOM_SIZE | KisTool::FLAG_USES_CUSTOM_PRESET;
380}
381
383{
385
386 // Create widgets
387 KisOptionButtonStrip *optionButtonStripEnclosingMethod =
390 optionButtonStripEnclosingMethod->addButton(
391 KisIconUtils::loadIcon("tool_rect_selection"));
393 optionButtonStripEnclosingMethod->addButton(
394 KisIconUtils::loadIcon("tool_elliptical_selection"));
395 m_buttonEnclosingMethodPath = optionButtonStripEnclosingMethod->addButton(
396 KisIconUtils::loadIcon("tool_path_selection"));
397 m_buttonEnclosingMethodLasso = optionButtonStripEnclosingMethod->addButton(
398 KisIconUtils::loadIcon("tool_outline_selection"));
399 m_buttonEnclosingMethodBrush = optionButtonStripEnclosingMethod->addButton(
400 KisIconUtils::loadIcon("krita_tool_freehand"));
401 m_buttonEnclosingMethodLasso->setChecked(true);
402
403 m_comboBoxRegionSelectionMethod = new QComboBox;
405 regionSelectionMethodToUserString(RegionSelectionMethod::SelectAllRegions),
406 static_cast<int>(RegionSelectionMethod::SelectAllRegions)
407 );
409 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsFilledWithSpecificColor),
410 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithSpecificColor)
411 );
413 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsFilledWithTransparent),
414 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithTransparent)
415 );
417 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent),
418 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent)
419 );
421 regionSelectionMethodToUserString(RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor),
422 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor)
423 );
425 regionSelectionMethodToUserString(RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent),
426 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent)
427 );
430 RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent
431 ),
432 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent)
433 );
435 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor),
436 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor)
437 );
439 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsSurroundedByTransparent),
440 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedByTransparent)
441 );
443 regionSelectionMethodToUserString(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent),
444 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent)
445 );
446 m_comboBoxRegionSelectionMethod->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
447 m_comboBoxRegionSelectionMethod->setMinimumContentsLength(15);
448 m_comboBoxRegionSelectionMethod->view()->setMinimumWidth(
449 m_comboBoxRegionSelectionMethod->view()->sizeHintForColumn(0)
450 );
453 new QCheckBox(
454 i18nc("The 'invert' checkbox in enclose and fill tool",
455 "Invert")
456 );
458 new QCheckBox(
459 i18nc("The 'include contour regions' checkbox in enclose and fill tool",
460 "Include contour regions")
461 );
462 m_checkBoxRegionSelectionIncludeContourRegions->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
463
464 KisOptionButtonStrip *optionButtonStripFillWith = new KisOptionButtonStrip;
465 m_buttonFillWithFG = optionButtonStripFillWith->addButton(
466 KisIconUtils::loadIcon("object-order-lower-calligra"));
467 m_buttonFillWithBG = optionButtonStripFillWith->addButton(
468 KisIconUtils::loadIcon("object-order-raise-calligra"));
470 optionButtonStripFillWith->addButton(KisIconUtils::loadIcon("pattern"));
471 m_buttonFillWithFG->setChecked(true);
473 m_sliderPatternScale->setRange(0, 10000, 2);
476 i18nc("The pattern 'scale' spinbox in enclose and fill tool options; {n} is the "
477 "number value, % is the percent sign",
478 "Scale: {n}%"));
482 m_checkBoxCustomBlendingOptions = new QCheckBox(i18n("Use custom blending options"));
483 m_checkBoxCustomBlendingOptions->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
487 i18nc("{n} is the number value, % is the percent sign", "Opacity: {n}%"));
489
491 m_sliderFillThreshold->setPrefix(i18nc("The 'threshold' spinbox prefix in enclose and fill tool options", "Threshold: "));
496 i18nc("The 'spread' spinbox in enclose and fill tool options; {n} is the number value, % is the percent sign",
497 "Spread: {n}%"));
500 m_sliderCloseGap->setPrefix(i18nc("The 'close gap' spinbox prefix in enclose and fill tool options", "Close Gap: "));
502 m_sliderCloseGap->setSuffix(i18n(" px"));
504 new QCheckBox(
505 i18nc("The 'use selection as boundary' checkbox in enclose and fill tool to use selection borders as boundary when filling",
506 "Use selection as boundary")
507 );
508 m_checkBoxSelectionAsBoundary->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
509
510 m_checkBoxAntiAlias = new QCheckBox(i18nc("The anti-alias checkbox in enclose and fill tool options", "Anti-aliasing"));
513 m_sliderExpand->setPrefix(i18nc("The 'grow/shrink' spinbox prefix in enclose and fill tool options", "Grow: "));
514 m_sliderExpand->setRange(-400, 400);
516 m_sliderExpand->setSuffix(i18n(" px"));
517 m_buttonStopGrowingAtDarkestPixel = new QToolButton;
518 m_buttonStopGrowingAtDarkestPixel->setAutoRaise(true);
519 m_buttonStopGrowingAtDarkestPixel->setCheckable(true);
520 m_buttonStopGrowingAtDarkestPixel->setIcon(KisIconUtils::loadIcon("stop-at-boundary"));
521 containerGrow->appendWidget("sliderExpand", m_sliderExpand);
522 containerGrow->appendWidget("buttonStopGrowingAtDarkestPixel", m_buttonStopGrowingAtDarkestPixel);
523 containerGrow->setOrientation(Qt::Horizontal);
525 m_sliderFeather->setPrefix(i18nc("The 'feather' spinbox prefix in enclose and fill tool options", "Feather: "));
526 m_sliderFeather->setRange(0, 400);
528 m_sliderFeather->setSuffix(i18n(" px"));
529
530 KisOptionButtonStrip *optionButtonStripReference = new KisOptionButtonStrip;
531 m_buttonReferenceCurrent = optionButtonStripReference->addButton(
532 KisIconUtils::loadIcon("current-layer"));
533 m_buttonReferenceAll = optionButtonStripReference->addButton(
534 KisIconUtils::loadIcon("all-layers"));
536 optionButtonStripReference->addButton(KisIconUtils::loadIcon("tag"));
537 m_buttonReferenceCurrent->setChecked(true);
543 m_checkBoxUseActiveLayer = new QCheckBox(i18n("Use active layer"));
544
545 QPushButton *buttonReset = new QPushButton(i18nc("The 'reset' button in enclose and fill tool options", "Reset"));
546
547 // Set the tooltips
548 m_buttonEnclosingMethodRectangle->setToolTip(i18n("Rectangle"));
549 m_buttonEnclosingMethodEllipse->setToolTip(i18n("Ellipse"));
550 m_buttonEnclosingMethodPath->setToolTip(i18n("Bezier Curve"));
551 m_buttonEnclosingMethodLasso->setToolTip(i18n("Lasso"));
552 m_buttonEnclosingMethodBrush->setToolTip(i18n("Brush"));
554 m_checkBoxRegionSelectionInvert->setToolTip(i18n("Enable to fill opposite regions instead"));
555 m_checkBoxRegionSelectionIncludeContourRegions->setToolTip(i18n("Enable to also fill shapes that touch the contour of the enclosing region"));
556 m_buttonFillWithFG->setToolTip(i18n("Foreground color"));
557 m_buttonFillWithBG->setToolTip(i18n("Background color"));
558 m_buttonFillWithPattern->setToolTip(i18n("Pattern"));
559 m_sliderPatternScale->setToolTip(i18n("Set the scale of the pattern"));
560 m_angleSelectorPatternRotation->setToolTip(i18n("Set the rotation of the pattern"));
561 m_checkBoxCustomBlendingOptions->setToolTip(i18n("Set custom blending options instead of using the brush ones"));
562 m_sliderCustomOpacity->setToolTip(i18n("Set a custom opacity for the fill"));
563 m_comboBoxCustomCompositeOp->setToolTip(i18n("Set a custom blend mode for the fill"));
564
565 m_sliderFillThreshold->setToolTip(i18n("Set the color similarity tolerance of the fill. Increasing threshold increases the range of similar colors to be filled."));
566 m_sliderFillOpacitySpread->setToolTip(i18n("Set the extent of the opaque portion of the fill. Decreasing spread decreases opacity of fill areas depending on color similarity."));
567 m_sliderCloseGap->setToolTip(i18n("Close gaps in lines up to the set amount"));
568 m_checkBoxSelectionAsBoundary->setToolTip(i18n("Set if the contour of the active selection should be treated as a boundary when filling the region"));
569
570 m_checkBoxAntiAlias->setToolTip(i18n("Smooths the edges of the fill"));
571 m_sliderExpand->setToolTip(i18n("Grow or shrink the fill by the set amount"));
572 m_buttonStopGrowingAtDarkestPixel->setToolTip(i18n("Stop growing at the darkest and/or most opaque pixels"));
573 m_sliderFeather->setToolTip(i18n("Blur the fill by the set amount"));
574
575 m_buttonReferenceCurrent->setToolTip(i18n("Fill regions found from the active layer"));
576 m_buttonReferenceAll->setToolTip(i18n("Fill regions found from the merging of all layers"));
577 m_buttonReferenceLabeled->setToolTip(i18n("Fill regions found from the merging of layers with specific color labels"));
578 m_checkBoxUseActiveLayer->setToolTip(i18n("Includes the active layer in regions found from merging of layers with specific color labels"));
579
580 buttonReset->setToolTip(i18n("Reset the options to their default values"));
581
582 // Construct the option widget
584 m_optionWidget->setContentsMargins(0, 10, 0, 10);
586
587 KisOptionCollectionWidgetWithHeader *sectionEnclosingMethod =
589 i18nc("The 'enclosing method' section label in enclose and fill tool options", "Enclosing method")
590 );
591 sectionEnclosingMethod->setPrimaryWidget(optionButtonStripEnclosingMethod);
592 m_optionWidget->appendWidget("sectionEnclosingMethod", sectionEnclosingMethod);
593
595 widgetLabelsGroup->appendWidget("labelWidget", m_widgetLabels);
596 widgetLabelsGroup->appendWidget("checkBoxUseActiveLayer", m_checkBoxUseActiveLayer);
597 widgetLabelsGroup->setWidgetsMargin(0);
598
599 KisOptionCollectionWidgetWithHeader *sectionReference =
601 i18nc("The 'reference' section label in enclose and fill tool options", "Reference")
602 );
603 sectionReference->setPrimaryWidget(optionButtonStripReference);
604 sectionReference->appendWidget("widgetLabels", widgetLabelsGroup);
605 sectionReference->setWidgetVisible("widgetLabels", false);
606 m_optionWidget->appendWidget("sectionReference", sectionReference);
607
608
609 KisOptionCollectionWidgetWithHeader *sectionWhatToFill =
611 i18nc("The 'target regions' section label in enclose and fill tool options", "Target regions")
612 );
614 sectionWhatToFill->appendWidget("buttonRegionSelectionColor", m_buttonRegionSelectionColor);
615 sectionWhatToFill->appendWidget("checkBoxRegionSelectionInvert", m_checkBoxRegionSelectionInvert);
616 sectionWhatToFill->appendWidget("checkBoxRegionSelectionIncludeContourRegions", m_checkBoxRegionSelectionIncludeContourRegions);
617 m_optionWidget->appendWidget("sectionWhatToFill", sectionWhatToFill);
618
619 KisOptionCollectionWidgetWithHeader *sectionFillWith =
621 i18nc("The 'fill source' section label in enclose and fill tool options", "Fill source")
622 );
623 sectionFillWith->setPrimaryWidget(optionButtonStripFillWith);
624 sectionFillWith->appendWidget("sliderPatternScale", m_sliderPatternScale);
625 sectionFillWith->appendWidget("angleSelectorPatternRotation", m_angleSelectorPatternRotation);
626 sectionFillWith->appendWidget("checkBoxCustomBlendingOptions", m_checkBoxCustomBlendingOptions);
627 sectionFillWith->appendWidget("sliderCustomOpacity", m_sliderCustomOpacity);
628 sectionFillWith->appendWidget("comboBoxCustomCompositeOp", m_comboBoxCustomCompositeOp);
629 sectionFillWith->setWidgetVisible("sliderPatternScale", false);
630 sectionFillWith->setWidgetVisible("angleSelectorPatternRotation", false);
631 m_optionWidget->appendWidget("sectionFillWith", sectionFillWith);
632
633 KisOptionCollectionWidgetWithHeader *sectionRegionExtent =
635 i18nc("The 'fill extent' section label in enclose and fill tool options", "Fill extent")
636 );
637 sectionRegionExtent->appendWidget("sliderThreshold", m_sliderFillThreshold);
638 sectionRegionExtent->appendWidget("sliderSpread", m_sliderFillOpacitySpread);
639 sectionRegionExtent->appendWidget("sliderCloseGap", m_sliderCloseGap);
640 sectionRegionExtent->appendWidget("checkBoxSelectionAsBoundary", m_checkBoxSelectionAsBoundary);
641 m_optionWidget->appendWidget("sectionRegionExtent", sectionRegionExtent);
642
643 KisOptionCollectionWidgetWithHeader *sectionAdjustments =
645 i18nc("The 'adjustments' section label in enclose and fill tool options", "Adjustments")
646 );
647 sectionAdjustments->appendWidget("checkBoxAntiAlias", m_checkBoxAntiAlias);
648 sectionAdjustments->appendWidget("containerGrow", containerGrow);
649 sectionAdjustments->appendWidget("sliderFeather", m_sliderFeather);
650 m_optionWidget->appendWidget("sectionAdjustments", sectionAdjustments);
651
652 m_optionWidget->appendWidget("buttonReset", buttonReset);
653
654 // Initialize widgets
656 m_buttonEnclosingMethodRectangle->setChecked(true);
657 } else if (m_enclosingMethod == Ellipse) {
658 m_buttonEnclosingMethodEllipse->setChecked(true);
659 } else if (m_enclosingMethod == Path) {
660 m_buttonEnclosingMethodPath->setChecked(true);
661 } else if (m_enclosingMethod == Lasso) {
662 m_buttonEnclosingMethodLasso->setChecked(true);
663 } else {
664 m_buttonEnclosingMethodBrush->setChecked(true);
665 }
668 sectionWhatToFill->setWidgetVisible(
669 "buttonRegionSelectionColor",
670 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor ||
671 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent ||
672 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor ||
673 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent ||
674 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor ||
675 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent
676 );
679 sectionWhatToFill->setWidgetVisible(
680 "checkBoxRegionSelectionIncludeContourRegions",
681 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegions ||
682 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor ||
683 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent ||
684 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent ||
685 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor ||
686 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent ||
687 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent
688 );
690 m_buttonFillWithBG->setChecked(true);
691 } else if (m_fillType == FillWithPattern) {
692 m_buttonFillWithPattern->setChecked(true);
693 sectionFillWith->setWidgetVisible("sliderPatternScale", true);
694 sectionFillWith->setWidgetVisible("angleSelectorPatternRotation", true);
695 }
701 ? currentNode()->paintDevice()->colorSpace()
702 : nullptr);
705 sectionFillWith->setWidgetVisible("sliderCustomOpacity", false);
706 sectionFillWith->setWidgetVisible("comboBoxCustomCompositeOp", false);
707 }
712 m_checkBoxAntiAlias->setChecked(m_antiAlias);
716 if (m_reference == AllLayers) {
717 m_buttonReferenceAll->setChecked(true);
718 } else if (m_reference == ColorLabeledLayers) {
719 m_buttonReferenceLabeled->setChecked(true);
720 sectionReference->setWidgetVisible("widgetLabels", true);
721 }
724
725 // Make connections
726 connect(optionButtonStripEnclosingMethod,
727 SIGNAL(buttonToggled(KoGroupButton *, bool)),
730 bool)));
732 SIGNAL(currentIndexChanged(int)),
735 SIGNAL(changed(const KoColor&)),
738 SIGNAL(toggled(bool)),
741 SIGNAL(toggled(bool)),
743 connect(optionButtonStripFillWith,
744 SIGNAL(buttonToggled(KoGroupButton *, bool)),
747 SIGNAL(valueChanged(double)),
750 SIGNAL(angleChanged(double)),
753 SIGNAL(toggled(bool)),
756 SIGNAL(valueChanged(int)),
759 SIGNAL(currentIndexChanged(int)),
762 SIGNAL(valueChanged(int)),
765 SIGNAL(valueChanged(int)),
768 SIGNAL(valueChanged(int)),
771 SIGNAL(toggled(bool)),
774 SIGNAL(toggled(bool)),
777 SIGNAL(valueChanged(int)),
780 SIGNAL(toggled(bool)),
783 SIGNAL(valueChanged(int)),
785 connect(optionButtonStripReference,
786 SIGNAL(buttonToggled(KoGroupButton *, bool)),
789 SIGNAL(selectionChanged()),
792 SIGNAL(toggled(bool)),
794 connect(buttonReset,
795 SIGNAL(clicked()),
797
798 return m_optionWidget;
799}
800
802{
806 m_regionSelectionInvert = m_configGroup.readEntry<bool>("regionSelectionInvert", false);
807 m_regionSelectionIncludeContourRegions = m_configGroup.readEntry<bool>("regionSelectionIncludeContourRegions", false);
808 {
809 const QString fillTypeStr = m_configGroup.readEntry<QString>("fillWith", "");
810 if (fillTypeStr == "foregroundColor") {
812 } else if (fillTypeStr == "backgroundColor") {
814 } else if (fillTypeStr == "pattern") {
816 } else {
817 if (m_configGroup.readEntry<bool>("usePattern", false)) {
819 } else {
821 }
822 }
823 }
824 m_patternScale = m_configGroup.readEntry<qreal>("patternScale", 100.0);
825 m_patternRotation = m_configGroup.readEntry<qreal>("patternRotate", 0.0);
826 m_useCustomBlendingOptions = m_configGroup.readEntry<bool>("useCustomBlendingOptions", false);
827 m_customOpacity = qBound(0, m_configGroup.readEntry<int>("customOpacity", 100), 100);
828 m_customCompositeOp = m_configGroup.readEntry<QString>("customCompositeOp", COMPOSITE_OVER);
831 }
832 m_fillThreshold = m_configGroup.readEntry<int>("fillThreshold", 8);
833 m_fillOpacitySpread = m_configGroup.readEntry<int>("fillOpacitySpread", 100);
834 m_closeGap = m_configGroup.readEntry<int>("closeGapAmount", 0);
835 m_useSelectionAsBoundary = m_configGroup.readEntry<bool>("useSelectionAsBoundary", true);
836 m_antiAlias = m_configGroup.readEntry<bool>("antiAlias", false);
837 m_expand = m_configGroup.readEntry<int>("expand", 0);
838 m_stopGrowingAtDarkestPixel = m_configGroup.readEntry<bool>("stopGrowingAtDarkestPixel", false);
839 m_feather = m_configGroup.readEntry<int>("feather", 0);
840 {
841 const QString sampleLayersModeStr = m_configGroup.readEntry<QString>("reference", "currentLayer");
842 if (sampleLayersModeStr == "allLayers") {
844 } else if (sampleLayersModeStr == "colorLabeledLayers") {
846 } else {
848 }
849 }
850 {
851 const QStringList colorLabelsStr = m_configGroup.readEntry<QString>("colorLabels", "").split(',', Qt::SkipEmptyParts);
852
853 m_selectedColorLabels.clear();
854 for (const QString &colorLabelStr : colorLabelsStr) {
855 bool ok;
856 const int colorLabel = colorLabelStr.toInt(&ok);
857 if (ok) {
858 m_selectedColorLabels << colorLabel;
859 }
860 }
861 }
862 m_useActiveLayer = m_configGroup.readEntry<bool>("useActiveLayer", false);
863
865}
866
871
873{
874 m_configGroup.writeEntry("enclosingMethod", enclosingMethodToConfigString(enclosingMethod));
875}
876
878{
879 switch (enclosingMethod) {
880 case Rectangle: return "rectangle";
881 case Ellipse: return "ellipse";
882 case Path: return "path";
883 case Brush: return "brush";
884 default: return "lasso";
885 }
886}
887
889{
890 if (configString == "rectangle") {
891 return Rectangle;
892 } else if (configString == "ellipse") {
893 return Ellipse;
894 } else if (configString == "path") {
895 return Path;
896 } else if (configString == "brush") {
897 return Brush;
898 }
899 return Lasso;
900}
901
903{
904 if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegions) {
905 return i18nc("Region selection method in enclose and fill tool",
906 "All");
907 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor) {
908 return i18nc("Region selection method in enclose and fill tool",
909 "Specific color");
910 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent) {
911 return i18nc("Region selection method in enclose and fill tool",
912 "Transparency");
913 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent) {
914 return i18nc("Region selection method in enclose and fill tool",
915 "Specific color or transparency");
916 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor) {
917 return i18nc("Region selection method in enclose and fill tool",
918 "All, excluding a specific color");
919 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent) {
920 return i18nc("Region selection method in enclose and fill tool",
921 "All, excluding transparency");
922 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent) {
923 return i18nc("Region selection method in enclose and fill tool",
924 "All, excluding a specific color or transparency");
925 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor) {
926 return i18nc("Region selection method in enclose and fill tool",
927 "Any surrounded by a specific color");
928 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedByTransparent) {
929 return i18nc("Region selection method in enclose and fill tool",
930 "Any surrounded by transparency");
931 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent) {
932 return i18nc("Region selection method in enclose and fill tool",
933 "Any surrounded by a specific color or transparency");
934 }
935 return QString();
936}
937
942
944{
945 m_configGroup.writeEntry("regionSelectionMethod", regionSelectionMethodToConfigString(regionSelectionMethod));
946}
947
949{
950 if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegions) {
951 return "allRegions";
952 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor) {
953 return "regionsFilledWithSpecificColor";
954 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent) {
955 return "regionsFilledWithTransparent";
956 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent) {
957 return "regionsFilledWithSpecificColorOrTransparent";
958 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor) {
959 return "allRegionsExceptFilledWithSpecificColor";
960 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent) {
961 return "allRegionsExceptFilledWithTransparent";
962 } else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent) {
963 return "allRegionsExceptFilledWithSpecificColorOrTransparent";
964 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor) {
965 return "regionsSurroundedBySpecificColor";
966 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedByTransparent) {
967 return "regionsSurroundedByTransparent";
968 } else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent) {
969 return "regionsSurroundedBySpecificColorOrTransparent";
970 }
971 return QString();
972}
973
975{
976 if (configString == "regionsFilledWithSpecificColor") {
977 return RegionSelectionMethod::SelectRegionsFilledWithSpecificColor;
978 } else if (configString == "regionsFilledWithTransparent") {
979 return RegionSelectionMethod::SelectRegionsFilledWithTransparent;
980 } else if (configString == "regionsFilledWithSpecificColorOrTransparent") {
981 return RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent;
982 } else if (configString == "allRegionsExceptFilledWithSpecificColor") {
983 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor;
984 } else if (configString == "allRegionsExceptFilledWithTransparent") {
985 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent;
986 } else if (configString == "allRegionsExceptFilledWithSpecificColorOrTransparent") {
987 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent;
988 } else if (configString == "regionsSurroundedBySpecificColor") {
989 return RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor;
990 } else if (configString == "regionsSurroundedByTransparent") {
991 return RegionSelectionMethod::SelectRegionsSurroundedByTransparent;
992 } else if (configString == "regionsSurroundedBySpecificColorOrTransparent") {
993 return RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent;
994 }
995 return RegionSelectionMethod::SelectAllRegions;
996}
997
999{
1000 const QString xmlColor = m_configGroup.readEntry("regionSelectionColor", QString());
1001 QDomDocument doc;
1002 if (doc.setContent(xmlColor)) {
1003 QDomElement e = doc.documentElement().firstChild().toElement();
1004 QString channelDepthID = doc.documentElement().attribute("channeldepth", Integer16BitsColorDepthID.id());
1005 bool ok;
1006 if (e.hasAttribute("space") || e.tagName().toLower() == "srgb") {
1007 return KoColor::fromXML(e, channelDepthID, &ok);
1008 } else if (doc.documentElement().hasAttribute("space") || doc.documentElement().tagName().toLower() == "srgb"){
1009 return KoColor::fromXML(doc.documentElement(), channelDepthID, &ok);
1010 }
1011 }
1012 return KoColor();
1013}
1014
1016{
1017 if (m_configGroup.hasKey("reference")) {
1019 } else {
1020 bool sampleMerged = m_configGroup.readEntry("sampleMerged", false);
1021 return sampleMerged ? AllLayers : CurrentLayer;
1022 }
1023 return CurrentLayer;
1024}
1025
1027{
1028 m_configGroup.writeEntry("reference", referenceToConfigString(reference));
1029}
1030
1032{
1033 if (reference == AllLayers) {
1034 return "allLayers";
1035 } else if (reference == ColorLabeledLayers) {
1036 return "colorLabeledLayers";
1037 }
1038 return "currentLayer";
1039}
1040
1042{
1043 if (configString == "allLayers") {
1044 return AllLayers;
1045 } else if (configString == "colorLabeledLayers") {
1046 return ColorLabeledLayers;
1047 }
1048 return CurrentLayer;
1049}
1050
1074
1076{
1078
1079 KisOptionCollectionWidgetWithHeader *sectionWhatToFill =
1081 sectionWhatToFill->setWidgetVisible("buttonRegionSelectionColor",
1082 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor ||
1083 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent ||
1084 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor ||
1085 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent ||
1086 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor ||
1087 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent
1088 );
1089 sectionWhatToFill->setWidgetVisible(
1090 "checkBoxRegionSelectionIncludeContourRegions",
1091 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegions ||
1092 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor ||
1093 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent ||
1094 m_regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent ||
1095 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor ||
1096 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent ||
1097 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent
1098 );
1099
1101
1103}
1104
1106{
1107 if (color == m_regionSelectionColor) {
1108 return;
1109 }
1110 m_regionSelectionColor = color;
1111 m_configGroup.writeEntry("regionSelectionColor", color.toXML());
1112}
1113
1115{
1116 if (checked == m_regionSelectionInvert) {
1117 return;
1118 }
1119 m_regionSelectionInvert = checked;
1120 m_configGroup.writeEntry("regionSelectionInvert", checked);
1121}
1122
1124{
1126 return;
1127 }
1129 m_configGroup.writeEntry("regionSelectionIncludeContourRegions", checked);
1130}
1131
1134 bool checked)
1135{
1136 if (!checked) {
1137 return;
1138 }
1139 const bool visible = button == m_buttonFillWithPattern;
1140 KisOptionCollectionWidgetWithHeader *sectionFillWith =
1142 sectionFillWith->setWidgetVisible("sliderPatternScale", visible);
1143 sectionFillWith->setWidgetVisible("angleSelectorPatternRotation", visible);
1144
1147
1148 m_configGroup.writeEntry(
1149 "fillWith",
1150 button == m_buttonFillWithFG ? "foregroundColor" : (button == m_buttonFillWithBG ? "backgroundColor" : "pattern")
1151 );
1152}
1153
1155{
1156 if (value == m_patternScale) {
1157 return;
1158 }
1160 m_configGroup.writeEntry("patternScale", value);
1161}
1162
1164{
1165 if (value == m_patternRotation) {
1166 return;
1167 }
1169 m_configGroup.writeEntry("patternRotate", value);
1170}
1171
1173{
1174 KisOptionCollectionWidgetWithHeader *sectionFillWith =
1176 sectionFillWith->setWidgetVisible("sliderCustomOpacity", checked);
1177 sectionFillWith->setWidgetVisible("comboBoxCustomCompositeOp", checked);
1179 m_configGroup.writeEntry("useCustomBlendingOptions", checked);
1180}
1181
1183{
1184 if (value == m_customOpacity) {
1185 return;
1186 }
1188 m_configGroup.writeEntry("customOpacity", value);
1189}
1190
1192{
1193 Q_UNUSED(index);
1194 const QString compositeOpId = m_comboBoxCustomCompositeOp->selectedCompositeOp().id();
1195 if (compositeOpId == m_customCompositeOp) {
1196 return;
1197 }
1198 m_customCompositeOp = compositeOpId;
1199 m_configGroup.writeEntry("customCompositeOp", compositeOpId);
1200}
1201
1203{
1204 if (value == m_fillThreshold) {
1205 return;
1206 }
1208 m_configGroup.writeEntry("fillThreshold", value);
1209}
1210
1212{
1213 if (value == m_fillOpacitySpread) {
1214 return;
1215 }
1217 m_configGroup.writeEntry("fillOpacitySpread", value);
1218}
1219
1221{
1222 if (value == m_closeGap) {
1223 return;
1224 }
1225 m_closeGap = value;
1226 m_configGroup.writeEntry("closeGapAmount", value);
1227}
1228
1230{
1231 if (checked == m_useSelectionAsBoundary) {
1232 return;
1233 }
1234 m_useSelectionAsBoundary = checked;
1235 m_configGroup.writeEntry("useSelectionAsBoundary", checked);
1236}
1237
1239{
1240 if (checked == m_antiAlias) {
1241 return;
1242 }
1243 m_antiAlias = checked;
1244 m_configGroup.writeEntry("antiAlias", checked);
1245}
1246
1248{
1249 if (value == m_expand) {
1250 return;
1251 }
1252 m_expand = value;
1253 m_configGroup.writeEntry("expand", value);
1254}
1255
1257{
1258 if (enabled == m_stopGrowingAtDarkestPixel) {
1259 return;
1260 }
1262 m_configGroup.writeEntry("stopGrowingAtDarkestPixel", enabled);
1263}
1264
1266{
1267 if (value == m_feather) {
1268 return;
1269 }
1270 m_feather = value;
1271 m_configGroup.writeEntry("feather", value);
1272}
1273
1276 bool checked)
1277{
1278 if (!checked) {
1279 return;
1280 }
1281 KisOptionCollectionWidgetWithHeader *sectionReference =
1283 sectionReference->setWidgetVisible("widgetLabels", button == m_buttonReferenceLabeled);
1284
1287
1288 m_configGroup.writeEntry(
1289 "reference",
1290 button == m_buttonReferenceCurrent ? "currentLayer" : (button == m_buttonReferenceAll ? "allLayers" : "colorLabeledLayers")
1291 );
1292}
1293
1295{
1297 if (labels == m_selectedColorLabels) {
1298 return;
1299 }
1300 m_selectedColorLabels = labels;
1301 if (labels.isEmpty()) {
1302 return;
1303 }
1304 QString colorLabels = QString::number(labels.first());
1305 for (int i = 1; i < labels.size(); ++i) {
1306 colorLabels += "," + QString::number(labels[i]);
1307 }
1308 m_configGroup.writeEntry("colorLabels", colorLabels);
1309}
1310
1312{
1313 m_buttonEnclosingMethodLasso->setChecked(true);
1314 m_comboBoxRegionSelectionMethod->setCurrentIndex(
1315 m_comboBoxRegionSelectionMethod->findData(static_cast<int>(RegionSelectionMethod::SelectAllRegions))
1316 );
1318 m_checkBoxRegionSelectionInvert->setChecked(false);
1320 m_buttonFillWithFG->setChecked(true);
1323 m_checkBoxCustomBlendingOptions->setChecked(false);
1329 m_checkBoxSelectionAsBoundary->setChecked(true);
1330 m_checkBoxAntiAlias->setChecked(false);
1332 m_buttonStopGrowingAtDarkestPixel->setChecked(false);
1334 m_buttonReferenceCurrent->setChecked(true);
1336}
1337
1339{
1341 disconnect(m_previousNode->paintDevice().data(),
1342 SIGNAL(colorSpaceChanged(const KoColorSpace*)),
1343 this,
1344 SLOT(slot_colorSpaceChanged(const KoColorSpace*)));
1345 }
1346 if (node && node->paintDevice()) {
1347 connect(node->paintDevice().data(),
1348 SIGNAL(colorSpaceChanged(const KoColorSpace*)),
1349 this,
1350 SLOT(slot_colorSpaceChanged(const KoColorSpace*)));
1352 }
1353 m_previousNode = node;
1354}
1355
1357{
1359 return;
1360 }
1361 const KoColorSpace *compositionSpace = colorSpace;
1362 if (currentNode() && currentNode()->paintDevice()) {
1363 // Currently, composition source is enough to determine the available blending mode,
1364 // because either destination is the same (paint layers), or composition happens
1365 // in source space (masks).
1366 compositionSpace = currentNode()->paintDevice()->compositionSourceColorSpace();
1367 }
1368 m_comboBoxCustomCompositeOp->validate(compositionSpace);
1369}
1370
1372{
1373 if (checked == m_useActiveLayer) {
1374 return;
1375 }
1376 m_useActiveLayer = checked;
1377 m_configGroup.writeEntry("useActiveLayer", checked);
1378}
float value(const T *src, size_t ch)
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const QString COMPOSITE_OVER
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
@ IncreasingDirection_Clockwise
A widget with several options to select an angle.
@ FlipOptionsMode_ContextMenu
The flip options are shown only as a context menu when right-clicking the gauge widget.
void setFlipOptionsMode(FlipOptionsMode newMode)
Sets the mode in which the flip options should be shown.
void setIncreasingDirection(KisAngleGauge::IncreasingDirection newIncreasingDirection)
Sets the increasing direction in the angle gauge.
void setAngle(qreal newAngle)
Sets the current angle.
KisViewManager * viewManager() const
A pushbutton to display or allow user selection of a color.
void setColor(const KoColor &c)
void setButtonSize(int size)
Set the size of the buttons.
void setSelection(const QList< int > &indices)
Set the list of checked button indices.
void setExclusive(bool exclusive)
Set if the button selection is mutually exclusive. This allows switching between single or multiple s...
void setButtonWrapEnabled(bool enabled)
Set if the buttons should wrap in multiple lines if there is no enough space horizontally.
void setMouseDragEnabled(bool enabled)
Set if the user can drag to check/uncheck multiple buttons.
QList< int > selection() const
Get the list of checked button indices.
void validate(const KoColorSpace *cs)
void selectCompositeOp(const KoID &op)
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
void setValue(qreal newValue)
void setRange(qreal newMinimum, qreal newMaximum, int newNumberOfDecimals=0, bool computeNewFastSliderStep=true)
Set the minimum and the maximum values of the range.
void setSoftMaximum(qreal newSoftMaximum)
void beginPrimaryAction(KoPointerEvent *event) override
void activateAlternateAction(typename BaseClass::AlternateAction action) override
void continueAlternateAction(KoPointerEvent *event, typename BaseClass::AlternateAction action) override
void beginAlternateDoubleClickAction(KoPointerEvent *event, typename BaseClass::AlternateAction action) override
void endAlternateAction(KoPointerEvent *event, typename BaseClass::AlternateAction action) override
void beginAlternateAction(KoPointerEvent *event, typename BaseClass::AlternateAction action) override
void activate(const QSet< KoShape * > &shapes) override
void setDelegateTool(DelegateType *newDelegateTool)
void deactivateAlternateAction(typename BaseClass::AlternateAction action) override
KisImageAnimationInterface * animationInterface() const
KisPaintDeviceSP projection() const
void addJob(KisStrokeId id, KisStrokeJobData *data) override
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void endStroke(KisStrokeId id) override
static KisPaintDeviceSP createRefPaintDevice(KisImageSP originalImage, QString name="Merge Labeled Layers Reference Paint Device")
@ GroupSelectionPolicy_SelectIfColorLabeled
Groups will be taken into account only if they have set an explicit color label. This ignores groups ...
Provides a list of consecutive tool buttons.
KoGroupButton * addButton(const QIcon &icon, const QString &text=QString())
Wrapper class around a KisOptionCollectionWidget that also provide a header with a title label and an...
void setPrimaryWidget(QWidget *widget)
Set the primary widget. The list widget takes ownership of it.
void appendWidget(const QString &id, QWidget *widget)
Insert the given widget with the given id at the end of the list. The list widget takes ownership of ...
void setWidgetVisible(int index, bool visible)
Set the visibility of the widget that is at the given position.
Class providing a list of widgets with some addons such as separators, orientation or individual widg...
void setWidgetsMargin(int margin)
Set the margins of the widgets. This allows to indent the widgets with respect to the separators....
T widgetAs(int index) const
Get the widget that is at the given position casted to some other class.
void setOrientation(Qt::Orientation orientation, bool recursive=false)
Set the orientation of the list of widgets.
void appendWidget(const QString &id, QWidget *widget)
Insert the given widget with the given id at the end of the list. The list widget takes ownership of ...
void setSeparatorsVisible(bool visible)
Set the visibility of the separators.
virtual const KoColorSpace * compositionSourceColorSpace() const
const KoColorSpace * colorSpace() const
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
KisSelectionSP activeSelection() const
void setFillTransform(QTransform transform)
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
void setSoftRange(int newSoftMinimum, int newSoftMaximum)
Set the minimum and the maximum values of the soft range.
void setValue(int newValue)
void setRange(int newMinimum, int newMaximum, bool computeNewFastSliderStep=true)
Set the minimum and the maximum values of the range, computing a new "fast slider step" based on the ...
void saveReferenceToConfig(Reference reference)
void endAlternateAction(KoPointerEvent *event, AlternateAction action) override
void activate(const QSet< KoShape * > &shapes) override
KisAngleSelector * m_angleSelectorPatternRotation
void slot_sliderFillOpacitySpread_valueChanged(int value)
void saveEnclosingMethodToConfig(EnclosingMethod enclosingMethod)
void slot_sliderExpand_valueChanged(int value)
KisCompositeOpComboBox * m_comboBoxCustomCompositeOp
void slot_sliderFeather_valueChanged(int value)
QComboBox * m_comboBoxRegionSelectionMethod
RegionSelectionMethod configStringToRegionSelectionMethod(const QString &configString) const
void slot_optionButtonStripEnclosingMethod_buttonToggled(KoGroupButton *button, bool checked)
void deactivateAlternateAction(AlternateAction action) override
KisSliderSpinBox * m_sliderFillThreshold
void slot_delegateTool_enclosingMaskProduced(KisPixelSelectionSP enclosingMask)
QSharedPointer< QRect > m_dirtyRect
static constexpr EnclosingMethod defaultEnclosingMethod()
KisColorLabelSelectorWidget * m_widgetLabels
void slot_checkBoxRegionSelectionInvert_toggled(bool checked)
void beginAlternateDoubleClickAction(KoPointerEvent *event, AlternateAction action) override
void slot_optionButtonStripFillWith_buttonToggled(KoGroupButton *button, bool checked)
void slot_comboBoxCustomCompositeOp_currentIndexChanged(int index)
QString referenceToConfigString(Reference reference) const
void slot_sliderFillThreshold_valueChanged(int value)
void slot_checkBoxSelectionAsBoundary_toggled(bool checked)
QWidget * createOptionWidget() override
KisDoubleSliderSpinBox * m_sliderPatternScale
KisSliderSpinBox * m_sliderFillOpacitySpread
KoGroupButton * m_buttonEnclosingMethodLasso
KisMergeLabeledLayersCommand::ReferenceNodeInfoListSP m_referenceNodeList
KisSliderSpinBox * m_sliderFeather
QString regionSelectionMethodToUserString(RegionSelectionMethod regionSelectionMethod) const
void slot_buttonStopGrowingAtDarkestPixel_toggled(bool enabled)
void slot_checkBoxAntiAlias_toggled(bool checked)
EnclosingMethod m_enclosingMethod
Reference loadReferenceFromConfig() const
KisSliderSpinBox * m_sliderCloseGap
void beginPrimaryAction(KoPointerEvent *event) override
KoGroupButton * m_buttonEnclosingMethodEllipse
KisOptionCollectionWidget * m_optionWidget
RegionSelectionMethod m_regionSelectionMethod
void continueAlternateAction(KoPointerEvent *event, AlternateAction action) override
QString enclosingMethodToConfigString(EnclosingMethod enclosingMethod) const
QCheckBox * m_checkBoxRegionSelectionIncludeContourRegions
KoGroupButton * m_buttonEnclosingMethodBrush
void slot_angleSelectorPatternRotation_angleChanged(double value)
KoGroupButton * m_buttonReferenceLabeled
void slot_buttonRegionSelectionColor_changed(const KoColor &color)
KoGroupButton * m_buttonReferenceCurrent
void saveRegionSelectionMethodToConfig(RegionSelectionMethod regionSelectionMethod)
KisColorButton * m_buttonRegionSelectionColor
void slot_comboBoxRegionSelectionMethod_currentIndexChanged(int)
QToolButton * m_buttonStopGrowingAtDarkestPixel
QCheckBox * m_checkBoxCustomBlendingOptions
void slot_sliderCustomOpacity_valueChanged(int value)
void slot_sliderCloseGap_valueChanged(int value)
static constexpr RegionSelectionMethod defaultRegionSelectionMethod()
KisPaintDeviceSP m_referencePaintDevice
static constexpr Reference defaultReference()
KisSliderSpinBox * m_sliderCustomOpacity
KisSliderSpinBox * m_sliderExpand
void slot_checkBoxRegionSelectionIncludeContourRegions_toggled(bool checked)
EnclosingMethod loadEnclosingMethodFromConfig() const
QString regionSelectionMethodToConfigString(RegionSelectionMethod regionSelectionMethod) const
void slot_checkBoxUseCustomBlendingOptions_toggled(bool checked)
KoGroupButton * m_buttonFillWithPattern
KoGroupButton * m_buttonEnclosingMethodPath
bool subtoolHasUserInteractionRunning() const
void slot_currentNodeChanged(const KisNodeSP node)
KoGroupButton * m_buttonEnclosingMethodRectangle
Reference configStringToReference(const QString &configString) const
QCheckBox * m_checkBoxRegionSelectionInvert
KisToolEncloseAndFill(KoCanvasBase *canvas)
void slot_sliderPatternScale_valueChanged(double value)
void slot_checkBoxUseActiveLayer_toggled(bool checked)
EnclosingMethod configStringToEnclosingMethod(const QString &configString) const
void slot_optionButtonStripReference_buttonToggled(KoGroupButton *button, bool checked)
void activateAlternateAction(AlternateAction action) override
void slot_colorSpaceChanged(const KoColorSpace *colorSpace)
void beginAlternateAction(KoPointerEvent *event, AlternateAction action) override
KoGroupButton * m_buttonReferenceAll
RegionSelectionMethod loadRegionSelectionMethodFromConfig() const
KisCanvasResourceProvider * canvasResourceProvider()
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
Definition KoColor.cpp:350
void toXML(QDomDocument &doc, QDomElement &colorElt) const
Definition KoColor.cpp:304
static const KoCompositeOpRegistry & instance()
KoID getKoID(const QString &compositeOpID) const
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
void selectionChanged(bool hasSelection)
Q_INVOKABLE QString toolId() const
QAction * action(const QString &name) const
bool isActivated() const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QString button(const QWheelEvent &ev)
QSharedPointer< KUndo2Command > KUndo2CommandSP
Definition kis_types.h:262
KUndo2MagicString kundo2_i18n(const char *text)
QIcon loadIcon(const QString &name)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
virtual KisPaintDeviceSP paintDevice() const =0
KisImageWSP currentImage()
Definition kis_tool.cc:393
KisTool::NodePaintAbility nodePaintAbility()
Definition kis_tool.cc:539
bool nodeEditable()
Checks checks if the current node is editable.
Definition kis_tool.cc:651
KisNodeSP currentNode() const
Definition kis_tool.cc:370
@ FLAG_USES_CUSTOM_SIZE
Definition kis_tool.h:47
@ FLAG_USES_CUSTOM_PRESET
Definition kis_tool.h:47
bool overrideCursorIfNotEditable()
Override the cursor appropriately if current node is not editable.
Definition kis_tool.cc:618
KisImageWSP image() const
Definition kis_tool.cc:332
QCursor cursor
Definition kis_tool.cc:64
AlternateAction
Definition kis_tool.h:134
KisCanvas2 * canvas