File indexing completed on 2024-05-26 04:33:55

0001 /*
0002  *  SPDX-FileCopyrightText: 2009, 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_experiment_paintop_settings.h"
0008 #include "kis_current_outline_fetcher.h"
0009 #include "kis_algebra_2d.h"
0010 #include <KisOptimizedBrushOutline.h>
0011 
0012 struct KisExperimentPaintOpSettings::Private
0013 {
0014     QList<KisUniformPaintOpPropertyWSP> uniformProperties;
0015 };
0016 
0017 KisExperimentPaintOpSettings::KisExperimentPaintOpSettings(KisResourcesInterfaceSP resourcesInterface)
0018     : KisNoSizePaintOpSettings(resourcesInterface),
0019       m_d(new Private)
0020 {
0021 }
0022 
0023 KisExperimentPaintOpSettings::~KisExperimentPaintOpSettings()
0024 {
0025 }
0026 
0027 bool KisExperimentPaintOpSettings::paintIncremental()
0028 {
0029     /**
0030      * The experiment brush supports working in the
0031      * WASH mode only!
0032      */
0033     return false;
0034 }
0035 
0036 KisOptimizedBrushOutline KisExperimentPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom)
0037 {
0038     QPainterPath path;
0039     if (mode.isVisible) {
0040 
0041         QRectF ellipse(0, 0, 3, 3);
0042         ellipse.translate(-ellipse.center());
0043         path.addEllipse(ellipse);
0044         ellipse.setRect(0,0, 12, 12);
0045         ellipse.translate(-ellipse.center());
0046         path.addEllipse(ellipse);
0047 
0048         if (mode.showTiltDecoration) {
0049             path.addPath(makeTiltIndicator(info, QPointF(0.0, 0.0), 0.0, 3.0));
0050         }
0051 
0052         path.translate(KisAlgebra2D::alignForZoom(info.pos(), alignForZoom));
0053     }
0054     return path;
0055 }
0056 
0057 #include <brushengine/kis_slider_based_paintop_property.h>
0058 #include "kis_paintop_preset.h"
0059 #include "KisPaintOpPresetUpdateProxy.h"
0060 #include "kis_standard_uniform_properties_factory.h"
0061 #include <KisOptimizedBrushOutline.h>
0062 #include "KisExperimentOpOptionData.h"
0063 
0064 
0065 
0066 QList<KisUniformPaintOpPropertySP> KisExperimentPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings, QPointer<KisPaintOpPresetUpdateProxy> updateProxy)
0067 {
0068     QList<KisUniformPaintOpPropertySP> props =
0069         listWeakToStrong(m_d->uniformProperties);
0070 
0071     if (props.isEmpty()) {
0072         {
0073             KisIntSliderBasedPaintOpPropertyCallback *prop =
0074                 new KisIntSliderBasedPaintOpPropertyCallback(KisIntSliderBasedPaintOpPropertyCallback::Int, KoID("shape_speed", i18n("Speed")), settings, 0);
0075 
0076             prop->setRange(0, 100);
0077             prop->setSingleStep(1);
0078             prop->setSuffix(i18n("%"));
0079 
0080             prop->setReadCallback(
0081                 [](KisUniformPaintOpProperty *prop) {
0082                     KisExperimentOpOptionData option;
0083                     option.read(prop->settings().data());
0084 
0085                     prop->setValue(int(option.speed));
0086                 });
0087             prop->setWriteCallback(
0088                 [](KisUniformPaintOpProperty *prop) {
0089                     KisExperimentOpOptionData option;
0090                     option.read(prop->settings().data());
0091                     option.speed = prop->value().toInt();
0092                     option.write(prop->settings().data());
0093                 });
0094             prop->setIsVisibleCallback(
0095                 [](const KisUniformPaintOpProperty *prop) -> bool {
0096                     KisExperimentOpOptionData option;
0097                     option.read(prop->settings().data());
0098                     return option.isSpeedEnabled;
0099                 });
0100 
0101             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0102             prop->requestReadValue();
0103             props << toQShared(prop);
0104         }
0105         {
0106             KisIntSliderBasedPaintOpPropertyCallback *prop =
0107                 new KisIntSliderBasedPaintOpPropertyCallback(KisIntSliderBasedPaintOpPropertyCallback::Int, KoID("shape_smooth", i18n("Smooth")), settings, 0);
0108 
0109             prop->setRange(0, 100);
0110             prop->setSingleStep(1);
0111             prop->setSuffix(i18n(" px"));
0112 
0113             prop->setReadCallback(
0114                 [](KisUniformPaintOpProperty *prop) {
0115                     KisExperimentOpOptionData option;
0116                     option.read(prop->settings().data());
0117 
0118                     prop->setValue(int(option.smoothing));
0119                 });
0120             prop->setWriteCallback(
0121                 [](KisUniformPaintOpProperty *prop) {
0122                     KisExperimentOpOptionData option;
0123                     option.read(prop->settings().data());
0124                     option.smoothing = prop->value().toInt();
0125                     option.write(prop->settings().data());
0126                 });
0127             prop->setIsVisibleCallback(
0128                 [](const KisUniformPaintOpProperty *prop) {
0129                     KisExperimentOpOptionData option;
0130                     option.read(prop->settings().data());
0131                     return option.isSmoothingEnabled;
0132                 });
0133 
0134             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0135             prop->requestReadValue();
0136             props << toQShared(prop);
0137         }
0138 
0139         {
0140             KisIntSliderBasedPaintOpPropertyCallback *prop = new KisIntSliderBasedPaintOpPropertyCallback(KisIntSliderBasedPaintOpPropertyCallback::Int,
0141                                                                                                           KoID("shape_displace", i18n("Displace")),
0142                                                                                                           settings,
0143                                                                                                           0);
0144 
0145             prop->setRange(0, 100);
0146             prop->setSingleStep(1);
0147             prop->setSuffix(i18n("%"));
0148 
0149             prop->setReadCallback(
0150                 [](KisUniformPaintOpProperty *prop) {
0151                     KisExperimentOpOptionData option;
0152                     option.read(prop->settings().data());
0153 
0154                     prop->setValue(int(option.displacement));
0155                 });
0156             prop->setWriteCallback(
0157                 [](KisUniformPaintOpProperty *prop) {
0158                     KisExperimentOpOptionData option;
0159                     option.read(prop->settings().data());
0160                     option.displacement = prop->value().toInt();
0161                     option.write(prop->settings().data());
0162                 });
0163             prop->setIsVisibleCallback(
0164                 [](const KisUniformPaintOpProperty *prop) {
0165                     KisExperimentOpOptionData option;
0166                     option.read(prop->settings().data());
0167                     return option.isDisplacementEnabled;
0168                 });
0169 
0170             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0171             prop->requestReadValue();
0172             props << toQShared(prop);
0173         }
0174 
0175         {
0176             KisUniformPaintOpPropertyCallback *prop =
0177                 new KisUniformPaintOpPropertyCallback(KisUniformPaintOpPropertyCallback::Bool, KoID("shape_windingfill", i18n("Winding Fill")), settings, 0);
0178 
0179             prop->setReadCallback(
0180                 [](KisUniformPaintOpProperty *prop) {
0181                     KisExperimentOpOptionData option;
0182                     option.read(prop->settings().data());
0183 
0184                     prop->setValue(option.windingFill);
0185                 });
0186             prop->setWriteCallback(
0187                 [](KisUniformPaintOpProperty *prop) {
0188                     KisExperimentOpOptionData option;
0189                     option.read(prop->settings().data());
0190                     option.windingFill = prop->value().toBool();
0191                     option.write(prop->settings().data());
0192                 });
0193 
0194             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0195             prop->requestReadValue();
0196             props << toQShared(prop);
0197         }
0198 
0199         {
0200             KisUniformPaintOpPropertyCallback *prop =
0201                 new KisUniformPaintOpPropertyCallback(KisUniformPaintOpPropertyCallback::Bool, KoID("shape_hardedge", i18n("Hard Edge")), settings, 0);
0202 
0203             prop->setReadCallback(
0204                 [](KisUniformPaintOpProperty *prop) {
0205                     KisExperimentOpOptionData option;
0206                     option.read(prop->settings().data());
0207 
0208                     prop->setValue(option.hardEdge);
0209                 });
0210             prop->setWriteCallback(
0211                 [](KisUniformPaintOpProperty *prop) {
0212                     KisExperimentOpOptionData option;
0213                     option.read(prop->settings().data());
0214                     option.hardEdge = prop->value().toBool();
0215                     option.write(prop->settings().data());
0216                 });
0217 
0218             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0219             prop->requestReadValue();
0220             props << toQShared(prop);
0221         }
0222     }
0223 
0224     {
0225         using namespace KisStandardUniformPropertiesFactory;
0226 
0227         Q_FOREACH (KisUniformPaintOpPropertySP prop, KisPaintOpSettings::uniformProperties(settings, updateProxy)) {
0228             if (prop->id() == opacity.id()) {
0229                 props.prepend(prop);
0230             }
0231         }
0232     }
0233 
0234     return props;
0235 }