1 /*
2  *  Copyright (c) 2009,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 
19 #include "kis_experiment_paintop_settings.h"
20 #include "kis_current_outline_fetcher.h"
21 #include "kis_algebra_2d.h"
22 
23 struct KisExperimentPaintOpSettings::Private
24 {
25     QList<KisUniformPaintOpPropertyWSP> uniformProperties;
26 };
27 
KisExperimentPaintOpSettings()28 KisExperimentPaintOpSettings::KisExperimentPaintOpSettings()
29     : m_d(new Private)
30 {
31 }
32 
~KisExperimentPaintOpSettings()33 KisExperimentPaintOpSettings::~KisExperimentPaintOpSettings()
34 {
35 }
36 
lodSizeThresholdSupported() const37 bool KisExperimentPaintOpSettings::lodSizeThresholdSupported() const
38 {
39     return false;
40 }
41 
paintIncremental()42 bool KisExperimentPaintOpSettings::paintIncremental()
43 {
44     /**
45      * The experiment brush supports working in the
46      * WASH mode only!
47      */
48     return false;
49 }
50 
brushOutline(const KisPaintInformation & info,const OutlineMode & mode,qreal alignForZoom)51 QPainterPath KisExperimentPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom)
52 {
53     QPainterPath path;
54     if (mode.isVisible) {
55 
56         QRectF ellipse(0, 0, 3, 3);
57         ellipse.translate(-ellipse.center());
58         path.addEllipse(ellipse);
59         ellipse.setRect(0,0, 12, 12);
60         ellipse.translate(-ellipse.center());
61         path.addEllipse(ellipse);
62 
63         if (mode.showTiltDecoration) {
64             path.addPath(makeTiltIndicator(info, QPointF(0.0, 0.0), 0.0, 3.0));
65         }
66 
67         path.translate(KisAlgebra2D::alignForZoom(info.pos(), alignForZoom));
68     }
69     return path;
70 }
71 
72 #include <brushengine/kis_slider_based_paintop_property.h>
73 #include "kis_paintop_preset.h"
74 #include "kis_paintop_settings_update_proxy.h"
75 #include "kis_experimentop_option.h"
76 #include "kis_standard_uniform_properties_factory.h"
77 
78 
uniformProperties(KisPaintOpSettingsSP settings)79 QList<KisUniformPaintOpPropertySP> KisExperimentPaintOpSettings::uniformProperties(KisPaintOpSettingsSP settings)
80 {
81     QList<KisUniformPaintOpPropertySP> props =
82         listWeakToStrong(m_d->uniformProperties);
83 
84     if (props.isEmpty()) {
85         {
86             KisIntSliderBasedPaintOpPropertyCallback *prop =
87                 new KisIntSliderBasedPaintOpPropertyCallback(
88                     KisIntSliderBasedPaintOpPropertyCallback::Int,
89                     "shape_speed",
90                     i18n("Speed"),
91                     settings, 0);
92 
93             prop->setRange(0, 100);
94             prop->setSingleStep(1);
95             prop->setSuffix(i18n("%"));
96 
97             prop->setReadCallback(
98                 [](KisUniformPaintOpProperty *prop) {
99                     ExperimentOption option;
100                     option.readOptionSetting(prop->settings().data());
101 
102                     prop->setValue(int(option.speed));
103                 });
104             prop->setWriteCallback(
105                 [](KisUniformPaintOpProperty *prop) {
106                     ExperimentOption option;
107                     option.readOptionSetting(prop->settings().data());
108                     option.speed = prop->value().toInt();
109                     option.writeOptionSetting(prop->settings().data());
110                 });
111             prop->setIsVisibleCallback(
112                 [](const KisUniformPaintOpProperty *prop) -> bool {
113                     ExperimentOption option;
114                     option.readOptionSetting(prop->settings().data());
115                     return option.isSpeedEnabled;
116                 });
117 
118             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
119             prop->requestReadValue();
120             props << toQShared(prop);
121         }
122         {
123             KisIntSliderBasedPaintOpPropertyCallback *prop =
124                 new KisIntSliderBasedPaintOpPropertyCallback(
125                     KisIntSliderBasedPaintOpPropertyCallback::Int,
126                     "shape_smooth",
127                     i18n("Smooth"),
128                     settings, 0);
129 
130             prop->setRange(0, 100);
131             prop->setSingleStep(1);
132             prop->setSuffix(i18n(" px"));
133 
134             prop->setReadCallback(
135                 [](KisUniformPaintOpProperty *prop) {
136                     ExperimentOption option;
137                     option.readOptionSetting(prop->settings().data());
138 
139                     prop->setValue(int(option.smoothing));
140                 });
141             prop->setWriteCallback(
142                 [](KisUniformPaintOpProperty *prop) {
143                     ExperimentOption option;
144                     option.readOptionSetting(prop->settings().data());
145                     option.smoothing = prop->value().toInt();
146                     option.writeOptionSetting(prop->settings().data());
147                 });
148             prop->setIsVisibleCallback(
149                 [](const KisUniformPaintOpProperty *prop) {
150                     ExperimentOption option;
151                     option.readOptionSetting(prop->settings().data());
152                     return option.isSmoothingEnabled;
153                 });
154 
155             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
156             prop->requestReadValue();
157             props << toQShared(prop);
158         }
159 
160         {
161             KisIntSliderBasedPaintOpPropertyCallback *prop =
162                 new KisIntSliderBasedPaintOpPropertyCallback(
163                     KisIntSliderBasedPaintOpPropertyCallback::Int,
164                     "shape_displace",
165                     i18n("Displace"),
166                     settings, 0);
167 
168             prop->setRange(0, 100);
169             prop->setSingleStep(1);
170             prop->setSuffix(i18n("%"));
171 
172             prop->setReadCallback(
173                 [](KisUniformPaintOpProperty *prop) {
174                     ExperimentOption option;
175                     option.readOptionSetting(prop->settings().data());
176 
177                     prop->setValue(int(option.displacement));
178                 });
179             prop->setWriteCallback(
180                 [](KisUniformPaintOpProperty *prop) {
181                     ExperimentOption option;
182                     option.readOptionSetting(prop->settings().data());
183                     option.displacement = prop->value().toInt();
184                     option.writeOptionSetting(prop->settings().data());
185                 });
186             prop->setIsVisibleCallback(
187                 [](const KisUniformPaintOpProperty *prop) {
188                     ExperimentOption option;
189                     option.readOptionSetting(prop->settings().data());
190                     return option.isDisplacementEnabled;
191                 });
192 
193             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
194             prop->requestReadValue();
195             props << toQShared(prop);
196         }
197 
198         {
199             KisUniformPaintOpPropertyCallback *prop =
200                 new KisUniformPaintOpPropertyCallback(
201                     KisUniformPaintOpPropertyCallback::Bool,
202                     "shape_windingfill",
203                     i18n("Winding Fill"),
204                     settings, 0);
205 
206             prop->setReadCallback(
207                 [](KisUniformPaintOpProperty *prop) {
208                     ExperimentOption option;
209                     option.readOptionSetting(prop->settings().data());
210 
211                     prop->setValue(option.windingFill);
212                 });
213             prop->setWriteCallback(
214                 [](KisUniformPaintOpProperty *prop) {
215                     ExperimentOption option;
216                     option.readOptionSetting(prop->settings().data());
217                     option.windingFill = prop->value().toBool();
218                     option.writeOptionSetting(prop->settings().data());
219                 });
220 
221             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
222             prop->requestReadValue();
223             props << toQShared(prop);
224         }
225 
226         {
227             KisUniformPaintOpPropertyCallback *prop =
228                 new KisUniformPaintOpPropertyCallback(
229                     KisUniformPaintOpPropertyCallback::Bool,
230                     "shape_hardedge",
231                     i18n("Hard Edge"),
232                     settings, 0);
233 
234             prop->setReadCallback(
235                 [](KisUniformPaintOpProperty *prop) {
236                     ExperimentOption option;
237                     option.readOptionSetting(prop->settings().data());
238 
239                     prop->setValue(option.hardEdge);
240                 });
241             prop->setWriteCallback(
242                 [](KisUniformPaintOpProperty *prop) {
243                     ExperimentOption option;
244                     option.readOptionSetting(prop->settings().data());
245                     option.hardEdge = prop->value().toBool();
246                     option.writeOptionSetting(prop->settings().data());
247                 });
248 
249             QObject::connect(preset()->updateProxy(), SIGNAL(sigSettingsChanged()), prop, SLOT(requestReadValue()));
250             prop->requestReadValue();
251             props << toQShared(prop);
252         }
253     }
254 
255     {
256         using namespace KisStandardUniformPropertiesFactory;
257 
258         Q_FOREACH (KisUniformPaintOpPropertySP prop, KisPaintOpSettings::uniformProperties(settings)) {
259             if (prop->id() == opacity.id()) {
260                 props.prepend(prop);
261             }
262         }
263     }
264 
265     return props;
266 }
267