Krita Source Code Documentation
Loading...
Searching...
No Matches
MyPaintCurveRangeModel.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8#include "kis_algebra_2d.h"
9#include "kis_cubic_curve.h"
10#include <lager/lenses.hpp>
11#include <lager/constant.hpp>
12#include <KisZug.h>
14#include <KisCurveRangeModel.h>
15
16namespace {
17 auto formatQRealAsString = [] (qreal value) {
18 return QString("%1").arg(value, 0, 'f', 2);
19 };
20
21 auto formatQRealAsStringWithSuffix = [] (const QString &suffix) {
22 return [suffix] (qreal value) {
23 return QString("%1%2").arg(value, 0, 'f', 2).arg(suffix);
24 };
25 };
26
27
28 auto curveToNormalizedCurve = lager::lenses::getset(
29 [] (const std::tuple<QString, QRectF> &curveData)
30 {
32 QList<KisCubicCurvePoint> points = KisCubicCurve(std::get<0>(curveData)).curvePoints();
33 const QRectF bounds = std::get<1>(curveData);
34
35 normalized.yLimit = qMax(qAbs(bounds.top()), qAbs(bounds.bottom()));
36 normalized.xMax = bounds.right();
37 normalized.xMin = bounds.left();
38
39 if (qFuzzyIsNull(normalized.yLimit)) {
40 points = {{0.0, 0.5, false}, {1.0, 0.5, false}};
41 } else {
42 for (auto it = points.begin(); it != points.end(); ++it) {
43 it->setX((it->x() - bounds.left()) / bounds.width());
44 it->setY(it->y() / (2.0 * normalized.yLimit) + 0.5);
45 }
46 }
47
48 normalized.curve = KisCubicCurve(points).toString();
49
50 //qDebug() << "get" << std::get<0>(curveData) << "->" << normalized.curve << bounds;
51 return normalized;
52 },
53 [] (std::tuple<QString, QRectF> curveData, const MyPaintCurveRangeModel::NormalizedCurve &normalizedCurve) {
54 QList<KisCubicCurvePoint> points = KisCubicCurve(normalizedCurve.curve).curvePoints();
55
56 for (auto it = points.begin(); it != points.end(); ++it) {
57 it->setX(it->x() * (normalizedCurve.xMax - normalizedCurve.xMin) + normalizedCurve.xMin);
58 it->setY((it->y() - 0.5) * normalizedCurve.yLimit * 2.0);
59 }
60
61 std::get<0>(curveData) = KisCubicCurve(points).toString();
62
63 std::get<1>(curveData) = QRectF(normalizedCurve.xMin,
64 -normalizedCurve.yLimit,
65 normalizedCurve.xMax - normalizedCurve.xMin,
66 2.0 * normalizedCurve.yLimit);
67
68 //qDebug() << "set" << std::get<0>(curveData) << "<-" << normalizedCurve.curve << std::get<1>(curveData);
69 return curveData;
70 }
71 );
72
73} // namespace
74
75
77
79 lager::cursor<QRectF> curveRange,
80 lager::reader<QString> activeSensorId,
81 lager::reader<int> activeSensorLength,
82 qreal maxYRange,
83 const QString &yValueSuffix)
84 : m_curve(std::move(curve))
85 , m_curveRange(std::move(curveRange))
86 , m_activeSensorId(std::move(activeSensorId))
87 , m_activeSensorLength(std::move(activeSensorLength))
88 , m_normalizedCurve(lager::with(m_curve, m_curveRange).zoom(curveToNormalizedCurve))
89 , m_maxYRange(maxYRange)
90 , m_yValueSuffix(yValueSuffix)
92 , LAGER_QT(xMin) {m_normalizedCurve[&NormalizedCurve::xMin]}
93 , LAGER_QT(xMax) {m_normalizedCurve[&NormalizedCurve::xMax]}
94 , LAGER_QT(xMinState) {lager::with(m_normalizedCurve[&NormalizedCurve::xMin],
96 lager::make_constant(0.0),
97 lager::make_constant(true))
98 .map(ToSpinBoxState{})}
99 , LAGER_QT(xMaxState) {lager::with(m_normalizedCurve[&NormalizedCurve::xMax],
100 lager::make_constant(1.0),
101 lager::with(m_activeSensorId, m_activeSensorLength)
103 lager::make_constant(true))
104 .map(ToSpinBoxState{})}
105{
106
107}
108
110{
111
112}
113
114KisCurveRangeModelFactory MyPaintCurveRangeModel::factory(qreal maxYRange, const QString &yValueSuffix)
115{
116 return
117 [maxYRange, yValueSuffix](lager::cursor<QString> curve, lager::cursor<QRectF> curveRange, lager::reader<QString> activeSensorId, lager::reader<int> activeSensorLength) {
118 return new MyPaintCurveRangeModel(curve, curveRange, activeSensorId, activeSensorLength, maxYRange, yValueSuffix);
119 };
120}
121
122std::tuple<QString, QRectF> MyPaintCurveRangeModel::reshapeCurve(std::tuple<QString, QRectF> curve)
123{
128 std::get<1>(curve) |= QRect(0, -1, 1, 2);
129
130 NormalizedCurve normalized = lager::view(curveToNormalizedCurve, curve);
131 curve = lager::set(curveToNormalizedCurve, curve, normalized);
132 return curve;
133}
134
135lager::cursor<QString> MyPaintCurveRangeModel::curve()
136{
138}
139
140lager::reader<QString> MyPaintCurveRangeModel::xMinLabel()
141{
142 return m_normalizedCurve[&NormalizedCurve::xMin].map(formatQRealAsString);
143}
144
145lager::reader<QString> MyPaintCurveRangeModel::xMaxLabel()
146{
147 return m_normalizedCurve[&NormalizedCurve::xMax].map(formatQRealAsString);
148}
149
150lager::reader<QString> MyPaintCurveRangeModel::yMinLabel()
151{
152 return yMinValue().map(formatQRealAsStringWithSuffix(m_yValueSuffix));
153}
154
155lager::reader<QString> MyPaintCurveRangeModel::yMaxLabel()
156{
157 return yMaxValue().map(formatQRealAsStringWithSuffix(m_yValueSuffix));
158}
159
160lager::reader<qreal> MyPaintCurveRangeModel::yMinValue()
161{
162 return m_normalizedCurve[&NormalizedCurve::yLimit].xform(kiszug::map_multiply<qreal>(-1.0));
163}
164
165lager::reader<qreal> MyPaintCurveRangeModel::yMaxValue()
166{
168}
169
170lager::reader<QString> MyPaintCurveRangeModel::yValueSuffix()
171{
172 return lager::make_constant(m_yValueSuffix);
173}
174
175lager::reader<qreal> MyPaintCurveRangeModel::xMinValue()
176{
178}
179
180lager::reader<qreal> MyPaintCurveRangeModel::xMaxValue()
181{
183}
184
185lager::reader<QString> MyPaintCurveRangeModel::xValueSuffix()
186{
187 return lager::make_constant(QString());
188}
189
191{
192 return m_maxYRange;
193}
float value(const T *src, size_t ch)
std::function< KisCurveRangeModelInterface *(lager::cursor< QString >, lager::cursor< QRectF >, lager::reader< QString >, lager::reader< int >)> KisCurveRangeModelFactory
LAGER_QT(xMin)
static qreal calcXMaxValueWithFactory(const QString &activeSensorId, const int length)
static qreal calcXMinValueWithFactory(const QString &sensorId)
lager::reader< qreal > xMaxValue() override
lager::reader< qreal > yMinValue() override
lager::reader< qreal > yMaxValue() override
lager::reader< QString > yValueSuffix() override
lager::reader< QString > yMinLabel() override
lager::reader< QString > yMaxLabel() override
lager::cursor< NormalizedCurve > m_normalizedCurve
qreal maxYRange() const
lager::cursor< QString > curve() override
lager::reader< QString > xMinLabel() override
lager::reader< QString > xValueSuffix() override
static std::tuple< QString, QRectF > reshapeCurve(std::tuple< QString, QRectF > curve)
static KisCurveRangeModelFactory factory(qreal maxYRange, const QString &yValueSuffix)
lager::reader< qreal > xMinValue() override
MyPaintCurveRangeModel(lager::cursor< QString > curve, lager::cursor< QRectF > curveRange, lager::reader< QString > activeSensorId, lager::reader< int > activeSensorLength, qreal maxYRange, const QString &yValueSuffix)
lager::reader< QString > xMaxLabel() override
static bool qFuzzyIsNull(half h)
#define bounds(x, a, b)
QString toString() const
const QList< KisCubicCurvePoint > & curvePoints() const