File indexing completed on 2024-05-26 04:34:12

0001 /*
0002  *  SPDX-FileCopyrightText: 2008, 2009, 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include <cmath>
0008 
0009 #include <KisPaintingModeOptionData.h>
0010 #include <KisColorOptionData.h>
0011 
0012 #include "kis_spray_paintop_settings.h"
0013 #include "KisSprayShapeOptionData.h"
0014 #include <KisOptimizedBrushOutline.h>
0015 #include <KisSprayOpOptionData.h>
0016 
0017 struct KisSprayPaintOpSettings::Private
0018 {
0019     QList<KisUniformPaintOpPropertyWSP> uniformProperties;
0020 };
0021 
0022 
0023 KisSprayPaintOpSettings::KisSprayPaintOpSettings(KisResourcesInterfaceSP resourcesInterface)
0024     : KisOutlineGenerationPolicy<KisPaintOpSettings>(KisCurrentOutlineFetcher::SIZE_OPTION |
0025                                                      KisCurrentOutlineFetcher::ROTATION_OPTION,
0026                                                      resourcesInterface),
0027     m_d(new Private)
0028 {
0029 }
0030 
0031 KisSprayPaintOpSettings::~KisSprayPaintOpSettings()
0032 {
0033 }
0034 
0035 void KisSprayPaintOpSettings::setPaintOpSize(qreal value)
0036 {
0037     KisSprayOpOptionData option;
0038     option.read(this);
0039     option.diameter = value;
0040     option.write(this);
0041 }
0042 
0043 qreal KisSprayPaintOpSettings::paintOpSize() const
0044 {
0045 
0046     KisSprayOpOptionData option;
0047     option.read(this);
0048 
0049     return option.diameter;
0050 }
0051 
0052 void KisSprayPaintOpSettings::setPaintOpAngle(qreal value)
0053 {
0054     Q_UNUSED(value);
0055 }
0056 
0057 qreal KisSprayPaintOpSettings::paintOpAngle() const
0058 {
0059     return 0.0;
0060 }
0061 
0062 bool KisSprayPaintOpSettings::paintIncremental()
0063 {
0064     KisPaintingModeOptionData data;
0065     data.read(this);
0066     return data.paintingMode == enumPaintingMode::BUILDUP;
0067 }
0068 
0069 
0070 KisOptimizedBrushOutline KisSprayPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom)
0071 {
0072     KisOptimizedBrushOutline path;
0073     if (mode.isVisible) {
0074         qreal width = getInt(SPRAY_DIAMETER);
0075         qreal height = getInt(SPRAY_DIAMETER) * getDouble(SPRAY_ASPECT);
0076         path = ellipseOutline(width, height, getDouble(SPRAY_SCALE), getDouble(SPRAY_ROTATION));
0077 
0078         path = outlineFetcher()->fetchOutline(info, this, path, mode, alignForZoom);
0079 
0080         if (mode.forceFullSize) {
0081             QPainterPath tiltLine =
0082                 makeTiltIndicator(info, QPointF(0.0, 0.0), width * 0.5, 3.0);
0083             path.addPath(outlineFetcher()->fetchOutline(info, this, tiltLine, mode, alignForZoom, 1.0, 0.0, true, 0, 0));
0084         }
0085     }
0086     return path;
0087 }
0088 
0089 #include <brushengine/kis_slider_based_paintop_property.h>
0090 #include "kis_paintop_preset.h"
0091 #include "KisPaintOpPresetUpdateProxy.h"
0092 #include "kis_standard_uniform_properties_factory.h"
0093 
0094 
0095 QList<KisUniformPaintOpPropertySP> KisSprayPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings, QPointer<KisPaintOpPresetUpdateProxy> updateProxy)
0096 {
0097     QList<KisUniformPaintOpPropertySP> props =
0098         listWeakToStrong(m_d->uniformProperties);
0099 
0100     if (props.isEmpty()) {
0101         {
0102             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
0103                 new KisDoubleSliderBasedPaintOpPropertyCallback(KisDoubleSliderBasedPaintOpPropertyCallback::Double,
0104                                                                 KoID("spacing", i18n("Spacing")),
0105                                                                 settings,
0106                                                                 0);
0107 
0108             prop->setRange(0.01, 10);
0109             prop->setSingleStep(0.01);
0110             prop->setExponentRatio(3.0);
0111 
0112             prop->setReadCallback(
0113                 [](KisUniformPaintOpProperty *prop) {
0114                     KisSprayOpOptionData option;
0115                     option.read(prop->settings().data());
0116 
0117                     prop->setValue(option.spacing);
0118                 });
0119             prop->setWriteCallback(
0120                 [](KisUniformPaintOpProperty *prop) {
0121                     KisSprayOpOptionData option;
0122                     option.read(prop->settings().data());
0123                     option.spacing = prop->value().toReal();
0124                     option.write(prop->settings().data());
0125                 });
0126 
0127             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0128             prop->requestReadValue();
0129             props << toQShared(prop);
0130         }
0131         {
0132             KisIntSliderBasedPaintOpPropertyCallback *prop = new KisIntSliderBasedPaintOpPropertyCallback(KisIntSliderBasedPaintOpPropertyCallback::Int,
0133                                                                                                           KoID("spray_particlecount", i18n("Particle Count")),
0134                                                                                                           settings,
0135                                                                                                           0);
0136 
0137             prop->setRange(0, 1000);
0138             prop->setExponentRatio(3);
0139 
0140             prop->setReadCallback(
0141                 [](KisUniformPaintOpProperty *prop) {
0142                     KisSprayOpOptionData option;
0143                     option.read(prop->settings().data());
0144 
0145                     prop->setValue(int(option.particleCount));
0146                 });
0147             prop->setWriteCallback(
0148                 [](KisUniformPaintOpProperty *prop) {
0149                     KisSprayOpOptionData option;
0150                     option.read(prop->settings().data());
0151                     option.particleCount = prop->value().toInt();
0152                     option.write(prop->settings().data());
0153                 });
0154             prop->setIsVisibleCallback(
0155                 [](const KisUniformPaintOpProperty *prop) {
0156                     KisSprayOpOptionData option;
0157                     option.read(prop->settings().data());
0158                     return !option.useDensity;
0159                 });
0160 
0161             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0162             prop->requestReadValue();
0163             props << toQShared(prop);
0164         }
0165         {
0166             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
0167                 new KisDoubleSliderBasedPaintOpPropertyCallback(KisDoubleSliderBasedPaintOpPropertyCallback::Double,
0168                                                                 KoID("spray_density", i18n("Density")),
0169                                                                 settings,
0170                                                                 0);
0171 
0172             prop->setRange(0.1, 100);
0173             prop->setSingleStep(0.01);
0174             prop->setDecimals(2);
0175             prop->setExponentRatio(3);
0176             prop->setSuffix("%");
0177             prop->setReadCallback(
0178                 [](KisUniformPaintOpProperty *prop) {
0179                     KisSprayOpOptionData option;
0180                     option.read(prop->settings().data());
0181                     prop->setValue(option.coverage);
0182                 });
0183             prop->setWriteCallback(
0184                 [](KisUniformPaintOpProperty *prop) {
0185                     KisSprayOpOptionData option;
0186                     option.read(prop->settings().data());
0187                     option.coverage = prop->value().toReal();
0188                     option.write(prop->settings().data());
0189                 });
0190             prop->setIsVisibleCallback(
0191                 [](const KisUniformPaintOpProperty *prop) {
0192                     KisSprayOpOptionData option;
0193                     option.read(prop->settings().data());
0194                     return option.useDensity;
0195                 });
0196             QObject::connect(updateProxy, SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
0197             prop->requestReadValue();
0198             props << toQShared(prop);
0199         }
0200     }
0201     {
0202         using namespace KisStandardUniformPropertiesFactory;
0203 
0204         Q_FOREACH (KisUniformPaintOpPropertySP prop, KisPaintOpSettings::uniformProperties(settings, updateProxy)) {
0205             if (prop->id() == opacity.id() ||
0206                 prop->id() == size.id()) {
0207 
0208                 props.prepend(prop);
0209             }
0210         }
0211     }
0212 
0213     return props;
0214 }