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 }