1 /*
2  *  Copyright (c) 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 #include "kis_particle_paintop_settings.h"
19 
20 #include "kis_particle_paintop_settings_widget.h"
21 #include "kis_particleop_option.h"
22 
23 #include <kis_paint_action_type_option.h>
24 #include <kis_airbrush_option_widget.h>
25 
26 struct KisParticlePaintOpSettings::Private
27 {
28     QList<KisUniformPaintOpPropertyWSP> uniformProperties;
29 };
30 
KisParticlePaintOpSettings()31 KisParticlePaintOpSettings::KisParticlePaintOpSettings()
32     : m_d(new Private)
33 {
34 }
35 
~KisParticlePaintOpSettings()36 KisParticlePaintOpSettings::~KisParticlePaintOpSettings()
37 {
38 }
39 
lodSizeThresholdSupported() const40 bool KisParticlePaintOpSettings::lodSizeThresholdSupported() const
41 {
42     return false;
43 }
44 
paintIncremental()45 bool KisParticlePaintOpSettings::paintIncremental()
46 {
47     return (enumPaintActionType)getInt("PaintOpAction", WASH) == BUILDUP;
48 }
49 
50 
51 #include <brushengine/kis_slider_based_paintop_property.h>
52 #include "kis_paintop_preset.h"
53 #include "kis_paintop_settings_update_proxy.h"
54 #include "kis_standard_uniform_properties_factory.h"
55 
56 
uniformProperties(KisPaintOpSettingsSP settings)57 QList<KisUniformPaintOpPropertySP> KisParticlePaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings)
58 {
59     QList<KisUniformPaintOpPropertySP> props =
60         listWeakToStrong(m_d->uniformProperties);
61 
62     if (props.isEmpty()) {
63         {
64             KisIntSliderBasedPaintOpPropertyCallback *prop =
65                 new KisIntSliderBasedPaintOpPropertyCallback(
66                     KisIntSliderBasedPaintOpPropertyCallback::Int,
67                     "particle_particles",
68                     i18n("Particles"),
69                     settings, 0);
70 
71             prop->setRange(1, 500);
72             prop->setSingleStep(1);
73 
74             prop->setReadCallback(
75                 [](KisUniformPaintOpProperty *prop) {
76                     ParticleOption option;
77                     option.readOptionSetting(prop->settings().data());
78 
79                     prop->setValue(int(option.particle_count));
80                 });
81             prop->setWriteCallback(
82                 [](KisUniformPaintOpProperty *prop) {
83                     ParticleOption option;
84                     option.readOptionSetting(prop->settings().data());
85                     option.particle_count = prop->value().toInt();
86                     option.writeOptionSetting(prop->settings().data());
87                 });
88 
89             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
90             prop->requestReadValue();
91             props << toQShared(prop);
92         }
93         {
94             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
95                 new KisDoubleSliderBasedPaintOpPropertyCallback(
96                     KisDoubleSliderBasedPaintOpPropertyCallback::Double,
97                     "particle_opecityweight",
98                     i18n("Opacity Weight"),
99                     settings, 0);
100 
101             prop->setRange(0.01, 1.0);
102             prop->setSingleStep(0.01);
103             prop->setDecimals(2);
104 
105             prop->setReadCallback(
106                 [](KisUniformPaintOpProperty *prop) {
107                     ParticleOption option;
108                     option.readOptionSetting(prop->settings().data());
109                     prop->setValue(option.particle_weight);
110                 });
111             prop->setWriteCallback(
112                 [](KisUniformPaintOpProperty *prop) {
113                     ParticleOption option;
114                     option.readOptionSetting(prop->settings().data());
115                     option.particle_weight = prop->value().toReal();
116                     option.writeOptionSetting(prop->settings().data());
117                 });
118 
119             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
120             prop->requestReadValue();
121             props << toQShared(prop);
122         }
123         {
124             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
125                 new KisDoubleSliderBasedPaintOpPropertyCallback(
126                     KisDoubleSliderBasedPaintOpPropertyCallback::Double,
127                     "particle_dx_scale",
128                     i18n("dx scale"),
129                     settings, 0);
130 
131             prop->setRange(-2, 2);
132             prop->setSingleStep(0.01);
133             prop->setDecimals(2);
134 
135             prop->setReadCallback(
136                 [](KisUniformPaintOpProperty *prop) {
137                     ParticleOption option;
138                     option.readOptionSetting(prop->settings().data());
139                     prop->setValue(option.particle_scale_x);
140                 });
141             prop->setWriteCallback(
142                 [](KisUniformPaintOpProperty *prop) {
143                     ParticleOption option;
144                     option.readOptionSetting(prop->settings().data());
145                     option.particle_scale_x = prop->value().toReal();
146                     option.writeOptionSetting(prop->settings().data());
147                 });
148 
149             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
150             prop->requestReadValue();
151             props << toQShared(prop);
152         }
153         {
154             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
155                 new KisDoubleSliderBasedPaintOpPropertyCallback(
156                     KisDoubleSliderBasedPaintOpPropertyCallback::Double,
157                     "particle_dy_scale",
158                     i18n("dy scale"),
159                     settings, 0);
160 
161             prop->setRange(-2, 2);
162             prop->setSingleStep(0.01);
163             prop->setDecimals(2);
164 
165             prop->setReadCallback(
166                 [](KisUniformPaintOpProperty *prop) {
167                     ParticleOption option;
168                     option.readOptionSetting(prop->settings().data());
169                     prop->setValue(option.particle_scale_y);
170                 });
171             prop->setWriteCallback(
172                 [](KisUniformPaintOpProperty *prop) {
173                     ParticleOption option;
174                     option.readOptionSetting(prop->settings().data());
175                     option.particle_scale_y = prop->value().toReal();
176                     option.writeOptionSetting(prop->settings().data());
177                 });
178 
179             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
180             prop->requestReadValue();
181             props << toQShared(prop);
182         }
183         {
184             KisDoubleSliderBasedPaintOpPropertyCallback *prop =
185                 new KisDoubleSliderBasedPaintOpPropertyCallback(
186                     KisDoubleSliderBasedPaintOpPropertyCallback::Double,
187                     "particle_gravity",
188                     i18n("Gravity"),
189                     settings, 0);
190 
191             prop->setRange(0.01, 1.0);
192             prop->setSingleStep(0.01);
193             prop->setDecimals(2);
194 
195             prop->setReadCallback(
196                 [](KisUniformPaintOpProperty *prop) {
197                     ParticleOption option;
198                     option.readOptionSetting(prop->settings().data());
199                     prop->setValue(option.particle_gravity);
200                 });
201             prop->setWriteCallback(
202                 [](KisUniformPaintOpProperty *prop) {
203                     ParticleOption option;
204                     option.readOptionSetting(prop->settings().data());
205                     option.particle_gravity = prop->value().toReal();
206                     option.writeOptionSetting(prop->settings().data());
207                 });
208 
209             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
210             prop->requestReadValue();
211             props << toQShared(prop);
212         }
213         {
214             KisIntSliderBasedPaintOpPropertyCallback *prop =
215                 new KisIntSliderBasedPaintOpPropertyCallback(
216                     KisIntSliderBasedPaintOpPropertyCallback::Int,
217                     "particle_iterations",
218                     i18n("Iterations"),
219                     settings, 0);
220 
221             prop->setRange(1, 300);
222             prop->setSingleStep(1);
223 
224             prop->setReadCallback(
225                 [](KisUniformPaintOpProperty *prop) {
226                     ParticleOption option;
227                     option.readOptionSetting(prop->settings().data());
228 
229                     prop->setValue(int(option.particle_iterations));
230                 });
231             prop->setWriteCallback(
232                 [](KisUniformPaintOpProperty *prop) {
233                     ParticleOption option;
234                     option.readOptionSetting(prop->settings().data());
235                     option.particle_iterations = prop->value().toInt();
236                     option.writeOptionSetting(prop->settings().data());
237                 });
238 
239             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
240             prop->requestReadValue();
241             props << toQShared(prop);
242         }
243     }
244 
245     {
246         using namespace KisStandardUniformPropertiesFactory;
247 
248         Q_FOREACH (KisUniformPaintOpPropertySP prop, KisPaintOpSettings::uniformProperties(settings)) {
249             if (prop->id() == opacity.id()) {
250                 props.prepend(prop);
251             }
252         }
253     }
254 
255     return props;
256 }
257