Krita Source Code Documentation
Loading...
Searching...
No Matches
KisCurveOptionWidget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2008 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2009 Sven Langkamp <sven.langkamp@gmail.com>
4 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de>
5 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
10
11#include "ui_wdgcurveoption2.h"
13#include "kis_global.h"
14#include "kis_icon_utils.h"
15
16#include <kis_signals_blocker.h>
17#include <KisCurveOptionModel.h>
19
20#include <kis_algebra_2d.h>
21
25#include <KisCurveRangeModel.h>
27
29{
30 Private(lager::cursor<KisCurveOptionDataCommon> optionData,
31 lager::reader<bool> enabledLink,
32 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader,
33 qreal strengthDisplayMultiplier,
34 KisCurveRangeModelFactory curveRangeFactory)
35 : model(optionData, enabledLink, strengthRangeReader, strengthDisplayMultiplier, curveRangeFactory)
36 {}
37
39};
40
41KisCurveOptionWidget::KisCurveOptionWidget(lager::cursor<KisCurveOptionDataCommon> optionData,
42 PaintopCategory category,
43 lager::reader<bool> enabledLink,
44 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader)
45 : KisCurveOptionWidget(optionData,
46 category,
47 i18n("0%"), i18n("100%"),
48 enabledLink,
49 strengthRangeReader)
50{
51}
52
53KisCurveOptionWidget::KisCurveOptionWidget(lager::cursor<KisCurveOptionDataCommon> optionData,
54 PaintopCategory category,
55 const QString &curveMinLabel, const QString &curveMaxLabel,
56 lager::reader<bool> enabledLink,
57 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader)
58 : KisCurveOptionWidget(optionData,
59 category,
60 curveMinLabel, curveMaxLabel,
61 0, 100, i18n("%"),
62 enabledLink,
63 strengthRangeReader)
64{
65
66}
67
68KisCurveOptionWidget::KisCurveOptionWidget(lager::cursor<KisCurveOptionDataCommon> optionData,
69 PaintopCategory category,
70 const QString &curveMinLabel, const QString &curveMaxLabel,
71 int curveMinValue, int curveMaxValue, const QString &curveValueSuffix,
72 lager::reader<bool> enabledLink,
73 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader)
74 : KisCurveOptionWidget(optionData,
75 category,
76 curveMinLabel, curveMaxLabel,
77 curveMinValue, curveMaxValue, curveValueSuffix,
78 i18n("Strength: "), i18n("%"), 100.0,
79 enabledLink,
80 strengthRangeReader)
81{
82}
83
84KisCurveOptionWidget::KisCurveOptionWidget(lager::cursor<KisCurveOptionDataCommon> optionData,
85 PaintopCategory category,
86 const QString &curveMinLabel, const QString &curveMaxLabel,
87 int curveMinValue, int curveMaxValue, const QString &curveValueSuffix,
88 const QString &strengthPrefix, const QString &strengthSuffix,
89 qreal strengthDisplayMultiplier,
90 lager::reader<bool> enabledLink,
91 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader)
92 : KisCurveOptionWidget(optionData,
93 category,
94 strengthPrefix, strengthSuffix, strengthDisplayMultiplier,
95 enabledLink,
96 strengthRangeReader,
97 KisCurveRangeModel::factory(curveMinLabel,
98 curveMaxLabel,
99 curveMinValue,
100 curveMaxValue,
101 curveValueSuffix),
103 {},
104 SupportsCommonCurve | SupportsCurveMode)
105{
106}
107
108KisCurveOptionWidget::KisCurveOptionWidget(lager::cursor<KisCurveOptionDataCommon> optionData,
109 PaintopCategory category,
110 const QString &strengthPrefix, const QString &strengthSuffix,
111 qreal strengthDisplayMultiplier,
112 lager::reader<bool> enabledLink,
113 std::optional<lager::reader<std::tuple<qreal, qreal>>> strengthRangeReader,
114 KisCurveRangeModelFactory curveRangeModelFactory,
117 Flags flags)
118 : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionDataCommon::isChecked], enabledLink)
119 , m_widget(new QWidget)
120 , m_curveOptionWidget(new Ui_WdgCurveOption2())
121 , m_d(new Private(optionData, enabledLink, strengthRangeReader,
122 strengthDisplayMultiplier,
123 curveRangeModelFactory))
124{
125 using namespace KisWidgetConnectionUtils;
126
127 setObjectName("KisCurveOptionWidget");
128
130 m_curveOptionWidget->sensorSelector->setOptionDataCursor(m_d->model.optionData);
131
132 KIS_SAFE_ASSERT_RECOVER (inputControlsFactory) {
134 }
135
137 inputControlsFactory(m_d->model.rangeModel.get(),
138 m_curveOptionWidget->curveWidget,
139 m_curveOptionWidget->intInPlaceholder,
140 m_curveOptionWidget->intOutPlaceholder));
141
142 if (rangeControlsFactory) {
144 rangeControlsFactory(m_d->model.rangeModel.get(),
145 m_curveOptionWidget->wdgRangeControlsPlaceholder));
146 } else {
147 m_curveOptionWidget->wdgRangeControlsPlaceholder->setVisible(false);
148 }
149
151
152 connect(&m_d->model, &KisCurveOptionModel::curveXMinLabelChanged,
153 m_curveOptionWidget->label_xmin, &QLabel::setText);
154 m_curveOptionWidget->label_xmin->setText(m_d->model.curveXMinLabel());
155
156 connect(&m_d->model, &KisCurveOptionModel::curveXMaxLabelChanged,
157 m_curveOptionWidget->label_xmax, &QLabel::setText);
158 m_curveOptionWidget->label_xmax->setText(m_d->model.curveXMaxLabel());
159
160 connect(&m_d->model, &KisCurveOptionModel::curveYMinLabelChanged,
161 m_curveOptionWidget->label_ymin, &QLabel::setText);
162 m_curveOptionWidget->label_ymin->setText(m_d->model.curveYMinLabel());
163
164 connect(&m_d->model, &KisCurveOptionModel::curveYMaxLabelChanged,
165 m_curveOptionWidget->label_ymax, &QLabel::setText);
166 m_curveOptionWidget->label_ymax->setText(m_d->model.curveYMaxLabel());
167
168 m_d->model.activeSensorIdData.bind(
169 std::bind(qOverload<const QString&>(&KisMultiSensorsSelector::setCurrent),
170 m_curveOptionWidget->sensorSelector,
171 std::placeholders::_1));
172 connect(m_curveOptionWidget->sensorSelector,
174 std::bind(&KisCurveOptionModel::setactiveSensorId, &m_d->model, std::placeholders::_1));
175
176 // set all the icons for the curve preset shapes
178
179 // various curve preset buttons with predefined curves
180 connect(m_curveOptionWidget->linearCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveLinear()));
181 connect(m_curveOptionWidget->revLinearButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveReverseLinear()));
182 connect(m_curveOptionWidget->jCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveJShape()));
183 connect(m_curveOptionWidget->lCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveLShape()));
184 connect(m_curveOptionWidget->sCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveSShape()));
185 connect(m_curveOptionWidget->reverseSCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveReverseSShape()));
186 connect(m_curveOptionWidget->uCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveUShape()));
187 connect(m_curveOptionWidget->revUCurveButton, SIGNAL(clicked(bool)), this, SLOT(changeCurveArchShape()));
188
189 m_curveOptionWidget->strengthSlider->setPrefix(strengthPrefix);
190 m_curveOptionWidget->strengthSlider->setSuffix(strengthSuffix);
191
192 connect(m_curveOptionWidget->strengthSlider, qOverload<qreal>(&KisDoubleSliderSpinBox::valueChanged),
193 &m_d->model, &KisCurveOptionModel::setstrengthValueDenorm);
194
195 const bool useFloatingPointStrength = flags & UseFloatingPointStrength;
196
197 if (useFloatingPointStrength) {
198 m_curveOptionWidget->strengthSlider->setSingleStep(0.01);
199 }
200
201 m_d->model.LAGER_QT(effectiveStrengthStateDenorm).bind(
202 kismpl::unzip_wrapper([this, useFloatingPointStrength] (qreal value, qreal min, qreal max) {
203 KisSignalsBlocker b(m_curveOptionWidget->strengthSlider);
204 m_curveOptionWidget->strengthSlider->setRange(min, max, useFloatingPointStrength ? 2 : 0);
205 m_curveOptionWidget->strengthSlider->setValue(value);
206 }));
207
208 connectControl(m_curveOptionWidget->curveWidget, &m_d->model, "displayedCurve");
209
210 m_d->model.LAGER_QT(useCurve).bind(std::bind(&KisCurveOptionWidget::setCurveWidgetsEnabled, this, std::placeholders::_1));
211 connectControl(m_curveOptionWidget->checkBoxUseCurve, &m_d->model, "useCurve");
212
213 if (flags & SupportsCommonCurve) {
214 connectControl(m_curveOptionWidget->checkBoxUseSameCurve, &m_d->model, "useSameCurve");
215 } else {
216 m_curveOptionWidget->checkBoxUseSameCurve->setVisible(false);
217 }
218
219 if (flags & SupportsCurveMode) {
220 connectControl(m_curveOptionWidget->curveMode, &m_d->model, "curveMode");
221 } else {
222 m_curveOptionWidget->curveMode->setVisible(false);
223 m_curveOptionWidget->lblCurveMode->setVisible(false);
224 }
225
226 m_d->model.optionData.bind(std::bind(&KisCurveOptionWidget::emitSettingChanged, this));
227}
228
233
235{
236 m_d->model.bakedOptionData().write(setting.data());
237}
238
240{
241 KisCurveOptionDataCommon data(*m_d->model.optionData);
242 data.read(setting.data());
243 m_d->model.optionData.set(data);
244}
245
247{
248 return m_d->model.isCheckable();
249}
250
252{
253 return m_d->model.LAGER_QT(strengthValueDenorm);
254}
255
257{
258 m_curveOptionWidget->checkBoxUseSameCurve->setEnabled(value);
259 m_curveOptionWidget->curveWidget->setEnabled(value);
260 m_curveOptionWidget->sensorSelector->setEnabled(value);
261 m_curveOptionWidget->label_xmax->setEnabled(value);
262 m_curveOptionWidget->label_xmin->setEnabled(value);
263 m_curveOptionWidget->label_ymax->setEnabled(value);
264 m_curveOptionWidget->label_ymin->setEnabled(value);
265 m_curveOptionWidget->intInPlaceholder->setEnabled(value);
266 m_curveOptionWidget->intOutPlaceholder->setEnabled(value);
267
268 m_curveOptionWidget->linearCurveButton->setEnabled(value);
269 m_curveOptionWidget->revLinearButton->setEnabled(value);
270 m_curveOptionWidget->jCurveButton->setEnabled(value);
271 m_curveOptionWidget->lCurveButton->setEnabled(value);
272 m_curveOptionWidget->revUCurveButton->setEnabled(value);
273 m_curveOptionWidget->reverseSCurveButton->setEnabled(value);
274 m_curveOptionWidget->uCurveButton->setEnabled(value);
275 m_curveOptionWidget->sCurveButton->setEnabled(value);
276
277 m_curveOptionWidget->curveMode->setEnabled(value);
278 m_curveOptionWidget->lblCurveMode->setEnabled(value);
279
280}
281
283{
284 return m_widget;
285}
286
288{
289 QList<QPointF> points;
290 points.push_back(QPointF(0,0));
291 points.push_back(QPointF(1,1));
292 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
293}
294
296{
297 QList<QPointF> points;
298 points.push_back(QPointF(0,1));
299 points.push_back(QPointF(1,0));
300 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
301}
302
304{
305 QList<QPointF> points;
306 points.push_back(QPointF(0,0));
307 points.push_back(QPointF(0.25,0.1));
308 points.push_back(QPointF(0.75,0.9));
309 points.push_back(QPointF(1, 1));
310 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
311}
312
313
315{
316 QList<QPointF> points;
317 points.push_back(QPointF(0,1));
318 points.push_back(QPointF(0.25,0.9));
319 points.push_back(QPointF(0.75,0.1));
320 points.push_back(QPointF(1,0));
321 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
322}
323
325{
326 QList<QPointF> points;
327 points.push_back(QPointF(0,0));
328 points.push_back(QPointF(0.35,0.1));
329 points.push_back(QPointF(1,1));
330 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
331}
332
334{
335 QList<QPointF> points;
336 points.push_back(QPointF(0,1));
337 points.push_back(QPointF(0.25,0.48));
338 points.push_back(QPointF(1,0));
339 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
340}
341
343{
344 QList<QPointF> points;
345 points.push_back(QPointF(0,1));
346 points.push_back(QPointF(0.5,0));
347 points.push_back(QPointF(1,1));
348 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
349}
350
352{
353 QList<QPointF> points;
354 points.push_back(QPointF(0,0));
355 points.push_back(QPointF(0.5,1));
356 points.push_back(QPointF(1,0));
357 m_d->model.setdisplayedCurve(KisCubicCurve(points).toString());
358}
359
361{
362 // set all the icons for the curve preset shapes
363 m_curveOptionWidget->linearCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-linear"));
364 m_curveOptionWidget->revLinearButton->setIcon(KisIconUtils::loadIcon("curve-preset-linear-reverse"));
365 m_curveOptionWidget->jCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-j"));
366 m_curveOptionWidget->lCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-l"));
367 m_curveOptionWidget->sCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-s"));
368 m_curveOptionWidget->reverseSCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-s-reverse"));
369 m_curveOptionWidget->uCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-u"));
370 m_curveOptionWidget->revUCurveButton->setIcon(KisIconUtils::loadIcon("curve-preset-arch"));
371
372 // this helps make the checkboxes show themselves on the dark color themes
373 QPalette pal = m_curveOptionWidget->sensorSelector->palette();
374 QPalette newPalette = pal;
375 newPalette.setColor(QPalette::Active, QPalette::Window, pal.text().color() );
376 m_curveOptionWidget->sensorSelector->setPalette(newPalette);
377
378}
float value(const T *src, size_t ch)
std::function< KisCurveOptionInputControlsStrategyInterface *( KisCurveRangeModelInterface *, KisCurveWidget *, QWidget *, QWidget *)> KisCurveOptionInputControlsStrategyFactory
std::function< KisCurveOptionRangeControlsStrategyInterface *( KisCurveRangeModelInterface *, QWidget *)> KisCurveOptionRangeControlsStrategyFactory
std::function< KisCurveRangeModelInterface *(lager::cursor< QString >, lager::cursor< QRectF >, lager::reader< QString >, lager::reader< int >)> KisCurveRangeModelFactory
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisCurveOptionInputControlsStrategyFactory factory()
bool isCheckable() const override
void readOptionSetting(const KisPropertiesConfigurationSP setting) override
KisCurveOptionWidget(lager::cursor< KisCurveOptionDataCommon > optionData, KisPaintOpOption::PaintopCategory category, lager::reader< bool > enabledLink=lager::make_constant(true), std::optional< lager::reader< std::tuple< qreal, qreal > > > strengthRangeReader=std::nullopt)
QScopedPointer< KisCurveOptionInputControlsStrategyInterface > m_curveInputControlsStrategy
lager::cursor< qreal > strengthValueDenorm()
Ui_WdgCurveOption2 * m_curveOptionWidget
void setCurveWidgetsEnabled(bool value)
const QScopedPointer< Private > m_d
QScopedPointer< KisCurveOptionRangeControlsStrategyInterface > m_curveRangeControlsStrategy
void writeOptionSetting(KisPropertiesConfigurationSP setting) const override
void setCurrent(const QString &id)
void highlightedSensorChanged(const QString &id)
void setConfigurationPage(QWidget *page)
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
QIcon loadIcon(const QString &name)
constexpr auto unzip_wrapper
Definition KisMpl.h:70
bool read(const KisPropertiesConfiguration *setting)
Private(lager::cursor< KisCurveOptionDataCommon > optionData, lager::reader< bool > enabledLink, std::optional< lager::reader< std::tuple< qreal, qreal > > > strengthRangeReader, qreal strengthDisplayMultiplier, KisCurveRangeModelFactory curveRangeFactory)