From 661dbaa24182ede7cd658c4fffcd8654190bbb81 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 2 Dec 2022 17:43:51 +0300 Subject: [PATCH 01/20] Split logic from KisCurveOptionData into a polymorphic class That is needed to let MyPaint brush engine to have a different set of sensors. Basically, KisCurveOptionDataCommon now accepts an abstract KisSensorPackInterface object that defines its behavior. The sensors pack is stored in a lazy-shared structure, so, hopefully, it will not be copied/allocated too often. Now we have two non-intersectinc subsets of "curve option data" hierarchies: 1) KisCurveOptionData; and 2) MyPaintCurveOptionData. They both can be passed to a KisCurveOptionWidget2, but otherwise they are not interchangable. --- .../KisPaintThicknessOptionWidget.cpp | 2 +- .../KisSmudgeLengthOptionWidget.cpp | 2 +- .../colorsmudge/KisSmudgeRadiusOptionData.cpp | 2 +- plugins/paintops/libpaintop/CMakeLists.txt | 4 + .../paintops/libpaintop/KisCurveOption2.cpp | 35 +- .../libpaintop/KisCurveOptionData.cpp | 390 ++---------------- .../paintops/libpaintop/KisCurveOptionData.h | 168 +------- .../libpaintop/KisCurveOptionDataCommon.cpp | 72 ++++ .../libpaintop/KisCurveOptionDataCommon.h | 90 ++++ .../KisCurveOptionDataUniformProperty.h | 2 +- .../libpaintop/KisCurveOptionModel.cpp | 42 +- .../paintops/libpaintop/KisCurveOptionModel.h | 6 +- .../libpaintop/KisCurveOptionWidget2.cpp | 14 +- .../libpaintop/KisCurveOptionWidget2.h | 10 +- .../libpaintop/KisDynamicSensorFactory.h | 2 +- .../KisDynamicSensorFactoryDistance.cpp | 27 +- .../KisDynamicSensorFactoryDistance.h | 2 +- .../KisDynamicSensorFactoryDrawingAngle.cpp | 27 +- .../KisDynamicSensorFactoryDrawingAngle.h | 2 +- .../KisDynamicSensorFactoryFade.cpp | 27 +- .../libpaintop/KisDynamicSensorFactoryFade.h | 2 +- .../KisDynamicSensorFactoryTime.cpp | 27 +- .../libpaintop/KisDynamicSensorFactoryTime.h | 2 +- .../libpaintop/KisKritaSensorPack.cpp | 264 ++++++++++++ .../paintops/libpaintop/KisKritaSensorPack.h | 82 ++++ .../KisLightnessStrengthOptionWidget.cpp | 2 +- .../libpaintop/KisMirrorOptionWidget.cpp | 2 +- .../libpaintop/KisMultiSensorsSelector2.cpp | 10 +- .../libpaintop/KisMultiSensorsSelector2.h | 2 +- .../paintops/libpaintop/KisRotationOption.cpp | 8 +- .../libpaintop/KisScatterOptionData.cpp | 2 +- .../libpaintop/KisScatterOptionWidget.cpp | 2 +- plugins/paintops/libpaintop/KisSensorData.cpp | 132 ++++++ plugins/paintops/libpaintop/KisSensorData.h | 80 ++++ .../libpaintop/KisSensorPackInterface.cpp | 16 + .../libpaintop/KisSensorPackInterface.h | 39 ++ .../libpaintop/KisSharpnessOptionData.cpp | 2 +- .../libpaintop/KisSharpnessOptionWidget.cpp | 2 +- .../KisSimpleDynamicSensorFactory.cpp | 2 +- .../KisSimpleDynamicSensorFactory.h | 2 +- .../paintops/libpaintop/KisSizeOptionData.cpp | 4 +- .../libpaintop/KisSizeOptionWidget.cpp | 2 +- .../libpaintop/KisSpacingOptionWidget.cpp | 2 +- .../tests/KisCurveOptionDataTest.cpp | 28 +- plugins/paintops/mypaint/CMakeLists.txt | 2 + .../mypaint/MyPaintCurveOptionData.cpp | 45 ++ .../paintops/mypaint/MyPaintCurveOptionData.h | 35 ++ .../paintops/mypaint/MyPaintSensorPack.cpp | 95 +++++ plugins/paintops/mypaint/MyPaintSensorPack.h | 75 ++++ 49 files changed, 1264 insertions(+), 630 deletions(-) create mode 100644 plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveOptionDataCommon.h create mode 100644 plugins/paintops/libpaintop/KisKritaSensorPack.cpp create mode 100644 plugins/paintops/libpaintop/KisKritaSensorPack.h create mode 100644 plugins/paintops/libpaintop/KisSensorData.cpp create mode 100644 plugins/paintops/libpaintop/KisSensorData.h create mode 100644 plugins/paintops/libpaintop/KisSensorPackInterface.cpp create mode 100644 plugins/paintops/libpaintop/KisSensorPackInterface.h create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionData.cpp create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionData.h create mode 100644 plugins/paintops/mypaint/MyPaintSensorPack.cpp create mode 100644 plugins/paintops/mypaint/MyPaintSensorPack.h diff --git a/plugins/paintops/colorsmudge/KisPaintThicknessOptionWidget.cpp b/plugins/paintops/colorsmudge/KisPaintThicknessOptionWidget.cpp index 903030d9356..a875ae47367 100644 --- a/plugins/paintops/colorsmudge/KisPaintThicknessOptionWidget.cpp +++ b/plugins/paintops/colorsmudge/KisPaintThicknessOptionWidget.cpp @@ -28,7 +28,7 @@ struct KisPaintThicknessOptionWidget::Private KisPaintThicknessOptionWidget::KisPaintThicknessOptionWidget(lager::cursor optionData, lager::reader lightnessModeEnabled) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL, lightnessModeEnabled) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL, lightnessModeEnabled) , m_d(new Private(optionData, lightnessModeEnabled)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/colorsmudge/KisSmudgeLengthOptionWidget.cpp b/plugins/paintops/colorsmudge/KisSmudgeLengthOptionWidget.cpp index 540c62f9462..f8a06fd0c51 100644 --- a/plugins/paintops/colorsmudge/KisSmudgeLengthOptionWidget.cpp +++ b/plugins/paintops/colorsmudge/KisSmudgeLengthOptionWidget.cpp @@ -39,7 +39,7 @@ struct KisSmudgeLengthOptionWidget::Private KisSmudgeLengthOptionWidget::KisSmudgeLengthOptionWidget(lager::cursor optionData, lager::reader isBrushPierced, lager::reader forceNewEngine) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) , m_d(new Private(optionData, isBrushPierced, forceNewEngine)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp b/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp index bb789671945..747eb462225 100644 --- a/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp +++ b/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp @@ -12,7 +12,7 @@ KisSmudgeRadiusOptionData::KisSmudgeRadiusOptionData() true, false, false, 0.0, 3.0) { - valueFixUpReadCallback = [] (KisCurveOptionData *data, const KisPropertiesConfiguration *setting) { + valueFixUpReadCallback = [] (KisCurveOptionDataCommon *data, const KisPropertiesConfiguration *setting) { const int smudgeRadiusVersion = setting->getInt("SmudgeRadiusVersion", 1); if (smudgeRadiusVersion < 2) { data->strengthValue = data->strengthValue / 100.0; diff --git a/plugins/paintops/libpaintop/CMakeLists.txt b/plugins/paintops/libpaintop/CMakeLists.txt index 39b492fc995..c62476bafb2 100644 --- a/plugins/paintops/libpaintop/CMakeLists.txt +++ b/plugins/paintops/libpaintop/CMakeLists.txt @@ -15,6 +15,10 @@ set(kritalibpaintop_LIB_SRCS kis_curve_option_widget.cpp kis_curve_option_uniform_property.cpp KisCurveOptionDataUniformProperty.cpp + KisSensorData.cpp + KisSensorPackInterface.cpp + KisKritaSensorPack.cpp + KisCurveOptionDataCommon.cpp KisCurveOptionData.cpp KisCurveOptionModel.cpp KisCurveOptionWidget2.cpp diff --git a/plugins/paintops/libpaintop/KisCurveOption2.cpp b/plugins/paintops/libpaintop/KisCurveOption2.cpp index f804246f46d..5cc70952170 100644 --- a/plugins/paintops/libpaintop/KisCurveOption2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOption2.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "KisCurveOption2.h" +#include "KisCurveOptionData.h" #include "kis_algebra_2d.h" #include @@ -34,22 +35,24 @@ std::vector> generateSensors(const KisCurveOp commonCurve = KisCubicCurve(data.commonCurve); } - addSensor(result, data.sensorPressure, commonCurve); - addSensor(result, data.sensorPressureIn, commonCurve); - addSensor(result, data.sensorTangentialPressure, commonCurve); - addSensor(result, data.sensorDrawingAngle, commonCurve); - addSensor(result, data.sensorXTilt, commonCurve); - addSensor(result, data.sensorYTilt, commonCurve); - addSensor(result, data.sensorTiltDirection, commonCurve); - addSensor(result, data.sensorTiltElevation, commonCurve); - addSensor(result, data.sensorRotation, commonCurve); - addSensor(result, data.sensorFuzzyPerDab, commonCurve); - addSensor(result, data.sensorFuzzyPerStroke, commonCurve, data.id.id()); - addSensor(result, data.sensorSpeed, commonCurve); - addSensor(result, data.sensorFade, commonCurve); - addSensor(result, data.sensorDistance, commonCurve); - addSensor(result, data.sensorTime, commonCurve); - addSensor(result, data.sensorPerspective, commonCurve); + const KisKritaSensorData &sensorStruct = data.sensorStruct(); + + addSensor(result, sensorStruct.sensorPressure, commonCurve); + addSensor(result, sensorStruct.sensorPressureIn, commonCurve); + addSensor(result, sensorStruct.sensorTangentialPressure, commonCurve); + addSensor(result, sensorStruct.sensorDrawingAngle, commonCurve); + addSensor(result, sensorStruct.sensorXTilt, commonCurve); + addSensor(result, sensorStruct.sensorYTilt, commonCurve); + addSensor(result, sensorStruct.sensorTiltDirection, commonCurve); + addSensor(result, sensorStruct.sensorTiltElevation, commonCurve); + addSensor(result, sensorStruct.sensorRotation, commonCurve); + addSensor(result, sensorStruct.sensorFuzzyPerDab, commonCurve); + addSensor(result, sensorStruct.sensorFuzzyPerStroke, commonCurve, data.id.id()); + addSensor(result, sensorStruct.sensorSpeed, commonCurve); + addSensor(result, sensorStruct.sensorFade, commonCurve); + addSensor(result, sensorStruct.sensorDistance, commonCurve); + addSensor(result, sensorStruct.sensorTime, commonCurve); + addSensor(result, sensorStruct.sensorPerspective, commonCurve); return result; } diff --git a/plugins/paintops/libpaintop/KisCurveOptionData.cpp b/plugins/paintops/libpaintop/KisCurveOptionData.cpp index 152fae374b2..114dc08d85c 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionData.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionData.cpp @@ -3,379 +3,43 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "KisCurveOptionData.h" - -#include -#include - -#include - -KisSensorData::KisSensorData(const KoID &sensorId) - : id(sensorId), - curve(DEFAULT_CURVE_STRING) -{ -} - -KisSensorData::~KisSensorData() -{ -} - -void KisSensorData::write(QDomDocument& doc, QDomElement &e) const -{ - e.setAttribute("id", id.id()); - if (curve != DEFAULT_CURVE_STRING) { - QDomElement curve_elt = doc.createElement("curve"); - QDomText text = doc.createTextNode(curve); - curve_elt.appendChild(text); - e.appendChild(curve_elt); - } -} - -void KisSensorData::read(const QDomElement& e) -{ - KIS_ASSERT(e.attribute("id", "") == id.id()); - QDomElement curve_elt = e.firstChildElement("curve"); - if (!curve_elt.isNull()) { - curve = curve_elt.text(); - } else { - curve = DEFAULT_CURVE_STRING; - } -} - -void KisSensorData::reset() -{ - *this = KisSensorData(id); -} - -KisSensorWithLengthData::KisSensorWithLengthData(const KoID &sensorId, const QLatin1String &lengthTag) - : KisSensorData(sensorId) - , m_lengthTag(lengthTag.isNull() ? QLatin1Literal("length") : lengthTag) -{ - if (sensorId == FadeId) { - isPeriodic = false; - length = 1000; - } else if (sensorId == DistanceId) { - isPeriodic = false; - length = 30; - } else if (sensorId == TimeId) { - isPeriodic = false; - length = 30; - } else { - qFatal("This sensor type \"%s\" has no length associated!", sensorId.id().toLatin1().data()); - } -} - -void KisSensorWithLengthData::write(QDomDocument &doc, QDomElement &e) const -{ - KisSensorData::write(doc, e); - e.setAttribute("periodic", isPeriodic); - e.setAttribute(m_lengthTag, length); -} - -void KisSensorWithLengthData::read(const QDomElement &e) -{ - reset(); - KisSensorData::read(e); - - if (e.hasAttribute("periodic")) { - isPeriodic = e.attribute("periodic").toInt(); - } - - if (e.hasAttribute(m_lengthTag)) { - length = e.attribute(m_lengthTag).toInt(); - } -} - -void KisSensorWithLengthData::reset() -{ - *this = KisSensorWithLengthData(id, m_lengthTag); -} - -KisDrawingAngleSensorData::KisDrawingAngleSensorData() - : KisSensorData(DrawingAngleId) -{ -} - -void KisDrawingAngleSensorData::write(QDomDocument &doc, QDomElement &e) const -{ - KisSensorData::write(doc, e); - e.setAttribute("fanCornersEnabled", fanCornersEnabled); - e.setAttribute("fanCornersStep", fanCornersStep); - e.setAttribute("angleOffset", angleOffset); - e.setAttribute("lockedAngleMode", lockedAngleMode); -} - -void KisDrawingAngleSensorData::read(const QDomElement &e) -{ - reset(); - KisSensorData::read(e); - - if (e.hasAttribute("fanCornersEnabled")) { - fanCornersEnabled = e.attribute("fanCornersEnabled").toInt(); - } - if (e.hasAttribute("fanCornersStep")) { - fanCornersStep = e.attribute("fanCornersStep").toInt(); - } - if (e.hasAttribute("angleOffset")) { - angleOffset = e.attribute("angleOffset").toInt(); - } - if (e.hasAttribute("lockedAngleMode")) { - lockedAngleMode = e.attribute("lockedAngleMode").toInt(); - } -} - -void KisDrawingAngleSensorData::reset() -{ - *this = KisDrawingAngleSensorData(); -} - -KisCurveOptionData::KisCurveOptionData(const QString &_prefix, const KoID _id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue) - : id(_id), - prefix(_prefix), - isCheckable(_isCheckable), - separateCurveValue(_separateCurveValue), - strengthMinValue(_minValue), - strengthMaxValue(_maxValue), - isChecked(_isChecked), - strengthValue(_maxValue), - sensorPressure(PressureId), - sensorPressureIn(PressureInId), - sensorXTilt(XTiltId), - sensorYTilt(YTiltId), - sensorTiltDirection(TiltDirectionId), - sensorTiltElevation(TiltElevationId), - sensorSpeed(SpeedId), - sensorDrawingAngle(), - sensorRotation(RotationId), - sensorDistance(DistanceId), - sensorTime(TimeId, QLatin1Literal("duration")), - sensorFuzzyPerDab(FuzzyPerDabId), - sensorFuzzyPerStroke(FuzzyPerStrokeId), - sensorFade(FadeId), - sensorPerspective(PerspectiveId), - sensorTangentialPressure(TangentialPressureId) -{ - sensorPressure.isActive = true; -} - -KisCurveOptionData::KisCurveOptionData(const KoID _id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue) - : KisCurveOptionData("", _id, _isCheckable, _isChecked, _separateCurveValue, _minValue, _maxValue) -{ -} - -namespace detail { -template , - KisSensorData>> -std::vector sensors(Data *data) -{ - std::vector result; - - result.reserve(16); - - result.push_back(&data->sensorPressure); - result.push_back(&data->sensorPressureIn); - result.push_back(&data->sensorTangentialPressure); - - result.push_back(&data->sensorDrawingAngle); - result.push_back(&data->sensorXTilt); - result.push_back(&data->sensorYTilt); - result.push_back(&data->sensorTiltDirection); - result.push_back(&data->sensorTiltElevation); - result.push_back(&data->sensorRotation); - result.push_back(&data->sensorFuzzyPerDab); - result.push_back(&data->sensorFuzzyPerStroke); - - result.push_back(&data->sensorSpeed); - result.push_back(&data->sensorFade); - result.push_back(&data->sensorDistance); - result.push_back(&data->sensorTime); - - result.push_back(&data->sensorPerspective); - - - return result; -} -} - -std::vector KisCurveOptionData::sensors() const -{ - return detail::sensors(this); -} +#include "KisCurveOptionData.h" -std::vector KisCurveOptionData::sensors() +KisCurveOptionData::KisCurveOptionData(const QString &prefix, + const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue) + : KisCurveOptionDataCommon(prefix, + id, + isCheckable, + isChecked, + separateCurveValue, + minValue, + maxValue, + new KisKritaSensorPack()) { - return detail::sensors(this); } -bool KisCurveOptionData::read(const KisPropertiesConfiguration *setting) +KisCurveOptionData::KisCurveOptionData(const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue) + : KisCurveOptionData("", id, isCheckable, isChecked, separateCurveValue, minValue, maxValue) { - if (!setting) return false; - - if (prefix.isEmpty()) { - return readPrefixed(setting); - } else { - KisPropertiesConfiguration prefixedSetting; - setting->getPrefixedProperties(prefix, &prefixedSetting); - return readPrefixed(&prefixedSetting); - } } -void KisCurveOptionData::write(KisPropertiesConfiguration *setting) const +KisKritaSensorData &KisCurveOptionData::sensorStruct() { - if (prefix.isEmpty()) { - writePrefixed(setting); - } else { - KisPropertiesConfiguration prefixedSetting; - writePrefixed(&prefixedSetting); - setting->setPrefixedProperties(prefix, &prefixedSetting); - } + return dynamic_cast(sensorData.data())->sensorsStruct(); } -bool KisCurveOptionData::readPrefixed(const KisPropertiesConfiguration *setting) +const KisKritaSensorData &KisCurveOptionData::sensorStruct() const { - isChecked = !isCheckable || setting->getBool("Pressure" + id.id(), false); - - std::vector sensors = this->sensors(); - QMap sensorById; - - Q_FOREACH (KisSensorData *sensor, sensors) { - sensorById.insert(sensor->id.id(), sensor); - } - - QSet sensorsToReset = - QSet::fromList(sensorById.values()); - - const QString sensorDefinition = setting->getString(id.id() + "Sensor"); - - if (sensorDefinition.isEmpty()) { - // noop - } else if (!sensorDefinition.contains("sensorslist")) { - QDomDocument doc; - doc.setContent(sensorDefinition); - QDomElement e = doc.documentElement(); - - const QString sensorId = e.attribute("id", ""); - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!sensorId.isEmpty(), false); - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sensorById.contains(sensorId), false); - - KisSensorData *sensor = sensorById[sensorId]; - sensor->read(e); - sensor->isActive = true; - sensorsToReset.remove(sensor); - - commonCurve = sensor->curve; - - } else { - QString proposedCommonCurve; - - QDomDocument doc; - doc.setContent(sensorDefinition); - QDomElement elt = doc.documentElement(); - QDomNode node = elt.firstChild(); - while (!node.isNull()) { - if (node.isElement()) { - QDomElement childelt = node.toElement(); - if (childelt.tagName() == "ChildSensor") { - - const QString sensorId = childelt.attribute("id", ""); - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!sensorId.isEmpty(), false); - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sensorById.contains(sensorId), false); - - KisSensorData *sensor = sensorById[sensorId]; - sensor->read(childelt); - sensor->isActive = true; - sensorsToReset.remove(sensor); - - /// due to legacy reasons we initialize common curve - /// with the "last read curve value" - proposedCommonCurve = sensor->curve; - } - } - node = node.nextSibling(); - } - - commonCurve = !proposedCommonCurve.isEmpty() ? proposedCommonCurve : DEFAULT_CURVE_STRING; - } - - useSameCurve = setting->getBool(id.id() + "UseSameCurve", true); - - // Only load the old curve format if the curve wasn't saved by the sensor - // This will give every sensor the same curve. - if (!sensorDefinition.contains("curve")) { - if (setting->getBool("Custom" + id.id(), false)) { - commonCurve = setting->getString("Curve" + id.id(), DEFAULT_CURVE_STRING); - Q_FOREACH (KisSensorData *sensor, sensors) { - sensor->curve = commonCurve; - sensorsToReset.remove(sensor); - } - } else { - commonCurve = DEFAULT_CURVE_STRING; - } - } - - if (useSameCurve) { - commonCurve = setting->getString(id.id() + "commonCurve", DEFAULT_CURVE_STRING); - } - - Q_FOREACH (KisSensorData *sensor, sensorsToReset) { - sensor->reset(); - } - - // At least one sensor needs to be active - if (std::find_if(sensors.begin(), sensors.end(), - std::mem_fn(&KisSensorData::isActive)) == sensors.end()) { - - sensorById[PressureId.id()]->isActive = true; - } - - strengthValue = setting->getDouble(id.id() + "Value", strengthMaxValue); - - if (valueFixUpReadCallback) { - valueFixUpReadCallback(this, setting); - } - - useCurve = setting->getBool(id.id() + "UseCurve", true); - curveMode = setting->getInt(id.id() + "curveMode", 0); - - return true; -} - -void KisCurveOptionData::writePrefixed(KisPropertiesConfiguration *setting) const -{ - setting->setProperty("Pressure" + id.id(), isChecked || !isCheckable); - - QVector activeSensors; - Q_FOREACH(const KisSensorData *sensor, sensors()) { - if (sensor->isActive) { - activeSensors.append(sensor); - } - } - - QDomDocument doc = QDomDocument("params"); - QDomElement root = doc.createElement("params"); - doc.appendChild(root); - - if (activeSensors.size() == 1) { - activeSensors.first()->write(doc, root); - } else { - root.setAttribute("id", "sensorslist"); - Q_FOREACH (const KisSensorData *sensor, activeSensors) { - QDomElement childelt = doc.createElement("ChildSensor"); - sensor->write(doc, childelt); - root.appendChild(childelt); - } - } - setting->setProperty(id.id() + "Sensor", doc.toString()); - - setting->setProperty(id.id() + "UseCurve", useCurve); - setting->setProperty(id.id() + "UseSameCurve", useSameCurve); - setting->setProperty(id.id() + "Value", strengthValue); - if (valueFixUpWriteCallback) { - valueFixUpWriteCallback(strengthValue, setting); - } - setting->setProperty(id.id() + "curveMode", curveMode); - setting->setProperty(id.id() + "commonCurve", commonCurve); + return dynamic_cast(sensorData.constData())->constSensorsStruct(); } diff --git a/plugins/paintops/libpaintop/KisCurveOptionData.h b/plugins/paintops/libpaintop/KisCurveOptionData.h index 835358a0c25..e8799f58099 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionData.h +++ b/plugins/paintops/libpaintop/KisCurveOptionData.h @@ -3,181 +3,33 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ + #ifndef KISCURVEOPTIONDATA_H #define KISCURVEOPTIONDATA_H -#include -#include - -#include "kis_paintop_option.h" -#include "kis_dynamic_sensor.h" - - -struct PAINTOP_EXPORT KisSensorData : public boost::equality_comparable -{ - KisSensorData(const KoID &sensorId); - virtual ~KisSensorData(); - - inline friend bool operator==(const KisSensorData &lhs, const KisSensorData &rhs) { - return lhs.id == rhs.id && - lhs.curve == rhs.curve && - lhs.isActive == rhs.isActive; - } - - virtual void write(QDomDocument& doc, QDomElement &e) const; - virtual void read(const QDomElement &e); - virtual void reset(); - - KoID id; - QString curve; - - // not a part of XML data, managed by the curve option - bool isActive = false; -}; - -struct PAINTOP_EXPORT KisSensorWithLengthData : public KisSensorData, public boost::equality_comparable -{ - KisSensorWithLengthData(const KoID &sensorId, const QLatin1String &lengthTag = {}); +#include +#include - inline friend bool operator==(const KisSensorWithLengthData &lhs, const KisSensorWithLengthData &rhs) { - return *static_cast(&lhs) == *static_cast(&rhs) && - lhs.length == rhs.length && - lhs.isPeriodic == rhs.isPeriodic && - lhs.m_lengthTag == rhs.m_lengthTag; - } - void write(QDomDocument& doc, QDomElement &e) const override; - void read(const QDomElement &e) override; - void reset() override; - - int length = 30; - bool isPeriodic = false; -private: - QLatin1String m_lengthTag; -}; - -struct PAINTOP_EXPORT KisDrawingAngleSensorData : public KisSensorData, public boost::equality_comparable +struct PAINTOP_EXPORT KisCurveOptionData : KisCurveOptionDataCommon { - KisDrawingAngleSensorData(); - - inline friend bool operator==(const KisDrawingAngleSensorData &lhs, const KisDrawingAngleSensorData &rhs) { - return *static_cast(&lhs) == *static_cast(&rhs) && - lhs.fanCornersEnabled == rhs.fanCornersEnabled && - lhs.fanCornersStep == rhs.fanCornersStep && - lhs.angleOffset == rhs.angleOffset && - lhs.lockedAngleMode == rhs.lockedAngleMode; - } - - void write(QDomDocument& doc, QDomElement &e) const override; - void read(const QDomElement &e) override; - void reset() override; - - bool fanCornersEnabled = false; - int fanCornersStep = 30; - int angleOffset = 0; // in degrees - bool lockedAngleMode = false; -}; - - - -struct PAINTOP_EXPORT KisCurveOptionData : boost::equality_comparable -{ - static constexpr bool supports_prefix = true; - KisCurveOptionData(const QString &prefix, - const KoID id, + const KoID &id, bool isCheckable = true, bool isChecked = false, bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); - KisCurveOptionData(const KoID id, + KisCurveOptionData(const KoID &id, bool isCheckable = true, bool isChecked = false, bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); - - inline friend bool operator==(const KisCurveOptionData &lhs, const KisCurveOptionData &rhs) { - return lhs.id == rhs.id && - lhs.prefix == rhs.prefix && - lhs.isCheckable == rhs.isCheckable && - lhs.isChecked == rhs.isChecked && - lhs.useCurve == rhs.useCurve && - lhs.useSameCurve == rhs.useSameCurve && - lhs.separateCurveValue == rhs.separateCurveValue && - lhs.curveMode == rhs.curveMode && - lhs.commonCurve == rhs.commonCurve && - lhs.strengthValue == rhs.strengthValue && - lhs.strengthMinValue == rhs.strengthMinValue && - lhs.strengthMaxValue == rhs.strengthMaxValue && - lhs.sensorPressure == rhs.sensorPressure && - lhs.sensorPressureIn == rhs.sensorPressureIn && - lhs.sensorXTilt == rhs.sensorXTilt && - lhs.sensorYTilt == rhs.sensorYTilt && - lhs.sensorTiltDirection == rhs.sensorTiltDirection && - lhs.sensorTiltElevation == rhs.sensorTiltElevation && - lhs.sensorSpeed == rhs.sensorSpeed && - lhs.sensorDrawingAngle == rhs.sensorDrawingAngle && - lhs.sensorRotation == rhs.sensorRotation && - lhs.sensorDistance == rhs.sensorDistance && - lhs.sensorTime == rhs.sensorTime && - lhs.sensorFuzzyPerDab == rhs.sensorFuzzyPerDab && - lhs.sensorFuzzyPerStroke == rhs.sensorFuzzyPerStroke && - lhs.sensorFade == rhs.sensorFade && - lhs.sensorPerspective == rhs.sensorPerspective && - lhs.sensorTangentialPressure == rhs.sensorTangentialPressure; - } - - KoID id; - QString prefix; - bool isCheckable = true; - bool separateCurveValue = false; - qreal strengthMinValue = 0.0; - qreal strengthMaxValue = 1.0; - - bool isChecked = true; - bool useCurve = true; - bool useSameCurve = true; - - int curveMode = 0; // TODO: to enum! - QString commonCurve = DEFAULT_CURVE_STRING; - qreal strengthValue = 1.0; - - KisSensorData sensorPressure; - KisSensorData sensorPressureIn; - KisSensorData sensorXTilt; - KisSensorData sensorYTilt; - KisSensorData sensorTiltDirection; - KisSensorData sensorTiltElevation; - KisSensorData sensorSpeed; - KisDrawingAngleSensorData sensorDrawingAngle; - KisSensorData sensorRotation; - KisSensorWithLengthData sensorDistance; - KisSensorWithLengthData sensorTime; - KisSensorData sensorFuzzyPerDab; - KisSensorData sensorFuzzyPerStroke; - KisSensorWithLengthData sensorFade; - KisSensorData sensorPerspective; - KisSensorData sensorTangentialPressure; - - std::vector sensors() const; - std::vector sensors(); - - bool read(const KisPropertiesConfiguration *setting); - void write(KisPropertiesConfiguration *setting) const; - - using ValueFixUpReadCallback = std::function; - ValueFixUpReadCallback valueFixUpReadCallback; - - using ValueFixUpWriteCallback= std::function; - ValueFixUpWriteCallback valueFixUpWriteCallback; - -private: - bool readPrefixed(const KisPropertiesConfiguration *setting); - void writePrefixed(KisPropertiesConfiguration *setting) const; + + KisKritaSensorData& sensorStruct(); + const KisKritaSensorData& sensorStruct() const; }; - -#endif // KISCURVEOPTIONDATA_H +#endif // KISCURVEOPTIONDATA_H \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp new file mode 100644 index 00000000000..1bf6e29039b --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "KisCurveOptionDataCommon.h" +#include "KisSensorPackInterface.h" + +KisCurveOptionDataCommon::KisCurveOptionDataCommon(const QString &_prefix, const KoID &_id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) + : id(_id), + prefix(_prefix), + isCheckable(_isCheckable), + separateCurveValue(_separateCurveValue), + strengthMinValue(_minValue), + strengthMaxValue(_maxValue), + isChecked(_isChecked), + strengthValue(_maxValue), + sensorData(sensorInterface) +{ +} + +KisCurveOptionDataCommon::KisCurveOptionDataCommon(const KoID &_id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) + : KisCurveOptionDataCommon("", _id, _isCheckable, _isChecked, _separateCurveValue, _minValue, _maxValue, sensorInterface) +{ +} + +// TODO: rename into constSensors +std::vector KisCurveOptionDataCommon::sensors() const +{ + return sensorData->constSensors(); +} + +std::vector KisCurveOptionDataCommon::sensors() +{ + return sensorData->sensors(); +} + +bool KisCurveOptionDataCommon::read(const KisPropertiesConfiguration *setting) +{ + if (!setting) return false; + + if (prefix.isEmpty()) { + return readPrefixed(setting); + } else { + KisPropertiesConfiguration prefixedSetting; + setting->getPrefixedProperties(prefix, &prefixedSetting); + return readPrefixed(&prefixedSetting); + } +} + +void KisCurveOptionDataCommon::write(KisPropertiesConfiguration *setting) const +{ + if (prefix.isEmpty()) { + writePrefixed(setting); + } else { + KisPropertiesConfiguration prefixedSetting; + writePrefixed(&prefixedSetting); + setting->setPrefixedProperties(prefix, &prefixedSetting); + } +} + +bool KisCurveOptionDataCommon::readPrefixed(const KisPropertiesConfiguration *setting) +{ + return sensorData->read(*this, setting); +} + +void KisCurveOptionDataCommon::writePrefixed(KisPropertiesConfiguration *setting) const +{ + sensorData->write(*this, setting); +} + + diff --git a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h new file mode 100644 index 00000000000..e307e0666bd --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef KISCURVEOPTIONDATACOMMON_H +#define KISCURVEOPTIONDATACOMMON_H + +#include + +#include "kis_assert.h" +#include "kis_paintop_option.h" +#include "kis_dynamic_sensor.h" +#include "kritapaintop_export.h" + +#include + + +struct PAINTOP_EXPORT KisCurveOptionDataCommon : boost::equality_comparable +{ + static constexpr bool supports_prefix = true; + + KisCurveOptionDataCommon(const QString &prefix, + const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue, + KisSensorPackInterface *sensorInterface); + + KisCurveOptionDataCommon(const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue, + KisSensorPackInterface *sensorInterface); + + inline friend bool operator==(const KisCurveOptionDataCommon &lhs, const KisCurveOptionDataCommon &rhs) { + return lhs.id == rhs.id && + lhs.prefix == rhs.prefix && + lhs.isCheckable == rhs.isCheckable && + lhs.isChecked == rhs.isChecked && + lhs.useCurve == rhs.useCurve && + lhs.useSameCurve == rhs.useSameCurve && + lhs.separateCurveValue == rhs.separateCurveValue && + lhs.curveMode == rhs.curveMode && + lhs.commonCurve == rhs.commonCurve && + lhs.strengthValue == rhs.strengthValue && + lhs.strengthMinValue == rhs.strengthMinValue && + lhs.strengthMaxValue == rhs.strengthMaxValue && + lhs.sensorData->compare(rhs.sensorData.constData()); + } + + KoID id; + QString prefix; + bool isCheckable = true; + bool separateCurveValue = false; + qreal strengthMinValue = 0.0; + qreal strengthMaxValue = 1.0; + + bool isChecked = true; + bool useCurve = true; + bool useSameCurve = true; + + int curveMode = 0; // TODO: to enum! + QString commonCurve = DEFAULT_CURVE_STRING; + qreal strengthValue = 1.0; + + QSharedDataPointer sensorData; + + std::vector sensors() const; + std::vector sensors(); + + bool read(const KisPropertiesConfiguration *setting); + void write(KisPropertiesConfiguration *setting) const; + + using ValueFixUpReadCallback = std::function; + ValueFixUpReadCallback valueFixUpReadCallback; + + using ValueFixUpWriteCallback= std::function; + ValueFixUpWriteCallback valueFixUpWriteCallback; + +private: + bool readPrefixed(const KisPropertiesConfiguration *setting); + void writePrefixed(KisPropertiesConfiguration *setting) const; +}; + +#endif // KISCURVEOPTIONDATACOMMON_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionDataUniformProperty.h b/plugins/paintops/libpaintop/KisCurveOptionDataUniformProperty.h index df6625e9522..66c169f313f 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionDataUniformProperty.h +++ b/plugins/paintops/libpaintop/KisCurveOptionDataUniformProperty.h @@ -10,7 +10,7 @@ #include "kis_slider_based_paintop_property.h" #include -class KisCurveOptionData; +struct KisCurveOptionData; class KisPaintOpPresetUpdateProxy; class PAINTOP_EXPORT KisCurveOptionDataUniformProperty : public KisDoubleSliderBasedPaintOpProperty diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp index ae33c8916a4..d9bbbfb8202 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp @@ -10,7 +10,7 @@ #include auto activeCurveLens = lager::lenses::getset( - [](const std::tuple &data) -> QString { + [](const std::tuple &data) -> QString { QString activeCurve; const bool useSameCurve = std::get<0>(data).useSameCurve; @@ -35,7 +35,7 @@ auto activeCurveLens = lager::lenses::getset( return activeCurve; }, - [](std::tuple data, QString curve) { + [](std::tuple data, QString curve) { const bool useSameCurve = std::get<0>(data).useSameCurve; if (useSameCurve) { @@ -60,48 +60,38 @@ auto activeCurveLens = lager::lenses::getset( return data; }); -int calcActiveSensorLength(const KisCurveOptionData &data, const QString &activeSensorId) { - int length = -1; - - if (activeSensorId == FadeId.id()) { - return data.sensorFade.length; - } else if (activeSensorId == DistanceId.id()) { - return data.sensorDistance.length; - } else if (activeSensorId == TimeId.id()) { - return data.sensorTime.length; - } - - return length; +int calcActiveSensorLength(const KisCurveOptionDataCommon &data, const QString &activeSensorId) { + return data.sensorData->calcActiveSensorLength(activeSensorId); } -KisCurveOptionModel::KisCurveOptionModel(lager::cursor _optionData, +KisCurveOptionModel::KisCurveOptionModel(lager::cursor _optionData, lager::reader externallyEnabled, std::optional> rangeOverride) : optionData(_optionData) , rangeNorm(rangeOverride ? *rangeOverride : - lager::with(optionData[&KisCurveOptionData::strengthMinValue], - optionData[&KisCurveOptionData::strengthMaxValue])) + lager::with(optionData[&KisCurveOptionDataCommon::strengthMinValue], + optionData[&KisCurveOptionDataCommon::strengthMaxValue])) , activeSensorIdData(PressureId.id()) - , LAGER_QT(isCheckable) {optionData[&KisCurveOptionData::isCheckable]} - , LAGER_QT(isChecked) {optionData[&KisCurveOptionData::isChecked]} + , LAGER_QT(isCheckable) {optionData[&KisCurveOptionDataCommon::isCheckable]} + , LAGER_QT(isChecked) {optionData[&KisCurveOptionDataCommon::isChecked]} , LAGER_QT(effectiveIsChecked) {lager::with(LAGER_QT(isChecked), externallyEnabled).map(std::logical_and{})} , LAGER_QT(effectiveStrengthValueNorm) { lager::with(rangeNorm.zoom(lager::lenses::first), - optionData[&KisCurveOptionData::strengthValue], + optionData[&KisCurveOptionDataCommon::strengthValue], rangeNorm.zoom(lager::lenses::second)) .map(&qBound)} , LAGER_QT(strengthValueDenorm) { - optionData[&KisCurveOptionData::strengthValue] + optionData[&KisCurveOptionDataCommon::strengthValue] .zoom(kiszug::lenses::scale(100.0))} , LAGER_QT(effectiveStrengthStateDenorm) { lager::with(LAGER_QT(effectiveStrengthValueNorm), rangeNorm.zoom(lager::lenses::first), rangeNorm.zoom(lager::lenses::second)) .xform(kiszug::foreach_arg(kiszug::map_mupliply(100.0)))} - , LAGER_QT(useCurve) {optionData[&KisCurveOptionData::useCurve]} - , LAGER_QT(useSameCurve) {optionData[&KisCurveOptionData::useSameCurve]} - , LAGER_QT(curveMode) {optionData[&KisCurveOptionData::curveMode]} + , LAGER_QT(useCurve) {optionData[&KisCurveOptionDataCommon::useCurve]} + , LAGER_QT(useSameCurve) {optionData[&KisCurveOptionDataCommon::useSameCurve]} + , LAGER_QT(curveMode) {optionData[&KisCurveOptionDataCommon::curveMode]} , LAGER_QT(activeSensorId) {activeSensorIdData} , LAGER_QT(activeSensorLength) {lager::with(optionData, activeSensorIdData).map(&calcActiveSensorLength)} , LAGER_QT(labelsState) {lager::with(LAGER_QT(activeSensorId), LAGER_QT(activeSensorLength))} @@ -115,9 +105,9 @@ KisCurveOptionModel::~KisCurveOptionModel() { } -KisCurveOptionData KisCurveOptionModel::bakedOptionData() const +KisCurveOptionDataCommon KisCurveOptionModel::bakedOptionData() const { - KisCurveOptionData data = optionData.get(); + KisCurveOptionDataCommon data = optionData.get(); data.isChecked = effectiveIsChecked(); std::tie(data.strengthMinValue, data.strengthMaxValue) = rangeNorm.get(); diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.h b/plugins/paintops/libpaintop/KisCurveOptionModel.h index 6958fc520d2..770bf37e735 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.h +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.h @@ -23,13 +23,13 @@ class PAINTOP_EXPORT KisCurveOptionModel : public QObject { Q_OBJECT public: - KisCurveOptionModel(lager::cursor optionData, + KisCurveOptionModel(lager::cursor optionData, lager::reader externallyEnabled, std::optional> rangeOverride); ~KisCurveOptionModel(); // the state must be declared **before** any cursors or readers - lager::cursor optionData; + lager::cursor optionData; lager::reader rangeNorm; lager::state activeSensorIdData; LAGER_QT_READER(bool, isCheckable); @@ -46,7 +46,7 @@ class PAINTOP_EXPORT KisCurveOptionModel : public QObject LAGER_QT_READER(LabelsState, labelsState); LAGER_QT_CURSOR(QString, activeCurve); - KisCurveOptionData bakedOptionData() const; + KisCurveOptionDataCommon bakedOptionData() const; }; #endif // KISCURVEOPTIONMODEL_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index bd64db9ae5d..92f14f9f09e 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -24,7 +24,7 @@ struct KisCurveOptionWidget2::Private { - Private(lager::cursor optionData, + Private(lager::cursor optionData, lager::reader enabledLink, std::optional>> rangeReader) : model(optionData, enabledLink, rangeReader) @@ -37,7 +37,7 @@ struct KisCurveOptionWidget2::Private QString curveValueSuffix; }; -KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, +KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, lager::reader enabledLink, std::optional>> rangeReader) @@ -49,7 +49,7 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor o { } -KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, +KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, lager::reader enabledLink, @@ -65,7 +65,7 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor o } -KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, +KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, @@ -81,14 +81,14 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor o { } -KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, +KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, const QString &strengthPrefix, const QString &strengthSuffix, lager::reader enabledLink, std::optional>> rangeReader) - : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionData::isChecked], enabledLink) + : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionDataCommon::isChecked], enabledLink) , m_widget(new QWidget) , m_curveOptionWidget(new Ui_WdgCurveOption2()) , m_d(new Private(optionData, enabledLink, rangeReader)) @@ -176,7 +176,7 @@ void KisCurveOptionWidget2::writeOptionSetting(KisPropertiesConfigurationSP sett void KisCurveOptionWidget2::readOptionSetting(const KisPropertiesConfigurationSP setting) { - KisCurveOptionData data(*m_d->model.optionData); + KisCurveOptionDataCommon data(*m_d->model.optionData); data.read(setting.data()); m_d->model.optionData.set(data); } diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index e9168737f82..e89f2d842f3 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -21,27 +21,27 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption { Q_OBJECT public: - using data_type = KisCurveOptionData; + using data_type = KisCurveOptionDataCommon; - KisCurveOptionWidget2(lager::cursor optionData, + KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt); - KisCurveOptionWidget2(lager::cursor optionData, + KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt); - KisCurveOptionWidget2(lager::cursor optionData, + KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt); - KisCurveOptionWidget2(lager::cursor optionData, + KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactory.h b/plugins/paintops/libpaintop/KisDynamicSensorFactory.h index 5e3bbd5381b..11ba9cd0aba 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactory.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactory.h @@ -21,7 +21,7 @@ class PAINTOP_EXPORT KisDynamicSensorFactory virtual QString minimumLabel() = 0; virtual QString maximumLabel(int length) = 0; virtual QString valueSuffix() = 0; - virtual QWidget* createConfigWidget(lager::cursor, QWidget*) = 0; + virtual QWidget* createConfigWidget(lager::cursor, QWidget*) = 0; }; #endif // KISDYNAMICSENSORFACTORY_H diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.cpp b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.cpp index a7586600ac5..4e7a48c0c50 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.cpp +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.cpp @@ -9,6 +9,29 @@ #include #include +#include + +namespace { + auto safeDereferenceDistanceSensor = lager::lenses::getset( + [](const KisCurveOptionDataCommon &data) -> KisSensorWithLengthData { + const KisKritaSensorPack *pack = dynamic_cast(data.sensorData.constData()); + if (pack) { + return pack->constSensorsStruct().sensorDistance; + } else { + qWarning() << "safeDereferenceDistanceSensor(get): failed to get a Krita sensor data"; + return KisSensorWithLengthData(DistanceId); + } + }, + [](KisCurveOptionDataCommon data, KisSensorWithLengthData sensor) -> KisCurveOptionDataCommon { + KisKritaSensorPack *pack = dynamic_cast(data.sensorData.data()); + if (pack) { + pack->sensorsStruct().sensorDistance = sensor; + } else { + qWarning() << "safeDereferenceDistanceSensor(set): failed to get a Krita sensor data"; + } + return data; + }); +} KisDynamicSensorFactoryDistance::KisDynamicSensorFactoryDistance() : KisSimpleDynamicSensorFactory( @@ -19,14 +42,14 @@ KisDynamicSensorFactoryDistance::KisDynamicSensorFactoryDistance() } -QWidget *KisDynamicSensorFactoryDistance::createConfigWidget(lager::cursor data, QWidget *parent) +QWidget *KisDynamicSensorFactoryDistance::createConfigWidget(lager::cursor data, QWidget *parent) { QWidget* wdg = new QWidget(parent); Ui_SensorDistanceConfiguration stc; stc.setupUi(wdg); KisSensorWithLengthModel *model = - new KisSensorWithLengthModel(data[&KisCurveOptionData::sensorDistance], wdg); + new KisSensorWithLengthModel(data.zoom(safeDereferenceDistanceSensor), wdg); using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.h index 41d63147ca9..1ed7acfbee3 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDistance.h @@ -12,7 +12,7 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryDistance : public KisSimpleDynamicSe { public: KisDynamicSensorFactoryDistance(); - QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; + QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; int maximumValue(int length) override; QString maximumLabel(int length) override; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.cpp b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.cpp index 156f31ce82b..12e3c180e1a 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.cpp +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.cpp @@ -12,6 +12,29 @@ #include "KisDrawingAngleSensorModel.h" #include "KisWidgetConnectionUtils.h" +#include "KisKritaSensorPack.h" + +namespace { + auto safeDereferenceDrawingAngleSensor = lager::lenses::getset( + [](const KisCurveOptionDataCommon &data) -> KisDrawingAngleSensorData { + const KisKritaSensorPack *pack = dynamic_cast(data.sensorData.constData()); + if (pack) { + return pack->constSensorsStruct().sensorDrawingAngle; + } else { + qWarning() << "safeDereferenceDrawingAngleSensor(get): failed to get a Krita sensor data"; + return KisDrawingAngleSensorData(); + } + }, + [](KisCurveOptionDataCommon data, KisDrawingAngleSensorData sensor) -> KisCurveOptionDataCommon { + KisKritaSensorPack *pack = dynamic_cast(data.sensorData.data()); + if (pack) { + pack->sensorsStruct().sensorDrawingAngle = sensor; + } else { + qWarning() << "safeDereferenceDrawingAngleSensor(set): failed to get a Krita sensor data"; + } + return data; + }); +} KisDynamicSensorFactoryDrawingAngle::KisDynamicSensorFactoryDrawingAngle() : KisSimpleDynamicSensorFactory( @@ -22,12 +45,12 @@ KisDynamicSensorFactoryDrawingAngle::KisDynamicSensorFactoryDrawingAngle() } -QWidget *KisDynamicSensorFactoryDrawingAngle::createConfigWidget(lager::cursor data, QWidget *parent) +QWidget *KisDynamicSensorFactoryDrawingAngle::createConfigWidget(lager::cursor data, QWidget *parent) { QWidget *widget = new QWidget(parent); KisDrawingAngleSensorModel *model = - new KisDrawingAngleSensorModel(data[&KisCurveOptionData::sensorDrawingAngle], widget); + new KisDrawingAngleSensorModel(data.zoom(safeDereferenceDrawingAngleSensor), widget); using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.h index 0cb2a16aa8b..68d9965af01 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryDrawingAngle.h @@ -12,7 +12,7 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryDrawingAngle : public KisSimpleDynam { public: KisDynamicSensorFactoryDrawingAngle(); - QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; + QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; }; #endif // KISDYNAMICSENSORFACTORYDRAWINGANGLE_H diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.cpp b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.cpp index ee012012378..b11ac2f5dee 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.cpp +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.cpp @@ -9,6 +9,29 @@ #include #include +#include + +namespace { + auto safeDereferenceFadeSensor = lager::lenses::getset( + [](const KisCurveOptionDataCommon &data) -> KisSensorWithLengthData { + const KisKritaSensorPack *pack = dynamic_cast(data.sensorData.constData()); + if (pack) { + return pack->constSensorsStruct().sensorFade; + } else { + qWarning() << "safeDereferenceFadeSensor(get): failed to get a Krita sensor data"; + return KisSensorWithLengthData(FadeId); + } + }, + [](KisCurveOptionDataCommon data, KisSensorWithLengthData sensor) -> KisCurveOptionDataCommon { + KisKritaSensorPack *pack = dynamic_cast(data.sensorData.data()); + if (pack) { + pack->sensorsStruct().sensorFade = sensor; + } else { + qWarning() << "safeDereferenceFadeSensor(set): failed to get a Krita sensor data"; + } + return data; + }); +} KisDynamicSensorFactoryFade::KisDynamicSensorFactoryFade() : KisSimpleDynamicSensorFactory( @@ -19,14 +42,14 @@ KisDynamicSensorFactoryFade::KisDynamicSensorFactoryFade() } -QWidget *KisDynamicSensorFactoryFade::createConfigWidget(lager::cursor data, QWidget *parent) +QWidget *KisDynamicSensorFactoryFade::createConfigWidget(lager::cursor data, QWidget *parent) { QWidget* wdg = new QWidget(parent); Ui_SensorFadeConfiguration stc; stc.setupUi(wdg); KisSensorWithLengthModel *model = - new KisSensorWithLengthModel(data[&KisCurveOptionData::sensorFade], wdg); + new KisSensorWithLengthModel(data.zoom(safeDereferenceFadeSensor), wdg); using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h index 6993075cc36..86c99869353 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h @@ -12,7 +12,7 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryFade : public KisSimpleDynamicSensor { public: KisDynamicSensorFactoryFade(); - QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; + QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; int maximumValue(int length); QString maximumLabel(int length); diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.cpp b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.cpp index d700b2a1212..8a582ac1895 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.cpp +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.cpp @@ -9,6 +9,29 @@ #include #include +#include + +namespace { + auto safeDereferenceTimeSensor = lager::lenses::getset( + [](const KisCurveOptionDataCommon &data) -> KisSensorWithLengthData { + const KisKritaSensorPack *pack = dynamic_cast(data.sensorData.constData()); + if (pack) { + return pack->constSensorsStruct().sensorTime; + } else { + qWarning() << "safeDereferenceTimeSensor(get): failed to get a Krita sensor data"; + return KisSensorWithLengthData(FadeId); + } + }, + [](KisCurveOptionDataCommon data, KisSensorWithLengthData sensor) -> KisCurveOptionDataCommon { + KisKritaSensorPack *pack = dynamic_cast(data.sensorData.data()); + if (pack) { + pack->sensorsStruct().sensorTime = sensor; + } else { + qWarning() << "safeDereferenceTimeSensor(set): failed to get a Krita sensor data"; + } + return data; + }); +} KisDynamicSensorFactoryTime::KisDynamicSensorFactoryTime() : KisSimpleDynamicSensorFactory( @@ -19,14 +42,14 @@ KisDynamicSensorFactoryTime::KisDynamicSensorFactoryTime() } -QWidget *KisDynamicSensorFactoryTime::createConfigWidget(lager::cursor data, QWidget *parent) +QWidget *KisDynamicSensorFactoryTime::createConfigWidget(lager::cursor data, QWidget *parent) { QWidget* wdg = new QWidget(parent); Ui_SensorTimeConfiguration stc; stc.setupUi(wdg); KisSensorWithLengthModel *model = - new KisSensorWithLengthModel(data[&KisCurveOptionData::sensorTime], wdg); + new KisSensorWithLengthModel(data.zoom(safeDereferenceTimeSensor), wdg); using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h index a1e3ba8c009..b03f1c97b43 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h @@ -12,7 +12,7 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryTime : public KisSimpleDynamicSensor { public: KisDynamicSensorFactoryTime(); - QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; + QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; int maximumValue(int length); QString maximumLabel(int length); diff --git a/plugins/paintops/libpaintop/KisKritaSensorPack.cpp b/plugins/paintops/libpaintop/KisKritaSensorPack.cpp new file mode 100644 index 00000000000..25ea778463d --- /dev/null +++ b/plugins/paintops/libpaintop/KisKritaSensorPack.cpp @@ -0,0 +1,264 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisKritaSensorPack.h" +#include "KisCppQuirks.h" +#include "kis_assert.h" + +#include +#include + +#include + +namespace detail { +template , + KisSensorData>> +inline std::vector sensors(Data *data) +{ + std::vector result; + + result.reserve(16); + + result.push_back(&data->sensorPressure); + result.push_back(&data->sensorPressureIn); + result.push_back(&data->sensorTangentialPressure); + + result.push_back(&data->sensorDrawingAngle); + result.push_back(&data->sensorXTilt); + result.push_back(&data->sensorYTilt); + result.push_back(&data->sensorTiltDirection); + result.push_back(&data->sensorTiltElevation); + result.push_back(&data->sensorRotation); + + result.push_back(&data->sensorFuzzyPerDab); + result.push_back(&data->sensorFuzzyPerStroke); + + result.push_back(&data->sensorSpeed); + result.push_back(&data->sensorFade); + result.push_back(&data->sensorDistance); + result.push_back(&data->sensorTime); + + result.push_back(&data->sensorPerspective); + + + return result; +} +} // namespace detail + +KisKritaSensorData::KisKritaSensorData() + : sensorPressure(PressureId), + sensorPressureIn(PressureInId), + sensorXTilt(XTiltId), + sensorYTilt(YTiltId), + sensorTiltDirection(TiltDirectionId), + sensorTiltElevation(TiltElevationId), + sensorSpeed(SpeedId), + sensorDrawingAngle(), + sensorRotation(RotationId), + sensorDistance(DistanceId), + sensorTime(TimeId, QLatin1Literal("duration")), + sensorFuzzyPerDab(FuzzyPerDabId), + sensorFuzzyPerStroke(FuzzyPerStrokeId), + sensorFade(FadeId), + sensorPerspective(PerspectiveId), + sensorTangentialPressure(TangentialPressureId) +{ + sensorPressure.isActive = true; +} + +KisSensorPackInterface * KisKritaSensorPack::clone() const +{ + return new KisKritaSensorPack(*this); +} + +std::vector KisKritaSensorPack::constSensors() const +{ + return detail::sensors(&m_data); +} + +std::vector KisKritaSensorPack::sensors() +{ + return detail::sensors(&m_data); +} + +const KisKritaSensorData& KisKritaSensorPack::constSensorsStruct() const +{ + return m_data; +} + +KisKritaSensorData& KisKritaSensorPack::sensorsStruct() +{ + return m_data; +} + +bool KisKritaSensorPack::compare(const KisSensorPackInterface *rhs) const +{ + const KisKritaSensorPack *pack = dynamic_cast(rhs); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(pack, false); + + return m_data == pack->m_data; +} + +bool KisKritaSensorPack::read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const +{ + data.isChecked = !data.isCheckable || setting->getBool("Pressure" + data.id.id(), false); + + std::vector sensors = data.sensors(); + QMap sensorById; + + Q_FOREACH (KisSensorData *sensor, sensors) { + sensorById.insert(sensor->id.id(), sensor); + } + + QSet sensorsToReset = + QSet::fromList(sensorById.values()); + + const QString sensorDefinition = setting->getString(data.id.id() + "Sensor"); + + if (sensorDefinition.isEmpty()) { + // noop + } else if (!sensorDefinition.contains("sensorslist")) { + QDomDocument doc; + doc.setContent(sensorDefinition); + QDomElement e = doc.documentElement(); + + const QString sensorId = e.attribute("id", ""); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!sensorId.isEmpty(), false); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sensorById.contains(sensorId), false); + + KisSensorData *sensor = sensorById[sensorId]; + sensor->read(e); + sensor->isActive = true; + sensorsToReset.remove(sensor); + + data.commonCurve = sensor->curve; + + } else { + QString proposedCommonCurve; + + QDomDocument doc; + doc.setContent(sensorDefinition); + QDomElement elt = doc.documentElement(); + QDomNode node = elt.firstChild(); + while (!node.isNull()) { + if (node.isElement()) { + QDomElement childelt = node.toElement(); + if (childelt.tagName() == "ChildSensor") { + + const QString sensorId = childelt.attribute("id", ""); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!sensorId.isEmpty(), false); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(sensorById.contains(sensorId), false); + + KisSensorData *sensor = sensorById[sensorId]; + sensor->read(childelt); + sensor->isActive = true; + sensorsToReset.remove(sensor); + + /// due to legacy reasons we initialize common curve + /// with the "last read curve value" + proposedCommonCurve = sensor->curve; + } + } + node = node.nextSibling(); + } + + data.commonCurve = !proposedCommonCurve.isEmpty() ? proposedCommonCurve : DEFAULT_CURVE_STRING; + } + + data.useSameCurve = setting->getBool(data.id.id() + "UseSameCurve", true); + + // Only load the old curve format if the curve wasn't saved by the sensor + // This will give every sensor the same curve. + if (!sensorDefinition.contains("curve")) { + if (setting->getBool("Custom" + data.id.id(), false)) { + data.commonCurve = setting->getString("Curve" + data.id.id(), DEFAULT_CURVE_STRING); + Q_FOREACH (KisSensorData *sensor, sensors) { + sensor->curve = data.commonCurve; + sensorsToReset.remove(sensor); + } + } else { + data.commonCurve = DEFAULT_CURVE_STRING; + } + } + + if (data.useSameCurve) { + data.commonCurve = setting->getString(data.id.id() + "commonCurve", DEFAULT_CURVE_STRING); + } + + Q_FOREACH (KisSensorData *sensor, sensorsToReset) { + sensor->reset(); + } + + // At least one sensor needs to be active + if (std::find_if(sensors.begin(), sensors.end(), + std::mem_fn(&KisSensorData::isActive)) == sensors.end()) { + + sensorById[PressureId.id()]->isActive = true; + } + + data.strengthValue = setting->getDouble(data.id.id() + "Value", data.strengthMaxValue); + + if (data.valueFixUpReadCallback) { + data.valueFixUpReadCallback(&data, setting); + } + + data.useCurve = setting->getBool(data.id.id() + "UseCurve", true); + data.curveMode = setting->getInt(data.id.id() + "curveMode", 0); + + return true; +} + +void KisKritaSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const +{ + setting->setProperty("Pressure" + data.id.id(), data.isChecked || !data.isCheckable); + + QVector activeSensors; + Q_FOREACH(const KisSensorData *sensor, data.sensors()) { + if (sensor->isActive) { + activeSensors.append(sensor); + } + } + + QDomDocument doc = QDomDocument("params"); + QDomElement root = doc.createElement("params"); + doc.appendChild(root); + + if (activeSensors.size() == 1) { + activeSensors.first()->write(doc, root); + } else { + root.setAttribute("id", "sensorslist"); + Q_FOREACH (const KisSensorData *sensor, activeSensors) { + QDomElement childelt = doc.createElement("ChildSensor"); + sensor->write(doc, childelt); + root.appendChild(childelt); + } + } + setting->setProperty(data.id.id() + "Sensor", doc.toString()); + + setting->setProperty(data.id.id() + "UseCurve", data.useCurve); + setting->setProperty(data.id.id() + "UseSameCurve", data.useSameCurve); + setting->setProperty(data.id.id() + "Value", data.strengthValue); + if (data.valueFixUpWriteCallback) { + data.valueFixUpWriteCallback(data.strengthValue, setting); + } + setting->setProperty(data.id.id() + "curveMode", data.curveMode); + setting->setProperty(data.id.id() + "commonCurve", data.commonCurve); +} + +int KisKritaSensorPack::calcActiveSensorLength(const QString &activeSensorId) const +{ + if (activeSensorId == FadeId.id()) { + return m_data.sensorFade.length; + } else if (activeSensorId == DistanceId.id()) { + return m_data.sensorDistance.length; + } else if (activeSensorId == TimeId.id()) { + return m_data.sensorTime.length; + } + + return -1; +} diff --git a/plugins/paintops/libpaintop/KisKritaSensorPack.h b/plugins/paintops/libpaintop/KisKritaSensorPack.h new file mode 100644 index 00000000000..6bec09143f1 --- /dev/null +++ b/plugins/paintops/libpaintop/KisKritaSensorPack.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISKRITASENSORPACK_H +#define KISKRITASENSORPACK_H + +#include "kritapaintop_export.h" +#include + +#include +#include + + +struct PAINTOP_EXPORT KisKritaSensorData : boost::equality_comparable +{ + KisKritaSensorData(); + + inline friend bool operator==(const KisKritaSensorData &lhs, const KisKritaSensorData &rhs) { + return lhs.sensorPressure == rhs.sensorPressure && + lhs.sensorPressureIn == rhs.sensorPressureIn && + lhs.sensorXTilt == rhs.sensorXTilt && + lhs.sensorYTilt == rhs.sensorYTilt && + lhs.sensorTiltDirection == rhs.sensorTiltDirection && + lhs.sensorTiltElevation == rhs.sensorTiltElevation && + lhs.sensorSpeed == rhs.sensorSpeed && + lhs.sensorDrawingAngle == rhs.sensorDrawingAngle && + lhs.sensorRotation == rhs.sensorRotation && + lhs.sensorDistance == rhs.sensorDistance && + lhs.sensorTime == rhs.sensorTime && + lhs.sensorFuzzyPerDab == rhs.sensorFuzzyPerDab && + lhs.sensorFuzzyPerStroke == rhs.sensorFuzzyPerStroke && + lhs.sensorFade == rhs.sensorFade && + lhs.sensorPerspective == rhs.sensorPerspective && + lhs.sensorTangentialPressure == rhs.sensorTangentialPressure; + } + + KisSensorData sensorPressure; + KisSensorData sensorPressureIn; + KisSensorData sensorXTilt; + KisSensorData sensorYTilt; + KisSensorData sensorTiltDirection; + KisSensorData sensorTiltElevation; + KisSensorData sensorSpeed; + KisDrawingAngleSensorData sensorDrawingAngle; + KisSensorData sensorRotation; + KisSensorWithLengthData sensorDistance; + KisSensorWithLengthData sensorTime; + KisSensorData sensorFuzzyPerDab; + KisSensorData sensorFuzzyPerStroke; + KisSensorWithLengthData sensorFade; + KisSensorData sensorPerspective; + KisSensorData sensorTangentialPressure; +}; + +class PAINTOP_EXPORT KisKritaSensorPack : public KisSensorPackInterface +{ +public: + KisKritaSensorPack() = default; + KisKritaSensorPack(const KisKritaSensorPack &rhs) = default; + + KisSensorPackInterface * clone() const override; + + std::vector constSensors() const override; + std::vector sensors() override; + + const KisKritaSensorData& constSensorsStruct() const; + KisKritaSensorData& sensorsStruct(); + + bool compare(const KisSensorPackInterface *rhs) const override; + bool read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const override; + void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const override; + + int calcActiveSensorLength(const QString &activeSensorId) const override; + +private: + KisKritaSensorData m_data; +}; + +#endif // KISKRITASENSORPACK_H \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisLightnessStrengthOptionWidget.cpp b/plugins/paintops/libpaintop/KisLightnessStrengthOptionWidget.cpp index f638692d198..7373da83b89 100644 --- a/plugins/paintops/libpaintop/KisLightnessStrengthOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisLightnessStrengthOptionWidget.cpp @@ -22,7 +22,7 @@ struct KisLightnessStrengthOptionWidget::Private }; KisLightnessStrengthOptionWidget::KisLightnessStrengthOptionWidget(lager::cursor optionData, lager::reader lightnessModeEnabled) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL, lightnessModeEnabled) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL, lightnessModeEnabled) , m_d(new Private(lightnessModeEnabled)) { QWidget* page = new QWidget; diff --git a/plugins/paintops/libpaintop/KisMirrorOptionWidget.cpp b/plugins/paintops/libpaintop/KisMirrorOptionWidget.cpp index 630f2b18576..3c24bb548d7 100644 --- a/plugins/paintops/libpaintop/KisMirrorOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisMirrorOptionWidget.cpp @@ -34,7 +34,7 @@ KisMirrorOptionWidget::KisMirrorOptionWidget(lager::cursor } KisMirrorOptionWidget::KisMirrorOptionWidget(lager::cursor optionData, PaintopCategory categoryOverride) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) , m_d(new Private(optionData)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisMultiSensorsSelector2.cpp b/plugins/paintops/libpaintop/KisMultiSensorsSelector2.cpp index 34549238db4..46b6d92e8ee 100644 --- a/plugins/paintops/libpaintop/KisMultiSensorsSelector2.cpp +++ b/plugins/paintops/libpaintop/KisMultiSensorsSelector2.cpp @@ -6,13 +6,15 @@ */ #include "KisMultiSensorsSelector2.h" +#include "KisCurveOptionData.h" +#include "kis_dynamic_sensor.h" #include "ui_wdgmultisensorsselector.h" #include "KisMultiSensorsModel2.h" #include struct KisMultiSensorsSelector2::Private { - lager::cursor optionData; + lager::cursor optionData; Ui_WdgMultiSensorsSelector form; KisMultiSensorsModel2* model; @@ -21,7 +23,7 @@ struct KisMultiSensorsSelector2::Private { }; auto sensorsLens = lager::lenses::getset( - [](const KisCurveOptionData &data) -> KisMultiSensorsModel2::MultiSensorData { + [](const KisCurveOptionDataCommon &data) -> KisMultiSensorsModel2::MultiSensorData { std::vector srcSensors = data.sensors(); KisMultiSensorsModel2::MultiSensorData sensors; @@ -32,7 +34,7 @@ auto sensorsLens = lager::lenses::getset( } return sensors; }, - [](KisCurveOptionData data, KisMultiSensorsModel2::MultiSensorData sensors) -> KisCurveOptionData { + [](KisCurveOptionDataCommon data, KisMultiSensorsModel2::MultiSensorData sensors) -> KisCurveOptionDataCommon { std::vector parentSensors = data.sensors(); KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(parentSensors.size() == sensors.size(), data); @@ -73,7 +75,7 @@ KisMultiSensorsSelector2::~KisMultiSensorsSelector2() delete d; } -void KisMultiSensorsSelector2::setOptionDataCursor(lager::cursor optionData) +void KisMultiSensorsSelector2::setOptionDataCursor(lager::cursor optionData) { d->optionData = optionData; d->model = new KisMultiSensorsModel2(optionData.zoom(sensorsLens), this); diff --git a/plugins/paintops/libpaintop/KisMultiSensorsSelector2.h b/plugins/paintops/libpaintop/KisMultiSensorsSelector2.h index ade0727b2c1..b5e5e90aa0e 100644 --- a/plugins/paintops/libpaintop/KisMultiSensorsSelector2.h +++ b/plugins/paintops/libpaintop/KisMultiSensorsSelector2.h @@ -22,7 +22,7 @@ class KisMultiSensorsSelector2 : public QWidget KisMultiSensorsSelector2(QWidget* parent); ~KisMultiSensorsSelector2() override; - void setOptionDataCursor(lager::cursor optionData); + void setOptionDataCursor(lager::cursor optionData); void setCurrent(const QString &id); QString currentHighlighted(); diff --git a/plugins/paintops/libpaintop/KisRotationOption.cpp b/plugins/paintops/libpaintop/KisRotationOption.cpp index bda26380e0c..5d40cefbaab 100644 --- a/plugins/paintops/libpaintop/KisRotationOption.cpp +++ b/plugins/paintops/libpaintop/KisRotationOption.cpp @@ -23,11 +23,11 @@ KisRotationOption::KisRotationOption(const KisPropertiesConfiguration *setting) KisRotationOption::KisRotationOption(const KisRotationOptionData &data) : KisCurveOption2(data) { - if (data.sensorDrawingAngle.isActive) { + if (data.sensorStruct().sensorDrawingAngle.isActive) { m_fanCornersEnabled = - data.sensorDrawingAngle.fanCornersEnabled && - !data.sensorDrawingAngle.lockedAngleMode; - m_fanCornersStep = qreal(data.sensorDrawingAngle.fanCornersStep); + data.sensorStruct().sensorDrawingAngle.fanCornersEnabled && + !data.sensorStruct().sensorDrawingAngle.lockedAngleMode; + m_fanCornersStep = qreal(data.sensorStruct().sensorDrawingAngle.fanCornersStep); } } diff --git a/plugins/paintops/libpaintop/KisScatterOptionData.cpp b/plugins/paintops/libpaintop/KisScatterOptionData.cpp index daf400369dd..0008605336b 100644 --- a/plugins/paintops/libpaintop/KisScatterOptionData.cpp +++ b/plugins/paintops/libpaintop/KisScatterOptionData.cpp @@ -30,7 +30,7 @@ KisScatterOptionData::KisScatterOptionData(const QString &prefix) KoID("Scatter", i18n("Scatter")), true, false, false, 0.0, 5.0) { - valueFixUpReadCallback = [] (KisCurveOptionData *data, const KisPropertiesConfiguration *setting) { + valueFixUpReadCallback = [] (KisCurveOptionDataCommon *data, const KisPropertiesConfiguration *setting) { if (setting->hasProperty(SCATTER_AMOUNT) && !setting->hasProperty("ScatterValue")) { data->strengthValue = setting->getDouble(SCATTER_AMOUNT); diff --git a/plugins/paintops/libpaintop/KisScatterOptionWidget.cpp b/plugins/paintops/libpaintop/KisScatterOptionWidget.cpp index 2ab8f833a00..114f2b891ed 100644 --- a/plugins/paintops/libpaintop/KisScatterOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisScatterOptionWidget.cpp @@ -35,7 +35,7 @@ KisScatterOptionWidget::KisScatterOptionWidget(lager::cursor optionData, PaintopCategory categoryOverride) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) , m_d(new Private(optionData)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisSensorData.cpp b/plugins/paintops/libpaintop/KisSensorData.cpp new file mode 100644 index 00000000000..b95b9c278d5 --- /dev/null +++ b/plugins/paintops/libpaintop/KisSensorData.cpp @@ -0,0 +1,132 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisSensorData.h" + +// TODO: remove this incude +#include "kis_dynamic_sensor.h" + +#include +#include + +KisSensorData::KisSensorData(const KoID &sensorId) + : id(sensorId), + curve(DEFAULT_CURVE_STRING) +{ +} + +KisSensorData::~KisSensorData() +{ +} + +void KisSensorData::write(QDomDocument& doc, QDomElement &e) const +{ + e.setAttribute("id", id.id()); + if (curve != DEFAULT_CURVE_STRING) { + QDomElement curve_elt = doc.createElement("curve"); + QDomText text = doc.createTextNode(curve); + curve_elt.appendChild(text); + e.appendChild(curve_elt); + } +} + +void KisSensorData::read(const QDomElement& e) +{ + KIS_ASSERT(e.attribute("id", "") == id.id()); + QDomElement curve_elt = e.firstChildElement("curve"); + if (!curve_elt.isNull()) { + curve = curve_elt.text(); + } else { + curve = DEFAULT_CURVE_STRING; + } +} + +void KisSensorData::reset() +{ + *this = KisSensorData(id); +} + +KisSensorWithLengthData::KisSensorWithLengthData(const KoID &sensorId, const QLatin1String &lengthTag) + : KisSensorData(sensorId) + , m_lengthTag(lengthTag.isNull() ? QLatin1Literal("length") : lengthTag) +{ + if (sensorId == FadeId) { + isPeriodic = false; + length = 1000; + } else if (sensorId == DistanceId) { + isPeriodic = false; + length = 30; + } else if (sensorId == TimeId) { + isPeriodic = false; + length = 30; + } else { + qFatal("This sensor type \"%s\" has no length associated!", sensorId.id().toLatin1().data()); + } +} + +void KisSensorWithLengthData::write(QDomDocument &doc, QDomElement &e) const +{ + KisSensorData::write(doc, e); + e.setAttribute("periodic", isPeriodic); + e.setAttribute(m_lengthTag, length); +} + +void KisSensorWithLengthData::read(const QDomElement &e) +{ + reset(); + KisSensorData::read(e); + + if (e.hasAttribute("periodic")) { + isPeriodic = e.attribute("periodic").toInt(); + } + + if (e.hasAttribute(m_lengthTag)) { + length = e.attribute(m_lengthTag).toInt(); + } +} + +void KisSensorWithLengthData::reset() +{ + *this = KisSensorWithLengthData(id, m_lengthTag); +} + +KisDrawingAngleSensorData::KisDrawingAngleSensorData() + : KisSensorData(DrawingAngleId) +{ +} + +void KisDrawingAngleSensorData::write(QDomDocument &doc, QDomElement &e) const +{ + KisSensorData::write(doc, e); + e.setAttribute("fanCornersEnabled", fanCornersEnabled); + e.setAttribute("fanCornersStep", fanCornersStep); + e.setAttribute("angleOffset", angleOffset); + e.setAttribute("lockedAngleMode", lockedAngleMode); +} + +void KisDrawingAngleSensorData::read(const QDomElement &e) +{ + reset(); + KisSensorData::read(e); + + if (e.hasAttribute("fanCornersEnabled")) { + fanCornersEnabled = e.attribute("fanCornersEnabled").toInt(); + } + if (e.hasAttribute("fanCornersStep")) { + fanCornersStep = e.attribute("fanCornersStep").toInt(); + } + if (e.hasAttribute("angleOffset")) { + angleOffset = e.attribute("angleOffset").toInt(); + } + if (e.hasAttribute("lockedAngleMode")) { + lockedAngleMode = e.attribute("lockedAngleMode").toInt(); + } +} + +void KisDrawingAngleSensorData::reset() +{ + *this = KisDrawingAngleSensorData(); +} \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisSensorData.h b/plugins/paintops/libpaintop/KisSensorData.h new file mode 100644 index 00000000000..47753929996 --- /dev/null +++ b/plugins/paintops/libpaintop/KisSensorData.h @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISSENSORDATA_H +#define KISSENSORDATA_H + +#include +#include "kritapaintop_export.h" +#include "kis_assert.h" +#include "kis_paintop_option.h" + +struct PAINTOP_EXPORT KisSensorData : public boost::equality_comparable +{ + KisSensorData(const KoID &sensorId); + virtual ~KisSensorData(); + + inline friend bool operator==(const KisSensorData &lhs, const KisSensorData &rhs) { + return lhs.id == rhs.id && + lhs.curve == rhs.curve && + lhs.isActive == rhs.isActive; + } + + virtual void write(QDomDocument& doc, QDomElement &e) const; + virtual void read(const QDomElement &e); + virtual void reset(); + + KoID id; + QString curve; + + // not a part of XML data, managed by the curve option + bool isActive = false; +}; + +struct PAINTOP_EXPORT KisSensorWithLengthData : public KisSensorData, public boost::equality_comparable +{ + KisSensorWithLengthData(const KoID &sensorId, const QLatin1String &lengthTag = {}); + + inline friend bool operator==(const KisSensorWithLengthData &lhs, const KisSensorWithLengthData &rhs) { + return *static_cast(&lhs) == *static_cast(&rhs) && + lhs.length == rhs.length && + lhs.isPeriodic == rhs.isPeriodic && + lhs.m_lengthTag == rhs.m_lengthTag; + } + + void write(QDomDocument& doc, QDomElement &e) const override; + void read(const QDomElement &e) override; + void reset() override; + + int length = 30; + bool isPeriodic = false; +private: + QLatin1String m_lengthTag; +}; + +struct PAINTOP_EXPORT KisDrawingAngleSensorData : public KisSensorData, public boost::equality_comparable +{ + KisDrawingAngleSensorData(); + + inline friend bool operator==(const KisDrawingAngleSensorData &lhs, const KisDrawingAngleSensorData &rhs) { + return *static_cast(&lhs) == *static_cast(&rhs) && + lhs.fanCornersEnabled == rhs.fanCornersEnabled && + lhs.fanCornersStep == rhs.fanCornersStep && + lhs.angleOffset == rhs.angleOffset && + lhs.lockedAngleMode == rhs.lockedAngleMode; + } + + void write(QDomDocument& doc, QDomElement &e) const override; + void read(const QDomElement &e) override; + void reset() override; + + bool fanCornersEnabled = false; + int fanCornersStep = 30; + int angleOffset = 0; // in degrees + bool lockedAngleMode = false; +}; + +#endif // KISSENSORDATA_H \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisSensorPackInterface.cpp b/plugins/paintops/libpaintop/KisSensorPackInterface.cpp new file mode 100644 index 00000000000..c7cd85c4c7c --- /dev/null +++ b/plugins/paintops/libpaintop/KisSensorPackInterface.cpp @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisSensorPackInterface.h" + +KisSensorPackInterface::~KisSensorPackInterface() +{ +} + +int KisSensorPackInterface::calcActiveSensorLength(const QString &) const +{ + return -1; +} \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisSensorPackInterface.h b/plugins/paintops/libpaintop/KisSensorPackInterface.h new file mode 100644 index 00000000000..b2798548b6c --- /dev/null +++ b/plugins/paintops/libpaintop/KisSensorPackInterface.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISSENSORPACKINTERFACE_H +#define KISSENSORPACKINTERFACE_H + +#include "kritapaintop_export.h" +#include + +struct KisSensorData; +struct KisCurveOptionDataCommon; +class KisPropertiesConfiguration; + +class PAINTOP_EXPORT KisSensorPackInterface : public QSharedData +{ +public: + virtual ~KisSensorPackInterface(); + + virtual KisSensorPackInterface * clone() const = 0; + + virtual std::vector constSensors() const = 0; + virtual std::vector sensors() = 0; + + virtual bool compare(const KisSensorPackInterface *rhs) const = 0; + virtual bool read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const = 0; + virtual void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const = 0; + virtual int calcActiveSensorLength(const QString &activeSensorId) const; +}; + +template<> +inline KisSensorPackInterface* QSharedDataPointer::clone() +{ + return d->clone(); +} + +#endif // KISSENSORPACKINTERFACE_H \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisSharpnessOptionData.cpp b/plugins/paintops/libpaintop/KisSharpnessOptionData.cpp index 388df0824d1..87d0beba556 100644 --- a/plugins/paintops/libpaintop/KisSharpnessOptionData.cpp +++ b/plugins/paintops/libpaintop/KisSharpnessOptionData.cpp @@ -31,7 +31,7 @@ void KisSharpnessOptionMixInImpl::write(KisPropertiesConfiguration *setting) con KisSharpnessOptionData::KisSharpnessOptionData(const QString &prefix) : KisOptionTuple(prefix, KoID("Sharpness", i18n("Sharpness"))) { - valueFixUpReadCallback = [] (KisCurveOptionData *data, const KisPropertiesConfiguration *setting) { + valueFixUpReadCallback = [] (KisCurveOptionDataCommon *data, const KisPropertiesConfiguration *setting) { if (setting->hasProperty(SHARPNESS_FACTOR) && !setting->hasProperty("SharpnessValue")) { data->strengthValue = setting->getDouble(SHARPNESS_FACTOR); diff --git a/plugins/paintops/libpaintop/KisSharpnessOptionWidget.cpp b/plugins/paintops/libpaintop/KisSharpnessOptionWidget.cpp index 22653d4fd3d..4da4e11c14f 100644 --- a/plugins/paintops/libpaintop/KisSharpnessOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisSharpnessOptionWidget.cpp @@ -31,7 +31,7 @@ struct KisSharpnessOptionWidget::Private }; KisSharpnessOptionWidget::KisSharpnessOptionWidget(lager::cursor optionData) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) , m_d(new Private(optionData)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.cpp b/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.cpp index 07ff26fd233..437b2a9d83f 100644 --- a/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.cpp +++ b/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.cpp @@ -45,7 +45,7 @@ QString KisSimpleDynamicSensorFactory::valueSuffix() return m_valueSuffix; } -QWidget *KisSimpleDynamicSensorFactory::createConfigWidget(lager::cursor, QWidget *) +QWidget *KisSimpleDynamicSensorFactory::createConfigWidget(lager::cursor, QWidget *) { return nullptr; } diff --git a/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.h b/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.h index 9449ec88f4c..d9f3415c535 100644 --- a/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.h +++ b/plugins/paintops/libpaintop/KisSimpleDynamicSensorFactory.h @@ -22,7 +22,7 @@ class PAINTOP_EXPORT KisSimpleDynamicSensorFactory : public KisDynamicSensorFact QString minimumLabel() override; QString maximumLabel(int length) override; QString valueSuffix() override; - QWidget* createConfigWidget(lager::cursor, QWidget*) override; + QWidget* createConfigWidget(lager::cursor, QWidget*) override; int m_minimumValue; int m_maximumValue; diff --git a/plugins/paintops/libpaintop/KisSizeOptionData.cpp b/plugins/paintops/libpaintop/KisSizeOptionData.cpp index 0df308fe42b..7aa3fe20ca8 100644 --- a/plugins/paintops/libpaintop/KisSizeOptionData.cpp +++ b/plugins/paintops/libpaintop/KisSizeOptionData.cpp @@ -21,11 +21,11 @@ KisPaintopLodLimitations KisSizeOptionData::lodLimitations() const if (!isCheckable || isChecked) { // HINT: FUZZY_PER_STROKE doesn't affect instant preview - if (sensorFuzzyPerDab.isActive) { + if (sensorStruct().sensorFuzzyPerDab.isActive) { l.limitations << KoID("size-fade", i18nc("PaintOp instant preview limitation", "Size -> Fuzzy (sensor)")); } - if (sensorFade.isActive) { + if (sensorStruct().sensorFade.isActive) { l.blockers << KoID("size-fuzzy", i18nc("PaintOp instant preview limitation", "Size -> Fade (sensor)")); } } diff --git a/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp b/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp index fccd1849790..f5bd1c6b470 100644 --- a/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp @@ -23,7 +23,7 @@ KisSizeOptionWidget::KisSizeOptionWidget(lager::cursor option } KisSizeOptionWidget::KisSizeOptionWidget(lager::cursor optionData, PaintopCategory categoryOverride) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), categoryOverride) , m_d(new Private(optionData)) { } diff --git a/plugins/paintops/libpaintop/KisSpacingOptionWidget.cpp b/plugins/paintops/libpaintop/KisSpacingOptionWidget.cpp index 4278c5b1def..a28a44118f4 100644 --- a/plugins/paintops/libpaintop/KisSpacingOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisSpacingOptionWidget.cpp @@ -28,7 +28,7 @@ struct KisSpacingOptionWidget::Private }; KisSpacingOptionWidget::KisSpacingOptionWidget(lager::cursor optionData) - : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), KisPaintOpOption::GENERAL) , m_d(new Private(optionData)) { using namespace KisWidgetConnectionUtils; diff --git a/plugins/paintops/libpaintop/tests/KisCurveOptionDataTest.cpp b/plugins/paintops/libpaintop/tests/KisCurveOptionDataTest.cpp index 2e06746312b..4042a716095 100644 --- a/plugins/paintops/libpaintop/tests/KisCurveOptionDataTest.cpp +++ b/plugins/paintops/libpaintop/tests/KisCurveOptionDataTest.cpp @@ -26,8 +26,8 @@ void KisCurveOptionDataTest::testCurveOptionData() QVERIFY(data == data2); - data2.sensorPressure.isActive = true; - data2.sensorPressure.curve = "0.0,0.5;1,1;"; + data2.sensorStruct().sensorPressure.isActive = true; + data2.sensorStruct().sensorPressure.curve = "0.0,0.5;1,1;"; QVERIFY(data != data2); @@ -35,8 +35,8 @@ void KisCurveOptionDataTest::testCurveOptionData() QVERIFY(data == data2); - data2.sensorPressure.isActive = true; - data2.sensorPressure.curve = "0.0,0.5;1,1;"; + data2.sensorStruct().sensorPressure.isActive = true; + data2.sensorStruct().sensorPressure.curve = "0.0,0.5;1,1;"; KisPropertiesConfiguration config; @@ -56,11 +56,11 @@ void KisCurveOptionDataTest::testSerializeDisabledSensors() KisPaintOpOption::GENERAL); // sensor is disabled! - data.sensorPressure.isActive = false; - data.sensorPressure.curve = "0.0,0.5;1,1;"; + data.sensorStruct().sensorPressure.isActive = false; + data.sensorStruct().sensorPressure.curve = "0.0,0.5;1,1;"; - data.sensorRotation.isActive = true; - data.sensorRotation.curve = "0.0,0.5;1,1;"; + data.sensorStruct().sensorRotation.isActive = true; + data.sensorStruct().sensorRotation.curve = "0.0,0.5;1,1;"; KisCurveOptionData data2(KoID("Opacity"), KisPaintOpOption::GENERAL); @@ -83,11 +83,11 @@ void KisCurveOptionDataTest::testSerializeDisabledSensors() * in the same data in C++ sense. */ - QCOMPARE(data2.sensorPressure.isActive, false); - QCOMPARE(data2.sensorRotation.isActive, true); + QCOMPARE(data2.sensorStruct().sensorPressure.isActive, false); + QCOMPARE(data2.sensorStruct().sensorRotation.isActive, true); QVERIFY(data != data2); - data2.sensorPressure.curve = data.sensorPressure.curve; + data2.sensorStruct().sensorPressure.curve = data.sensorStruct().sensorPressure.curve; QVERIFY(data == data2); } @@ -114,9 +114,9 @@ void KisCurveOptionDataTest::testSerializeNoSensors() * sensors with the default curve. */ - QCOMPARE(data.sensorPressure.isActive, false); - QCOMPARE(data2.sensorPressure.isActive, true); - QCOMPARE(data2.sensorPressure.curve, DEFAULT_CURVE_STRING); + QCOMPARE(data.sensorStruct().sensorPressure.isActive, false); + QCOMPARE(data2.sensorStruct().sensorPressure.isActive, true); + QCOMPARE(data2.sensorStruct().sensorPressure.curve, DEFAULT_CURVE_STRING); QVERIFY(data != data2); } diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index 6d288d60cea..d1651e952ee 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -5,6 +5,8 @@ include_directories(${LIBMYPAINT_INCLUDE_DIR}) link_directories(${LIBMYPAINT_LIBRARIES}) set(kritamypaintop_SOURCES + MyPaintSensorPack.cpp + MyPaintCurveOptionData.cpp MyPaintPaintOp.cpp MyPaintPaintOpOption.cpp MyPaintPaintOpSettings.cpp diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp new file mode 100644 index 00000000000..6c1a90ec5d8 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintCurveOptionData.h" + +MyPaintCurveOptionData::MyPaintCurveOptionData(const QString &prefix, + const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue) + : KisCurveOptionDataCommon(prefix, + id, + isCheckable, + isChecked, + separateCurveValue, + minValue, + maxValue, + new MyPaintSensorPack()) +{ +} + +MyPaintCurveOptionData::MyPaintCurveOptionData(const KoID &id, + bool isCheckable, + bool isChecked, + bool separateCurveValue, + qreal minValue, + qreal maxValue) + : MyPaintCurveOptionData("", id, isCheckable, isChecked, separateCurveValue, minValue, maxValue) +{ +} + +MyPaintSensorData &MyPaintCurveOptionData::sensorStruct() +{ + return dynamic_cast(sensorData.data())->sensorsStruct(); +} + +const MyPaintSensorData &MyPaintCurveOptionData::sensorStruct() const +{ + return dynamic_cast(sensorData.constData())->constSensorsStruct(); +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.h b/plugins/paintops/mypaint/MyPaintCurveOptionData.h new file mode 100644 index 00000000000..5449d107dd5 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTCURVEOPTIONDATA_H +#define MYPAINTCURVEOPTIONDATA_H + +#include +#include "MyPaintSensorPack.h" + + +struct MyPaintCurveOptionData : KisCurveOptionDataCommon +{ + MyPaintCurveOptionData(const QString &prefix, + const KoID &id, + bool isCheckable = true, + bool isChecked = false, + bool separateCurveValue = false, + qreal minValue = 0.0, + qreal maxValue = 1.0); + + MyPaintCurveOptionData(const KoID &id, + bool isCheckable = true, + bool isChecked = false, + bool separateCurveValue = false, + qreal minValue = 0.0, + qreal maxValue = 1.0); + + MyPaintSensorData& sensorStruct(); + const MyPaintSensorData& sensorStruct() const; +}; + +#endif // MYPAINTCURVEOPTIONDATA_H \ No newline at end of file diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.cpp b/plugins/paintops/mypaint/MyPaintSensorPack.cpp new file mode 100644 index 00000000000..6cfb9bee7a3 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintSensorPack.cpp @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintSensorPack.h" + +#include +#include "kis_assert.h" + +namespace detail { + +template , + KisSensorData>> +inline std::vector sensors(Data *data) +{ + std::vector result; + + result.reserve(9); + + result.push_back(&data->sensorPressure); + result.push_back(&data->sensorFineSpeed); + result.push_back(&data->sensorGrossSpeed); + result.push_back(&data->sensorRandom); + result.push_back(&data->sensorStroke); + result.push_back(&data->sensorDirection); + result.push_back(&data->sensorDeclination); + result.push_back(&data->sensorAscension); + result.push_back(&data->sensorCustom); + + return result; +} + +} // namespace detail + +MyPaintSensorData::MyPaintSensorData() + : sensorPressure(MyPaintPressureId), + sensorFineSpeed(MyPaintFineSpeedId), + sensorGrossSpeed(MyPaintGrossSpeedId), + sensorRandom(MyPaintRandomId), + sensorStroke(MyPaintStrokeId), + sensorDirection(MyPaintDirectionId), + sensorDeclination(MyPaintDeclinationId), + sensorAscension(MyPaintAscensionId), + sensorCustom(MyPaintCustomId) +{ + sensorPressure.isActive = true; +} + +KisSensorPackInterface * MyPaintSensorPack::clone() const +{ + return new MyPaintSensorPack(*this); +} + +std::vector MyPaintSensorPack::constSensors() const +{ + return detail::sensors(&m_data); +} + +std::vector MyPaintSensorPack::sensors() +{ + return detail::sensors(&m_data); +} + +const MyPaintSensorData& MyPaintSensorPack::constSensorsStruct() const +{ + return m_data; +} + +MyPaintSensorData& MyPaintSensorPack::sensorsStruct() +{ + return m_data; +} + +bool MyPaintSensorPack::compare(const KisSensorPackInterface *rhs) const +{ + const MyPaintSensorPack *pack = dynamic_cast(rhs); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(pack, false); + + return m_data == pack->m_data; +} + +bool MyPaintSensorPack::read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const +{ + // TODO: + return true; +} + +void MyPaintSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const +{ + // TODO: +} \ No newline at end of file diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.h b/plugins/paintops/mypaint/MyPaintSensorPack.h new file mode 100644 index 00000000000..511b95b6b7b --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintSensorPack.h @@ -0,0 +1,75 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTSENSORPACK_H +#define MYPAINTSENSORPACK_H + +#include + +#include +#include + +const KoID MyPaintPressureId("pressure", ki18n("Pressure")); +const KoID MyPaintFineSpeedId("speed1", ki18n("Fine Speed")); +const KoID MyPaintGrossSpeedId("speed2", ki18n("Gross Speed")); +const KoID MyPaintRandomId("random", ki18n("Random")); +const KoID MyPaintStrokeId("stroke", ki18nc("The duration of a brush stroke", "Stroke")); +const KoID MyPaintDirectionId("direction", ki18nc("Drawing Angle", "Direction")); +const KoID MyPaintDeclinationId("tilt_declination", ki18nc("Pen tilt declination", "Declination")); +const KoID MyPaintAscensionId("tilt_ascension", ki18nc("Pen tilt ascension", "Ascension")); +const KoID MyPaintCustomId("custom", ki18n("Custom")); + +struct MyPaintSensorData : boost::equality_comparable +{ + MyPaintSensorData(); + + inline friend bool operator==(const MyPaintSensorData &lhs, const MyPaintSensorData &rhs) { + return lhs.sensorPressure == rhs.sensorPressure && + lhs.sensorFineSpeed == rhs.sensorFineSpeed && + lhs.sensorGrossSpeed == rhs.sensorGrossSpeed && + lhs.sensorRandom == rhs.sensorRandom && + lhs.sensorStroke == rhs.sensorStroke && + lhs.sensorDirection == rhs.sensorDirection && + lhs.sensorDeclination == rhs.sensorDeclination && + lhs.sensorAscension == rhs.sensorAscension && + lhs.sensorCustom == rhs.sensorCustom; + } + + KisSensorData sensorPressure; + KisSensorData sensorFineSpeed; + KisSensorData sensorGrossSpeed; + KisSensorData sensorRandom; + KisSensorData sensorStroke; + KisSensorData sensorDirection; + KisSensorData sensorDeclination; + KisSensorData sensorAscension; + KisSensorData sensorCustom; +}; + +class MyPaintSensorPack : public KisSensorPackInterface +{ +public: + MyPaintSensorPack() = default; + MyPaintSensorPack(const MyPaintSensorPack &rhs) = default; + + KisSensorPackInterface * clone() const override; + + std::vector constSensors() const override; + std::vector sensors() override; + + const MyPaintSensorData& constSensorsStruct() const; + MyPaintSensorData& sensorsStruct(); + + bool compare(const KisSensorPackInterface *rhs) const override; + bool read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const override; + void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const override; + + +private: + MyPaintSensorData m_data; +}; + +#endif // MYPAINTSENSORPACK_H \ No newline at end of file From 87fc2cd1f2e719a494c5cfc902c50c1da624dc35 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 2 Dec 2022 17:47:52 +0300 Subject: [PATCH 02/20] Rename KisMyPaintBrushOption->MyPaintDynamicSensor Otherwise it is too confusing to work with :) --- plugins/paintops/mypaint/CMakeLists.txt | 2 +- .../paintops/mypaint/MyPaintCurveOption.cpp | 54 ++++++++-------- plugins/paintops/mypaint/MyPaintCurveOption.h | 2 +- .../mypaint/MyPaintCurveOptionWidget.cpp | 8 +-- ...ushOption.cpp => MyPaintDynamicSensor.cpp} | 62 +++++++++---------- ...ntBrushOption.h => MyPaintDynamicSensor.h} | 8 +-- 6 files changed, 68 insertions(+), 68 deletions(-) rename plugins/paintops/mypaint/{MyPaintBrushOption.cpp => MyPaintDynamicSensor.cpp} (73%) rename plugins/paintops/mypaint/{MyPaintBrushOption.h => MyPaintDynamicSensor.h} (94%) diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index d1651e952ee..68f4be8328e 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -15,7 +15,7 @@ set(kritamypaintop_SOURCES MyPaintPaintOpPreset.cpp MyPaintPaintOpFactory.cpp MyPaintCurveOptionWidget.cpp - MyPaintBrushOption.cpp + MyPaintDynamicSensor.cpp MyPaintCurveOption.cpp ../libpaintop/kis_multi_sensors_selector.cpp ../libpaintop/kis_multi_sensors_model_p.cpp diff --git a/plugins/paintops/mypaint/MyPaintCurveOption.cpp b/plugins/paintops/mypaint/MyPaintCurveOption.cpp index d872f7476b7..74c7995bbbc 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOption.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOption.cpp @@ -63,12 +63,12 @@ void KisMyPaintCurveOption::writeOptionSetting(KisPropertiesConfigurationSP sett Q_FOREACH(KisDynamicSensorSP val, m_sensorMap.values()) { - KisMyPaintBrushOption *option = dynamic_cast(val.data()); + MyPaintDynamicSensor *sensor = dynamic_cast(val.data()); QVariantList pointsList; - QList curve_points = option->getControlPoints(); + QList curve_points = sensor->getControlPoints(); - if(!option->isActive()){ - inputs_map.remove(option->id(option->sensorType())); + if(!sensor->isActive()){ + inputs_map.remove(sensor->id(sensor->sensorType())); continue; } @@ -78,7 +78,7 @@ void KisMyPaintCurveOption::writeOptionSetting(KisPropertiesConfigurationSP sett pointsList.push_back(point); } - inputs_map[option->id(option->sensorType())] = pointsList; + inputs_map[sensor->id(sensor->sensorType())] = pointsList; } if(!m_useCurve || activeSensors().size()==0) @@ -133,27 +133,27 @@ void KisMyPaintCurveOption::readNamedOptionSetting(const QString& prefix, const points << QPointF(x, y); } - KisMyPaintBrushOption *option = new KisMyPaintBrushOption(KisMyPaintBrushOption::typeForInput(inp)); + MyPaintDynamicSensor *sensor = new MyPaintDynamicSensor(MyPaintDynamicSensor::typeForInput(inp)); if(points.size()) { - option->setCurveFromPoints(points); + sensor->setCurveFromPoints(points); } - if (!setting->getProperty(m_id.id() + option->identifier() + "XMIN").isNull()) - option->setXRangeMin(setting->getProperty(m_id.id() + option->identifier() + "XMIN").toReal()); + if (!setting->getProperty(m_id.id() + sensor->identifier() + "XMIN").isNull()) + sensor->setXRangeMin(setting->getProperty(m_id.id() + sensor->identifier() + "XMIN").toReal()); - if (!setting->getProperty(m_id.id() + option->identifier() + "XMAX").isNull()) - option->setXRangeMax(setting->getProperty(m_id.id() + option->identifier() + "XMAX").toReal()); + if (!setting->getProperty(m_id.id() + sensor->identifier() + "XMAX").isNull()) + sensor->setXRangeMax(setting->getProperty(m_id.id() + sensor->identifier() + "XMAX").toReal()); - if (!setting->getProperty(m_id.id() + option->identifier() + "YMIN").isNull()) - option->setYRangeMin(setting->getProperty(m_id.id() + option->identifier() + "YMIN").toReal()); + if (!setting->getProperty(m_id.id() + sensor->identifier() + "YMIN").isNull()) + sensor->setYRangeMin(setting->getProperty(m_id.id() + sensor->identifier() + "YMIN").toReal()); - if (!setting->getProperty(m_id.id() + option->identifier() + "YMAX").isNull()) - option->setYRangeMax(setting->getProperty(m_id.id() + option->identifier() + "YMAX").toReal()); + if (!setting->getProperty(m_id.id() + sensor->identifier() + "YMAX").isNull()) + sensor->setYRangeMax(setting->getProperty(m_id.id() + sensor->identifier() + "YMAX").toReal()); - replaceSensor(option); - option->setActive(points.size()>0); + replaceSensor(sensor); + sensor->setActive(points.size()>0); } m_useSameCurve = setting->getBool(m_id.id() + "UseSameCurve", false); @@ -359,23 +359,23 @@ KisDynamicSensorSP KisMyPaintCurveOption::id2Sensor(const KoID& id, const QStrin { Q_UNUSED(parentOptionName); if(id.id()==Pressure.id()) - return new KisMyPaintBrushOption(MYPAINT_PRESSURE); + return new MyPaintDynamicSensor(MYPAINT_PRESSURE); else if(id.id()==FineSpeed.id()) - return new KisMyPaintBrushOption(MYPAINT_FINE_SPEED); + return new MyPaintDynamicSensor(MYPAINT_FINE_SPEED); else if(id.id()==GrossSpeed.id()) - return new KisMyPaintBrushOption(MYPAINT_GROSS_SPEED); + return new MyPaintDynamicSensor(MYPAINT_GROSS_SPEED); else if(id.id()==Random.id()) - return new KisMyPaintBrushOption(MYPAINT_RANDOM); + return new MyPaintDynamicSensor(MYPAINT_RANDOM); else if(id.id()==Stroke.id()) - return new KisMyPaintBrushOption(MYPAINT_STROKE); + return new MyPaintDynamicSensor(MYPAINT_STROKE); else if(id.id()==Direction.id()) - return new KisMyPaintBrushOption(MYPAINT_DIRECTION); + return new MyPaintDynamicSensor(MYPAINT_DIRECTION); else if(id.id()==Ascension.id()) - return new KisMyPaintBrushOption(MYPAINT_ASCENSION); + return new MyPaintDynamicSensor(MYPAINT_ASCENSION); else if(id.id()==Declination.id()) - return new KisMyPaintBrushOption(MYPAINT_DECLINATION); + return new MyPaintDynamicSensor(MYPAINT_DECLINATION); else if(id.id()==Custom.id()) - return new KisMyPaintBrushOption(MYPAINT_CUSTOM); + return new MyPaintDynamicSensor(MYPAINT_CUSTOM); else { return 0; } @@ -401,5 +401,5 @@ QList KisMyPaintCurveOption::sensorsTypes() KisDynamicSensorSP KisMyPaintCurveOption::type2Sensor(DynamicSensorType sensorType, const QString &parentOptionName) { Q_UNUSED(parentOptionName); - return new KisMyPaintBrushOption(sensorType); + return new MyPaintDynamicSensor(sensorType); } diff --git a/plugins/paintops/mypaint/MyPaintCurveOption.h b/plugins/paintops/mypaint/MyPaintCurveOption.h index 0d9bf61c2fa..0c324f6d971 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOption.h +++ b/plugins/paintops/mypaint/MyPaintCurveOption.h @@ -17,7 +17,7 @@ #include "kis_curve_option.h" #include #include "kritapaintop_export.h" -#include "MyPaintBrushOption.h" +#include "MyPaintDynamicSensor.h" #include "libmypaint/mypaint-brush.h" class KisMyPaintCurveOption: public KisCurveOption diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp index 35a40e8dd33..3baad19ce3b 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp @@ -16,7 +16,7 @@ #include #include -#include "MyPaintBrushOption.h" +#include "MyPaintDynamicSensor.h" #include "MyPaintCurveOption.h" #include "MyPaintPaintOpOption.h" #include "MyPaintPaintOpSettingsWidget.h" @@ -58,7 +58,7 @@ void KisMyPaintCurveOptionWidget::writeOptionSetting(KisPropertiesConfigurationS { checkRanges(); KisDynamicSensorSP dynamicSensor = m_curveOptionWidget->sensorSelector->currentHighlighted(); - KisMyPaintBrushOption* currentSensor = dynamic_cast(m_curveOptionWidget->sensorSelector->currentHighlighted().data()); + MyPaintDynamicSensor* currentSensor = dynamic_cast(m_curveOptionWidget->sensorSelector->currentHighlighted().data()); KIS_SAFE_ASSERT_RECOVER(dynamicSensor && currentSensor) { } if (dynamicSensor) { setting->setProperty(m_curveOption->id().id() + dynamicSensor->identifier() + "XMIN", m_curveOptionWidget->xMinBox->value()); @@ -99,7 +99,7 @@ void KisMyPaintCurveOptionWidget::slotUnCheckUseCurve() { void KisMyPaintCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) const { KisCurveOptionWidget::updateSensorCurveLabels(sensor); - KisMyPaintBrushOption* mySensor = dynamic_cast(sensor.data()); + MyPaintDynamicSensor* mySensor = dynamic_cast(sensor.data()); if (mySensor) { m_curveOptionWidget->label_xmin->setText(mySensor->minimumXLabel()); @@ -111,7 +111,7 @@ void KisMyPaintCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sen void KisMyPaintCurveOptionWidget::updateRangeSpinBoxes(KisDynamicSensorSP sensor) const { - KisMyPaintBrushOption* mySensor = dynamic_cast(sensor.data()); + MyPaintDynamicSensor* mySensor = dynamic_cast(sensor.data()); m_curveOptionWidget->xMinBox->blockSignals(true); m_curveOptionWidget->xMaxBox->blockSignals(true); m_curveOptionWidget->yMinBox->blockSignals(true); diff --git a/plugins/paintops/mypaint/MyPaintBrushOption.cpp b/plugins/paintops/mypaint/MyPaintDynamicSensor.cpp similarity index 73% rename from plugins/paintops/mypaint/MyPaintBrushOption.cpp rename to plugins/paintops/mypaint/MyPaintDynamicSensor.cpp index 90e096eebd3..3a70b05f117 100644 --- a/plugins/paintops/mypaint/MyPaintBrushOption.cpp +++ b/plugins/paintops/mypaint/MyPaintDynamicSensor.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "MyPaintBrushOption.h" +#include "MyPaintDynamicSensor.h" #include #include @@ -16,21 +16,21 @@ using namespace std; -KisMyPaintBrushOption::KisMyPaintBrushOption(DynamicSensorType type) +MyPaintDynamicSensor::MyPaintDynamicSensor(DynamicSensorType type) : KisDynamicSensor (type) { m_type = type; m_customCurve = false; m_active = false; m_length = -1; - m_id = KisMyPaintBrushOption::id(type); + m_id = MyPaintDynamicSensor::id(type); } -KisMyPaintBrushOption::~KisMyPaintBrushOption() +MyPaintDynamicSensor::~MyPaintDynamicSensor() { } -qreal KisMyPaintBrushOption::value(const KisPaintInformation &info) +qreal MyPaintDynamicSensor::value(const KisPaintInformation &info) { if (info.isHoveringMode()) return 1.0; @@ -40,7 +40,7 @@ qreal KisMyPaintBrushOption::value(const KisPaintInformation &info) return qreal(currentValue) / m_length; } -QString KisMyPaintBrushOption::minimumLabel(DynamicSensorType sensorType) +QString MyPaintDynamicSensor::minimumLabel(DynamicSensorType sensorType) { switch (sensorType) { default: @@ -48,7 +48,7 @@ QString KisMyPaintBrushOption::minimumLabel(DynamicSensorType sensorType) } } -QString KisMyPaintBrushOption::maximumLabel(DynamicSensorType sensorType, int max) +QString MyPaintDynamicSensor::maximumLabel(DynamicSensorType sensorType, int max) { Q_UNUSED(max); switch (sensorType) { @@ -57,27 +57,27 @@ QString KisMyPaintBrushOption::maximumLabel(DynamicSensorType sensorType, int ma }; } -QString KisMyPaintBrushOption::minimumXLabel() { +QString MyPaintDynamicSensor::minimumXLabel() { return QString::number(curveXMin); } -QString KisMyPaintBrushOption::minimumYLabel() { +QString MyPaintDynamicSensor::minimumYLabel() { return QString::number(curveYMin); } -QString KisMyPaintBrushOption::maximumXLabel() { +QString MyPaintDynamicSensor::maximumXLabel() { return QString::number(curveXMax); } -QString KisMyPaintBrushOption::maximumYLabel() { +QString MyPaintDynamicSensor::maximumYLabel() { return QString::number(curveYMax); } -int KisMyPaintBrushOption::minimumValue(DynamicSensorType sensorType) +int MyPaintDynamicSensor::minimumValue(DynamicSensorType sensorType) { switch (sensorType) { @@ -87,7 +87,7 @@ int KisMyPaintBrushOption::minimumValue(DynamicSensorType sensorType) } -int KisMyPaintBrushOption::maximumValue(DynamicSensorType sensorType, int max) +int MyPaintDynamicSensor::maximumValue(DynamicSensorType sensorType, int max) { Q_UNUSED(max); switch (sensorType) { @@ -96,7 +96,7 @@ int KisMyPaintBrushOption::maximumValue(DynamicSensorType sensorType, int max) }; } -QString KisMyPaintBrushOption::valueSuffix(DynamicSensorType sensorType) +QString MyPaintDynamicSensor::valueSuffix(DynamicSensorType sensorType) { switch (sensorType) { @@ -105,7 +105,7 @@ QString KisMyPaintBrushOption::valueSuffix(DynamicSensorType sensorType) }; } -DynamicSensorType KisMyPaintBrushOption::typeForInput(MyPaintBrushInput input) +DynamicSensorType MyPaintDynamicSensor::typeForInput(MyPaintBrushInput input) { switch(input) { @@ -133,7 +133,7 @@ DynamicSensorType KisMyPaintBrushOption::typeForInput(MyPaintBrushInput input) } } -MyPaintBrushInput KisMyPaintBrushOption::input() +MyPaintBrushInput MyPaintDynamicSensor::input() { switch(m_type) { @@ -161,48 +161,48 @@ MyPaintBrushInput KisMyPaintBrushOption::input() } } -qreal KisMyPaintBrushOption::getXRangeMin() { +qreal MyPaintDynamicSensor::getXRangeMin() { return curveXMin; } -qreal KisMyPaintBrushOption::getXRangeMax() { +qreal MyPaintDynamicSensor::getXRangeMax() { return curveXMax; } -qreal KisMyPaintBrushOption::getYRangeMin() { +qreal MyPaintDynamicSensor::getYRangeMin() { return curveYMin; } -qreal KisMyPaintBrushOption::getYRangeMax() { +qreal MyPaintDynamicSensor::getYRangeMax() { return curveYMax; } -void KisMyPaintBrushOption::setXRangeMin(qreal value) { +void MyPaintDynamicSensor::setXRangeMin(qreal value) { curveXMin = value; } -void KisMyPaintBrushOption::setXRangeMax(qreal value) { +void MyPaintDynamicSensor::setXRangeMax(qreal value) { curveXMax = value; } -void KisMyPaintBrushOption::setYRangeMin(qreal value) { +void MyPaintDynamicSensor::setYRangeMin(qreal value) { curveYMin = value; } -void KisMyPaintBrushOption::setYRangeMax(qreal value) { +void MyPaintDynamicSensor::setYRangeMax(qreal value) { curveYMax = value; } -QString KisMyPaintBrushOption::id(DynamicSensorType sensorType) +QString MyPaintDynamicSensor::id(DynamicSensorType sensorType) { switch (sensorType) { @@ -230,7 +230,7 @@ QString KisMyPaintBrushOption::id(DynamicSensorType sensorType) }; } -void KisMyPaintBrushOption::setCurveFromPoints(QList points) { +void MyPaintDynamicSensor::setCurveFromPoints(QList points) { setRangeFromPoints(points); @@ -243,7 +243,7 @@ void KisMyPaintBrushOption::setCurveFromPoints(QList points) { setCurve(curve); } -QList KisMyPaintBrushOption::getControlPoints() { +QList MyPaintDynamicSensor::getControlPoints() { QList curvePoints = curve().points(); for(int i=0; i KisMyPaintBrushOption::getControlPoints() { return curvePoints; } -QPointF KisMyPaintBrushOption::scaleTo0_1(QPointF point) { +QPointF MyPaintDynamicSensor::scaleTo0_1(QPointF point) { QPointF scaledPoint; scaledPoint.setX(scaleToRange(curveXMin, curveXMax, 0, 1, point.x())); @@ -263,7 +263,7 @@ QPointF KisMyPaintBrushOption::scaleTo0_1(QPointF point) { return scaledPoint; } -QPointF KisMyPaintBrushOption::scaleFrom0_1(QPointF point) { +QPointF MyPaintDynamicSensor::scaleFrom0_1(QPointF point) { QPointF scaledPoint; scaledPoint.setX(scaleToRange(0, 1, curveXMin, curveXMax, point.x())); @@ -272,7 +272,7 @@ QPointF KisMyPaintBrushOption::scaleFrom0_1(QPointF point) { return scaledPoint; } -qreal KisMyPaintBrushOption::scaleToRange(qreal inMin, qreal inMax, qreal outMin, qreal outMax, qreal inValue) { +qreal MyPaintDynamicSensor::scaleToRange(qreal inMin, qreal inMax, qreal outMin, qreal outMax, qreal inValue) { qreal inRange = (inMax - inMin); qreal outRange = (outMax - outMin); @@ -281,7 +281,7 @@ qreal KisMyPaintBrushOption::scaleToRange(qreal inMin, qreal inMax, qreal outMin return value; } -void KisMyPaintBrushOption::setRangeFromPoints(QList points) { +void MyPaintDynamicSensor::setRangeFromPoints(QList points) { curveXMin = points[0].x(); curveXMax = points[0].x(); diff --git a/plugins/paintops/mypaint/MyPaintBrushOption.h b/plugins/paintops/mypaint/MyPaintDynamicSensor.h similarity index 94% rename from plugins/paintops/mypaint/MyPaintBrushOption.h rename to plugins/paintops/mypaint/MyPaintDynamicSensor.h index 0368e9f7e38..d10c01fcd79 100644 --- a/plugins/paintops/mypaint/MyPaintBrushOption.h +++ b/plugins/paintops/mypaint/MyPaintDynamicSensor.h @@ -36,13 +36,13 @@ const KoID Declination("tilt_declination", ki18nc("Pen tilt declination", "Decli const KoID Ascension("tilt_ascension", ki18nc("Pen tilt ascension", "Ascension")); const KoID Custom("custom", ki18n("Custom")); -class KisMyPaintBrushOption : public KisDynamicSensor +class MyPaintDynamicSensor : public KisDynamicSensor { public: - KisMyPaintBrushOption(DynamicSensorType type); - ~KisMyPaintBrushOption() override; + MyPaintDynamicSensor(DynamicSensorType type); + ~MyPaintDynamicSensor() override; qreal value(const KisPaintInformation &info) override; @@ -102,7 +102,7 @@ class KisMyPaintBrushOption : public KisDynamicSensor qreal curveYMax = 1; private: - Q_DISABLE_COPY(KisMyPaintBrushOption) + Q_DISABLE_COPY(MyPaintDynamicSensor) }; From 453b04454ebcb9994a95d9196ca8a2d4e9760f17 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Wed, 7 Dec 2022 13:10:25 +0300 Subject: [PATCH 03/20] Split IO-widget management from KisCurveWidget That will let us use QDoubleSpinBox in the mypaint widgets --- libs/ui/CMakeLists.txt | 1 + .../KisCurveWidgetControlsManagerInt.cpp | 124 ++++++++++++++++++ .../KisCurveWidgetControlsManagerInt.h | 50 +++++++ libs/ui/widgets/kis_curve_widget.cpp | 82 ++---------- libs/ui/widgets/kis_curve_widget.h | 20 +-- libs/ui/widgets/kis_curve_widget_p.h | 61 +-------- .../kis_cross_channel_filter.cpp | 4 +- .../colorsfilters/kis_cross_channel_filter.h | 3 + .../colorsfilters/kis_perchannel_filter.cpp | 6 +- .../colorsfilters/kis_perchannel_filter.h | 5 + .../libpaintop/KisCurveOptionWidget2.cpp | 8 +- .../libpaintop/KisCurveOptionWidget2.h | 4 + .../libpaintop/kis_curve_option_widget.cpp | 10 +- .../libpaintop/kis_curve_option_widget.h | 4 +- .../mypaint/MyPaintCurveOptionWidget.cpp | 4 +- .../mypaint/MyPaintCurveOptionWidget.h | 2 +- 16 files changed, 234 insertions(+), 154 deletions(-) create mode 100644 libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp create mode 100644 libs/ui/widgets/KisCurveWidgetControlsManagerInt.h diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index 71ccc9bd5c4..50d16e37530 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -245,6 +245,7 @@ set(kritaui_LIB_SRCS widgets/kis_transport_controls.cpp widgets/kis_utility_title_bar.cpp widgets/kis_curve_widget.cpp + widgets/KisCurveWidgetControlsManagerInt.cpp widgets/kis_custom_image_widget.cc widgets/kis_image_from_clipboard_widget.cpp widgets/kis_double_widget.cc diff --git a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp new file mode 100644 index 00000000000..b00c7edc193 --- /dev/null +++ b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveWidgetControlsManagerInt.h" + +#include +#include + +#include +#include + +KisCurveWidgetControlsManagerInt::KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget) + : QObject(curveWidget) + , m_curveWidget(curveWidget) +{ + connect(m_curveWidget, SIGNAL(shouldSyncIOControls()), this, SLOT(syncIOControls())); + connect(m_curveWidget, SIGNAL(shouldFocusIOControls()), this, SLOT(focusIOControls())); +} + +KisCurveWidgetControlsManagerInt::KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget, QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax) + : KisCurveWidgetControlsManagerInt(curveWidget) +{ + setupInOutControls(in, out, inMin, inMax, outMin, outMax); +} + +KisCurveWidgetControlsManagerInt::~KisCurveWidgetControlsManagerInt() +{ +} + +void KisCurveWidgetControlsManagerInt::setupInOutControls(QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax) +{ + dropInOutControls(); + + m_intIn = in; + m_intOut = out; + + if (!m_intIn || !m_intOut) + return; + + m_inMin = inMin; + m_inMax = inMax; + m_outMin = outMin; + m_outMax = outMax; + + int realInMin = qMin(inMin, inMax); // tilt elevation has range (90, 0), which QSpinBox can't handle + int realInMax = qMax(inMin, inMax); + + m_intIn->setRange(realInMin, realInMax); + m_intOut->setRange(m_outMin, m_outMax); + + connect(m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged()), Qt::UniqueConnection); + connect(m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged()), Qt::UniqueConnection); + + syncIOControls(); +} + +void KisCurveWidgetControlsManagerInt::dropInOutControls() +{ + if (!m_intIn || !m_intOut) + return; + + disconnect(m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged())); + disconnect(m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged())); + + m_intIn = m_intOut = 0; + +} + +void KisCurveWidgetControlsManagerInt::inOutChanged() +{ + QPointF pt; + + KIS_SAFE_ASSERT_RECOVER_RETURN(m_curveWidget->currentPoint()); + + pt.setX(io2sp(m_intIn->value(), m_inMin, m_inMax)); + pt.setY(io2sp(m_intOut->value(), m_outMin, m_outMax)); + + if (m_curveWidget->setCurrentPoint(pt)) { + syncIOControls(); + } +} + +void KisCurveWidgetControlsManagerInt::syncIOControls() +{ + if (!m_intIn || !m_intOut) + return; + + std::optional currentPoint = m_curveWidget->currentPoint(); + + m_intIn->setEnabled(currentPoint.has_value()); + m_intOut->setEnabled(currentPoint.has_value()); + + if (currentPoint) { + KisSignalsBlocker b(m_intIn, m_intOut); + + m_intIn->setValue(sp2io(currentPoint->x(), m_inMin, m_inMax)); + m_intOut->setValue(sp2io(currentPoint->y(), m_outMin, m_outMax)); + } else { + /*FIXME: Ideally, these controls should hide away now */ + } +} + +void KisCurveWidgetControlsManagerInt::focusIOControls() +{ + if (m_intIn) { + m_intIn->setFocus(); + } +} + +double KisCurveWidgetControlsManagerInt::io2sp(int x, int min, int max) +{ + KisSpinBoxSplineUnitConverter unitConverter; + return unitConverter.io2sp(x, min, max); +} + +int KisCurveWidgetControlsManagerInt::sp2io(double x, int min, int max) +{ + KisSpinBoxSplineUnitConverter unitConverter; + return unitConverter.sp2io(x, min, max); +} + diff --git a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h new file mode 100644 index 00000000000..63ecf296f9a --- /dev/null +++ b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVEWIDGETCONTROLSMANAGERINT_H +#define KISCURVEWIDGETCONTROLSMANAGERINT_H + +#include +#include + +class QSpinBox; +class KisCurveWidget; + +class KRITAUI_EXPORT KisCurveWidgetControlsManagerInt : public QObject +{ + Q_OBJECT +public: + KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget); + KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget, QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax); + ~KisCurveWidgetControlsManagerInt(); + + void setupInOutControls(QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax); + void dropInOutControls(); + +private Q_SLOTS: + void inOutChanged(); + void syncIOControls(); + void focusIOControls(); + +private: + double io2sp(int x, int min, int max); + int sp2io(double x, int min, int max); + +private: + /* In/Out controls */ + QSpinBox *m_intIn {nullptr}; + QSpinBox *m_intOut {nullptr}; + + /* Working range of them */ + int m_inMin {0}; + int m_inMax {0}; + int m_outMin {0}; + int m_outMax {0}; + + KisCurveWidget *m_curveWidget {nullptr}; +}; + +#endif // KISCURVEWIDGETCONTROLSMANAGERINT_H diff --git a/libs/ui/widgets/kis_curve_widget.cpp b/libs/ui/widgets/kis_curve_widget.cpp index ef18f3ee047..bc2d276616a 100644 --- a/libs/ui/widgets/kis_curve_widget.cpp +++ b/libs/ui/widgets/kis_curve_widget.cpp @@ -76,57 +76,13 @@ KisCurveWidget::~KisCurveWidget() delete d; } -void KisCurveWidget::setupInOutControls(QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax) +bool KisCurveWidget::setCurrentPoint(QPointF pt) { - dropInOutControls(); - - d->m_intIn = in; - d->m_intOut = out; - - if (!d->m_intIn || !d->m_intOut) - return; - - d->m_inMin = inMin; - d->m_inMax = inMax; - d->m_outMin = outMin; - d->m_outMax = outMax; - - int realInMin = qMin(inMin, inMax); // tilt elevation has range (90, 0), which QSpinBox can't handle - int realInMax = qMax(inMin, inMax); - - d->m_intIn->setRange(realInMin, realInMax); - d->m_intOut->setRange(d->m_outMin, d->m_outMax); - - connect(d->m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)), Qt::UniqueConnection); - connect(d->m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int)), Qt::UniqueConnection); - - d->syncIOControls(); - -} -void KisCurveWidget::dropInOutControls() -{ - if (!d->m_intIn || !d->m_intOut) - return; - - disconnect(d->m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int))); - disconnect(d->m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged(int))); - - d->m_intIn = d->m_intOut = 0; - -} - -void KisCurveWidget::inOutChanged(int) -{ - QPointF pt; - Q_ASSERT(d->m_grab_point_index >= 0); - pt.setX(d->io2sp(d->m_intIn->value(), d->m_inMin, d->m_inMax)); - pt.setY(d->io2sp(d->m_intOut->value(), d->m_outMin, d->m_outMax)); - - bool newPoint = false; + bool needResyncControls = true; if (d->jumpOverExistingPoints(pt, d->m_grab_point_index)) { - newPoint = true; + needResyncControls = false; d->m_curve.setPoint(d->m_grab_point_index, pt); d->m_grab_point_index = d->m_curve.points().indexOf(pt); @@ -135,22 +91,15 @@ void KisCurveWidget::inOutChanged(int) pt = d->m_curve.points()[d->m_grab_point_index]; } - if (!newPoint) { - // if there is a new Point, no point in rewriting values in spinboxes - - d->m_intIn->blockSignals(true); - d->m_intOut->blockSignals(true); - - d->m_intIn->setValue(d->sp2io(pt.x(), d->m_inMin, d->m_inMax)); - d->m_intOut->setValue(d->sp2io(pt.y(), d->m_outMin, d->m_outMax)); - - d->m_intIn->blockSignals(false); - d->m_intOut->blockSignals(false); - } - d->setCurveModified(false); + return needResyncControls; } +std::optional KisCurveWidget::currentPoint() const +{ + return d->m_grab_point_index >= 0 && d->m_grab_point_index < d->m_curve.points().count() ? + std::make_optional(d->m_curve.points()[d->m_grab_point_index]) : std::nullopt; +} void KisCurveWidget::reset(void) { @@ -177,16 +126,6 @@ QPixmap KisCurveWidget::getPixmap() return d->m_pix; } -void KisCurveWidget::setBasePixmap(const QPixmap &pix) -{ - d->m_pixmapBase = pix; -} - -QPixmap KisCurveWidget::getBasePixmap() -{ - return d->m_pixmapBase; -} - bool KisCurveWidget::pointSelected() const { return d->m_grab_point_index > 0 && d->m_grab_point_index < d->m_curve.points().count() - 1; @@ -242,8 +181,7 @@ void KisCurveWidget::addPointInTheMiddle() d->m_grab_point_index = d->m_curve.addPoint(pt); emit pointSelectedChanged(); - if (d->m_intIn) - d->m_intIn->setFocus(Qt::TabFocusReason); + emit shouldFocusIOControls(); d->setCurveModified(); } diff --git a/libs/ui/widgets/kis_curve_widget.h b/libs/ui/widgets/kis_curve_widget.h index 740103e133f..95b6ed60ac6 100644 --- a/libs/ui/widgets/kis_curve_widget.h +++ b/libs/ui/widgets/kis_curve_widget.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -56,14 +57,6 @@ class KRITAUI_EXPORT KisCurveWidget : public QWidget */ void reset(void); - /** - * Enable the guide and set the guide color to the specified color. - * - * XXX: it seems that the guide feature isn't actually implemented yet? - */ - void setCurveGuide(const QColor & color); - - /** * Set a background pixmap. The background pixmap will be drawn under * the grid and the curve. @@ -74,15 +67,15 @@ class KRITAUI_EXPORT KisCurveWidget : public QWidget void setPixmap(const QPixmap & pix); QPixmap getPixmap(); - void setBasePixmap(const QPixmap & pix); - QPixmap getBasePixmap(); - /** * Whether or not there is a point selected * This does NOT include the first and last points */ bool pointSelected() const; + bool setCurrentPoint(QPointF pt); + std::optional currentPoint() const; + Q_SIGNALS: /** @@ -103,9 +96,11 @@ class KRITAUI_EXPORT KisCurveWidget : public QWidget */ void compressorShouldEmitModified(); + void shouldSyncIOControls(); + void shouldFocusIOControls(); + protected Q_SLOTS: - void inOutChanged(int); void notifyModified(); /** @@ -160,7 +155,6 @@ protected Q_SLOTS: class Private; Private * const d {nullptr}; - }; diff --git a/libs/ui/widgets/kis_curve_widget_p.h b/libs/ui/widgets/kis_curve_widget_p.h index ba7d8348793..d0fa78a00da 100644 --- a/libs/ui/widgets/kis_curve_widget_p.h +++ b/libs/ui/widgets/kis_curve_widget_p.h @@ -9,7 +9,6 @@ #include #include #include -#include enum enumState { ST_NORMAL, @@ -23,8 +22,6 @@ class Q_DECL_HIDDEN KisCurveWidget::Private { KisCurveWidget *m_curveWidget {nullptr}; - KisSpinBoxSplineUnitConverter unitConverter; - public: Private(KisCurveWidget *parent); @@ -45,20 +42,9 @@ class Q_DECL_HIDDEN KisCurveWidget::Private KisCubicCurve m_curve; QPixmap m_pix; - QPixmap m_pixmapBase; bool m_pixmapDirty {true}; QPixmap *m_pixmapCache {nullptr}; - /* In/Out controls */ - QSpinBox *m_intIn {nullptr}; - QSpinBox *m_intOut {nullptr}; - - /* Working range of them */ - int m_inMin {0}; - int m_inMax {0}; - int m_outMin {0}; - int m_outMax {0}; - /* view-logic variables */ int m_handleSize {12}; // size of the control points (diameter, in logical pixels) - both for painting and for detecting clicks @@ -82,19 +68,10 @@ class Q_DECL_HIDDEN KisCurveWidget::Private /** * Common update routines */ - void setCurveModified(bool rewriteSpinBoxesValues); + void setCurveModified(bool rewriteSpinBoxesValues = true); void setCurveRepaint(); - /** - * Convert working range of - * In/Out controls to normalized - * range of spline (and reverse) - * See notes on KisSpinBoxSplineUnitConverter - */ - double io2sp(int x, int min, int max); - int sp2io(double x, int min, int max); - /** * Check whether newly created/moved point @p pt doesn't overlap @@ -133,17 +110,6 @@ KisCurveWidget::Private::Private(KisCurveWidget *parent) m_curveWidget = parent; } -double KisCurveWidget::Private::io2sp(int x, int min, int max) -{ - return unitConverter.io2sp(x, min, max); -} - -int KisCurveWidget::Private::sp2io(double x, int min, int max) -{ - return unitConverter.sp2io(x, min, max); -} - - bool KisCurveWidget::Private::jumpOverExistingPoints(QPointF &pt, int skipIndex) { Q_FOREACH (const QPointF &it, m_curve.points()) { @@ -232,36 +198,17 @@ void KisCurveWidget::Private::drawGrid(QPainter &p, int wWidth, int wHeight) void KisCurveWidget::Private::syncIOControls() { - if (!m_intIn || !m_intOut) - return; - - bool somethingSelected = (m_grab_point_index >= 0); - - m_intIn->setEnabled(somethingSelected); - m_intOut->setEnabled(somethingSelected); - - if (m_grab_point_index >= 0) { - m_intIn->blockSignals(true); - m_intOut->blockSignals(true); - - m_intIn->setValue(sp2io(m_curve.points()[m_grab_point_index].x(), m_inMin, m_inMax)); - m_intOut->setValue(sp2io(m_curve.points()[m_grab_point_index].y(), m_outMin, m_outMax)); - - m_intIn->blockSignals(false); - m_intOut->blockSignals(false); - } else { - /*FIXME: Ideally, these controls should hide away now */ - } + emit m_curveWidget->shouldSyncIOControls(); } -void KisCurveWidget::Private::setCurveModified(bool rewriteSpinBoxesValues = true) +void KisCurveWidget::Private::setCurveModified(bool rewriteSpinBoxesValues) { if (rewriteSpinBoxesValues) { syncIOControls(); } m_splineDirty = true; m_curveWidget->update(); - m_curveWidget->emit compressorShouldEmitModified(); + emit m_curveWidget->compressorShouldEmitModified(); } void KisCurveWidget::Private::setCurveRepaint() diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp index 258b3990056..1ac79eea327 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp @@ -40,6 +40,7 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include +#include #include "../../color/colorspaceextensions/kis_hsv_adjustment.h" @@ -200,7 +201,8 @@ KisPropertiesConfigurationSP KisCrossChannelConfigWidget::configuration() const void KisCrossChannelConfigWidget::updateChannelControls() { - m_page->curveWidget->setupInOutControls(m_page->intIn, m_page->intOut, 0, 100, -100, 100); + m_curveControlsManager.reset(new KisCurveWidgetControlsManagerInt(m_page->curveWidget, + m_page->intIn, m_page->intOut, 0, 100, -100, 100)); const int index = m_page->cmbDriverChannel->findData(m_driverChannels[m_activeVChannel]); m_page->cmbDriverChannel->setCurrentIndex(index); diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.h b/plugins/filters/colorsfilters/kis_cross_channel_filter.h index 09eadd82e84..a276ac3d234 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.h +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.h @@ -23,6 +23,8 @@ #include "kis_multichannel_filter_base.h" +class KisCurveWidgetControlsManagerInt; + /** * Filter which applies a relative adjustment to a (virtual) color channel based on the value of another. * The amount of adjustment for a given input is controlled by a user-defined curve. @@ -91,6 +93,7 @@ private Q_SLOTS: private: QVector m_driverChannels; + QScopedPointer m_curveControlsManager; }; #endif diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp index 8edacf1cf1e..0334ec10156 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp @@ -39,6 +39,7 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include +#include #include "kis_multichannel_utils.h" @@ -70,7 +71,7 @@ void KisPerChannelConfigWidget::updateChannelControls() int min; int max; - m_page->curveWidget->dropInOutControls(); + m_curveControlsManager.reset(); switch (valueType) { case KoChannelInfo::UINT8: @@ -107,7 +108,8 @@ void KisPerChannelConfigWidget::updateChannelControls() break; } - m_page->curveWidget->setupInOutControls(m_page->intIn, m_page->intOut, min, max, min, max); + m_curveControlsManager.reset(new KisCurveWidgetControlsManagerInt(m_page->curveWidget, + m_page->intIn, m_page->intOut, min, max, min, max)); } diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.h b/plugins/filters/colorsfilters/kis_perchannel_filter.h index 38db4bb1274..1c65b940ff7 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.h +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.h @@ -21,6 +21,8 @@ #include "kis_multichannel_filter_base.h" +class KisCurveWidgetControlsManagerInt; + class KisPerChannelFilterConfiguration : public KisMultiChannelFilterConfiguration { @@ -67,6 +69,9 @@ class KisPerChannelConfigWidget : public KisMultiChannelConfigWidget void updateChannelControls() override; virtual KisPropertiesConfigurationSP getDefaultConfiguration() override; + +private: + QScopedPointer m_curveControlsManager; }; #endif diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index 92f14f9f09e..b610f0d1ac4 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -21,6 +21,7 @@ #include #include +#include struct KisCurveOptionWidget2::Private { @@ -244,8 +245,11 @@ void KisCurveOptionWidget2::updateSensorCurveLabels(const QString &sensorId, con m_curveOptionWidget->intIn->setSuffix(inSuffix); m_curveOptionWidget->intOut->setSuffix(outSuffix); - m_curveOptionWidget->curveWidget->setupInOutControls(m_curveOptionWidget->intIn,m_curveOptionWidget->intOut, - inMinValue,inMaxValue,outMinValue,outMaxValue); + m_curveControlsManager.reset( + new KisCurveWidgetControlsManagerInt( + m_curveOptionWidget->curveWidget, + m_curveOptionWidget->intIn,m_curveOptionWidget->intOut, + inMinValue,inMaxValue,outMinValue,outMaxValue)); } void KisCurveOptionWidget2::changeCurveLinear() diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index e89f2d842f3..8bb854ea95c 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -17,6 +17,9 @@ class QComboBox; #include #include +class KisCurveWidgetControlsManagerInt; + + class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption { Q_OBJECT @@ -82,6 +85,7 @@ protected Q_SLOTS: protected: QWidget* m_widget {nullptr}; Ui_WdgCurveOption2* m_curveOptionWidget {nullptr}; + QScopedPointer m_curveControlsManager; QComboBox* m_curveMode {nullptr}; struct Private; const QScopedPointer m_d; diff --git a/plugins/paintops/libpaintop/kis_curve_option_widget.cpp b/plugins/paintops/libpaintop/kis_curve_option_widget.cpp index 719096d5427..c4632c89efc 100644 --- a/plugins/paintops/libpaintop/kis_curve_option_widget.cpp +++ b/plugins/paintops/libpaintop/kis_curve_option_widget.cpp @@ -15,6 +15,7 @@ #include "kis_curve_option.h" #include "kis_signals_blocker.h" #include "kis_icon_utils.h" +#include "KisCurveWidgetControlsManagerInt.h" KisCurveOptionWidget::KisCurveOptionWidget(KisCurveOption *curveOption, const QString &minLabel, const QString &maxLabel, bool hideSlider) : KisPaintOpOption(curveOption->id().name(), curveOption->category(), curveOption->isChecked()) @@ -189,7 +190,7 @@ void KisCurveOptionWidget::slotUseSameCurveChanged() emitSettingChanged(); } -void KisCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) const +void KisCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) { if (sensor) { m_curveOptionWidget->label_xmin->setText(sensor->minimumLabel(sensor->sensorType())); @@ -206,8 +207,11 @@ void KisCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) co m_curveOptionWidget->intIn->setSuffix(inSuffix); m_curveOptionWidget->intOut->setSuffix(outSuffix); - m_curveOptionWidget->curveWidget->setupInOutControls(m_curveOptionWidget->intIn,m_curveOptionWidget->intOut, - inMinValue,inMaxValue,outMinValue,outMaxValue); + m_curveControlsManager.reset( + new KisCurveWidgetControlsManagerInt( + m_curveOptionWidget->curveWidget, + m_curveOptionWidget->intIn,m_curveOptionWidget->intOut, + inMinValue,inMaxValue,outMinValue,outMaxValue)); } } diff --git a/plugins/paintops/libpaintop/kis_curve_option_widget.h b/plugins/paintops/libpaintop/kis_curve_option_widget.h index acfb41edd12..2a0b431bb13 100644 --- a/plugins/paintops/libpaintop/kis_curve_option_widget.h +++ b/plugins/paintops/libpaintop/kis_curve_option_widget.h @@ -14,6 +14,7 @@ class Ui_WdgCurveOption; class KisCurveOption; class QComboBox; +class KisCurveWidgetControlsManagerInt; #include @@ -46,7 +47,7 @@ protected Q_SLOTS: void slotModified(); void slotUseSameCurveChanged(); - virtual void updateSensorCurveLabels(KisDynamicSensorSP sensor) const; + virtual void updateSensorCurveLabels(KisDynamicSensorSP sensor); void updateCurve(KisDynamicSensorSP sensor); virtual void updateValues(); void updateMode(); @@ -69,6 +70,7 @@ protected Q_SLOTS: protected: QWidget* m_widget {nullptr}; Ui_WdgCurveOption* m_curveOptionWidget {nullptr}; + QScopedPointer m_curveControlsManager; QComboBox* m_curveMode {nullptr}; KisCurveOption* m_curveOption {nullptr}; qreal strengthToCurveOptionValueScale {0.0}; diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp index 3baad19ce3b..b29f18787fc 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp @@ -75,7 +75,7 @@ void KisMyPaintCurveOptionWidget::writeOptionSetting(KisPropertiesConfigurationS } if (dynamicSensor) { // don't use currentSensor here, because it would get converted to shared pointer - updateSensorCurveLabels(dynamicSensor); + const_cast(this)->updateSensorCurveLabels(dynamicSensor); } setBaseValue(setting, m_curveOptionWidget->strengthSlider->value()); m_curveOption->writeOptionSetting(setting); @@ -96,7 +96,7 @@ void KisMyPaintCurveOptionWidget::slotUnCheckUseCurve() { updateValues(); } -void KisMyPaintCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) const +void KisMyPaintCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) { KisCurveOptionWidget::updateSensorCurveLabels(sensor); MyPaintDynamicSensor* mySensor = dynamic_cast(sensor.data()); diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h index ce45db4317c..8f2736b220f 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h @@ -40,7 +40,7 @@ protected Q_SLOTS: void slotUnCheckUseCurve(); - void updateSensorCurveLabels(KisDynamicSensorSP sensor) const override; + void updateSensorCurveLabels(KisDynamicSensorSP sensor) override; void updateRangeSpinBoxes(KisDynamicSensorSP sensor) const; public Q_SLOTS: From 5c2d8164d982ff7e7b4210c2c25ad5d9c89ec537 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Thu, 8 Dec 2022 13:01:48 +0300 Subject: [PATCH 04/20] Split range and curve spinboxes creation code into separate strategies Now KisCurveOptionWidget2 can accept separate strategies that define how the range of the curve should be handled. * KisCurveRangeModelFactory defines how the range labels should be handled depending on the selected sensor * KisCurveOptionInputControlsStrategy defined the type of the spinboxes. Basically, it defines whether to use QSpinBox or QDoubleSpinBox --- libs/global/kis_algebra_2d.h | 20 ++ libs/ui/CMakeLists.txt | 2 +- libs/ui/kritaui_export_instance.h | 26 +++ .../widgets/KisCurveWidgetControlsManager.cpp | 210 ++++++++++++++++++ .../widgets/KisCurveWidgetControlsManager.h | 111 +++++++++ .../KisCurveWidgetControlsManagerInt.cpp | 124 ----------- .../KisCurveWidgetControlsManagerInt.h | 50 ----- .../kis_cross_channel_filter.cpp | 2 +- .../colorsfilters/kis_perchannel_filter.cpp | 2 +- plugins/paintops/libpaintop/CMakeLists.txt | 4 + .../KisCurveOptionInputControlsStrategy.cpp | 108 +++++++++ .../KisCurveOptionInputControlsStrategy.h | 61 +++++ ...veOptionInputControlsStrategyInterface.cpp | 11 + ...urveOptionInputControlsStrategyInterface.h | 35 +++ .../libpaintop/KisCurveOptionModel.cpp | 57 ++++- .../paintops/libpaintop/KisCurveOptionModel.h | 10 +- .../libpaintop/KisCurveOptionWidget2.cpp | 132 ++++++----- .../libpaintop/KisCurveOptionWidget2.h | 28 ++- .../libpaintop/KisCurveRangeModel.cpp | 161 ++++++++++++++ .../paintops/libpaintop/KisCurveRangeModel.h | 52 +++++ .../KisCurveRangeModelInterface.cpp | 12 + .../libpaintop/KisCurveRangeModelInterface.h | 39 ++++ plugins/paintops/libpaintop/KisSensorData.cpp | 13 +- plugins/paintops/libpaintop/KisSensorData.h | 4 +- .../libpaintop/forms/wdgcurveoption2.ui | 40 +--- .../libpaintop/kis_curve_option_widget.cpp | 2 +- .../libpaintop/kritapaintop_export_instance.h | 27 +++ 27 files changed, 1053 insertions(+), 290 deletions(-) create mode 100644 libs/ui/kritaui_export_instance.h create mode 100644 libs/ui/widgets/KisCurveWidgetControlsManager.cpp create mode 100644 libs/ui/widgets/KisCurveWidgetControlsManager.h delete mode 100644 libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp delete mode 100644 libs/ui/widgets/KisCurveWidgetControlsManagerInt.h create mode 100644 plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.h create mode 100644 plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.h create mode 100644 plugins/paintops/libpaintop/KisCurveRangeModel.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveRangeModel.h create mode 100644 plugins/paintops/libpaintop/KisCurveRangeModelInterface.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveRangeModelInterface.h create mode 100644 plugins/paintops/libpaintop/kritapaintop_export_instance.h diff --git a/libs/global/kis_algebra_2d.h b/libs/global/kis_algebra_2d.h index ce4b3e2dfb3..79c6b6fe2f8 100644 --- a/libs/global/kis_algebra_2d.h +++ b/libs/global/kis_algebra_2d.h @@ -142,6 +142,26 @@ T inwardUnitNormal(const T &a, int polygonDirection) return polygonDirection * leftUnitNormal(a); } +/** + * Helper function to convert a qreal to int lazily. If the + * passed type is an integer, then the value is rounded. + * Otherwise it is just passed forward. + */ +template +R lazyRound(qreal value); + +template<> +inline int lazyRound(qreal value) +{ + return qRound(value); +} + +template<> +inline qreal lazyRound(qreal value) +{ + return value; +} + /** * \return 1 if the polygon is counterclockwise * -1 if the polygon is clockwise diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index 50d16e37530..8ea026a0515 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -245,7 +245,7 @@ set(kritaui_LIB_SRCS widgets/kis_transport_controls.cpp widgets/kis_utility_title_bar.cpp widgets/kis_curve_widget.cpp - widgets/KisCurveWidgetControlsManagerInt.cpp + widgets/KisCurveWidgetControlsManager.cpp widgets/kis_custom_image_widget.cc widgets/kis_image_from_clipboard_widget.cpp widgets/kis_double_widget.cc diff --git a/libs/ui/kritaui_export_instance.h b/libs/ui/kritaui_export_instance.h new file mode 100644 index 00000000000..dc683141aac --- /dev/null +++ b/libs/ui/kritaui_export_instance.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2022 L. E. Segovia + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Ref: GPL-2.0-or-later + */ + +#ifndef KRITAUI_EXPORT_INSTANCE_H +#define KRITAUI_EXPORT_INSTANCE_H + +#include "kritaui_export.h" + +/* See https://reviews.llvm.org/D61118 */ + +#if defined(__MINGW64__) || defined(__MINGW32__) +#define KRITAUI_EXPORT_TEMPLATE KRITAUI_EXPORT +#define KRITAUI_EXPORT_INSTANCE +#elif defined(_MSC_VER) +#define KRITAUI_EXPORT_TEMPLATE +#define KRITAUI_EXPORT_INSTANCE KRITAUI_EXPORT +#else +#define KRITAUI_EXPORT_TEMPLATE KRITAUI_EXPORT +#define KRITAUI_EXPORT_INSTANCE KRITAUI_EXPORT +#endif + +#endif // KRITAUI_EXPORT_INSTANCE_H diff --git a/libs/ui/widgets/KisCurveWidgetControlsManager.cpp b/libs/ui/widgets/KisCurveWidgetControlsManager.cpp new file mode 100644 index 00000000000..cc2695b15a0 --- /dev/null +++ b/libs/ui/widgets/KisCurveWidgetControlsManager.cpp @@ -0,0 +1,210 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveWidgetControlsManager.h" + +#include +#include +#include +#include + +#include + +namespace detail { +qreal io2sp(int x, int min, int max) +{ + KisSpinBoxSplineUnitConverter unitConverter; + return unitConverter.io2sp(x, min, max); +} + +int sp2io(qreal x, int min, int max) +{ + KisSpinBoxSplineUnitConverter unitConverter; + return unitConverter.sp2io(x, min, max); +} + +qreal io2sp(qreal x, qreal min, qreal max) +{ + const qreal rangeLen = max - min; + return !qFuzzyIsNull(rangeLen) ? (x - min) / rangeLen : 0.0; +} + +qreal sp2io(qreal x, qreal min, qreal max) +{ + const qreal rangeLen = max - min; + return x * rangeLen + min; +} + +void setupStep(QSpinBox *spinBox, int min, int max) { + Q_UNUSED(min); + Q_UNUSED(max); + spinBox->setSingleStep(1); +} + +void setupStep(QDoubleSpinBox *spinBox, qreal min, qreal max) { + if (qAbs(max - min) > 10) { + spinBox->setSingleStep(1.0); + } else { + spinBox->setSingleStep(0.1); + } +} + +bool willChangeSpinBox(const QSpinBox *spinBox, int newValue) +{ + return spinBox->value() != newValue; +} + +bool willChangeSpinBox(const QDoubleSpinBox *spinBox, qreal newValue) +{ + return qRound(spinBox->value() * spinBox->decimals()) != + qRound(newValue * spinBox->decimals()); +} + +} // namespace detail + +KisCurveWidgetControlsManagerBase::KisCurveWidgetControlsManagerBase(KisCurveWidget *curveWidget) + : QObject(curveWidget) + , m_curveWidget(curveWidget) +{ + connect(m_curveWidget, &KisCurveWidget::shouldSyncIOControls, this, &KisCurveWidgetControlsManagerBase::syncIOControls); + connect(m_curveWidget, &KisCurveWidget::shouldFocusIOControls, this, &KisCurveWidgetControlsManagerBase::focusIOControls); +} + +KisCurveWidgetControlsManagerBase::~KisCurveWidgetControlsManagerBase() +{ +} + + +template +KisCurveWidgetControlsManager:: +KisCurveWidgetControlsManager(KisCurveWidget *curveWidget) + : KisCurveWidgetControlsManagerBase(curveWidget) +{ + +} + +template +KisCurveWidgetControlsManager:: +KisCurveWidgetControlsManager(KisCurveWidget *curveWidget, + SpinBox *in, SpinBox *out, + ValueType inMin, ValueType inMax, + ValueType outMin, ValueType outMax) + : KisCurveWidgetControlsManager(curveWidget) +{ + setupInOutControls(in, out, inMin, inMax, outMin, outMax); +} + +template +KisCurveWidgetControlsManager:: +~KisCurveWidgetControlsManager() +{ +} + +template +void KisCurveWidgetControlsManager:: +setupInOutControls(SpinBox *in, SpinBox *out, + ValueType inMin, ValueType inMax, + ValueType outMin, ValueType outMax) +{ + dropInOutControls(); + + m_intIn = in; + m_intOut = out; + + if (!m_intIn || !m_intOut) + return; + + m_inMin = inMin; + m_inMax = inMax; + m_outMin = outMin; + m_outMax = outMax; + + ValueType realInMin = qMin(inMin, inMax); // tilt elevation has range (90, 0), which QSpinBox can't handle + ValueType realInMax = qMax(inMin, inMax); + + m_intIn->setRange(realInMin, realInMax); + m_intOut->setRange(m_outMin, m_outMax); + + detail::setupStep(m_intIn, realInMin, realInMax); + detail::setupStep(m_intOut, m_outMin, m_outMax); + + connect(m_intIn, qOverload(&SpinBox::valueChanged), this, &KisCurveWidgetControlsManager::inOutChanged, Qt::UniqueConnection); + connect(m_intOut, qOverload(&SpinBox::valueChanged), this, &KisCurveWidgetControlsManager::inOutChanged, Qt::UniqueConnection); + + syncIOControls(); +} + +template +void KisCurveWidgetControlsManager:: +dropInOutControls() +{ + if (!m_intIn || !m_intOut) + return; + + disconnect(m_intIn, qOverload(&SpinBox::valueChanged), this, &KisCurveWidgetControlsManager::inOutChanged); + disconnect(m_intOut, qOverload(&SpinBox::valueChanged), this, &KisCurveWidgetControlsManager::inOutChanged); + + m_intIn = m_intOut = nullptr; + +} + +template +void KisCurveWidgetControlsManager:: +inOutChanged() +{ + QPointF pt; + + KIS_SAFE_ASSERT_RECOVER_RETURN(m_curveWidget->currentPoint()); + + pt.setX(detail::io2sp(m_intIn->value(), m_inMin, m_inMax)); + pt.setY(detail::io2sp(m_intOut->value(), m_outMin, m_outMax)); + + if (m_curveWidget->setCurrentPoint(pt)) { + syncIOControls(); + } +} + +template +void KisCurveWidgetControlsManager:: +syncIOControls() +{ + if (!m_intIn || !m_intOut) + return; + + std::optional currentPoint = m_curveWidget->currentPoint(); + + m_intIn->setEnabled(currentPoint.has_value()); + m_intOut->setEnabled(currentPoint.has_value()); + + if (currentPoint) { + KisSignalsBlocker b(m_intIn, m_intOut); + + const ValueType inValue = detail::sp2io(currentPoint->x(), m_inMin, m_inMax); + const ValueType outValue = detail::sp2io(currentPoint->y(), m_outMin, m_outMax); + + if (detail::willChangeSpinBox(m_intIn, inValue)) { + m_intIn->setValue(inValue); + } + + if (detail::willChangeSpinBox(m_intOut, outValue)) { + m_intOut->setValue(outValue); + } + } else { + /*FIXME: Ideally, these controls should hide away now */ + } +} + +template +void KisCurveWidgetControlsManager:: +focusIOControls() +{ + if (m_intIn) { + m_intIn->setFocus(); + } +} + +template class KRITAUI_EXPORT_INSTANCE KisCurveWidgetControlsManager; +template class KRITAUI_EXPORT_INSTANCE KisCurveWidgetControlsManager; diff --git a/libs/ui/widgets/KisCurveWidgetControlsManager.h b/libs/ui/widgets/KisCurveWidgetControlsManager.h new file mode 100644 index 00000000000..1197ce5f656 --- /dev/null +++ b/libs/ui/widgets/KisCurveWidgetControlsManager.h @@ -0,0 +1,111 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVEWIDGETCONTROLSMANAGER_H +#define KISCURVEWIDGETCONTROLSMANAGER_H + +#include +#include + +class QSpinBox; +class QDoubleSpinBox; + +namespace detail +{ +/** + * We don't use decltype(std::declval().value()) to avoid + * inclusion of both spinbox headers into this header. + */ +template +struct value_of_spin_box; + +template <> +struct value_of_spin_box { + using type = int; +}; + +template <> +struct value_of_spin_box { + using type = qreal; +}; + +template +using value_of_spin_box_t = typename value_of_spin_box::type; + +} // namespace detail + + +class KisCurveWidget; + +/** + * A base class for the manager to let moc generate signal/slot metadata + * (remember, moc doesn't support template classes) + */ +class KRITAUI_EXPORT KisCurveWidgetControlsManagerBase : public QObject +{ + Q_OBJECT +public: + KisCurveWidgetControlsManagerBase(KisCurveWidget *curveWidget); + ~KisCurveWidgetControlsManagerBase(); + +protected Q_SLOTS: + virtual void inOutChanged() = 0; + virtual void syncIOControls() = 0; + virtual void focusIOControls() = 0; + +protected: + KisCurveWidget *m_curveWidget {nullptr}; +}; + +template +class KRITAUI_EXPORT_TEMPLATE KisCurveWidgetControlsManager : public KisCurveWidgetControlsManagerBase +{ +public: + using ValueType = detail::value_of_spin_box_t; +public: + KisCurveWidgetControlsManager(KisCurveWidget *curveWidget); + KisCurveWidgetControlsManager(KisCurveWidget *curveWidget, + SpinBox *in, SpinBox *out, + ValueType inMin, ValueType inMax, + ValueType outMin, ValueType outMax); + ~KisCurveWidgetControlsManager(); + + void setupInOutControls(SpinBox *in, SpinBox *out, + ValueType inMin, ValueType inMax, + ValueType outMin, ValueType outMax); + void dropInOutControls(); + +protected: + void inOutChanged() override; + void syncIOControls() override; + void focusIOControls() override; + +private: + /* In/Out controls */ + SpinBox *m_intIn {nullptr}; + SpinBox *m_intOut {nullptr}; + + /* Working range of them */ + ValueType m_inMin {0}; + ValueType m_inMax {0}; + ValueType m_outMin {0}; + ValueType m_outMax {0}; +}; + +extern template class KisCurveWidgetControlsManager; +extern template class KisCurveWidgetControlsManager; + +class KisCurveWidgetControlsManagerInt : public KisCurveWidgetControlsManager +{ + using KisCurveWidgetControlsManager::KisCurveWidgetControlsManager; +}; + +class KisCurveWidgetControlsManagerDouble : public KisCurveWidgetControlsManager +{ + using KisCurveWidgetControlsManager::KisCurveWidgetControlsManager; +}; + +#endif // KISCURVEWIDGETCONTROLSMANAGER_H diff --git a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp deleted file mode 100644 index b00c7edc193..00000000000 --- a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Dmitry Kazakov - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "KisCurveWidgetControlsManagerInt.h" - -#include -#include - -#include -#include - -KisCurveWidgetControlsManagerInt::KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget) - : QObject(curveWidget) - , m_curveWidget(curveWidget) -{ - connect(m_curveWidget, SIGNAL(shouldSyncIOControls()), this, SLOT(syncIOControls())); - connect(m_curveWidget, SIGNAL(shouldFocusIOControls()), this, SLOT(focusIOControls())); -} - -KisCurveWidgetControlsManagerInt::KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget, QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax) - : KisCurveWidgetControlsManagerInt(curveWidget) -{ - setupInOutControls(in, out, inMin, inMax, outMin, outMax); -} - -KisCurveWidgetControlsManagerInt::~KisCurveWidgetControlsManagerInt() -{ -} - -void KisCurveWidgetControlsManagerInt::setupInOutControls(QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax) -{ - dropInOutControls(); - - m_intIn = in; - m_intOut = out; - - if (!m_intIn || !m_intOut) - return; - - m_inMin = inMin; - m_inMax = inMax; - m_outMin = outMin; - m_outMax = outMax; - - int realInMin = qMin(inMin, inMax); // tilt elevation has range (90, 0), which QSpinBox can't handle - int realInMax = qMax(inMin, inMax); - - m_intIn->setRange(realInMin, realInMax); - m_intOut->setRange(m_outMin, m_outMax); - - connect(m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged()), Qt::UniqueConnection); - connect(m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged()), Qt::UniqueConnection); - - syncIOControls(); -} - -void KisCurveWidgetControlsManagerInt::dropInOutControls() -{ - if (!m_intIn || !m_intOut) - return; - - disconnect(m_intIn, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged())); - disconnect(m_intOut, SIGNAL(valueChanged(int)), this, SLOT(inOutChanged())); - - m_intIn = m_intOut = 0; - -} - -void KisCurveWidgetControlsManagerInt::inOutChanged() -{ - QPointF pt; - - KIS_SAFE_ASSERT_RECOVER_RETURN(m_curveWidget->currentPoint()); - - pt.setX(io2sp(m_intIn->value(), m_inMin, m_inMax)); - pt.setY(io2sp(m_intOut->value(), m_outMin, m_outMax)); - - if (m_curveWidget->setCurrentPoint(pt)) { - syncIOControls(); - } -} - -void KisCurveWidgetControlsManagerInt::syncIOControls() -{ - if (!m_intIn || !m_intOut) - return; - - std::optional currentPoint = m_curveWidget->currentPoint(); - - m_intIn->setEnabled(currentPoint.has_value()); - m_intOut->setEnabled(currentPoint.has_value()); - - if (currentPoint) { - KisSignalsBlocker b(m_intIn, m_intOut); - - m_intIn->setValue(sp2io(currentPoint->x(), m_inMin, m_inMax)); - m_intOut->setValue(sp2io(currentPoint->y(), m_outMin, m_outMax)); - } else { - /*FIXME: Ideally, these controls should hide away now */ - } -} - -void KisCurveWidgetControlsManagerInt::focusIOControls() -{ - if (m_intIn) { - m_intIn->setFocus(); - } -} - -double KisCurveWidgetControlsManagerInt::io2sp(int x, int min, int max) -{ - KisSpinBoxSplineUnitConverter unitConverter; - return unitConverter.io2sp(x, min, max); -} - -int KisCurveWidgetControlsManagerInt::sp2io(double x, int min, int max) -{ - KisSpinBoxSplineUnitConverter unitConverter; - return unitConverter.sp2io(x, min, max); -} - diff --git a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h b/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h deleted file mode 100644 index 63ecf296f9a..00000000000 --- a/libs/ui/widgets/KisCurveWidgetControlsManagerInt.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Dmitry Kazakov - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef KISCURVEWIDGETCONTROLSMANAGERINT_H -#define KISCURVEWIDGETCONTROLSMANAGERINT_H - -#include -#include - -class QSpinBox; -class KisCurveWidget; - -class KRITAUI_EXPORT KisCurveWidgetControlsManagerInt : public QObject -{ - Q_OBJECT -public: - KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget); - KisCurveWidgetControlsManagerInt(KisCurveWidget *curveWidget, QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax); - ~KisCurveWidgetControlsManagerInt(); - - void setupInOutControls(QSpinBox *in, QSpinBox *out, int inMin, int inMax, int outMin, int outMax); - void dropInOutControls(); - -private Q_SLOTS: - void inOutChanged(); - void syncIOControls(); - void focusIOControls(); - -private: - double io2sp(int x, int min, int max); - int sp2io(double x, int min, int max); - -private: - /* In/Out controls */ - QSpinBox *m_intIn {nullptr}; - QSpinBox *m_intOut {nullptr}; - - /* Working range of them */ - int m_inMin {0}; - int m_inMax {0}; - int m_outMin {0}; - int m_outMax {0}; - - KisCurveWidget *m_curveWidget {nullptr}; -}; - -#endif // KISCURVEWIDGETCONTROLSMANAGERINT_H diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp index 1ac79eea327..0e9a7d62894 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp @@ -40,7 +40,7 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include -#include +#include #include "../../color/colorspaceextensions/kis_hsv_adjustment.h" diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp index 0334ec10156..cc7b17938b4 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp @@ -39,7 +39,7 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include -#include +#include #include "kis_multichannel_utils.h" diff --git a/plugins/paintops/libpaintop/CMakeLists.txt b/plugins/paintops/libpaintop/CMakeLists.txt index c62476bafb2..90502151778 100644 --- a/plugins/paintops/libpaintop/CMakeLists.txt +++ b/plugins/paintops/libpaintop/CMakeLists.txt @@ -20,6 +20,10 @@ set(kritalibpaintop_LIB_SRCS KisKritaSensorPack.cpp KisCurveOptionDataCommon.cpp KisCurveOptionData.cpp + KisCurveOptionInputControlsStrategyInterface.cpp + KisCurveOptionInputControlsStrategy.cpp + KisCurveRangeModelInterface.cpp + KisCurveRangeModel.cpp KisCurveOptionModel.cpp KisCurveOptionWidget2.cpp KisCurveOption2.cpp diff --git a/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.cpp b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.cpp new file mode 100644 index 00000000000..627bd3275ef --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.cpp @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveOptionInputControlsStrategy.h" + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + + + +template +KisCurveOptionInputControlsStrategy:: +KisCurveOptionInputControlsStrategy(KisCurveRangeModelInterface *rangeInterface, + KisCurveWidget *curveWidget, + QWidget *inPlaceholder, QWidget *outPlaceholder) +{ + this->curveWidget = curveWidget; + + inSpinBox = new SpinBox(inPlaceholder); + outSpinBox = new SpinBox(outPlaceholder); + + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(inSpinBox->sizePolicy().hasHeightForWidth()); + inSpinBox->setSizePolicy(sizePolicy); + outSpinBox->setSizePolicy(sizePolicy); + + inSpinBox->setMinimumSize(QSize(0, 0)); + outSpinBox->setMinimumSize(QSize(0, 0)); + + QFont font; + font.setPointSize(9); + inSpinBox->setFont(font); + outSpinBox->setFont(font); + + QHBoxLayout *inLayout = new QHBoxLayout(inPlaceholder); + inLayout->addWidget(inSpinBox); + inLayout->setMargin(0); + + QHBoxLayout *outLayout = new QHBoxLayout(outPlaceholder); + outLayout->addWidget(outSpinBox); + outLayout->setMargin(0); + + xValueSuffix = rangeInterface->xValueSuffix(); + yValueSuffix = rangeInterface->yValueSuffix(); + rangeValues = lager::with(rangeInterface->xMinValue(), rangeInterface->xMaxValue(), + rangeInterface->yMinValue(), rangeInterface->yMaxValue()); + + xValueSuffix.bind(std::bind(&SpinBox::setSuffix, inSpinBox, std::placeholders::_1)); + yValueSuffix.bind(std::bind(&SpinBox::setSuffix, outSpinBox, std::placeholders::_1)); + rangeValues.bind( + kismpl::unzip_wrapper(std::bind(&KisCurveOptionInputControlsStrategy::updateCurveLabels, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4))); + +} + +template +KisCurveOptionInputControlsStrategy::~KisCurveOptionInputControlsStrategy() +{ +} + +template +KisCurveOptionInputControlsStrategyFactory KisCurveOptionInputControlsStrategy::factory() +{ + return + [] (KisCurveRangeModelInterface *rangeInterface, + KisCurveWidget *curveWidget, + QWidget *inPlaceholder, QWidget *outPlaceholder) { + return new KisCurveOptionInputControlsStrategy(rangeInterface, + curveWidget, + inPlaceholder, + outPlaceholder); + + }; +} + +template +void KisCurveOptionInputControlsStrategy::updateCurveLabels(qreal xMin, qreal xMax, qreal yMin, qreal yMax) +{ + using ValueType = typename KisCurveWidgetControlsManager::ValueType; + + curveControlsManager.reset( + new KisCurveWidgetControlsManager( + curveWidget, + inSpinBox, outSpinBox, + KisAlgebra2D::lazyRound(xMin), + KisAlgebra2D::lazyRound(xMax), + KisAlgebra2D::lazyRound(yMin), + KisAlgebra2D::lazyRound(yMax))); +} + +template class PAINTOP_EXPORT_INSTANCE KisCurveOptionInputControlsStrategy; +template class PAINTOP_EXPORT_INSTANCE KisCurveOptionInputControlsStrategy; diff --git a/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.h b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.h new file mode 100644 index 00000000000..d807d4f91b1 --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategy.h @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVEOPTIONINPUTCONTROLSSTRATEGY_H +#define KISCURVEOPTIONINPUTCONTROLSSTRATEGY_H + +#include + +#include +#include +#include + +class KisCurveWidgetControlsManagerBase; +class QSpinBox; +class QDoubleSpinBox; + +template +class PAINTOP_EXPORT_TEMPLATE KisCurveOptionInputControlsStrategy + : public KisCurveOptionInputControlsStrategyInterface +{ +public: + KisCurveOptionInputControlsStrategy(KisCurveRangeModelInterface *rangeInterface, + KisCurveWidget *curveWidget, + QWidget *inPlaceholder, QWidget *outPlaceholder); + ~KisCurveOptionInputControlsStrategy(); + + static KisCurveOptionInputControlsStrategyFactory factory(); + +private: + void updateCurveLabels(qreal xMin, qreal xMax, qreal yMin, qreal yMax); + +private: + SpinBox *inSpinBox; + SpinBox *outSpinBox; + KisCurveWidget *curveWidget {nullptr}; + QScopedPointer curveControlsManager; + lager::reader xValueSuffix; + lager::reader yValueSuffix; + lager::reader> rangeValues; +}; + +extern template class KisCurveOptionInputControlsStrategy; +extern template class KisCurveOptionInputControlsStrategy; + +class KisCurveOptionInputControlsStrategyInt : public KisCurveOptionInputControlsStrategy +{ +public: + using KisCurveOptionInputControlsStrategy::KisCurveOptionInputControlsStrategy; +}; + +class KisCurveOptionInputControlsStrategyDouble : public KisCurveOptionInputControlsStrategy +{ +public: + using KisCurveOptionInputControlsStrategy::KisCurveOptionInputControlsStrategy; +}; + + +#endif // KISCURVEOPTIONINPUTCONTROLSSTRATEGY_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.cpp b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.cpp new file mode 100644 index 00000000000..dc3798f6725 --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.cpp @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveOptionInputControlsStrategyInterface.h" + +KisCurveOptionInputControlsStrategyInterface::~KisCurveOptionInputControlsStrategyInterface() +{ +} diff --git a/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.h b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.h new file mode 100644 index 00000000000..523fd2c2e4d --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionInputControlsStrategyInterface.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVEOPTIONINPUTCONTROLSSTRATEGYINTERFACE_H +#define KISCURVEOPTIONINPUTCONTROLSSTRATEGYINTERFACE_H + +#include +#include + +class KisCurveRangeModelInterface; +class KisCurveWidget; +class QWidget; + +class PAINTOP_EXPORT KisCurveOptionInputControlsStrategyInterface +{ +public: + virtual ~KisCurveOptionInputControlsStrategyInterface(); + + /** + * erm... yep! no public interface! :) + */ +}; + +using KisCurveOptionInputControlsStrategyFactory = + std::function< + KisCurveOptionInputControlsStrategyInterface* ( + KisCurveRangeModelInterface* /*rangeInterface*/, + KisCurveWidget* /*curveWidget*/, + QWidget* /*inPlaceholder*/, + QWidget* /*outPlaceholder*/)>; + +#endif // KISCURVEOPTIONINPUTCONTROLSSTRATEGYINTERFACE_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp index d9bbbfb8202..c4a46154e2b 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp @@ -60,19 +60,59 @@ auto activeCurveLens = lager::lenses::getset( return data; }); +auto activeCurveRangeLens = lager::lenses::getset( + [](const std::tuple &data) -> QRectF { + QRectF activeCurveRange(0.0, 0.0, 1.0, 1.0); + + const QString activeSensorId = std::get<1>(data); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!activeSensorId.isEmpty(), activeCurveRange); + std::vector srcSensors = std::get<0>(data).sensors(); + auto it = + std::find_if(srcSensors.begin(), srcSensors.end(), + [activeSensorId] (const KisSensorData *sensor) { + return sensor->id.id() == activeSensorId; + }); + + KIS_SAFE_ASSERT_RECOVER_NOOP(it != srcSensors.end()); + + if (it != srcSensors.end()) { + activeCurveRange = (*it)->baseCurveRange(); + } + + return activeCurveRange; + }, + [](std::tuple data, const QRectF curveRange) { + const QString activeSensorId = std::get<1>(data); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(!activeSensorId.isEmpty(), data); + std::vector srcSensors = std::get<0>(data).sensors(); + auto it = + std::find_if(srcSensors.begin(), srcSensors.end(), + [activeSensorId] (const KisSensorData *sensor) { + return sensor->id.id() == activeSensorId; + }); + + KIS_SAFE_ASSERT_RECOVER_NOOP(it != srcSensors.end()); + + if (it != srcSensors.end()) { + (*it)->setBaseCurveRange(curveRange); + } + + return data; + }); + int calcActiveSensorLength(const KisCurveOptionDataCommon &data, const QString &activeSensorId) { return data.sensorData->calcActiveSensorLength(activeSensorId); } - KisCurveOptionModel::KisCurveOptionModel(lager::cursor _optionData, lager::reader externallyEnabled, - std::optional> rangeOverride) + std::optional> rangeOverride, + KisCurveRangeModelFactory rangeModelFactory) : optionData(_optionData) , rangeNorm(rangeOverride ? *rangeOverride : lager::with(optionData[&KisCurveOptionDataCommon::strengthMinValue], optionData[&KisCurveOptionDataCommon::strengthMaxValue])) - , activeSensorIdData(PressureId.id()) + , activeSensorIdData(optionData->sensors().front()->id.id()) , LAGER_QT(isCheckable) {optionData[&KisCurveOptionDataCommon::isCheckable]} , LAGER_QT(isChecked) {optionData[&KisCurveOptionDataCommon::isChecked]} , LAGER_QT(effectiveIsChecked) {lager::with(LAGER_QT(isChecked), externallyEnabled).map(std::logical_and{})} @@ -98,6 +138,17 @@ KisCurveOptionModel::KisCurveOptionModel(lager::cursor , LAGER_QT(activeCurve) {lager::with(optionData, LAGER_QT(activeSensorId)) .zoom(activeCurveLens)} + , rangeModel(rangeModelFactory(LAGER_QT(activeCurve), + lager::with(optionData, + LAGER_QT(activeSensorId)) + .zoom(activeCurveRangeLens), + LAGER_QT(activeSensorId), + LAGER_QT(activeSensorLength))) + , LAGER_QT(displayedCurve) {rangeModel->curve()} + , LAGER_QT(curveXMinLabel) {rangeModel->xMinLabel()} + , LAGER_QT(curveXMaxLabel) {rangeModel->xMaxLabel()} + , LAGER_QT(curveYMinLabel) {rangeModel->yMinLabel()} + , LAGER_QT(curveYMaxLabel) {rangeModel->yMaxLabel()} { } diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.h b/plugins/paintops/libpaintop/KisCurveOptionModel.h index 770bf37e735..9b8d7c7db02 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.h +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.h @@ -9,6 +9,7 @@ #include "kritapaintop_export.h" #include "KisCurveOptionData.h" +#include "KisCurveRangeModelInterface.h" #include #include @@ -25,7 +26,8 @@ class PAINTOP_EXPORT KisCurveOptionModel : public QObject public: KisCurveOptionModel(lager::cursor optionData, lager::reader externallyEnabled, - std::optional> rangeOverride); + std::optional> rangeOverride, + KisCurveRangeModelFactory rangeModelFactory); ~KisCurveOptionModel(); // the state must be declared **before** any cursors or readers @@ -45,6 +47,12 @@ class PAINTOP_EXPORT KisCurveOptionModel : public QObject LAGER_QT_READER(int, activeSensorLength); LAGER_QT_READER(LabelsState, labelsState); LAGER_QT_CURSOR(QString, activeCurve); + std::unique_ptr rangeModel; + LAGER_QT_CURSOR(QString, displayedCurve); + LAGER_QT_READER(QString, curveXMinLabel); + LAGER_QT_READER(QString, curveXMaxLabel); + LAGER_QT_READER(QString, curveYMinLabel); + LAGER_QT_READER(QString, curveYMaxLabel); KisCurveOptionDataCommon bakedOptionData() const; }; diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index b610f0d1ac4..73243ee7837 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -18,17 +18,19 @@ #include #include +#include #include -#include -#include +#include +#include struct KisCurveOptionWidget2::Private { Private(lager::cursor optionData, lager::reader enabledLink, - std::optional>> rangeReader) - : model(optionData, enabledLink, rangeReader) + std::optional>> rangeReader, + KisCurveRangeModelFactory curveRangeFactory) + : model(optionData, enabledLink, rangeReader, curveRangeFactory) {} KisCurveOptionModel model; @@ -41,12 +43,16 @@ struct KisCurveOptionWidget2::Private KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, lager::reader enabledLink, - std::optional>> rangeReader) + std::optional>> rangeReader, + KisCurveRangeModelFactory curveRangeFactory, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory) : KisCurveOptionWidget2(optionData, category, i18n("0%"), i18n("100%"), enabledLink, - rangeReader) + rangeReader, + curveRangeFactory, + inputControlsFactory) { } @@ -54,14 +60,18 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader) + std::optional>> rangeReader, + KisCurveRangeModelFactory curveRangeFactory, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, 0, 100, i18n("%"), i18n("Strength: "), i18n("%"), enabledLink, - rangeReader) + rangeReader, + curveRangeFactory, + inputControlsFactory) { } @@ -71,14 +81,18 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader) + std::optional>> rangeReader, + KisCurveRangeModelFactory curveRangeFactory, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, curveMinValue, curveMaxValue, curveValueSuffix, i18n("Strength: "), i18n("%"), enabledLink, - rangeReader) + rangeReader, + curveRangeFactory, + inputControlsFactory) { } @@ -88,11 +102,20 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader) + std::optional>> rangeReader, + KisCurveRangeModelFactory curveRangeFactory, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory) : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionDataCommon::isChecked], enabledLink) , m_widget(new QWidget) , m_curveOptionWidget(new Ui_WdgCurveOption2()) - , m_d(new Private(optionData, enabledLink, rangeReader)) + , m_d(new Private(optionData, enabledLink, rangeReader, + curveRangeFactory ? + curveRangeFactory : + KisCurveRangeModel::factory(curveMinLabel, + curveMaxLabel, + curveMinValue, + curveMaxValue, + curveValueSuffix))) { using namespace KisWidgetConnectionUtils; @@ -100,14 +123,39 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorsetupUi(m_widget); m_curveOptionWidget->sensorSelector->setOptionDataCursor(m_d->model.optionData); + + if (!inputControlsFactory) { + inputControlsFactory = KisCurveOptionInputControlsStrategyInt::factory(); + } + + m_curveInputControlsStrategy.reset( + inputControlsFactory(m_d->model.rangeModel.get(), + m_curveOptionWidget->curveWidget, + m_curveOptionWidget->intInPlaceholder, + m_curveOptionWidget->intOutPlaceholder)); + setConfigurationPage(m_widget); hideRangeLabelsAndBoxes(true); m_d->curveMinValue = curveMinValue; m_d->curveMaxValue = curveMaxValue; m_d->curveValueSuffix = curveValueSuffix; - m_curveOptionWidget->label_ymin->setText(curveMinLabel); - m_curveOptionWidget->label_ymax->setText(curveMaxLabel); + + connect(&m_d->model, &KisCurveOptionModel::curveXMinLabelChanged, + m_curveOptionWidget->label_xmin, &QLabel::setText); + m_curveOptionWidget->label_xmin->setText(m_d->model.curveXMinLabel()); + + connect(&m_d->model, &KisCurveOptionModel::curveXMaxLabelChanged, + m_curveOptionWidget->label_xmax, &QLabel::setText); + m_curveOptionWidget->label_xmax->setText(m_d->model.curveXMaxLabel()); + + connect(&m_d->model, &KisCurveOptionModel::curveYMinLabelChanged, + m_curveOptionWidget->label_ymin, &QLabel::setText); + m_curveOptionWidget->label_ymin->setText(m_d->model.curveYMinLabel()); + + connect(&m_d->model, &KisCurveOptionModel::curveYMaxLabelChanged, + m_curveOptionWidget->label_ymax, &QLabel::setText); + m_curveOptionWidget->label_ymax->setText(m_d->model.curveYMaxLabel()); m_d->model.activeSensorIdData.bind( std::bind(qOverload(&KisMultiSensorsSelector2::setCurrent), @@ -117,10 +165,6 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursormodel, std::placeholders::_1)); - m_d->model.LAGER_QT(labelsState).bind( - kismpl::unzip_wrapper( - std::bind(&KisCurveOptionWidget2::updateSensorCurveLabels, this, std::placeholders::_1, std::placeholders::_2))); - // set all the icons for the curve preset shapes updateThemedIcons(); @@ -147,7 +191,7 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorstrengthSlider->setValue(value); })); - m_d->model.LAGER_QT(activeCurve).bind( + m_d->model.LAGER_QT(displayedCurve).bind( std::bind(&KisCurveWidget::setCurve, m_curveOptionWidget->curveWidget, std::placeholders::_1)); @@ -196,8 +240,8 @@ void KisCurveOptionWidget2::setCurveWidgetsEnabled(bool value) m_curveOptionWidget->label_xmin->setEnabled(value); m_curveOptionWidget->label_ymax->setEnabled(value); m_curveOptionWidget->label_ymin->setEnabled(value); - m_curveOptionWidget->intIn->setEnabled(value); - m_curveOptionWidget->intOut->setEnabled(value); + m_curveOptionWidget->intInPlaceholder->setEnabled(value); + m_curveOptionWidget->intOutPlaceholder->setEnabled(value); m_curveOptionWidget->linearCurveButton->setEnabled(value); m_curveOptionWidget->revLinearButton->setEnabled(value); @@ -221,35 +265,7 @@ QWidget* KisCurveOptionWidget2::curveWidget() void KisCurveOptionWidget2::slotCurveChanged(const KisCubicCurve &curve) { const QString string = curve.toString(); - m_d->model.setactiveCurve(string); -} - -void KisCurveOptionWidget2::updateSensorCurveLabels(const QString &sensorId, const int length) -{ - KisDynamicSensorFactory *factory = - KisDynamicSensorFactoryRegistry::instance()->get(sensorId); - - KIS_SAFE_ASSERT_RECOVER_RETURN(factory); - - m_curveOptionWidget->label_xmin->setText(factory->minimumLabel()); - m_curveOptionWidget->label_xmax->setText(factory->maximumLabel(length)); - - const int inMinValue = factory->minimumValue(); - const int inMaxValue = factory->maximumValue(length); - const QString inSuffix = factory->valueSuffix(); - - const int outMinValue = m_d->curveMinValue; - const int outMaxValue = m_d->curveMaxValue; - const QString outSuffix = m_d->curveValueSuffix; - - m_curveOptionWidget->intIn->setSuffix(inSuffix); - m_curveOptionWidget->intOut->setSuffix(outSuffix); - - m_curveControlsManager.reset( - new KisCurveWidgetControlsManagerInt( - m_curveOptionWidget->curveWidget, - m_curveOptionWidget->intIn,m_curveOptionWidget->intOut, - inMinValue,inMaxValue,outMinValue,outMaxValue)); + m_d->model.setdisplayedCurve(string); } void KisCurveOptionWidget2::changeCurveLinear() @@ -257,7 +273,7 @@ void KisCurveOptionWidget2::changeCurveLinear() QList points; points.push_back(QPointF(0,0)); points.push_back(QPointF(1,1)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveReverseLinear() @@ -265,7 +281,7 @@ void KisCurveOptionWidget2::changeCurveReverseLinear() QList points; points.push_back(QPointF(0,1)); points.push_back(QPointF(1,0)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveSShape() @@ -275,7 +291,7 @@ void KisCurveOptionWidget2::changeCurveSShape() points.push_back(QPointF(0.25,0.1)); points.push_back(QPointF(0.75,0.9)); points.push_back(QPointF(1, 1)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } @@ -286,7 +302,7 @@ void KisCurveOptionWidget2::changeCurveReverseSShape() points.push_back(QPointF(0.25,0.9)); points.push_back(QPointF(0.75,0.1)); points.push_back(QPointF(1,0)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveJShape() @@ -295,7 +311,7 @@ void KisCurveOptionWidget2::changeCurveJShape() points.push_back(QPointF(0,0)); points.push_back(QPointF(0.35,0.1)); points.push_back(QPointF(1,1)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveLShape() @@ -304,7 +320,7 @@ void KisCurveOptionWidget2::changeCurveLShape() points.push_back(QPointF(0,1)); points.push_back(QPointF(0.25,0.48)); points.push_back(QPointF(1,0)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveUShape() @@ -313,7 +329,7 @@ void KisCurveOptionWidget2::changeCurveUShape() points.push_back(QPointF(0,1)); points.push_back(QPointF(0.5,0)); points.push_back(QPointF(1,1)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::changeCurveArchShape() @@ -322,7 +338,7 @@ void KisCurveOptionWidget2::changeCurveArchShape() points.push_back(QPointF(0,0)); points.push_back(QPointF(0.5,1)); points.push_back(QPointF(1,0)); - m_d->model.setactiveCurve(KisCubicCurve(points).toString()); + m_d->model.setdisplayedCurve(KisCubicCurve(points).toString()); } void KisCurveOptionWidget2::updateThemedIcons() diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index 8bb854ea95c..920b208d970 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -14,11 +14,11 @@ class QComboBox; #include #include +#include +#include #include #include -class KisCurveWidgetControlsManagerInt; - class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption { @@ -29,28 +29,38 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt); + std::optional>> rangeReader = std::nullopt, + KisCurveRangeModelFactory curveRangeFactory = {}, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt); + std::optional>> rangeReader = std::nullopt, + KisCurveRangeModelFactory curveRangeFactory = {}, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt); - + std::optional>> rangeReader = std::nullopt, + KisCurveRangeModelFactory curveRangeFactory = {}, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); +private: KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, const QString &strengthPrefix, const QString &strengthSuffix, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt); + std::optional>> rangeReader = std::nullopt, + KisCurveRangeModelFactory curveRangeFactory = {}, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); + +public: ~KisCurveOptionWidget2() override; void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; @@ -67,7 +77,6 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption protected Q_SLOTS: void slotCurveChanged(const KisCubicCurve &curve); - void updateSensorCurveLabels(const QString &sensorId, const int length); void updateThemedIcons(); @@ -85,11 +94,10 @@ protected Q_SLOTS: protected: QWidget* m_widget {nullptr}; Ui_WdgCurveOption2* m_curveOptionWidget {nullptr}; - QScopedPointer m_curveControlsManager; + QScopedPointer m_curveInputControlsStrategy; QComboBox* m_curveMode {nullptr}; struct Private; const QScopedPointer m_d; - void hideRangeLabelsAndBoxes(bool isHidden); }; diff --git a/plugins/paintops/libpaintop/KisCurveRangeModel.cpp b/plugins/paintops/libpaintop/KisCurveRangeModel.cpp new file mode 100644 index 00000000000..a06a1f65626 --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveRangeModel.cpp @@ -0,0 +1,161 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveRangeModel.h" + +#include + +using LabelsState = std::tuple; + +namespace { +QString calcMinLabelWithFactory(const QString &sensorId) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(sensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, ""); + + return factory->minimumLabel(); +} + +QString calcMaxLabelWithFactory(const QString &activeSensorId, const int length) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(activeSensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, ""); + + return factory->maximumLabel(length); +} + +qreal calcMinValueWithFactory(const QString &sensorId) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(sensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 0.0); + + return qreal(factory->minimumValue()); +} + +qreal calcMaxValueWithFactory(const QString &activeSensorId, const int length) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(activeSensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 1.0); + + return factory->maximumValue(length); +} + +QString calcValueSuffixWithFactory(const QString &activeSensorId) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(activeSensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, ""); + + return factory->valueSuffix(); +} + + +} + +KisCurveRangeModel::KisCurveRangeModel(lager::cursor curve, + lager::reader activeSensorId, + lager::reader activeSensorLength, + const QString &yMinLabel, + const QString &yMaxLabel, + int yMinValue, + int yMaxValue, + const QString &yValueSuffix) + : m_curve(std::move(curve)) + , m_activeSensorId(std::move(activeSensorId)) + , m_activeSensorLength(std::move(activeSensorLength)) + , m_yMinLabel(yMinLabel) + , m_yMaxLabel(yMaxLabel) + , m_yMinValue(yMinValue) + , m_yMaxValue(yMaxValue) + , m_yValueSuffix(yValueSuffix) +{ +} + +KisCurveRangeModelFactory KisCurveRangeModel::factory(const QString &yMinLabel, + const QString &yMaxLabel, + int curveMinValue, + int curveMaxValue, + const QString &curveValueSuffix) +{ + return [yMinLabel, yMaxLabel, + curveMinValue, curveMaxValue, + curveValueSuffix](lager::cursor curve, + lager::cursor curveRange, + lager::reader activeSensorId, + lager::reader activeSensorLength) { + + Q_UNUSED(curveRange); + return new KisCurveRangeModel(curve, activeSensorId, activeSensorLength, yMinLabel, yMaxLabel, curveMinValue, curveMaxValue, curveValueSuffix); + }; +} + +KisCurveRangeModel::~KisCurveRangeModel() +{ +} + +lager::cursor KisCurveRangeModel::curve() +{ + return m_curve; +} + +lager::reader KisCurveRangeModel::xMinLabel() +{ + return m_activeSensorId.map(&calcMinLabelWithFactory); +} + +lager::reader KisCurveRangeModel::xMaxLabel() +{ + return lager::with(m_activeSensorId, m_activeSensorLength).map(&calcMaxLabelWithFactory); +} + +lager::reader KisCurveRangeModel::yMinLabel() +{ + return m_yMinLabel; +} + +lager::reader KisCurveRangeModel::yMaxLabel() +{ + return m_yMaxLabel; +} + +lager::reader KisCurveRangeModel::yMinValue() +{ + return m_yMinValue; +} + +lager::reader KisCurveRangeModel::yMaxValue() +{ + return m_yMaxValue; +} + +lager::reader KisCurveRangeModel::yValueSuffix() +{ + return m_yValueSuffix; +} + +lager::reader KisCurveRangeModel::xMinValue() +{ + return m_activeSensorId.map(&calcMinValueWithFactory); +} + +lager::reader KisCurveRangeModel::xMaxValue() +{ + return lager::with(m_activeSensorId, m_activeSensorLength).map(&calcMaxValueWithFactory); +} + +lager::reader KisCurveRangeModel::xValueSuffix() +{ + return m_activeSensorId.map(&calcValueSuffixWithFactory); +} diff --git a/plugins/paintops/libpaintop/KisCurveRangeModel.h b/plugins/paintops/libpaintop/KisCurveRangeModel.h new file mode 100644 index 00000000000..0b9fec4f44b --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveRangeModel.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVERANGEMODEL_H +#define KISCURVERANGEMODEL_H + +#include +#include + +class KisCurveRangeModel : public KisCurveRangeModelInterface +{ +public: + KisCurveRangeModel(lager::cursor curve, + lager::reader activeSensorId, + lager::reader activeSensorLength, + const QString &yMinLabel, + const QString &yMaxLabel, + int yMinValue, + int yMaxValue, + const QString &yValueSuffix); + + ~KisCurveRangeModel(); + + lager::cursor curve() override; + lager::reader xMinLabel() override; + lager::reader xMaxLabel() override; + lager::reader yMinLabel() override; + lager::reader yMaxLabel() override; + lager::reader yMinValue() override; + lager::reader yMaxValue() override; + lager::reader yValueSuffix() override; + lager::reader xMinValue() override; + lager::reader xMaxValue() override; + lager::reader xValueSuffix() override; + + static KisCurveRangeModelFactory factory(const QString &yMinLabel, const QString &yMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix); + +private: + lager::cursor m_curve; + lager::reader m_activeSensorId; + lager::reader m_activeSensorLength; + lager::constant m_yMinLabel; + lager::constant m_yMaxLabel; + lager::constant m_yMinValue; + lager::constant m_yMaxValue; + lager::constant m_yValueSuffix; +}; + +#endif // KISCURVERANGEMODEL_H diff --git a/plugins/paintops/libpaintop/KisCurveRangeModelInterface.cpp b/plugins/paintops/libpaintop/KisCurveRangeModelInterface.cpp new file mode 100644 index 00000000000..7227dc7dadd --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveRangeModelInterface.cpp @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveRangeModelInterface.h" + +KisCurveRangeModelInterface::~KisCurveRangeModelInterface() +{ + +} \ No newline at end of file diff --git a/plugins/paintops/libpaintop/KisCurveRangeModelInterface.h b/plugins/paintops/libpaintop/KisCurveRangeModelInterface.h new file mode 100644 index 00000000000..9dec13bfecb --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveRangeModelInterface.h @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVERANGEMODELINTERFACE_H +#define KISCURVERANGEMODELINTERFACE_H + +#include "kritapaintop_export.h" + +#include +#include + +class PAINTOP_EXPORT KisCurveRangeModelInterface +{ +public: + virtual ~KisCurveRangeModelInterface(); + virtual lager::cursor curve() = 0; + virtual lager::reader xMinLabel() = 0; + virtual lager::reader xMaxLabel() = 0; + virtual lager::reader yMinLabel() = 0; + virtual lager::reader yMaxLabel() = 0; + virtual lager::reader yMinValue() = 0; + virtual lager::reader yMaxValue() = 0; + virtual lager::reader yValueSuffix() = 0; + virtual lager::reader xMinValue() = 0; + virtual lager::reader xMaxValue() = 0; + virtual lager::reader xValueSuffix() = 0; +}; + +// usage: factory(curve, curveRange, activeSensorId, activeSensorLength) +using KisCurveRangeModelFactory = + std::function, + lager::cursor, + lager::reader, + lager::reader)>; + +#endif // KISCURVERANGEMODELINTERFACE_H diff --git a/plugins/paintops/libpaintop/KisSensorData.cpp b/plugins/paintops/libpaintop/KisSensorData.cpp index b95b9c278d5..d417aa4fc42 100644 --- a/plugins/paintops/libpaintop/KisSensorData.cpp +++ b/plugins/paintops/libpaintop/KisSensorData.cpp @@ -22,6 +22,17 @@ KisSensorData::~KisSensorData() { } +void KisSensorData::setBaseCurveRange(const QRectF &rect) +{ + Q_UNUSED(rect); + KIS_SAFE_ASSERT_RECOVER_NOOP(0 && "setBaseCurveRange is not implemented for standard Krita sensors"); +} + +QRectF KisSensorData::baseCurveRange() const +{ + return QRectF(0.0,0.0,1.0,1.0); +} + void KisSensorData::write(QDomDocument& doc, QDomElement &e) const { e.setAttribute("id", id.id()); @@ -129,4 +140,4 @@ void KisDrawingAngleSensorData::read(const QDomElement &e) void KisDrawingAngleSensorData::reset() { *this = KisDrawingAngleSensorData(); -} \ No newline at end of file +} diff --git a/plugins/paintops/libpaintop/KisSensorData.h b/plugins/paintops/libpaintop/KisSensorData.h index 47753929996..9ee715d1bed 100644 --- a/plugins/paintops/libpaintop/KisSensorData.h +++ b/plugins/paintops/libpaintop/KisSensorData.h @@ -23,6 +23,8 @@ struct PAINTOP_EXPORT KisSensorData : public boost::equality_comparable - - - - 0 - 0 - - - - - 9 - - - - false - - + @@ -374,28 +359,7 @@ - - - - 0 - 0 - - - - - 0 - 0 - - - - - 9 - - - - true - - + diff --git a/plugins/paintops/libpaintop/kis_curve_option_widget.cpp b/plugins/paintops/libpaintop/kis_curve_option_widget.cpp index c4632c89efc..ba49c2a4020 100644 --- a/plugins/paintops/libpaintop/kis_curve_option_widget.cpp +++ b/plugins/paintops/libpaintop/kis_curve_option_widget.cpp @@ -15,7 +15,7 @@ #include "kis_curve_option.h" #include "kis_signals_blocker.h" #include "kis_icon_utils.h" -#include "KisCurveWidgetControlsManagerInt.h" +#include "KisCurveWidgetControlsManager.h" KisCurveOptionWidget::KisCurveOptionWidget(KisCurveOption *curveOption, const QString &minLabel, const QString &maxLabel, bool hideSlider) : KisPaintOpOption(curveOption->id().name(), curveOption->category(), curveOption->isChecked()) diff --git a/plugins/paintops/libpaintop/kritapaintop_export_instance.h b/plugins/paintops/libpaintop/kritapaintop_export_instance.h new file mode 100644 index 00000000000..7f974bb12b9 --- /dev/null +++ b/plugins/paintops/libpaintop/kritapaintop_export_instance.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2022 L. E. Segovia + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Ref: GPL-2.0-or-later + */ + +#ifndef KRITAPAINTOP_EXPORT_INSTANCE_H +#define KRITAPAINTOP_EXPORT_INSTANCE_H + +#include "kritapaintop_export.h" + +/* See https://reviews.llvm.org/D61118 */ + +#if defined(__MINGW64__) || defined(__MINGW32__) +#define PAINTOP_EXPORT_TEMPLATE PAINTOP_EXPORT +#define PAINTOP_EXPORT_INSTANCE +#elif defined(_MSC_VER) +#define PAINTOP_EXPORT_TEMPLATE +#define PAINTOP_EXPORT_INSTANCE PAINTOP_EXPORT +#else +#define PAINTOP_EXPORT_TEMPLATE PAINTOP_EXPORT +#define PAINTOP_EXPORT_INSTANCE PAINTOP_EXPORT +#endif + + +#endif // KRITAPAINTOP_EXPORT_INSTANCE_H From dbb94b33d32a8d63483fae13262dd62a9a8facd1 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 13:21:00 +0300 Subject: [PATCH 05/20] Implement basic MyPaint-like curve option widget It supports ranges and works in denormalized 'double' space instead of 'int', like in Krita. The range configuration is implemented using KisCurveOptionRangeControlsStrategyInterface that is specialized but the MyPaint curve option widget. --- libs/image/kis_cubic_curve.cpp | 5 + libs/widgets/KisWidgetConnectionUtils.cpp | 107 ++++++ libs/widgets/KisWidgetConnectionUtils.h | 26 +- plugins/paintops/libpaintop/CMakeLists.txt | 1 + ...veOptionRangeControlsStrategyInterface.cpp | 11 + ...urveOptionRangeControlsStrategyInterface.h | 32 ++ .../libpaintop/KisCurveOptionWidget2.cpp | 29 +- .../libpaintop/KisCurveOptionWidget2.h | 14 +- .../libpaintop/KisCurveRangeModel.cpp | 44 +-- .../paintops/libpaintop/KisCurveRangeModel.h | 5 +- .../libpaintop/forms/wdgcurveoption2.ui | 219 +++++------ plugins/paintops/mypaint/CMakeLists.txt | 3 + ...yPaintCurveOptionRangeControlsStrategy.cpp | 63 ++++ .../MyPaintCurveOptionRangeControlsStrategy.h | 30 ++ .../mypaint/MyPaintCurveOptionWidget2.cpp | 29 ++ .../mypaint/MyPaintCurveOptionWidget2.h | 26 ++ .../mypaint/MyPaintCurveRangeModel.cpp | 187 ++++++++++ .../paintops/mypaint/MyPaintCurveRangeModel.h | 72 ++++ .../mypaint/MyPaintPaintOpSettingsWidget.cpp | 21 +- .../paintops/mypaint/MyPaintSensorPack.cpp | 347 +++++++++++++++++- plugins/paintops/mypaint/MyPaintSensorPack.h | 56 ++- 21 files changed, 1158 insertions(+), 169 deletions(-) create mode 100644 plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.cpp create mode 100644 plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.h create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.cpp create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.h create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp create mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h create mode 100644 plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp create mode 100644 plugins/paintops/mypaint/MyPaintCurveRangeModel.h diff --git a/libs/image/kis_cubic_curve.cpp b/libs/image/kis_cubic_curve.cpp index d33c97976c7..205519dde95 100644 --- a/libs/image/kis_cubic_curve.cpp +++ b/libs/image/kis_cubic_curve.cpp @@ -325,6 +325,11 @@ KisCubicCurve::KisCubicCurve(const QList& points) : d(new Private) d->data->keepSorted(); } +KisCubicCurve::KisCubicCurve(const QVector &points) + : KisCubicCurve(points.toList()) +{ +} + KisCubicCurve::KisCubicCurve(const KisCubicCurve& curve) : d(new Private(*curve.d)) { diff --git a/libs/widgets/KisWidgetConnectionUtils.cpp b/libs/widgets/KisWidgetConnectionUtils.cpp index 75b509b54fa..eb141a0d196 100644 --- a/libs/widgets/KisWidgetConnectionUtils.cpp +++ b/libs/widgets/KisWidgetConnectionUtils.cpp @@ -152,6 +152,113 @@ void connectControl(QDoubleSpinBox *spinBox, QObject *source, const char *proper } } +class ConnectIntSpinBoxStateHelper : public QObject +{ + Q_OBJECT +public: + + ConnectIntSpinBoxStateHelper(QSpinBox *parent) + : QObject(parent), + m_spinBox(parent) + { + } +public Q_SLOTS: + void setState(IntSpinBoxState state) { + QSignalBlocker b(m_spinBox); + + m_spinBox->setEnabled(state.enabled); + m_spinBox->setRange(state.min, state.max); + m_spinBox->setValue(state.value); + } + +private: + QSpinBox *m_spinBox; +}; + + +void connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty) +{ + const QMetaObject* meta = source->metaObject(); + QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty)); + + KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal()); + + QMetaMethod signal = readStateProp.notifySignal(); + + KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1); + KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("IntSpinBoxState")); + + ConnectIntSpinBoxStateHelper *helper = new ConnectIntSpinBoxStateHelper(spinBox); + + const QMetaObject* dstMeta = helper->metaObject(); + + QMetaMethod updateSlot = dstMeta->method( + dstMeta->indexOfSlot("setState(IntSpinBoxState)")); + QObject::connect(source, signal, helper, updateSlot); + + helper->setState(readStateProp.read(source).value()); + + QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty)); + if (writeProp.isWritable()) { + QObject::connect(spinBox, qOverload(&QSpinBox::valueChanged), + source, [writeProp, source] (int value) { writeProp.write(source, value); }); + } +} + +class ConnectDoubleSpinBoxStateHelper : public QObject +{ + Q_OBJECT +public: + + ConnectDoubleSpinBoxStateHelper(QDoubleSpinBox *parent) + : QObject(parent), + m_spinBox(parent) + { + } +public Q_SLOTS: + void setState(DoubleSpinBoxState state) { + QSignalBlocker b(m_spinBox); + + m_spinBox->setEnabled(state.enabled); + m_spinBox->setRange(state.min, state.max); + m_spinBox->setValue(state.value); + } + +private: + QDoubleSpinBox *m_spinBox; +}; + + +void connectControlState(QDoubleSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty) +{ + const QMetaObject* meta = source->metaObject(); + QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty)); + + KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal()); + + QMetaMethod signal = readStateProp.notifySignal(); + + KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1); + KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("DoubleSpinBoxState")); + + ConnectDoubleSpinBoxStateHelper *helper = new ConnectDoubleSpinBoxStateHelper(spinBox); + + const QMetaObject* dstMeta = helper->metaObject(); + + QMetaMethod updateSlot = dstMeta->method( + dstMeta->indexOfSlot("setState(DoubleSpinBoxState)")); + QObject::connect(source, signal, helper, updateSlot); + + helper->setState(readStateProp.read(source).value()); + + QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty)); + if (writeProp.isWritable()) { + QObject::connect(spinBox, qOverload(&QDoubleSpinBox::valueChanged), + source, [writeProp, source] (qreal value) { writeProp.write(source, value); }); + } +} + + void connectControl(KisMultipliersDoubleSliderSpinBox *spinBox, QObject *source, const char *property) { const QMetaObject* meta = source->metaObject(); diff --git a/libs/widgets/KisWidgetConnectionUtils.h b/libs/widgets/KisWidgetConnectionUtils.h index aa8ac282a84..9336700a752 100644 --- a/libs/widgets/KisWidgetConnectionUtils.h +++ b/libs/widgets/KisWidgetConnectionUtils.h @@ -66,9 +66,29 @@ struct FromSpacingState { } }; +template +struct SpinBoxState { + T value = T{}; + T min = T{}; + T max = T{}; + bool enabled = true; +}; + +struct ToSpinBoxState { + template + SpinBoxState> operator()(T &&value, T &&min, T &&max, bool enabled) { + return {std::forward(value), std::forward(min), std::forward(max), enabled}; + } +}; + +using IntSpinBoxState = SpinBoxState; +using DoubleSpinBoxState = SpinBoxState; + void KRITAWIDGETS_EXPORT connectControl(QAbstractButton *button, QObject *source, const char *property); void KRITAWIDGETS_EXPORT connectControl(QSpinBox *spinBox, QObject *source, const char *property); void KRITAWIDGETS_EXPORT connectControl(QDoubleSpinBox *spinBox, QObject *source, const char *property); +void KRITAWIDGETS_EXPORT connectControlState(QDoubleSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty); +void KRITAWIDGETS_EXPORT connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty); void KRITAWIDGETS_EXPORT connectControl(KisMultipliersDoubleSliderSpinBox *spinBox, QObject *source, const char *property); void KRITAWIDGETS_EXPORT connectControl(QButtonGroup *button, QObject *source, const char *property); void KRITAWIDGETS_EXPORT connectControl(QComboBox *button, QObject *source, const char *property); @@ -80,17 +100,21 @@ void KRITAWIDGETS_EXPORT connectControl(KisSpacingSelectionWidget *widget, QObje void KRITAWIDGETS_EXPORT connectControl(KisAngleSelector *widget, QObject *source, const char *property); void KRITAWIDGETS_EXPORT connectControl(QLineEdit *widget, QObject *source, const char *property); -}; +} // namespace KisWidgetConnectionUtils using KisWidgetConnectionUtils::CheckBoxState; using KisWidgetConnectionUtils::ButtonGroupState; using KisWidgetConnectionUtils::ComboBoxState; using KisWidgetConnectionUtils::SpacingState; +using KisWidgetConnectionUtils::DoubleSpinBoxState; +using KisWidgetConnectionUtils::IntSpinBoxState; Q_DECLARE_METATYPE(CheckBoxState) Q_DECLARE_METATYPE(ButtonGroupState) Q_DECLARE_METATYPE(ComboBoxState) Q_DECLARE_METATYPE(SpacingState) +Q_DECLARE_METATYPE(DoubleSpinBoxState) +Q_DECLARE_METATYPE(IntSpinBoxState) #endif // KISWIDGETCONNECTIONUTILS_H diff --git a/plugins/paintops/libpaintop/CMakeLists.txt b/plugins/paintops/libpaintop/CMakeLists.txt index 90502151778..222ea102cc3 100644 --- a/plugins/paintops/libpaintop/CMakeLists.txt +++ b/plugins/paintops/libpaintop/CMakeLists.txt @@ -22,6 +22,7 @@ set(kritalibpaintop_LIB_SRCS KisCurveOptionData.cpp KisCurveOptionInputControlsStrategyInterface.cpp KisCurveOptionInputControlsStrategy.cpp + KisCurveOptionRangeControlsStrategyInterface.cpp KisCurveRangeModelInterface.cpp KisCurveRangeModel.cpp KisCurveOptionModel.cpp diff --git a/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.cpp b/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.cpp new file mode 100644 index 00000000000..2b69ed717f2 --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.cpp @@ -0,0 +1,11 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "KisCurveOptionRangeControlsStrategyInterface.h" + +KisCurveOptionRangeControlsStrategyInterface::~KisCurveOptionRangeControlsStrategyInterface() +{ +} diff --git a/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.h b/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.h new file mode 100644 index 00000000000..7773030768f --- /dev/null +++ b/plugins/paintops/libpaintop/KisCurveOptionRangeControlsStrategyInterface.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef KISCURVEOPTIONRANGECONTROLSSTRATEGYINTERFACE_H +#define KISCURVEOPTIONRANGECONTROLSSTRATEGYINTERFACE_H + +#include +#include + +class KisCurveRangeModelInterface; +class QWidget; + +class PAINTOP_EXPORT KisCurveOptionRangeControlsStrategyInterface +{ +public: + virtual ~KisCurveOptionRangeControlsStrategyInterface(); + + /** + * erm... yep! no public interface! :) + */ +}; + +using KisCurveOptionRangeControlsStrategyFactory = + std::function< + KisCurveOptionRangeControlsStrategyInterface* ( + KisCurveRangeModelInterface* /*rangeInterface*/, + QWidget* /*rangeControlsPlaceholder*/)>; + +#endif // KISCURVEOPTIONRANGECONTROLSSTRATEGYINTERFACE_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index 73243ee7837..f7a4c2fb7aa 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -45,14 +45,16 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, std::optional>> rangeReader, KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory) + KisCurveOptionInputControlsStrategyFactory inputControlsFactory, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) : KisCurveOptionWidget2(optionData, category, i18n("0%"), i18n("100%"), enabledLink, rangeReader, curveRangeFactory, - inputControlsFactory) + inputControlsFactory, + rangeControlsFactory) { } @@ -62,7 +64,8 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, std::optional>> rangeReader, KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory) + KisCurveOptionInputControlsStrategyFactory inputControlsFactory, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, @@ -71,7 +74,8 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, std::optional>> rangeReader, KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory) + KisCurveOptionInputControlsStrategyFactory inputControlsFactory, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, @@ -92,7 +97,8 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, std::optional>> rangeReader, KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory) + KisCurveOptionInputControlsStrategyFactory inputControlsFactory, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionDataCommon::isChecked], enabledLink) , m_widget(new QWidget) , m_curveOptionWidget(new Ui_WdgCurveOption2()) @@ -134,6 +141,14 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorintInPlaceholder, m_curveOptionWidget->intOutPlaceholder)); + if (rangeControlsFactory) { + m_curveRangeControlsStrategy.reset( + rangeControlsFactory(m_d->model.rangeModel.get(), + m_curveOptionWidget->wdgRangeControlsPlaceholder)); + } else { + m_curveOptionWidget->wdgRangeControlsPlaceholder->setVisible(false); + } + setConfigurationPage(m_widget); hideRangeLabelsAndBoxes(true); diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index 920b208d970..15f063b0e78 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -16,6 +16,7 @@ class QComboBox; #include #include #include +#include #include #include @@ -31,7 +32,8 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt, KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, @@ -39,7 +41,8 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt, KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, @@ -48,7 +51,8 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt, KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); private: KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, @@ -58,7 +62,8 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption lager::reader enabledLink = lager::make_constant(true), std::optional>> rangeReader = std::nullopt, KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}); + KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); public: ~KisCurveOptionWidget2() override; @@ -95,6 +100,7 @@ protected Q_SLOTS: QWidget* m_widget {nullptr}; Ui_WdgCurveOption2* m_curveOptionWidget {nullptr}; QScopedPointer m_curveInputControlsStrategy; + QScopedPointer m_curveRangeControlsStrategy; QComboBox* m_curveMode {nullptr}; struct Private; const QScopedPointer m_d; diff --git a/plugins/paintops/libpaintop/KisCurveRangeModel.cpp b/plugins/paintops/libpaintop/KisCurveRangeModel.cpp index a06a1f65626..04ef9cad104 100644 --- a/plugins/paintops/libpaintop/KisCurveRangeModel.cpp +++ b/plugins/paintops/libpaintop/KisCurveRangeModel.cpp @@ -31,26 +31,6 @@ QString calcMaxLabelWithFactory(const QString &activeSensorId, const int length) return factory->maximumLabel(length); } -qreal calcMinValueWithFactory(const QString &sensorId) -{ - KisDynamicSensorFactory *factory = - KisDynamicSensorFactoryRegistry::instance()->get(sensorId); - - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 0.0); - - return qreal(factory->minimumValue()); -} - -qreal calcMaxValueWithFactory(const QString &activeSensorId, const int length) -{ - KisDynamicSensorFactory *factory = - KisDynamicSensorFactoryRegistry::instance()->get(activeSensorId); - - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 1.0); - - return factory->maximumValue(length); -} - QString calcValueSuffixWithFactory(const QString &activeSensorId) { KisDynamicSensorFactory *factory = @@ -101,6 +81,26 @@ KisCurveRangeModelFactory KisCurveRangeModel::factory(const QString &yMinLabel, }; } +qreal KisCurveRangeModel::calcXMinValueWithFactory(const QString &sensorId) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(sensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 0.0); + + return qreal(factory->minimumValue()); +} + +qreal KisCurveRangeModel::calcXMaxValueWithFactory(const QString &activeSensorId, const int length) +{ + KisDynamicSensorFactory *factory = + KisDynamicSensorFactoryRegistry::instance()->get(activeSensorId); + + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(factory, 1.0); + + return factory->maximumValue(length); +} + KisCurveRangeModel::~KisCurveRangeModel() { } @@ -147,12 +147,12 @@ lager::reader KisCurveRangeModel::yValueSuffix() lager::reader KisCurveRangeModel::xMinValue() { - return m_activeSensorId.map(&calcMinValueWithFactory); + return m_activeSensorId.map(&calcXMinValueWithFactory); } lager::reader KisCurveRangeModel::xMaxValue() { - return lager::with(m_activeSensorId, m_activeSensorLength).map(&calcMaxValueWithFactory); + return lager::with(m_activeSensorId, m_activeSensorLength).map(&calcXMaxValueWithFactory); } lager::reader KisCurveRangeModel::xValueSuffix() diff --git a/plugins/paintops/libpaintop/KisCurveRangeModel.h b/plugins/paintops/libpaintop/KisCurveRangeModel.h index 0b9fec4f44b..785ac889953 100644 --- a/plugins/paintops/libpaintop/KisCurveRangeModel.h +++ b/plugins/paintops/libpaintop/KisCurveRangeModel.h @@ -10,7 +10,7 @@ #include #include -class KisCurveRangeModel : public KisCurveRangeModelInterface +class PAINTOP_EXPORT KisCurveRangeModel : public KisCurveRangeModelInterface { public: KisCurveRangeModel(lager::cursor curve, @@ -38,6 +38,9 @@ class KisCurveRangeModel : public KisCurveRangeModelInterface static KisCurveRangeModelFactory factory(const QString &yMinLabel, const QString &yMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix); + static qreal calcXMinValueWithFactory(const QString &sensorId); + static qreal calcXMaxValueWithFactory(const QString &activeSensorId, const int length); + private: lager::cursor m_curve; lager::reader m_activeSensorId; diff --git a/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui b/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui index b6e8a3b5da0..136ad3b4b1d 100644 --- a/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui +++ b/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui @@ -249,6 +249,108 @@ + + + + Qt::Vertical + + + + 20 + 60 + + + + + + + + + + X Range: + + + + + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + To + + + + + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + + + + Y Range: + + + + + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + To + + + + + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + + Qt::Horizontal + + + + 13 + 13 + + + + @@ -407,69 +509,15 @@ - - - - Qt::Horizontal - - - - 13 - 13 - - - - - - - - - - Y Range: - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - To - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - - Qt::Vertical + + + + Share curve across all settings - - - 20 - 60 - + + true - + @@ -532,53 +580,8 @@ - - - - Share curve across all settings - - - true - - - - - - - - - X Range: - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - To - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - + + diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index 68f4be8328e..24259b5f9d3 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -7,6 +7,9 @@ link_directories(${LIBMYPAINT_LIBRARIES}) set(kritamypaintop_SOURCES MyPaintSensorPack.cpp MyPaintCurveOptionData.cpp + MyPaintCurveOptionWidget2.cpp + MyPaintCurveRangeModel.cpp + MyPaintCurveOptionRangeControlsStrategy.cpp MyPaintPaintOp.cpp MyPaintPaintOpOption.cpp MyPaintPaintOpSettings.cpp diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.cpp new file mode 100644 index 00000000000..5418a576e2d --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.cpp @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintCurveOptionRangeControlsStrategy.h" + +#include + +#include +#include +#include + +#include +#include +#include + +MyPaintCurveOptionRangeControlsStrategy::MyPaintCurveOptionRangeControlsStrategy(KisCurveRangeModelInterface *rangeInterface, QWidget *rangeControlsPlaceholder) + : m_rangeModel(dynamic_cast(rangeInterface)) + , m_xValueSuffix(m_rangeModel->xValueSuffix()) + , m_yValueSuffix(m_rangeModel->yValueSuffix()) +{ + using namespace KisWidgetConnectionUtils; + KIS_SAFE_ASSERT_RECOVER_RETURN(m_rangeModel); + + KisDoubleSliderSpinBox *yLimitSlider = new KisDoubleSliderSpinBox(rangeControlsPlaceholder); + yLimitSlider->setPrefix(i18n("Y limit: ")); + yLimitSlider->setRange(0.0, m_rangeModel->maxYRange(), 2); + m_yValueSuffix.bind(std::bind(&KisDoubleSliderSpinBox::setSuffix, yLimitSlider, std::placeholders::_1)); + connectControl(yLimitSlider, m_rangeModel, "yLimit"); + + KisDoubleSliderSpinBox *xMin = new KisDoubleSliderSpinBox(rangeControlsPlaceholder); + xMin->setPrefix(i18n("X min: ")); + m_xValueSuffix.bind(std::bind(&KisDoubleSliderSpinBox::setSuffix, xMin, std::placeholders::_1)); + connectControlState(xMin, m_rangeModel, "xMinState", "xMin"); + + KisDoubleSliderSpinBox *xMax = new KisDoubleSliderSpinBox(rangeControlsPlaceholder); + xMax->setPrefix(i18n("X max: ")); + m_xValueSuffix.bind(std::bind(&KisDoubleSliderSpinBox::setSuffix, xMax, std::placeholders::_1)); + connectControlState(xMax, m_rangeModel, "xMaxState", "xMax"); + + QHBoxLayout *xRangeLayout = new QHBoxLayout(); + xRangeLayout->addWidget(xMin); + xRangeLayout->addWidget(xMax); + + QVBoxLayout *layout = new QVBoxLayout(rangeControlsPlaceholder); + layout->addWidget(yLimitSlider); + layout->addLayout(xRangeLayout); + +} + +MyPaintCurveOptionRangeControlsStrategy::~MyPaintCurveOptionRangeControlsStrategy() +{ + +} + +KisCurveOptionRangeControlsStrategyFactory MyPaintCurveOptionRangeControlsStrategy::factory() +{ + return [] (KisCurveRangeModelInterface *rangeInterface, QWidget *rangeControlsPlaceholder) { + return new MyPaintCurveOptionRangeControlsStrategy(rangeInterface, rangeControlsPlaceholder); + }; +} diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.h b/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.h new file mode 100644 index 00000000000..9e21a542bf5 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionRangeControlsStrategy.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTCURVEOPTIONRANGECONTROLSSTRATEGY_H +#define MYPAINTCURVEOPTIONRANGECONTROLSSTRATEGY_H + +#include +#include + +class MyPaintCurveRangeModel; + +class MyPaintCurveOptionRangeControlsStrategy : public KisCurveOptionRangeControlsStrategyInterface +{ +public: + MyPaintCurveOptionRangeControlsStrategy(KisCurveRangeModelInterface* rangeInterface, + QWidget* rangeControlsPlaceholder); + ~MyPaintCurveOptionRangeControlsStrategy(); + + static KisCurveOptionRangeControlsStrategyFactory factory(); + +private: + MyPaintCurveRangeModel *m_rangeModel; + lager::reader m_xValueSuffix; + lager::reader m_yValueSuffix; +}; + +#endif // MYPAINTCURVEOPTIONRANGECONTROLSSTRATEGY_H diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp new file mode 100644 index 00000000000..c102a0a38f0 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintCurveOptionWidget2.h" +#include "KisZug.h" +#include "kis_paintop_option.h" +#include "MyPaintCurveRangeModel.h" +#include "MyPaintCurveOptionRangeControlsStrategy.h" +#include "KisCurveOptionInputControlsStrategy.h" + +MyPaintCurveOptionWidget2::MyPaintCurveOptionWidget2(lager::cursor optionData, + qreal maxYRange, + const QString &yValueSuffix) + : KisCurveOptionWidget2(optionData.zoom(kiszug::lenses::to_base), + KisPaintOpOption::GENERAL, + lager::make_constant(true), + std::nullopt, + MyPaintCurveRangeModel::factory(maxYRange, yValueSuffix), + KisCurveOptionInputControlsStrategyDouble::factory(), + MyPaintCurveOptionRangeControlsStrategy::factory()) +{ +} + +MyPaintCurveOptionWidget2::~MyPaintCurveOptionWidget2() +{ +} diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h new file mode 100644 index 00000000000..07bdc88c15e --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTCURVEOPTIONWIDGET2_H +#define MYPAINTCURVEOPTIONWIDGET2_H + +#include +#include + +class MyPaintCurveOptionWidget2 : public KisCurveOptionWidget2 +{ +public: + using data_type = MyPaintCurveOptionData; + +public: + MyPaintCurveOptionWidget2(lager::cursor optionData, + qreal maxYRange, const QString &yValueSuffix); + ~MyPaintCurveOptionWidget2(); + +private: +}; + +#endif // MYPAINTCURVEOPTIONWIDGET2_H diff --git a/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp b/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp new file mode 100644 index 00000000000..756214abe75 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp @@ -0,0 +1,187 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintCurveRangeModel.h" +#include "kis_algebra_2d.h" +#include "kis_cubic_curve.h" +#include +#include +#include +#include +#include + +namespace { + auto formatQRealAsString = [] (qreal value) { + return QString("%1").arg(value, 0, 'f', 2); + }; + + auto formatQRealAsStringWithSuffix = [] (const QString &suffix) { + return [suffix] (qreal value) { + return QString("%1%2").arg(value, 0, 'f', 2).arg(suffix); + }; + }; + + + auto curveToNormalizedCurve = lager::lenses::getset( + [] (const std::tuple &curveData) + { + MyPaintCurveRangeModel::NormalizedCurve normalized; + QList points = KisCubicCurve(std::get<0>(curveData)).points(); + const QRectF bounds = std::get<1>(curveData); + + normalized.yLimit = qMax(qAbs(bounds.top()), qAbs(bounds.bottom())); + normalized.xMax = bounds.right(); + normalized.xMin = bounds.left(); + + if (qFuzzyIsNull(normalized.yLimit)) { + points = {{0.0,0.5}, {1.0, 0.5}}; + } else { + for (auto it = points.begin(); it != points.end(); ++it) { + it->rx() = (it->x() - bounds.left()) / bounds.width(); + it->ry() = it->y() / (2.0 * normalized.yLimit) + 0.5; + } + } + + normalized.curve = KisCubicCurve(points).toString(); + + //qDebug() << "get" << std::get<0>(curveData) << "->" << normalized.curve << bounds; + return normalized; + }, + [] (std::tuple curveData, const MyPaintCurveRangeModel::NormalizedCurve &normalizedCurve) { + QList points = KisCubicCurve(normalizedCurve.curve).points(); + + for (auto it = points.begin(); it != points.end(); ++it) { + it->rx() = it->x() * (normalizedCurve.xMax - normalizedCurve.xMin) + normalizedCurve.xMin; + it->ry() = (it->y() - 0.5) * normalizedCurve.yLimit * 2.0; + } + + std::get<0>(curveData) = KisCubicCurve(points).toString(); + + std::get<1>(curveData) = QRectF(normalizedCurve.xMin, + -normalizedCurve.yLimit, + normalizedCurve.xMax - normalizedCurve.xMin, + 2.0 * normalizedCurve.yLimit); + + //qDebug() << "set" << std::get<0>(curveData) << "<-" << normalizedCurve.curve << std::get<1>(curveData); + return curveData; + } + ); + +} // namespace + + +using KisWidgetConnectionUtils::ToSpinBoxState; + +MyPaintCurveRangeModel::MyPaintCurveRangeModel(lager::cursor curve, + lager::cursor curveRange, + lager::reader activeSensorId, + lager::reader activeSensorLength, + qreal maxYRange, + const QString &yValueSuffix) + : m_curve(std::move(curve)) + , m_curveRange(std::move(curveRange)) + , m_activeSensorId(std::move(activeSensorId)) + , m_activeSensorLength(std::move(activeSensorLength)) + , m_normalizedCurve(lager::with(m_curve, m_curveRange).zoom(curveToNormalizedCurve)) + , m_maxYRange(maxYRange) + , m_yValueSuffix(yValueSuffix) + , LAGER_QT(yLimit) {m_normalizedCurve[&NormalizedCurve::yLimit]} + , LAGER_QT(xMin) {m_normalizedCurve[&NormalizedCurve::xMin]} + , LAGER_QT(xMax) {m_normalizedCurve[&NormalizedCurve::xMax]} + , LAGER_QT(xMinState) {lager::with(m_normalizedCurve[&NormalizedCurve::xMin], + m_activeSensorId.map(&KisCurveRangeModel::calcXMinValueWithFactory), + lager::make_constant(0.0), + lager::make_constant(true)) + .map(ToSpinBoxState{})} + , LAGER_QT(xMaxState) {lager::with(m_normalizedCurve[&NormalizedCurve::xMax], + lager::make_constant(1.0), + lager::with(m_activeSensorId, m_activeSensorLength) + .map(&KisCurveRangeModel::calcXMaxValueWithFactory), + lager::make_constant(true)) + .map(ToSpinBoxState{})} +{ + +} + +MyPaintCurveRangeModel::~MyPaintCurveRangeModel() +{ + +} + +KisCurveRangeModelFactory MyPaintCurveRangeModel::factory(qreal maxYRange, const QString &yValueSuffix) +{ + return + [maxYRange, yValueSuffix](lager::cursor curve, lager::cursor curveRange, lager::reader activeSensorId, lager::reader activeSensorLength) { + return new MyPaintCurveRangeModel(curve, curveRange, activeSensorId, activeSensorLength, maxYRange, yValueSuffix); + }; +} + +std::tuple MyPaintCurveRangeModel::reshapeCurve(std::tuple curve) +{ + NormalizedCurve normalized = lager::view(curveToNormalizedCurve, curve); + curve = lager::set(curveToNormalizedCurve, curve, normalized); + return curve; +} + +lager::cursor MyPaintCurveRangeModel::curve() +{ + return m_normalizedCurve[&NormalizedCurve::curve]; +} + +lager::reader MyPaintCurveRangeModel::xMinLabel() +{ + return m_normalizedCurve[&NormalizedCurve::xMin].map(formatQRealAsString); +} + +lager::reader MyPaintCurveRangeModel::xMaxLabel() +{ + return m_normalizedCurve[&NormalizedCurve::xMax].map(formatQRealAsString); +} + +lager::reader MyPaintCurveRangeModel::yMinLabel() +{ + return yMinValue().map(formatQRealAsStringWithSuffix(m_yValueSuffix)); +} + +lager::reader MyPaintCurveRangeModel::yMaxLabel() +{ + return yMaxValue().map(formatQRealAsStringWithSuffix(m_yValueSuffix)); +} + +lager::reader MyPaintCurveRangeModel::yMinValue() +{ + return m_normalizedCurve[&NormalizedCurve::yLimit].xform(kiszug::map_mupliply(-1.0)); +} + +lager::reader MyPaintCurveRangeModel::yMaxValue() +{ + return m_normalizedCurve[&NormalizedCurve::yLimit]; +} + +lager::reader MyPaintCurveRangeModel::yValueSuffix() +{ + return lager::make_constant(m_yValueSuffix); +} + +lager::reader MyPaintCurveRangeModel::xMinValue() +{ + return m_normalizedCurve[&NormalizedCurve::xMin]; +} + +lager::reader MyPaintCurveRangeModel::xMaxValue() +{ + return m_normalizedCurve[&NormalizedCurve::xMax]; +} + +lager::reader MyPaintCurveRangeModel::xValueSuffix() +{ + return lager::make_constant(QString()); +} + +qreal MyPaintCurveRangeModel::maxYRange() const +{ + return m_maxYRange; +} diff --git a/plugins/paintops/mypaint/MyPaintCurveRangeModel.h b/plugins/paintops/mypaint/MyPaintCurveRangeModel.h new file mode 100644 index 00000000000..5c921a1444c --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintCurveRangeModel.h @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTCURVERANGEMODEL_H +#define MYPAINTCURVERANGEMODEL_H + +#include +#include +#include +#include + + +class MyPaintCurveRangeModel : public QObject, public KisCurveRangeModelInterface +{ + Q_OBJECT +public: + struct NormalizedCurve { + QString curve; + qreal xMin = 0.0; + qreal xMax = 1.0; + qreal yLimit = 1.0; + }; + +public: + MyPaintCurveRangeModel(lager::cursor curve, + lager::cursor curveRange, + lager::reader activeSensorId, + lager::reader activeSensorLength, + qreal maxYRange, const QString &yValueSuffix); + ~MyPaintCurveRangeModel(); + + lager::cursor curve() override; + lager::reader xMinLabel() override; + lager::reader xMaxLabel() override; + lager::reader yMinLabel() override; + lager::reader yMaxLabel() override; + + lager::reader yMinValue() override; + lager::reader yMaxValue() override; + lager::reader yValueSuffix() override; + + lager::reader xMinValue() override; + lager::reader xMaxValue() override; + lager::reader xValueSuffix() override; + + qreal maxYRange() const; + + static KisCurveRangeModelFactory factory(qreal maxYRange, const QString &yValueSuffix); + + static std::tuple reshapeCurve(std::tuple curve); + +private: + lager::cursor m_curve; + lager::cursor m_curveRange; + lager::reader m_activeSensorId; + lager::reader m_activeSensorLength; + lager::cursor m_normalizedCurve; + const qreal m_maxYRange {0.0}; + const QString m_yValueSuffix; + +public: + LAGER_QT_CURSOR(qreal, yLimit); + LAGER_QT_CURSOR(qreal, xMin); + LAGER_QT_CURSOR(qreal, xMax); + LAGER_QT_READER(DoubleSpinBoxState, xMinState); + LAGER_QT_READER(DoubleSpinBoxState, xMaxState); +}; + +#endif // MYPAINTCURVERANGEMODEL_H diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp index 754e7bb26bf..837a751bf39 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp @@ -17,6 +17,19 @@ #include #include +#include +#include + +struct MyPaintEllipticDabAngle : MyPaintCurveOptionData +{ + MyPaintEllipticDabAngle() + : MyPaintCurveOptionData(KoID("elliptical_dab_angle", + i18n("Elliptical Dab Angle")), + false, true, false, 0.0, 180.0) + { + } +}; + KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) : KisPaintOpSettingsWidget(parent) { @@ -54,11 +67,11 @@ KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) "0", "100"), KisMyPaintOpOption::BASIC); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("elliptical_dab_angle", i18n("Elliptical Dab Angle")), KisPaintOpOption::GENERAL, false, 0.0, 0, 180), - "0", - "100"), + + // TODO: move category into the widget! + addPaintOpOption(kpowu::createOptionWidget(MyPaintEllipticDabAngle(), 180.0, "°"), KisMyPaintOpOption::BASIC); + addPaintOpOption(new KisMyPaintCurveOptionWidget( new KisMyPaintCurveOption(KoID("elliptical_dab_ratio", i18n("Elliptical Dab Ratio")), KisPaintOpOption::GENERAL, false, 1, 1, 10), "0", diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.cpp b/plugins/paintops/mypaint/MyPaintSensorPack.cpp index 6cfb9bee7a3..6acc49b8226 100644 --- a/plugins/paintops/mypaint/MyPaintSensorPack.cpp +++ b/plugins/paintops/mypaint/MyPaintSensorPack.cpp @@ -7,10 +7,51 @@ #include "MyPaintSensorPack.h" #include +#include "KisSensorData.h" #include "kis_assert.h" +#include +#include + +#include +#include +#include +#include +#include + +const QString MYPAINT_JSON = "MyPaint/json"; + namespace detail { +struct MyPaintSensorFactoriesRegistrar { + MyPaintSensorFactoriesRegistrar() { + auto addFactory = [](const KoID &id, + int minimumValue, + int maximumValue, + const QString &minimumLabel, + const QString &maximumLabel, + const QString &valueSuffix) { + KisDynamicSensorFactoryRegistry::instance()->add( + id.id(), + new KisSimpleDynamicSensorFactory(minimumValue, maximumValue, minimumLabel, maximumLabel, valueSuffix)); + }; + + addFactory(MyPaintPressureId, 0, 20, "", "", i18n("")); + addFactory(MyPaintFineSpeedId, -20, 20, "", "", i18n("")); + addFactory(MyPaintGrossSpeedId, -20, 20, "", "", i18n("")); + addFactory(MyPaintRandomId, 0, 1, "", "", i18n("")); + addFactory(MyPaintStrokeId, 0, 1, "", "", i18n("")); + addFactory(MyPaintDirectionId, 0, 180, "", "", i18n("")); + addFactory(MyPaintDeclinationId, 0, 90, "", "", i18n("%")); + addFactory(MyPaintAscensionId, -180, 180, "", "", i18n("%")); + addFactory(MyPaintCustomId, -20, 20, "", "", i18n("%")); + + + } +}; + +static MyPaintSensorFactoriesRegistrar myPaintSensorFactoriesRegistrar; + template , @@ -36,6 +77,59 @@ inline std::vector sensors(Data *data) } // namespace detail +MyPaintSensorDataWithRange::MyPaintSensorDataWithRange(const KoID &id) + : KisSensorData(id) +{ + QVector points; + + if (id == MyPaintPressureId) { + points = {{0,0}, {1,1}}; + } else if (id == MyPaintFineSpeedId) { + points = {{0,0}, {4,1}}; + } else if (id == MyPaintGrossSpeedId) { + points = {{0,0}, {4,1}}; + } else if (id == MyPaintRandomId) { + points = {{0,0}, {1,1}}; + } else if (id == MyPaintStrokeId) { + points = {{0,0}, {1,1}}; + } else if (id == MyPaintDirectionId) { + points = {{0,0}, {180,1}}; + } else if (id == MyPaintDeclinationId) { + points = {{0,0}, {90,1}}; + } else if (id == MyPaintAscensionId) { + points = {{-180,0}, {180,1}}; + } else if (id == MyPaintCustomId) { + points = {{-10,0}, {10,1}}; + } else { + qWarning() << "MyPaintSensorDataWithRange: unknown sensor type:" << id; + points = {{0,0}, {1,1}}; + } + + curve = KisCubicCurve(points).toString(); + curveRange = KisAlgebra2D::accumulateBounds(points); + reshapeCurve(); +} + +QRectF MyPaintSensorDataWithRange::baseCurveRange() const +{ + return curveRange; +} + +void MyPaintSensorDataWithRange::setBaseCurveRange(const QRectF &rect) +{ + curveRange = rect; +} + +void MyPaintSensorDataWithRange::reset() +{ + *this = MyPaintSensorDataWithRange(id); +} + +void MyPaintSensorDataWithRange::reshapeCurve() +{ + std::tie(curve, curveRange) = MyPaintCurveRangeModel::reshapeCurve(std::make_tuple(curve, curveRange)); +} + MyPaintSensorData::MyPaintSensorData() : sensorPressure(MyPaintPressureId), sensorFineSpeed(MyPaintFineSpeedId), @@ -83,13 +177,260 @@ bool MyPaintSensorPack::compare(const KisSensorPackInterface *rhs) const return m_data == pack->m_data; } +MyPaintBrushInput sensorIdToMyPaintBrushInput(const KoID &id) +{ + MyPaintBrushInput result = MYPAINT_BRUSH_INPUT_PRESSURE; + + if (id == MyPaintPressureId) { + result = MYPAINT_BRUSH_INPUT_PRESSURE; + } else if (id == MyPaintFineSpeedId) { + result = MYPAINT_BRUSH_INPUT_SPEED1; + } else if (id == MyPaintGrossSpeedId) { + result = MYPAINT_BRUSH_INPUT_SPEED2; + } else if (id == MyPaintRandomId) { + result = MYPAINT_BRUSH_INPUT_RANDOM; + } else if (id == MyPaintStrokeId) { + result = MYPAINT_BRUSH_INPUT_STROKE; + } else if (id == MyPaintDirectionId) { + result = MYPAINT_BRUSH_INPUT_DIRECTION; + } else if (id == MyPaintDeclinationId) { + result = MYPAINT_BRUSH_INPUT_TILT_DECLINATION; + } else if (id == MyPaintAscensionId) { + result = MYPAINT_BRUSH_INPUT_TILT_ASCENSION; + } else if (id == MyPaintCustomId) { + result = MYPAINT_BRUSH_INPUT_CUSTOM; + } else { + qWarning() << "sensorIdToMyPaintBrushInput: unknown sensor id"; + } + + return result; +} + +QString sensorIdToMyPaintBrushInputJsonKey(const KoID &id) +{ + QString result = "pressure"; + + if (id == MyPaintPressureId) { + result = "pressure"; + } else if (id == MyPaintFineSpeedId) { + result = "speed1"; + } else if (id == MyPaintGrossSpeedId) { + result = "speed2"; + } else if (id == MyPaintRandomId) { + result = "random"; + } else if (id == MyPaintStrokeId) { + result = "stroke"; + } else if (id == MyPaintDirectionId) { + result = "direction"; + } else if (id == MyPaintDeclinationId) { + result = "tilt_declination"; + } else if (id == MyPaintAscensionId) { + result = "tilt_ascension"; + } else if (id == MyPaintCustomId) { + result = "custom"; + } else { + qWarning() << "sensorIdToMyPaintBrushInputJsonKey: unknown sensor id"; + } + + return result; +} + +MyPaintBrushSetting optionIdToMyPaintBrushSettings(const KoID &id) { + if (id.id() == "eraser") + return MYPAINT_BRUSH_SETTING_ERASER; + else if (id.id() == "opaque") + return MYPAINT_BRUSH_SETTING_OPAQUE; + else if (id.id() == "smudge") + return MYPAINT_BRUSH_SETTING_SMUDGE; + else if (id.id() == "color_h") + return MYPAINT_BRUSH_SETTING_COLOR_H; + else if (id.id() == "color_s") + return MYPAINT_BRUSH_SETTING_COLOR_S; + else if (id.id() == "color_v") + return MYPAINT_BRUSH_SETTING_COLOR_V; + else if (id.id() == "colorize") + return MYPAINT_BRUSH_SETTING_COLORIZE; + else if (id.id() == "hardness") + return MYPAINT_BRUSH_SETTING_HARDNESS; + else if (id.id() == "speed1_gamma") + return MYPAINT_BRUSH_SETTING_SPEED1_GAMMA; + else if (id.id() == "speed2_gamma") + return MYPAINT_BRUSH_SETTING_SPEED2_GAMMA; + else if (id.id() == "anti_aliasing") + return MYPAINT_BRUSH_SETTING_ANTI_ALIASING; + else if (id.id() == "restore_color") + return MYPAINT_BRUSH_SETTING_RESTORE_COLOR; + else if (id.id() == "slow_tracking") + return MYPAINT_BRUSH_SETTING_SLOW_TRACKING; + else if (id.id() == "smudge_length") + return MYPAINT_BRUSH_SETTING_SMUDGE_LENGTH; + else if (id.id() == "snap_to_pixel") + return MYPAINT_BRUSH_SETTING_SNAP_TO_PIXEL; + else if (id.id() == "change_color_h") + return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_H; + else if (id.id() == "change_color_l") + return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_L; + else if (id.id() == "change_color_v") + return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_V; + else if (id.id() == "tracking_noise") + return MYPAINT_BRUSH_SETTING_TRACKING_NOISE; + else if (id.id() == "dabs_per_second") + return MYPAINT_BRUSH_SETTING_DABS_PER_SECOND; + else if (id.id() == "offset_by_speed") + return MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED; + else if (id.id() == "opaque_multiply") + return MYPAINT_BRUSH_SETTING_OPAQUE_MULTIPLY; + else if (id.id() == "speed1_slowness") + return MYPAINT_BRUSH_SETTING_SPEED1_SLOWNESS; + else if (id.id() == "speed2_slowness") + return MYPAINT_BRUSH_SETTING_SPEED2_SLOWNESS; + else if (id.id() == "stroke_holdtime") + return MYPAINT_BRUSH_SETTING_STROKE_HOLDTIME; + else if (id.id() == "direction_filter") + return MYPAINT_BRUSH_SETTING_DIRECTION_FILTER; + else if (id.id() == "offset_by_random") + return MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM; + else if (id.id() == "opaque_linearize") + return MYPAINT_BRUSH_SETTING_OPAQUE_LINEARIZE; + else if (id.id() == "radius_by_random") + return MYPAINT_BRUSH_SETTING_RADIUS_BY_RANDOM; + else if (id.id() == "stroke_threshold") + return MYPAINT_BRUSH_SETTING_STROKE_THRESHOLD; + else if (id.id() == "pressure_gain_log") + return MYPAINT_BRUSH_SETTING_PRESSURE_GAIN_LOG; + else if (id.id() == "smudge_radius_log") + return MYPAINT_BRUSH_SETTING_SMUDGE_RADIUS_LOG; + else if (id.id() == "change_color_hsl_s") + return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSL_S; + else if (id.id() == "change_color_hsv_s") + return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSV_S; + else if (id.id() == "radius_logarithmic") + return MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC; + else if (id.id() == "elliptical_dab_angle") + return MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_ANGLE; + else if (id.id() == "elliptical_dab_ratio") + return MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_RATIO; + else if (id.id() == "custom_input_slowness") + return MYPAINT_BRUSH_SETTING_CUSTOM_INPUT_SLOWNESS; + else if (id.id() == "custom_input") + return MYPAINT_BRUSH_SETTING_CUSTOM_INPUT; + else if (id.id() == "dabs_per_basic_radius") + return MYPAINT_BRUSH_SETTING_DABS_PER_BASIC_RADIUS; + else if (id.id() == "slow_tracking_per_dab") + return MYPAINT_BRUSH_SETTING_SLOW_TRACKING_PER_DAB; + else if (id.id() == "dabs_per_actual_radius") + return MYPAINT_BRUSH_SETTING_DABS_PER_ACTUAL_RADIUS; + else if (id.id() == "offset_by_speed_slowness") + return MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED_SLOWNESS; + else if (id.id() == "stroke_duration_logarithmic") + return MYPAINT_BRUSH_SETTING_STROKE_DURATION_LOGARITHMIC; + + return MYPAINT_BRUSH_SETTING_ERASER; +} + bool MyPaintSensorPack::read(KisCurveOptionDataCommon &data, const KisPropertiesConfiguration *setting) const { - // TODO: + data.isChecked = !data.isCheckable || setting->getBool("Pressure" + data.id.id(), false); + + std::vector sensors = data.sensors(); + + // TODO: refactor into library resource + std::unique_ptr + brush(mypaint_brush_new(), &mypaint_brush_unref); + + const MyPaintBrushSetting brushSetting = optionIdToMyPaintBrushSettings(data.id); + mypaint_brush_from_string(brush.get(), setting->getProperty(MYPAINT_JSON).toByteArray()); + + for (auto it = sensors.begin(); it != sensors.end(); ++it) { + const MyPaintBrushInput input = sensorIdToMyPaintBrushInput((*it)->id); + const int numPoints = mypaint_brush_get_mapping_n(brush.get(), brushSetting, input); + + QList points; + for(int i = 0; i < numPoints; i++) { + float x, y; + mypaint_brush_get_mapping_point(brush.get(), brushSetting, input, i, &x, &y); + points << QPointF(qreal(x), qreal(y)); + } + + if (points.size() > 1) { + (*it)->isActive = true; + (*it)->curve = KisCubicCurve(points).toString(); + (*it)->setBaseCurveRange(KisAlgebra2D::accumulateBounds(points)); + dynamic_cast(*it)->reshapeCurve(); + } else { + (*it)->reset(); + } + } + + // At least one sensor needs to be active + if (std::find_if(sensors.begin(), sensors.end(), + std::mem_fn(&KisSensorData::isActive)) == sensors.end()) { + + sensors.front()->isActive = true; + } + + data.strengthValue = qreal(mypaint_brush_get_base_value(brush.get(), brushSetting)); + data.useCurve = setting->getBool(data.id.id() + "UseCurve", true); + + data.useSameCurve = false; // not used in mypaint engine + data.commonCurve = DEFAULT_CURVE_STRING; // not used in mypaint engine + data.curveMode = 0; // not used in mypaint engine + return true; } void MyPaintSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const { - // TODO: -} \ No newline at end of file + setting->setProperty("Pressure" + data.id.id(), data.isChecked || !data.isCheckable); + + QVector activeSensors; + Q_FOREACH(const KisSensorData *sensor, data.sensors()) { + if (sensor->isActive) { + activeSensors.append(sensor); + } + } + + QJsonDocument doc = QJsonDocument::fromJson(setting->getProperty(MYPAINT_JSON).toByteArray()); + QJsonObject brush_json = doc.object(); + QVariantMap map = brush_json.toVariantMap(); + QVariantMap settings_map = map["settings"].toMap(); + QVariantMap name_map = settings_map[data.id.id()].toMap(); + QVariantMap inputs_map = name_map["inputs"].toMap(); + + const std::vector sensors = data.sensors(); + + for (auto it = sensors.begin(); it != sensors.end(); ++it) { + const KisSensorData *sensor = *it; + const QString sensorJsonId = sensorIdToMyPaintBrushInputJsonKey(sensor->id); + + if (!sensor->isActive) { + inputs_map.remove(sensorJsonId); + } else { + KisCubicCurve curve(sensor->curve); + const QList &points = curve.points(); + + QVariantList pointsList; + + Q_FOREACH(const QPointF &pt, points) { + pointsList.push_back(QVariantList{pt.x(), pt.y()}); + } + inputs_map[sensorJsonId] = pointsList; + } + } + + name_map["inputs"] = inputs_map; + name_map["base_value"] = data.strengthValue; + + settings_map[data.id.id()] = name_map; + map["settings"] = settings_map; + + doc = QJsonDocument(QJsonObject::fromVariantMap(map)); + setting->setProperty(MYPAINT_JSON, doc.toJson()); + + setting->setProperty(data.id.id() + "UseCurve", data.useCurve); + + // not used in mypaint engine + setting->setProperty(data.id.id() + "UseSameCurve", false); + setting->setProperty(data.id.id() + "commonCurve", DEFAULT_CURVE_STRING); + setting->setProperty(data.id.id() + "curveMode", 0); +} diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.h b/plugins/paintops/mypaint/MyPaintSensorPack.h index 511b95b6b7b..6d3bc51dcca 100644 --- a/plugins/paintops/mypaint/MyPaintSensorPack.h +++ b/plugins/paintops/mypaint/MyPaintSensorPack.h @@ -12,15 +12,33 @@ #include #include -const KoID MyPaintPressureId("pressure", ki18n("Pressure")); -const KoID MyPaintFineSpeedId("speed1", ki18n("Fine Speed")); -const KoID MyPaintGrossSpeedId("speed2", ki18n("Gross Speed")); -const KoID MyPaintRandomId("random", ki18n("Random")); -const KoID MyPaintStrokeId("stroke", ki18nc("The duration of a brush stroke", "Stroke")); -const KoID MyPaintDirectionId("direction", ki18nc("Drawing Angle", "Direction")); -const KoID MyPaintDeclinationId("tilt_declination", ki18nc("Pen tilt declination", "Declination")); -const KoID MyPaintAscensionId("tilt_ascension", ki18nc("Pen tilt ascension", "Ascension")); -const KoID MyPaintCustomId("custom", ki18n("Custom")); +const KoID MyPaintPressureId("mypaint_pressure", ki18n("Pressure")); +const KoID MyPaintFineSpeedId("mypaint_speed1", ki18n("Fine Speed")); +const KoID MyPaintGrossSpeedId("mypaint_speed2", ki18n("Gross Speed")); +const KoID MyPaintRandomId("mypaint_random", ki18n("Random")); +const KoID MyPaintStrokeId("mypaint_stroke", ki18nc("The duration of a brush stroke", "Stroke")); +const KoID MyPaintDirectionId("mypaint_direction", ki18nc("Drawing Angle", "Direction")); +const KoID MyPaintDeclinationId("mypaint_tilt_declination", ki18nc("Pen tilt declination", "Declination")); +const KoID MyPaintAscensionId("mypaint_tilt_ascension", ki18nc("Pen tilt ascension", "Ascension")); +const KoID MyPaintCustomId("mypaint_custom", ki18n("Custom")); + +struct MyPaintSensorDataWithRange : KisSensorData, boost::equality_comparable +{ + MyPaintSensorDataWithRange(const KoID &id); + + inline friend bool operator==(const MyPaintSensorDataWithRange &lhs, const MyPaintSensorDataWithRange &rhs) { + return lhs.curveRange == rhs.curveRange && + static_cast(lhs) == static_cast(rhs); + } + + QRectF baseCurveRange() const override; + void setBaseCurveRange(const QRectF &rect) override; + void reset() override; + + void reshapeCurve(); + + QRectF curveRange {0,-1,1,2}; +}; struct MyPaintSensorData : boost::equality_comparable { @@ -38,15 +56,15 @@ struct MyPaintSensorData : boost::equality_comparable lhs.sensorCustom == rhs.sensorCustom; } - KisSensorData sensorPressure; - KisSensorData sensorFineSpeed; - KisSensorData sensorGrossSpeed; - KisSensorData sensorRandom; - KisSensorData sensorStroke; - KisSensorData sensorDirection; - KisSensorData sensorDeclination; - KisSensorData sensorAscension; - KisSensorData sensorCustom; + MyPaintSensorDataWithRange sensorPressure; + MyPaintSensorDataWithRange sensorFineSpeed; + MyPaintSensorDataWithRange sensorGrossSpeed; + MyPaintSensorDataWithRange sensorRandom; + MyPaintSensorDataWithRange sensorStroke; + MyPaintSensorDataWithRange sensorDirection; + MyPaintSensorDataWithRange sensorDeclination; + MyPaintSensorDataWithRange sensorAscension; + MyPaintSensorDataWithRange sensorCustom; }; class MyPaintSensorPack : public KisSensorPackInterface @@ -72,4 +90,4 @@ class MyPaintSensorPack : public KisSensorPackInterface MyPaintSensorData m_data; }; -#endif // MYPAINTSENSORPACK_H \ No newline at end of file +#endif // MYPAINTSENSORPACK_H From 2861a28ca1dd851af6d0723c952b555704041023 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 13:21:10 +0300 Subject: [PATCH 06/20] Fix warnings --- plugins/paintops/libpaintop/KisCurveOption2.cpp | 1 - plugins/paintops/libpaintop/KisCurveOption2.h | 1 - plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h | 4 ++-- plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h | 4 ++-- plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h | 2 +- .../paintops/libpaintop/sensors2/KisDynamicSensorDistance2.h | 2 +- plugins/paintops/libpaintop/sensors2/KisDynamicSensorTime2.h | 2 +- plugins/paintops/mypaint/MyPaintPaintOpFactory.h | 2 +- 8 files changed, 8 insertions(+), 10 deletions(-) diff --git a/plugins/paintops/libpaintop/KisCurveOption2.cpp b/plugins/paintops/libpaintop/KisCurveOption2.cpp index 5cc70952170..b9524ccfd5d 100644 --- a/plugins/paintops/libpaintop/KisCurveOption2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOption2.cpp @@ -92,7 +92,6 @@ KisCurveOption2::KisCurveOption2(const KisCurveOptionData &data) : m_isChecked(data.isChecked) , m_useCurve(data.useCurve) , m_curveMode(data.curveMode) - , m_separateCurveValue(data.separateCurveValue) , m_strengthValue(data.strengthValue) , m_strengthMinValue(data.strengthMinValue) , m_strengthMaxValue(data.strengthMaxValue) diff --git a/plugins/paintops/libpaintop/KisCurveOption2.h b/plugins/paintops/libpaintop/KisCurveOption2.h index 9be5ef1a006..18efd4e82f4 100644 --- a/plugins/paintops/libpaintop/KisCurveOption2.h +++ b/plugins/paintops/libpaintop/KisCurveOption2.h @@ -62,7 +62,6 @@ class PAINTOP_EXPORT KisCurveOption2 bool m_isChecked; bool m_useCurve; int m_curveMode; - bool m_separateCurveValue; qreal m_strengthValue; qreal m_strengthMinValue; qreal m_strengthMaxValue; diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h index 86c99869353..b6c521196f8 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryFade.h @@ -14,8 +14,8 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryFade : public KisSimpleDynamicSensor KisDynamicSensorFactoryFade(); QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; - int maximumValue(int length); - QString maximumLabel(int length); + int maximumValue(int length) override; + QString maximumLabel(int length) override; }; #endif // KISDYNAMICSENSORFACTORYFADE_H diff --git a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h index b03f1c97b43..0a41b0ea197 100644 --- a/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h +++ b/plugins/paintops/libpaintop/KisDynamicSensorFactoryTime.h @@ -14,8 +14,8 @@ class PAINTOP_EXPORT KisDynamicSensorFactoryTime : public KisSimpleDynamicSensor KisDynamicSensorFactoryTime(); QWidget* createConfigWidget(lager::cursor data, QWidget*parent) override; - int maximumValue(int length); - QString maximumLabel(int length); + int maximumValue(int length) override; + QString maximumLabel(int length)override; }; #endif // KISDYNAMICSENSORFACTORYTIME_H diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h index 926a8e87d8c..c79d6829f3b 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h +++ b/plugins/paintops/libpaintop/KisMaskingBrushOptionProperties.h @@ -32,7 +32,7 @@ struct PAINTOP_EXPORT MaskingBrushData : public boost::equality_comparable prepareLinkedResources(const KisPaintOpSettingsSP settings, KisResourcesInterfaceSP resourcesInterface) override; QList prepareEmbeddedResources(const KisPaintOpSettingsSP settings, KisResourcesInterfaceSP resourcesInterface) override; - bool lodSizeThresholdSupported() const; + bool lodSizeThresholdSupported() const override; private: From c8d087ab328a104fed4052ab5c3aee66230542cb Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 13:42:56 +0300 Subject: [PATCH 07/20] Delete old range controls from KisCurveOptionWidget2 --- .../libpaintop/KisCurveOptionWidget2.cpp | 15 -- .../libpaintop/KisCurveOptionWidget2.h | 1 - .../libpaintop/forms/wdgcurveoption2.ui | 148 +++++------------- 3 files changed, 36 insertions(+), 128 deletions(-) diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index f7a4c2fb7aa..63f33f5b410 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -150,7 +150,6 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorcurveMinValue = curveMinValue; m_d->curveMaxValue = curveMaxValue; @@ -375,17 +374,3 @@ void KisCurveOptionWidget2::updateThemedIcons() m_curveOptionWidget->sensorSelector->setPalette(newPalette); } - -void KisCurveOptionWidget2::hideRangeLabelsAndBoxes(bool isHidden) { - - m_curveOptionWidget->xMaxBox->setHidden(isHidden); - m_curveOptionWidget->xMinBox->setHidden(isHidden); - m_curveOptionWidget->yMaxBox->setHidden(isHidden); - m_curveOptionWidget->yMinBox->setHidden(isHidden); - - m_curveOptionWidget->xRangeLabel->setHidden(isHidden); - m_curveOptionWidget->yRangeLabel->setHidden(isHidden); - m_curveOptionWidget->toLabel1->setHidden(isHidden); - m_curveOptionWidget->toLabel2->setHidden(isHidden); - -} diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index 15f063b0e78..ed638e01d5a 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -104,7 +104,6 @@ protected Q_SLOTS: QComboBox* m_curveMode {nullptr}; struct Private; const QScopedPointer m_d; - void hideRangeLabelsAndBoxes(bool isHidden); }; #endif // KISCURVEOPTIONWIDGET2_H diff --git a/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui b/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui index 136ad3b4b1d..4c5d51d417b 100644 --- a/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui +++ b/plugins/paintops/libpaintop/forms/wdgcurveoption2.ui @@ -249,107 +249,8 @@ - - - - Qt::Vertical - - - - 20 - 60 - - - - - - - - - X Range: - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - To - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - - - - Y Range: - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - To - - - - - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - - Qt::Horizontal - - - - 13 - 13 - - - + @@ -509,16 +410,6 @@ - - - - Share curve across all settings - - - true - - - @@ -580,8 +471,41 @@ - - + + + + Qt::Vertical + + + + 20 + 60 + + + + + + + + Qt::Horizontal + + + + 13 + 13 + + + + + + + + Share curve across all settings + + + true + + From bd3f7e5d5628067b78cfca02aa3917684e25c4f2 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 14:36:40 +0300 Subject: [PATCH 08/20] Fix minor issues in MyPaint's curve widget 1) Hide "Use same curve" option. It is not supported. 2) Hide "Curve mode" option. It is not supported. 3) Fix scaling of the strength slider. It is not "percents" in MyPaint widget. --- .../libpaintop/KisCurveOptionModel.cpp | 19 ++-- .../paintops/libpaintop/KisCurveOptionModel.h | 5 +- .../libpaintop/KisCurveOptionWidget2.cpp | 104 +++++++++--------- .../libpaintop/KisCurveOptionWidget2.h | 48 +++++--- .../mypaint/MyPaintCurveOptionWidget2.cpp | 4 +- 5 files changed, 100 insertions(+), 80 deletions(-) diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp index c4a46154e2b..6ca48762b95 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.cpp @@ -106,10 +106,11 @@ int calcActiveSensorLength(const KisCurveOptionDataCommon &data, const QString & KisCurveOptionModel::KisCurveOptionModel(lager::cursor _optionData, lager::reader externallyEnabled, - std::optional> rangeOverride, + std::optional> strengthRangeOverride, + qreal strengthDisplayMultiplier, KisCurveRangeModelFactory rangeModelFactory) : optionData(_optionData) - , rangeNorm(rangeOverride ? *rangeOverride : + , strengthRangeNorm(strengthRangeOverride ? *strengthRangeOverride : lager::with(optionData[&KisCurveOptionDataCommon::strengthMinValue], optionData[&KisCurveOptionDataCommon::strengthMaxValue])) , activeSensorIdData(optionData->sensors().front()->id.id()) @@ -117,18 +118,18 @@ KisCurveOptionModel::KisCurveOptionModel(lager::cursor , LAGER_QT(isChecked) {optionData[&KisCurveOptionDataCommon::isChecked]} , LAGER_QT(effectiveIsChecked) {lager::with(LAGER_QT(isChecked), externallyEnabled).map(std::logical_and{})} , LAGER_QT(effectiveStrengthValueNorm) { - lager::with(rangeNorm.zoom(lager::lenses::first), + lager::with(strengthRangeNorm.zoom(lager::lenses::first), optionData[&KisCurveOptionDataCommon::strengthValue], - rangeNorm.zoom(lager::lenses::second)) + strengthRangeNorm.zoom(lager::lenses::second)) .map(&qBound)} , LAGER_QT(strengthValueDenorm) { optionData[&KisCurveOptionDataCommon::strengthValue] - .zoom(kiszug::lenses::scale(100.0))} + .zoom(kiszug::lenses::scale(strengthDisplayMultiplier))} , LAGER_QT(effectiveStrengthStateDenorm) { lager::with(LAGER_QT(effectiveStrengthValueNorm), - rangeNorm.zoom(lager::lenses::first), - rangeNorm.zoom(lager::lenses::second)) - .xform(kiszug::foreach_arg(kiszug::map_mupliply(100.0)))} + strengthRangeNorm.zoom(lager::lenses::first), + strengthRangeNorm.zoom(lager::lenses::second)) + .xform(kiszug::foreach_arg(kiszug::map_mupliply(strengthDisplayMultiplier)))} , LAGER_QT(useCurve) {optionData[&KisCurveOptionDataCommon::useCurve]} , LAGER_QT(useSameCurve) {optionData[&KisCurveOptionDataCommon::useSameCurve]} , LAGER_QT(curveMode) {optionData[&KisCurveOptionDataCommon::curveMode]} @@ -161,7 +162,7 @@ KisCurveOptionDataCommon KisCurveOptionModel::bakedOptionData() const KisCurveOptionDataCommon data = optionData.get(); data.isChecked = effectiveIsChecked(); std::tie(data.strengthMinValue, data.strengthMaxValue) = - rangeNorm.get(); + strengthRangeNorm.get(); data.strengthValue = effectiveStrengthValueNorm(); return data; } diff --git a/plugins/paintops/libpaintop/KisCurveOptionModel.h b/plugins/paintops/libpaintop/KisCurveOptionModel.h index 9b8d7c7db02..89cbf7f9723 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionModel.h +++ b/plugins/paintops/libpaintop/KisCurveOptionModel.h @@ -26,13 +26,14 @@ class PAINTOP_EXPORT KisCurveOptionModel : public QObject public: KisCurveOptionModel(lager::cursor optionData, lager::reader externallyEnabled, - std::optional> rangeOverride, + std::optional> strengthRangeOverride, + qreal strengthDisplayMultiplier, KisCurveRangeModelFactory rangeModelFactory); ~KisCurveOptionModel(); // the state must be declared **before** any cursors or readers lager::cursor optionData; - lager::reader rangeNorm; + lager::reader strengthRangeNorm; lager::state activeSensorIdData; LAGER_QT_READER(bool, isCheckable); LAGER_QT_CURSOR(bool, isChecked); diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index 63f33f5b410..f134470af4e 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -28,33 +28,24 @@ struct KisCurveOptionWidget2::Private { Private(lager::cursor optionData, lager::reader enabledLink, - std::optional>> rangeReader, + std::optional>> strengthRangeReader, + qreal strengthDisplayMultiplier, KisCurveRangeModelFactory curveRangeFactory) - : model(optionData, enabledLink, rangeReader, curveRangeFactory) + : model(optionData, enabledLink, strengthRangeReader, strengthDisplayMultiplier, curveRangeFactory) {} KisCurveOptionModel model; - - int curveMinValue; - int curveMaxValue; - QString curveValueSuffix; }; KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, PaintopCategory category, lager::reader enabledLink, - std::optional>> rangeReader, - KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) + std::optional>> strengthRangeReader) : KisCurveOptionWidget2(optionData, category, i18n("0%"), i18n("100%"), enabledLink, - rangeReader, - curveRangeFactory, - inputControlsFactory, - rangeControlsFactory) + strengthRangeReader) { } @@ -62,20 +53,13 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader, - KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) + std::optional>> strengthRangeReader) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, 0, 100, i18n("%"), - i18n("Strength: "), i18n("%"), enabledLink, - rangeReader, - curveRangeFactory, - inputControlsFactory, - rangeControlsFactory) + strengthRangeReader) { } @@ -85,20 +69,14 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader, - KisCurveRangeModelFactory curveRangeFactory, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) + std::optional>> strengthRangeReader) : KisCurveOptionWidget2(optionData, category, curveMinLabel, curveMaxLabel, curveMinValue, curveMaxValue, curveValueSuffix, - i18n("Strength: "), i18n("%"), + i18n("Strength: "), i18n("%"), 100.0, enabledLink, - rangeReader, - curveRangeFactory, - inputControlsFactory, - rangeControlsFactory) + strengthRangeReader) { } @@ -107,22 +85,41 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor enabledLink, - std::optional>> rangeReader, - KisCurveRangeModelFactory curveRangeFactory, + std::optional>> strengthRangeReader) + : KisCurveOptionWidget2(optionData, + category, + strengthPrefix, strengthSuffix, strengthDisplayMultiplier, + enabledLink, + strengthRangeReader, + KisCurveRangeModel::factory(curveMinLabel, + curveMaxLabel, + curveMinValue, + curveMaxValue, + curveValueSuffix), + KisCurveOptionInputControlsStrategyInt::factory(), + {}, + SupportsCommonCurve | SupportsCurveMode) +{ +} + +KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursor optionData, + PaintopCategory category, + const QString &strengthPrefix, const QString &strengthSuffix, + qreal strengthDisplayMultiplier, + lager::reader enabledLink, + std::optional>> strengthRangeReader, + KisCurveRangeModelFactory curveRangeModelFactory, KisCurveOptionInputControlsStrategyFactory inputControlsFactory, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory) + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory, + Flags flags) : KisPaintOpOption(optionData->id.name(), category, optionData[&KisCurveOptionDataCommon::isChecked], enabledLink) , m_widget(new QWidget) , m_curveOptionWidget(new Ui_WdgCurveOption2()) - , m_d(new Private(optionData, enabledLink, rangeReader, - curveRangeFactory ? - curveRangeFactory : - KisCurveRangeModel::factory(curveMinLabel, - curveMaxLabel, - curveMinValue, - curveMaxValue, - curveValueSuffix))) + , m_d(new Private(optionData, enabledLink, strengthRangeReader, + strengthDisplayMultiplier, + curveRangeModelFactory)) { using namespace KisWidgetConnectionUtils; @@ -131,7 +128,7 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorsetupUi(m_widget); m_curveOptionWidget->sensorSelector->setOptionDataCursor(m_d->model.optionData); - if (!inputControlsFactory) { + KIS_SAFE_ASSERT_RECOVER (inputControlsFactory) { inputControlsFactory = KisCurveOptionInputControlsStrategyInt::factory(); } @@ -151,10 +148,6 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorcurveMinValue = curveMinValue; - m_d->curveMaxValue = curveMaxValue; - m_d->curveValueSuffix = curveValueSuffix; - connect(&m_d->model, &KisCurveOptionModel::curveXMinLabelChanged, m_curveOptionWidget->label_xmin, &QLabel::setText); m_curveOptionWidget->label_xmin->setText(m_d->model.curveXMinLabel()); @@ -217,8 +210,19 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursormodel.LAGER_QT(useCurve).bind(std::bind(&KisCurveOptionWidget2::setCurveWidgetsEnabled, this, std::placeholders::_1)); connectControl(m_curveOptionWidget->checkBoxUseCurve, &m_d->model, "useCurve"); - connectControl(m_curveOptionWidget->checkBoxUseSameCurve, &m_d->model, "useSameCurve"); - connectControl(m_curveOptionWidget->curveMode, &m_d->model, "curveMode"); + + if (flags & SupportsCommonCurve) { + connectControl(m_curveOptionWidget->checkBoxUseSameCurve, &m_d->model, "useSameCurve"); + } else { + m_curveOptionWidget->checkBoxUseSameCurve->setVisible(false); + } + + if (flags & SupportsCurveMode) { + connectControl(m_curveOptionWidget->curveMode, &m_d->model, "curveMode"); + } else { + m_curveOptionWidget->curveMode->setVisible(false); + m_curveOptionWidget->lblCurveMode->setVisible(false); + } m_d->model.optionData.bind(std::bind(&KisCurveOptionWidget2::emitSettingChanged, this)); } diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index ed638e01d5a..8f0cb2ceeac 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -24,48 +24,58 @@ class QComboBox; class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption { Q_OBJECT +public: + enum Flag { + None = 0x0, + SupportsCommonCurve = 0x1, + SupportsCurveMode = 0x2 + }; + + Q_DECLARE_FLAGS(Flags, Flag) + public: using data_type = KisCurveOptionDataCommon; KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt, - KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); + std::optional>> strengthRangeReader = std::nullopt); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt, - KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); + std::optional>> strengthRangeReader = std::nullopt); KisCurveOptionWidget2(lager::cursor optionData, KisPaintOpOption::PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt, - KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); -private: + std::optional>> strengthRangeReader = std::nullopt); + KisCurveOptionWidget2(lager::cursor optionData, - KisPaintOpOption::PaintopCategory category, + PaintopCategory category, const QString &curveMinLabel, const QString &curveMaxLabel, int curveMinValue, int curveMaxValue, const QString &curveValueSuffix, const QString &strengthPrefix, const QString &strengthSuffix, + qreal strengthDisplayMultiplier, lager::reader enabledLink = lager::make_constant(true), - std::optional>> rangeReader = std::nullopt, - KisCurveRangeModelFactory curveRangeFactory = {}, - KisCurveOptionInputControlsStrategyFactory inputControlsFactory = {}, - KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory = {}); + std::optional>> strengthRangeReader = std::nullopt); +protected: + KisCurveOptionWidget2(lager::cursor optionData, + KisPaintOpOption::PaintopCategory category, + const QString &strengthPrefix, const QString &strengthSuffix, + qreal strengthDisplayMultiplier, + lager::reader enabledLink, + std::optional>> strengthRangeReader, + KisCurveRangeModelFactory curveRangeModelFactory, + KisCurveOptionInputControlsStrategyFactory inputControlsFactory, + KisCurveOptionRangeControlsStrategyFactory rangeControlsFactory, + Flags flags); public: + ~KisCurveOptionWidget2() override; void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; @@ -106,4 +116,6 @@ protected Q_SLOTS: const QScopedPointer m_d; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(KisCurveOptionWidget2::Flags) + #endif // KISCURVEOPTIONWIDGET2_H diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp index c102a0a38f0..633da31d466 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp @@ -16,11 +16,13 @@ MyPaintCurveOptionWidget2::MyPaintCurveOptionWidget2(lager::cursor), KisPaintOpOption::GENERAL, + i18n("Base Value: "), yValueSuffix, 1.0, lager::make_constant(true), std::nullopt, MyPaintCurveRangeModel::factory(maxYRange, yValueSuffix), KisCurveOptionInputControlsStrategyDouble::factory(), - MyPaintCurveOptionRangeControlsStrategy::factory()) + MyPaintCurveOptionRangeControlsStrategy::factory(), + None) { } From 85ac459a3998faca9cffc45de2cf222a8de7ff44 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 14:44:54 +0300 Subject: [PATCH 09/20] Make sure x-limit of MyPaint curves is in supported range Krita doesn't support ranges more narrow than 0...1 due to control dependencies problems. --- plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp b/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp index 756214abe75..478dba73799 100644 --- a/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveRangeModel.cpp @@ -121,6 +121,12 @@ KisCurveRangeModelFactory MyPaintCurveRangeModel::factory(qreal maxYRange, const std::tuple MyPaintCurveRangeModel::reshapeCurve(std::tuple curve) { + /** + * Krita's GUI doesn't support x-range more narrow than 0...1, so + * we should extend it if necessary + */ + std::get<1>(curve) |= QRect(0, -1, 1, 2); + NormalizedCurve normalized = lager::view(curveToNormalizedCurve, curve); curve = lager::set(curveToNormalizedCurve, curve, normalized); return curve; From d9616be3f17db960049a79ba00eb60a10095b192 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 14:56:32 +0300 Subject: [PATCH 10/20] Remove separateCurveValue member of KisCurveOptionData It is not used anymore --- plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp | 2 +- plugins/paintops/curvebrush/KisCurveStandardOptionData.h | 4 ++-- plugins/paintops/libpaintop/KisCurveOptionData.cpp | 5 +---- plugins/paintops/libpaintop/KisCurveOptionData.h | 4 +--- plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp | 7 +++---- plugins/paintops/libpaintop/KisCurveOptionDataCommon.h | 4 ---- plugins/paintops/libpaintop/KisScatterOptionData.cpp | 2 +- plugins/paintops/libpaintop/KisStandardOptionData.h | 2 +- plugins/paintops/mypaint/MyPaintCurveOptionData.cpp | 7 ++----- plugins/paintops/mypaint/MyPaintCurveOptionData.h | 4 +--- plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp | 2 +- 11 files changed, 14 insertions(+), 29 deletions(-) diff --git a/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp b/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp index 747eb462225..c6a820b128e 100644 --- a/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp +++ b/plugins/paintops/colorsmudge/KisSmudgeRadiusOptionData.cpp @@ -9,7 +9,7 @@ KisSmudgeRadiusOptionData::KisSmudgeRadiusOptionData() : KisCurveOptionData( KoID("SmudgeRadius", i18n("Smudge Radius")), - true, false, false, + true, false, 0.0, 3.0) { valueFixUpReadCallback = [] (KisCurveOptionDataCommon *data, const KisPropertiesConfiguration *setting) { diff --git a/plugins/paintops/curvebrush/KisCurveStandardOptionData.h b/plugins/paintops/curvebrush/KisCurveStandardOptionData.h index 68d3a7d1c92..4e2ca5d4ac6 100644 --- a/plugins/paintops/curvebrush/KisCurveStandardOptionData.h +++ b/plugins/paintops/curvebrush/KisCurveStandardOptionData.h @@ -13,7 +13,7 @@ struct KisLineWidthOptionData : KisCurveOptionData KisLineWidthOptionData() : KisCurveOptionData( KoID("Line width", i18n("Line width")), - true, false, false, + true, false, 0.1, 1.0) {} }; @@ -23,7 +23,7 @@ struct KisCurvesOpacityOptionData : KisCurveOptionData KisCurvesOpacityOptionData() : KisCurveOptionData( KoID("Curves opacity", i18n("Curves opacity")), - true, false, false, + true, false, 0.1, 1.0) {} }; diff --git a/plugins/paintops/libpaintop/KisCurveOptionData.cpp b/plugins/paintops/libpaintop/KisCurveOptionData.cpp index 114dc08d85c..4d0dc9651a3 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionData.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionData.cpp @@ -10,14 +10,12 @@ KisCurveOptionData::KisCurveOptionData(const QString &prefix, const KoID &id, bool isCheckable, bool isChecked, - bool separateCurveValue, qreal minValue, qreal maxValue) : KisCurveOptionDataCommon(prefix, id, isCheckable, isChecked, - separateCurveValue, minValue, maxValue, new KisKritaSensorPack()) @@ -27,10 +25,9 @@ KisCurveOptionData::KisCurveOptionData(const QString &prefix, KisCurveOptionData::KisCurveOptionData(const KoID &id, bool isCheckable, bool isChecked, - bool separateCurveValue, qreal minValue, qreal maxValue) - : KisCurveOptionData("", id, isCheckable, isChecked, separateCurveValue, minValue, maxValue) + : KisCurveOptionData("", id, isCheckable, isChecked, minValue, maxValue) { } diff --git a/plugins/paintops/libpaintop/KisCurveOptionData.h b/plugins/paintops/libpaintop/KisCurveOptionData.h index e8799f58099..20dd6ab34ab 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionData.h +++ b/plugins/paintops/libpaintop/KisCurveOptionData.h @@ -17,14 +17,12 @@ struct PAINTOP_EXPORT KisCurveOptionData : KisCurveOptionDataCommon const KoID &id, bool isCheckable = true, bool isChecked = false, - bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); KisCurveOptionData(const KoID &id, bool isCheckable = true, bool isChecked = false, - bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); @@ -32,4 +30,4 @@ struct PAINTOP_EXPORT KisCurveOptionData : KisCurveOptionDataCommon const KisKritaSensorData& sensorStruct() const; }; -#endif // KISCURVEOPTIONDATA_H \ No newline at end of file +#endif // KISCURVEOPTIONDATA_H diff --git a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp index 1bf6e29039b..ca06c56d9c2 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.cpp @@ -6,11 +6,10 @@ #include "KisCurveOptionDataCommon.h" #include "KisSensorPackInterface.h" -KisCurveOptionDataCommon::KisCurveOptionDataCommon(const QString &_prefix, const KoID &_id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) +KisCurveOptionDataCommon::KisCurveOptionDataCommon(const QString &_prefix, const KoID &_id, bool _isCheckable, bool _isChecked, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) : id(_id), prefix(_prefix), isCheckable(_isCheckable), - separateCurveValue(_separateCurveValue), strengthMinValue(_minValue), strengthMaxValue(_maxValue), isChecked(_isChecked), @@ -19,8 +18,8 @@ KisCurveOptionDataCommon::KisCurveOptionDataCommon(const QString &_prefix, const { } -KisCurveOptionDataCommon::KisCurveOptionDataCommon(const KoID &_id, bool _isCheckable, bool _isChecked, bool _separateCurveValue, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) - : KisCurveOptionDataCommon("", _id, _isCheckable, _isChecked, _separateCurveValue, _minValue, _maxValue, sensorInterface) +KisCurveOptionDataCommon::KisCurveOptionDataCommon(const KoID &_id, bool _isCheckable, bool _isChecked, qreal _minValue, qreal _maxValue, KisSensorPackInterface *sensorInterface) + : KisCurveOptionDataCommon("", _id, _isCheckable, _isChecked, _minValue, _maxValue, sensorInterface) { } diff --git a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h index e307e0666bd..82f8a0544f4 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h +++ b/plugins/paintops/libpaintop/KisCurveOptionDataCommon.h @@ -24,7 +24,6 @@ struct PAINTOP_EXPORT KisCurveOptionDataCommon : boost::equality_comparable(prefix, KoID("Scatter", i18n("Scatter")), - true, false, false, 0.0, 5.0) + true, false, 0.0, 5.0) { valueFixUpReadCallback = [] (KisCurveOptionDataCommon *data, const KisPropertiesConfiguration *setting) { diff --git a/plugins/paintops/libpaintop/KisStandardOptionData.h b/plugins/paintops/libpaintop/KisStandardOptionData.h index ef439cb9cf6..76604909c76 100644 --- a/plugins/paintops/libpaintop/KisStandardOptionData.h +++ b/plugins/paintops/libpaintop/KisStandardOptionData.h @@ -48,7 +48,7 @@ struct KisSoftnessOptionData : KisCurveOptionData KisSoftnessOptionData() : KisCurveOptionData( KoID("Softness", i18n("Softness")), - true, false, false, + true, false, 0.1, 1.0) {} }; diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp index 6c1a90ec5d8..f1dc63860b3 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp @@ -10,14 +10,12 @@ MyPaintCurveOptionData::MyPaintCurveOptionData(const QString &prefix, const KoID &id, bool isCheckable, bool isChecked, - bool separateCurveValue, qreal minValue, qreal maxValue) : KisCurveOptionDataCommon(prefix, id, isCheckable, isChecked, - separateCurveValue, minValue, maxValue, new MyPaintSensorPack()) @@ -27,10 +25,9 @@ MyPaintCurveOptionData::MyPaintCurveOptionData(const QString &prefix, MyPaintCurveOptionData::MyPaintCurveOptionData(const KoID &id, bool isCheckable, bool isChecked, - bool separateCurveValue, qreal minValue, qreal maxValue) - : MyPaintCurveOptionData("", id, isCheckable, isChecked, separateCurveValue, minValue, maxValue) + : MyPaintCurveOptionData("", id, isCheckable, isChecked, minValue, maxValue) { } @@ -42,4 +39,4 @@ MyPaintSensorData &MyPaintCurveOptionData::sensorStruct() const MyPaintSensorData &MyPaintCurveOptionData::sensorStruct() const { return dynamic_cast(sensorData.constData())->constSensorsStruct(); -} \ No newline at end of file +} diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.h b/plugins/paintops/mypaint/MyPaintCurveOptionData.h index 5449d107dd5..aebca59d55c 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionData.h +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.h @@ -17,14 +17,12 @@ struct MyPaintCurveOptionData : KisCurveOptionDataCommon const KoID &id, bool isCheckable = true, bool isChecked = false, - bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); MyPaintCurveOptionData(const KoID &id, bool isCheckable = true, bool isChecked = false, - bool separateCurveValue = false, qreal minValue = 0.0, qreal maxValue = 1.0); @@ -32,4 +30,4 @@ struct MyPaintCurveOptionData : KisCurveOptionDataCommon const MyPaintSensorData& sensorStruct() const; }; -#endif // MYPAINTCURVEOPTIONDATA_H \ No newline at end of file +#endif // MYPAINTCURVEOPTIONDATA_H diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp index 837a751bf39..1db7256c850 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp @@ -25,7 +25,7 @@ struct MyPaintEllipticDabAngle : MyPaintCurveOptionData MyPaintEllipticDabAngle() : MyPaintCurveOptionData(KoID("elliptical_dab_angle", i18n("Elliptical Dab Angle")), - false, true, false, 0.0, 180.0) + false, true, 0.0, 180.0) { } }; From d064e0e6b18767255af0fe609cc13da4f65bc3c5 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 17:04:58 +0300 Subject: [PATCH 11/20] Port all mypaint option widgets into the lager framework! --- .../libpaintop/KisCurveOptionWidget2.cpp | 15 +- .../libpaintop/KisCurveOptionWidget2.h | 4 +- plugins/paintops/mypaint/CMakeLists.txt | 3 + .../mypaint/MyPaintBasicOptionData.cpp | 21 + .../paintops/mypaint/MyPaintBasicOptionData.h | 27 + .../mypaint/MyPaintBasicOptionModel.cpp | 19 + .../mypaint/MyPaintBasicOptionModel.h | 30 + .../mypaint/MyPaintBasicOptionWidget.cpp | 76 ++ .../mypaint/MyPaintBasicOptionWidget.h | 33 + .../mypaint/MyPaintCurveOptionWidget2.cpp | 2 +- .../mypaint/MyPaintCurveOptionWidget2.h | 2 + .../paintops/mypaint/MyPaintPaintOpOption.cpp | 2 +- .../mypaint/MyPaintPaintOpSettingsWidget.cpp | 703 +++++++++++------- .../mypaint/MyPaintPaintOpSettingsWidget.h | 20 +- 14 files changed, 676 insertions(+), 281 deletions(-) create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionData.cpp create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionData.h create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionModel.cpp create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionModel.h create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionWidget.cpp create mode 100644 plugins/paintops/mypaint/MyPaintBasicOptionWidget.h diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp index f134470af4e..989000aa269 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.cpp @@ -191,10 +191,16 @@ KisCurveOptionWidget2::KisCurveOptionWidget2(lager::cursorstrengthSlider, qOverload(&KisDoubleSliderSpinBox::valueChanged), &m_d->model, &KisCurveOptionModel::setstrengthValueDenorm); + const bool useFloatingPointStrength = flags & UseFloatingPointStrength; + + if (useFloatingPointStrength) { + m_curveOptionWidget->strengthSlider->setSingleStep(0.01); + } + m_d->model.LAGER_QT(effectiveStrengthStateDenorm).bind( - kismpl::unzip_wrapper([this] (qreal value, qreal min, qreal max) { + kismpl::unzip_wrapper([this, useFloatingPointStrength] (qreal value, qreal min, qreal max) { KisSignalsBlocker b(m_curveOptionWidget->strengthSlider); - m_curveOptionWidget->strengthSlider->setRange(min, max); + m_curveOptionWidget->strengthSlider->setRange(min, max, useFloatingPointStrength ? 2 : 0); m_curveOptionWidget->strengthSlider->setValue(value); })); @@ -249,6 +255,11 @@ bool KisCurveOptionWidget2::isCheckable() const return m_d->model.isCheckable(); } +lager::cursor KisCurveOptionWidget2::strengthValueDenorm() +{ + return m_d->model.LAGER_QT(strengthValueDenorm); +} + void KisCurveOptionWidget2::setCurveWidgetsEnabled(bool value) { m_curveOptionWidget->checkBoxUseSameCurve->setEnabled(value); diff --git a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h index 8f0cb2ceeac..7f5fcacb35a 100644 --- a/plugins/paintops/libpaintop/KisCurveOptionWidget2.h +++ b/plugins/paintops/libpaintop/KisCurveOptionWidget2.h @@ -28,7 +28,8 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption enum Flag { None = 0x0, SupportsCommonCurve = 0x1, - SupportsCurveMode = 0x2 + SupportsCurveMode = 0x2, + UseFloatingPointStrength = 0x4, }; Q_DECLARE_FLAGS(Flags, Flag) @@ -85,6 +86,7 @@ class PAINTOP_EXPORT KisCurveOptionWidget2 : public KisPaintOpOption void show(); protected: + lager::cursor strengthValueDenorm(); void setCurveWidgetsEnabled(bool value); QWidget* curveWidget(); diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index 24259b5f9d3..c9aa52684fa 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -11,6 +11,9 @@ set(kritamypaintop_SOURCES MyPaintCurveRangeModel.cpp MyPaintCurveOptionRangeControlsStrategy.cpp MyPaintPaintOp.cpp + MyPaintBasicOptionData.cpp + MyPaintBasicOptionModel.cpp + MyPaintBasicOptionWidget.cpp MyPaintPaintOpOption.cpp MyPaintPaintOpSettings.cpp MyPaintPaintOpSettingsWidget.cpp diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionData.cpp b/plugins/paintops/mypaint/MyPaintBasicOptionData.cpp new file mode 100644 index 00000000000..abd322d6bcf --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionData.cpp @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "MyPaintBasicOptionData.h" + +#include + +bool MyPaintBasicOptionData::read(const KisPropertiesConfiguration *setting) +{ + eraserMode = setting->getBool("EraserMode", false); + + return true; +} + +void MyPaintBasicOptionData::write(KisPropertiesConfiguration *setting) const +{ + setting->setProperty("EraserMode", eraserMode); +} diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionData.h b/plugins/paintops/mypaint/MyPaintBasicOptionData.h new file mode 100644 index 00000000000..9bdfaeef99e --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionData.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef MYPAINTBASICOPTIONDATA_H +#define MYPAINTBASICOPTIONDATA_H + +#include "kis_types.h" +#include + +class KisPropertiesConfiguration; + +struct MyPaintBasicOptionData : boost::equality_comparable +{ + inline friend bool operator==(const MyPaintBasicOptionData &lhs, const MyPaintBasicOptionData &rhs) { + return lhs.eraserMode == rhs.eraserMode; + } + + bool eraserMode {false}; + + bool read(const KisPropertiesConfiguration *setting); + void write(KisPropertiesConfiguration *setting) const; +}; + +#endif // MYPAINTBASICOPTIONDATA_H diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionModel.cpp b/plugins/paintops/mypaint/MyPaintBasicOptionModel.cpp new file mode 100644 index 00000000000..5d410992f6f --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionModel.cpp @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "MyPaintBasicOptionModel.h" + + +MyPaintBasicOptionModel::MyPaintBasicOptionModel(lager::cursor _optionData, + lager::cursor radiusCursor, + lager::cursor hardnessCursor, + lager::cursor opacityCursor) + : optionData(_optionData) + , LAGER_QT(eraserMode) {optionData[&MyPaintBasicOptionData::eraserMode]} + , LAGER_QT(radius) {radiusCursor} + , LAGER_QT(hardness) {hardnessCursor} + , LAGER_QT(opacity) {opacityCursor} +{ +} diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionModel.h b/plugins/paintops/mypaint/MyPaintBasicOptionModel.h new file mode 100644 index 00000000000..8bdd99e60ca --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionModel.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef MYPAINTBASICOPTIONMODEL_H +#define MYPAINTBASICOPTIONMODEL_H + +#include +#include + +#include "MyPaintBasicOptionData.h" + +class MyPaintBasicOptionModel : public QObject +{ + Q_OBJECT +public: + MyPaintBasicOptionModel(lager::cursor optionData, + lager::cursor radiusCursor, + lager::cursor hardnessCursor, + lager::cursor opacityCursor); + lager::cursor optionData; + + LAGER_QT_CURSOR(bool, eraserMode); + LAGER_QT_CURSOR(qreal, radius); + LAGER_QT_CURSOR(qreal, hardness); + LAGER_QT_CURSOR(qreal, opacity); +}; + +#endif // MYPAINTBASICOPTIONMODEL_H diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionWidget.cpp b/plugins/paintops/mypaint/MyPaintBasicOptionWidget.cpp new file mode 100644 index 00000000000..58be8086ae1 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionWidget.cpp @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "MyPaintBasicOptionWidget.h" + +#include "KisWidgetConnectionUtils.h" + +#include "MyPaintBasicOptionModel.h" +#include "ui_wdgmypaintoptions.h" + + +struct MyPaintBasicOptionWidget::Private +{ + Private(lager::cursor optionData, + lager::cursor radiusCursor, + lager::cursor hardnessCursor, + lager::cursor opacityCursor) + : model(optionData, radiusCursor, hardnessCursor, opacityCursor) + { + } + + MyPaintBasicOptionModel model; +}; + +MyPaintBasicOptionWidget::MyPaintBasicOptionWidget(lager::cursor optionData, + lager::cursor radiusCursor, + lager::cursor hardnessCursor, + lager::cursor opacityCursor) + : KisPaintOpOption(i18nc("MyPaint option name", "Basic"), KisPaintOpOption::GENERAL, true), + m_d(new Private(optionData, radiusCursor, hardnessCursor, opacityCursor)) +{ + using namespace KisWidgetConnectionUtils; + m_checkable = false; + + setObjectName("KisCompositeOpOption"); + + QWidget* widget = new QWidget(); + + Ui::WdgMyPaintOptions ui; + ui.setupUi(widget); + + ui.radiusSPBox->setRange(0.01, 8.0, 2); + ui.radiusSPBox->setSingleStep(0.01); + + ui.hardnessSPBox->setRange(0.02, 1.0, 2); + ui.hardnessSPBox->setSingleStep(0.01); + + ui.opacitySPBox->setRange(0.0, 1.0, 2); + ui.opacitySPBox->setSingleStep(0.01); + + connectControl(ui.eraserBox, &m_d->model, "eraserMode"); + connectControl(ui.radiusSPBox, &m_d->model, "radius"); + connectControl(ui.hardnessSPBox, &m_d->model, "hardness"); + connectControl(ui.opacitySPBox, &m_d->model, "opacity"); + + setConfigurationPage(widget); + m_d->model.optionData.bind(std::bind(&MyPaintBasicOptionWidget::emitSettingChanged, this)); +} + +MyPaintBasicOptionWidget::~MyPaintBasicOptionWidget() +{ +} + +void MyPaintBasicOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setting) const +{ + m_d->model.optionData->write(setting.data()); +} + +void MyPaintBasicOptionWidget::readOptionSetting(const KisPropertiesConfigurationSP setting) +{ + MyPaintBasicOptionData data = *m_d->model.optionData; + data.read(setting.data()); + m_d->model.optionData.set(data); +} diff --git a/plugins/paintops/mypaint/MyPaintBasicOptionWidget.h b/plugins/paintops/mypaint/MyPaintBasicOptionWidget.h new file mode 100644 index 00000000000..4a5bfa0c011 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintBasicOptionWidget.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef MYPAINTBASICOPTIONWIDGET_H +#define MYPAINTBASICOPTIONWIDGET_H + +#include +#include +#include + + +class MyPaintBasicOptionWidget : public KisPaintOpOption +{ +public: + using data_type = MyPaintBasicOptionData; + + MyPaintBasicOptionWidget(lager::cursor optionData, + lager::cursor radiusCursor, + lager::cursor hardnessCursor, + lager::cursor opacityCursor); + ~MyPaintBasicOptionWidget(); + + void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; + void readOptionSetting(const KisPropertiesConfigurationSP setting) override; + +private: + struct Private; + const QScopedPointer m_d; +}; + +#endif // MYPAINTBASICOPTIONWIDGET_H diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp index 633da31d466..a11b5674ca3 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp @@ -22,7 +22,7 @@ MyPaintCurveOptionWidget2::MyPaintCurveOptionWidget2(lager::cursor -#include #include -#include "MyPaintCurveOption.h" -#include "MyPaintCurveOptionWidget.h" -#include "MyPaintPaintOpOption.h" #include "MyPaintPaintOpSettings.h" #include #include #include #include +#include -struct MyPaintEllipticDabAngle : MyPaintCurveOptionData +struct MyPaintRadiusLogarithmicData : MyPaintCurveOptionData { - MyPaintEllipticDabAngle() + MyPaintRadiusLogarithmicData() + : MyPaintCurveOptionData(KoID("radius_logarithmic", + i18n("Radius Logarithmic")), + false, true, 0.01, 8.0) + { + } +}; + +struct MyPaintHardnessData : MyPaintCurveOptionData +{ + MyPaintHardnessData() + : MyPaintCurveOptionData(KoID("hardness", i18n("Hardness")), + false, true, 0.02, 1.0) + { + } +}; + +struct MyPaintOpacityData : MyPaintCurveOptionData +{ + MyPaintOpacityData() + : MyPaintCurveOptionData(KoID("opaque", i18n("Opaque")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintRadiusByRandomData : MyPaintCurveOptionData +{ + MyPaintRadiusByRandomData() + : MyPaintCurveOptionData(KoID("radius_by_random", i18n("Radius by Random")), + false, true, 0.0, 1.50) + { + } +}; + +struct MyPaintAntiAliasingData : MyPaintCurveOptionData +{ + MyPaintAntiAliasingData() + : MyPaintCurveOptionData(KoID("anti_aliasing", i18n("Anti Aliasing")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintEllipticalDabAngleData : MyPaintCurveOptionData +{ + MyPaintEllipticalDabAngleData() : MyPaintCurveOptionData(KoID("elliptical_dab_angle", i18n("Elliptical Dab Angle")), false, true, 0.0, 180.0) @@ -30,229 +72,429 @@ struct MyPaintEllipticDabAngle : MyPaintCurveOptionData } }; +struct MyPaintEllipticalDabRatioData : MyPaintCurveOptionData +{ + MyPaintEllipticalDabRatioData() + : MyPaintCurveOptionData(KoID("elliptical_dab_ratio", i18n("Elliptical Dab Ratio")), + false, true, 1.0, 10.0) + { + } +}; + + +struct MyPaintDirectionFilterData : MyPaintCurveOptionData +{ + MyPaintDirectionFilterData() + : MyPaintCurveOptionData(KoID("direction_filter", i18n("Direction Filter")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintSnapToPixelsData : MyPaintCurveOptionData +{ + MyPaintSnapToPixelsData() + : MyPaintCurveOptionData(KoID("snap_to_pixel", i18n("Snap To Pixel")), + false, true, 0.0, 10.0) + { + } +}; + + +struct MyPaintPressureGainData : MyPaintCurveOptionData +{ + MyPaintPressureGainData() + : MyPaintCurveOptionData(KoID("pressure_gain_log", i18n("Pressure Gain")), + false, true, -1.8, 1.8) + { + } +}; + + +struct MyPaintChangeColorHData : MyPaintCurveOptionData +{ + MyPaintChangeColorHData() + : MyPaintCurveOptionData(KoID("change_color_h", i18n("Change Color H")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorLData : MyPaintCurveOptionData +{ + MyPaintChangeColorLData() + : MyPaintCurveOptionData(KoID("change_color_l", i18n("Change Color L")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorVData : MyPaintCurveOptionData +{ + MyPaintChangeColorVData() + : MyPaintCurveOptionData(KoID("change_color_v", i18n("Change Color V")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorHSLSData : MyPaintCurveOptionData +{ + MyPaintChangeColorHSLSData() + : MyPaintCurveOptionData(KoID("change_color_hsl_s", i18n("Change Color HSL S")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorHSVSData : MyPaintCurveOptionData +{ + MyPaintChangeColorHSVSData() + : MyPaintCurveOptionData(KoID("change_color_hsv_s", i18n("Change Color HSV S")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintColorizeData : MyPaintCurveOptionData +{ + MyPaintColorizeData() + : MyPaintCurveOptionData(KoID("colorize", i18n("Colorize")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintFineSpeedGammaData : MyPaintCurveOptionData +{ + MyPaintFineSpeedGammaData() + : MyPaintCurveOptionData(KoID("speed1_gamma", i18n("Fine Speed Gamma")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintGrossSpeedGammaData : MyPaintCurveOptionData +{ + MyPaintGrossSpeedGammaData() + : MyPaintCurveOptionData(KoID("speed2_gamma", i18n("Gross Speed Gamma")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintFineSpeedSlownessData : MyPaintCurveOptionData +{ + MyPaintFineSpeedSlownessData() + : MyPaintCurveOptionData(KoID("speed1_slowness", i18n("Fine Speed Slowness")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintGrossSpeedSlownessData : MyPaintCurveOptionData +{ + MyPaintGrossSpeedSlownessData() + : MyPaintCurveOptionData(KoID("speed2_slowness", i18n("Gross Speed Slowness")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintOffsetBySpeedData : MyPaintCurveOptionData +{ + MyPaintOffsetBySpeedData() + : MyPaintCurveOptionData(KoID("offset_by_speed", i18n("Offset By Speed")), + false, true, -3.0, 3.0) + { + } +}; + +struct MyPaintOffsetBySpeedFilterData : MyPaintCurveOptionData +{ + MyPaintOffsetBySpeedFilterData() + : MyPaintCurveOptionData(KoID("offset_by_speed_slowness", i18n("Offset by Speed Filter")), + false, true, 0.0, 15.0) + { + } +}; + +struct MyPaintOffsetByRandomData : MyPaintCurveOptionData +{ + MyPaintOffsetByRandomData() + : MyPaintCurveOptionData(KoID("offset_by_random", i18n("Offset By Random")), + false, true, -3.0, 3.0) + { + } +}; + +struct MyPaintDabsPerBasicRadiusData : MyPaintCurveOptionData +{ + MyPaintDabsPerBasicRadiusData() + : MyPaintCurveOptionData(KoID("dabs_per_basic_radius", i18n("Dabs Per Basic Radius")), + false, true, 0.0, 6.0) + { + } +}; + +struct MyPaintDabsPerActualRadiusData : MyPaintCurveOptionData +{ + MyPaintDabsPerActualRadiusData() + : MyPaintCurveOptionData(KoID("dabs_per_actual_radius", i18n("Dabs Per Actual Radius")), + false, true, 0.0, 6.0) + { + } +}; + +struct MyPaintDabsPerSecondData : MyPaintCurveOptionData +{ + MyPaintDabsPerSecondData() + : MyPaintCurveOptionData(KoID("dabs_per_second", i18n("Dabs per Second")), + false, true, 0.0, 80.0) + { + } +}; + + +struct MyPaintOpaqueLinearizeData : MyPaintCurveOptionData +{ + MyPaintOpaqueLinearizeData() + : MyPaintCurveOptionData(KoID("opaque_linearize", i18n("Opaque Linearize")), + false, true, 0.0, 3.0) + { + } +}; + +struct MyPaintOpaqueMultiplyData : MyPaintCurveOptionData +{ + MyPaintOpaqueMultiplyData() + : MyPaintCurveOptionData(KoID("opaque_multiply", i18n("Opaque Multiply")), + false, true, 0.0, 2.0) + { + } +}; + +struct MyPaintSlowTrackingPerDabData : MyPaintCurveOptionData +{ + MyPaintSlowTrackingPerDabData() + : MyPaintCurveOptionData(KoID("slow_tracking_per_dab", i18n("Slow tracking per dab")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintSlowTrackingData : MyPaintCurveOptionData +{ + MyPaintSlowTrackingData() + : MyPaintCurveOptionData(KoID("slow_tracking", i18n("Slow Tracking")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintTrackingNoiseData : MyPaintCurveOptionData +{ + MyPaintTrackingNoiseData() + : MyPaintCurveOptionData(KoID("tracking_noise", i18n("Tracking Noise")), + false, true, 0.0, 12.0) + { + } +}; + +struct MyPaintSmudgeData : MyPaintCurveOptionData +{ + MyPaintSmudgeData() + : MyPaintCurveOptionData(KoID("smudge", i18n("Smudge")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintSmudgeLengthData : MyPaintCurveOptionData +{ + MyPaintSmudgeLengthData() + : MyPaintCurveOptionData(KoID("smudge_length", i18n("Smudge Length")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintSmudgeRadiusLogData : MyPaintCurveOptionData +{ + MyPaintSmudgeRadiusLogData() + : MyPaintCurveOptionData(KoID("smudge_radius_log", i18n("Smudge Radius Log")), + false, true, -1.6, 1.6) + { + } +}; + +struct MyPaintStrokeDurationLogData : MyPaintCurveOptionData +{ + MyPaintStrokeDurationLogData() + : MyPaintCurveOptionData(KoID("stroke_duration_logarithmic", i18n("Stroke Duration log")), + false, true, -1.0, 7.0) + { + } +}; + +struct MyPaintStrokeHoldtimeData : MyPaintCurveOptionData +{ + MyPaintStrokeHoldtimeData() + : MyPaintCurveOptionData(KoID("stroke_holdtime", i18n("Stroke Holdtime")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintStrokeThresholdData : MyPaintCurveOptionData +{ + MyPaintStrokeThresholdData() + : MyPaintCurveOptionData(KoID("stroke_threshold", i18n("Stroke Threshold")), + false, true, 0.0, 0.5) + { + } +}; + +struct MyPaintCustomInputData : MyPaintCurveOptionData +{ + MyPaintCustomInputData() + : MyPaintCurveOptionData(KoID("custom_input", i18n("Custom Input")), + false, true, -5.0, 5.0) + { + } +}; + +struct MyPaintCustomInputSlownessData : MyPaintCurveOptionData +{ + MyPaintCustomInputSlownessData() + : MyPaintCurveOptionData(KoID("custom_input_slowness", i18n("Custom Input Slowness")), + false, true, 0.0, 10.0) + { + } +}; + +namespace KisPaintOpOptionWidgetUtils { + +template +MyPaintCurveOptionWidget2* createMyPaintCurveOptionWidget(Data data, const QString &yValueSuffix = "") +{ + const qreal yLimit = qAbs(data.strengthMaxValue - data.strengthMinValue); + return createOptionWidget(std::move(data), yLimit, yValueSuffix); +} + +} // namespace + + KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) : KisPaintOpSettingsWidget(parent) { + /// TODO: move category into the widget itself, remove this + /// overridden enum + namespace kpowu = KisPaintOpOptionWidgetUtils; - KisMyPaintOpOption *basicOption = new KisMyPaintOpOption(); - m_baseOption = basicOption; - - KisMyPaintCurveOptionWidget *radiusOption = new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("radius_logarithmic", i18n("Radius Logarithmic")), KisPaintOpOption::GENERAL, false, 2.0, 0.01, 6.0), - "0", - "100"); - m_radiusWidget = radiusOption; - - KisMyPaintCurveOptionWidget *hardnessOption = - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("hardness", i18n("Hardness")), KisPaintOpOption::GENERAL, false, 0.8, 0.02, 1), - "0", - "100"); - m_hardnessWidget = hardnessOption; - - KisMyPaintCurveOptionWidget *opacityOption = - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("opaque", i18n("Opaque")), KisPaintOpOption::GENERAL, false, 1, 0, 1), "0", "100"); - m_opacityWidget = opacityOption; - - KisPaintOpSettingsWidget::addPaintOpOption(basicOption); - addPaintOpOption(radiusOption, KisMyPaintOpOption::BASIC); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("radius_by_random", i18n("Radius by Random")), KisPaintOpOption::GENERAL, false, 0.0, 0, 1.50), - "0", - "100"), + MyPaintCurveOptionWidget2 *radiusWidget = + kpowu::createMyPaintCurveOptionWidget(MyPaintRadiusLogarithmicData()); + MyPaintCurveOptionWidget2 *hardnessWidget = + kpowu::createMyPaintCurveOptionWidget(MyPaintHardnessData()); + MyPaintCurveOptionWidget2 *opacityWidget = + kpowu::createMyPaintCurveOptionWidget(MyPaintOpacityData()); + + KisPaintOpSettingsWidget::addPaintOpOption( + kpowu::createOptionWidget(MyPaintBasicOptionData(), + radiusWidget->strengthValueDenorm(), + hardnessWidget->strengthValueDenorm(), + opacityWidget->strengthValueDenorm())); + + addPaintOpOption(radiusWidget, KisMyPaintOpOption::BASIC); - addPaintOpOption(hardnessOption, KisMyPaintOpOption::BASIC); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("anti_aliasing", i18n("Anti Aliasing")), KisPaintOpOption::GENERAL, false, 0.0, 0, 1), - "0", - "100"), - KisMyPaintOpOption::BASIC); - - // TODO: move category into the widget! - addPaintOpOption(kpowu::createOptionWidget(MyPaintEllipticDabAngle(), 180.0, "°"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintRadiusByRandomData()), KisMyPaintOpOption::BASIC); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("elliptical_dab_ratio", i18n("Elliptical Dab Ratio")), KisPaintOpOption::GENERAL, false, 1, 1, 10), - "0", - "100"), + addPaintOpOption(hardnessWidget, KisMyPaintOpOption::BASIC); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("direction_filter", i18n("Direction Filter")), KisPaintOpOption::GENERAL, false, 2, 0, 10), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintAntiAliasingData()), KisMyPaintOpOption::BASIC); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("snap_to_pixel", i18n("Snap To Pixel")), KisPaintOpOption::GENERAL, false, 2, 0, 10), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintEllipticalDabAngleData(), "°"), + KisMyPaintOpOption::BASIC); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintEllipticalDabRatioData()), + KisMyPaintOpOption::BASIC); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDirectionFilterData()), + KisMyPaintOpOption::BASIC); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSnapToPixelsData()), + KisMyPaintOpOption::BASIC); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintPressureGainData()), KisMyPaintOpOption::BASIC); + addPaintOpOption(kpowu::createOptionWidget(), + KisMyPaintOpOption::AIRBRUSH); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("pressure_gain_log", i18n("Pressure Gain")), KisPaintOpOption::GENERAL, false, 0.0, -2, 3), - "0", - "100"), - KisMyPaintOpOption::BASIC); - - addPaintOpOption(kpowu::createOptionWidget(), KisMyPaintOpOption::AIRBRUSH); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("change_color_h", i18n("Change Color H")), KisPaintOpOption::GENERAL, false, 0.0, -2, 2), - "0", - "100"), - KisMyPaintOpOption::COLOR); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("change_color_l", i18n("Change Color L")), KisPaintOpOption::GENERAL, false, 0.0, -2, 2), - "0", - "100"), - KisMyPaintOpOption::COLOR); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("change_color_v", i18n("Change Color V")), KisPaintOpOption::GENERAL, false, 0.0, -2, 2), - "0", - "100"), - KisMyPaintOpOption::COLOR); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("change_color_hsl_s", i18n("Change Color HSL S")), KisPaintOpOption::GENERAL, false, 0.0, -2, 2), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHData()), + KisMyPaintOpOption::COLOR); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorLData()), + KisMyPaintOpOption::COLOR); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorVData()), + KisMyPaintOpOption::COLOR); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHSLSData()), KisMyPaintOpOption::COLOR); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("change_color_hsv_s", i18n("Change Color HSV S")), KisPaintOpOption::GENERAL, false, 0.0, -2, 2), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHSVSData()), KisMyPaintOpOption::COLOR); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("colorize", i18n("Colorize")), KisPaintOpOption::GENERAL, false, 0.0, 0, 1), "0", "100"), - KisMyPaintOpOption::COLOR); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("speed1_gamma", i18n("Fine Speed Gamma")), KisPaintOpOption::GENERAL, false, 4, -8, 8), - "0", - "100"), - KisMyPaintOpOption::SPEED); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("speed2_gamma", i18n("Gross Speed Gamma")), KisPaintOpOption::GENERAL, false, 4, -8, 8), - "0", - "100"), - KisMyPaintOpOption::SPEED); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("speed1_slowness", i18n("Fine Speed Slowness")), KisPaintOpOption::GENERAL, false, 4, -8, 8), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintColorizeData()), + KisMyPaintOpOption::COLOR); + + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintFineSpeedGammaData()), KisMyPaintOpOption::SPEED); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("speed2_slowness", i18n("Gross Speed Slowness")), KisPaintOpOption::GENERAL, false, 4, -8, 8), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintGrossSpeedGammaData()), KisMyPaintOpOption::SPEED); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("offset_by_speed", i18n("Offset By Speed")), KisPaintOpOption::GENERAL, false, 0.0, -3, 3), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintFineSpeedSlownessData()), KisMyPaintOpOption::SPEED); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("offset_by_speed_slowness", i18n("Offset by Speed Filter")), KisPaintOpOption::GENERAL, false, 2, 0, 15), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintGrossSpeedSlownessData()), KisMyPaintOpOption::SPEED); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("offset_by_random", i18n("Offset By Random")), KisPaintOpOption::GENERAL, false, 0.0, -3, 3), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetBySpeedData()), + KisMyPaintOpOption::SPEED); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetBySpeedFilterData()), + KisMyPaintOpOption::SPEED); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetByRandomData()), KisMyPaintOpOption::SPEED); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("dabs_per_basic_radius", i18n("Dabs Per Basic Radius")), KisPaintOpOption::GENERAL, false, 2, 0, 6), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerBasicRadiusData()), KisMyPaintOpOption::DABS); - - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("dabs_per_actual_radius", i18n("Dabs Per Actual Radius")), KisPaintOpOption::GENERAL, false, 2, 0, 6), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerActualRadiusData()), KisMyPaintOpOption::DABS); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("dabs_per_second", i18n("Dabs per Second")), KisPaintOpOption::GENERAL, false, 0, 0, 80), - "0", - "100"), - KisMyPaintOpOption::DABS); - addPaintOpOption(opacityOption, KisMyPaintOpOption::OPACITY); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("opaque_linearize", i18n("Opaque Linearize")), KisPaintOpOption::GENERAL, false, 0.9, 0, 3), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerSecondData()), + KisMyPaintOpOption::DABS); + + addPaintOpOption(opacityWidget, + KisMyPaintOpOption::OPACITY); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOpaqueLinearizeData()), + KisMyPaintOpOption::OPACITY); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOpaqueMultiplyData()), KisMyPaintOpOption::OPACITY); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("opaque_multiply", i18n("Opaque Multiply")), KisPaintOpOption::GENERAL, false, 0, 0, 2), - "0", - "100"), - KisMyPaintOpOption::OPACITY); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("slow_tracking_per_dab", i18n("Slow tracking per dab")), KisPaintOpOption::GENERAL, false, 0, 0, 10), - "0", - "100"), + + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSlowTrackingPerDabData()), + KisMyPaintOpOption::TRACKING); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSlowTrackingData()), KisMyPaintOpOption::TRACKING); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("slow_tracking", i18n("Slow Tracking")), KisPaintOpOption::GENERAL, false, 0, 0, 10), - "0", - "100"), - KisMyPaintOpOption::TRACKING); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("tracking_noise", i18n("Tracking Noise")), KisPaintOpOption::GENERAL, false, 0, 0, 12), - "0", - "100"), - KisMyPaintOpOption::TRACKING); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("smudge", i18n("Smudge")), KisPaintOpOption::GENERAL, false, 0, 0, 1), "0", "100"), - KisMyPaintOpOption::SMUDGE); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("smudge_length", i18n("Smudge Length")), KisPaintOpOption::GENERAL, false, 0.5, 0, 1), - "0", - "100"), - KisMyPaintOpOption::SMUDGE); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("smudge_radius_log", i18n("Smudge Radius Log")), KisPaintOpOption::GENERAL, false, 0, -1.6, 1.6), - "0", - "100"), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintTrackingNoiseData()), + KisMyPaintOpOption::TRACKING); + + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeData()), + KisMyPaintOpOption::SMUDGE); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeLengthData()), + KisMyPaintOpOption::SMUDGE); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeRadiusLogData()), KisMyPaintOpOption::SMUDGE); - addPaintOpOption( - new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("stroke_duration_logarithmic", i18n("Stroke Duration log")), KisPaintOpOption::GENERAL, false, 4, -1, 7), - "0", - "100"), - KisMyPaintOpOption::STROKE); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("stroke_holdtime", i18n("Stroke Holdtime")), KisPaintOpOption::GENERAL, false, 0, 0, 10), - "0", - "100"), - KisMyPaintOpOption::STROKE); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("stroke_threshold", i18n("Stroke Threshold")), KisPaintOpOption::GENERAL, false, 0, 0, 0.50), - "0", - "100"), - KisMyPaintOpOption::STROKE); - addPaintOpOption( - new KisMyPaintCurveOptionWidget(new KisMyPaintCurveOption(KoID("custom_input", i18n("Custom Input")), KisPaintOpOption::GENERAL, false, 0, -5, 5), - "0", - "100"), - KisMyPaintOpOption::CUSTOM); - addPaintOpOption(new KisMyPaintCurveOptionWidget( - new KisMyPaintCurveOption(KoID("custom_input_slowness", i18n("Custom Input Slowness")), KisPaintOpOption::GENERAL, false, 0, 0, 10), - "0", - "100"), - KisMyPaintOpOption::CUSTOM); - connect(radiusOption->slider(), SIGNAL(valueChanged(qreal)), SLOT(updateBaseOptionRadius(qreal))); - connect(hardnessOption->slider(), SIGNAL(valueChanged(qreal)), SLOT(updateBaseOptionHardness(qreal))); - connect(opacityOption->slider(), SIGNAL(valueChanged(qreal)), SLOT(updateBaseOptionOpacity(qreal))); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeDurationLogData()), + KisMyPaintOpOption::STROKE); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeHoldtimeData()), + KisMyPaintOpOption::STROKE); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeThresholdData()), + KisMyPaintOpOption::STROKE); - connect(basicOption->radiusSlider(), SIGNAL(valueChanged(qreal)), SLOT(updateRadiusOptionOpacity(qreal))); - connect(basicOption->hardnessSlider(), SIGNAL(valueChanged(qreal)), SLOT(updateHardnessOptionOpacity(qreal))); - connect(basicOption->opacitySlider(), SIGNAL(valueChanged(qreal)), SLOT(updateOpacityOptionOpacity(qreal))); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintCustomInputData()), + KisMyPaintOpOption::CUSTOM); + addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintCustomInputSlownessData()), + KisMyPaintOpOption::CUSTOM); } KisMyPaintOpSettingsWidget::~ KisMyPaintOpSettingsWidget() @@ -267,61 +509,6 @@ KisPropertiesConfigurationSP KisMyPaintOpSettingsWidget::configuration() const return config; } -void KisMyPaintOpSettingsWidget::showEvent(QShowEvent *event) -{ - Q_UNUSED(event); -} - -void KisMyPaintOpSettingsWidget::refreshBaseOption() -{ - m_baseOption->refresh(); -} - -void KisMyPaintOpSettingsWidget::updateBaseOptionRadius(qreal value) { - - m_baseOption->radiusSlider()->blockSignals(true); - m_baseOption->radiusSlider()->setValue(value); - m_baseOption->radiusSlider()->blockSignals(false); -} - -void KisMyPaintOpSettingsWidget::updateBaseOptionHardness(qreal value) { - - m_baseOption->hardnessSlider()->blockSignals(true); - m_baseOption->hardnessSlider()->setValue(value); - m_baseOption->hardnessSlider()->blockSignals(false); -} - -void KisMyPaintOpSettingsWidget::updateBaseOptionOpacity(qreal value) { - - m_baseOption->opacitySlider()->blockSignals(true); - m_baseOption->opacitySlider()->setValue(value); - m_baseOption->opacitySlider()->blockSignals(false); -} - -void KisMyPaintOpSettingsWidget::updateRadiusOptionOpacity(qreal value) { - - m_radiusWidget->slider()->blockSignals(true); - m_radiusWidget->slider()->setValue(value); - m_radiusWidget->slider()->blockSignals(false); - refreshBaseOption(); -} - -void KisMyPaintOpSettingsWidget::updateHardnessOptionOpacity(qreal value) { - - m_hardnessWidget->slider()->blockSignals(true); - m_hardnessWidget->slider()->setValue(value); - m_hardnessWidget->slider()->blockSignals(false); - refreshBaseOption(); -} - -void KisMyPaintOpSettingsWidget::updateOpacityOptionOpacity(qreal value) { - - m_opacityWidget->slider()->blockSignals(true); - m_opacityWidget->slider()->setValue(value); - m_opacityWidget->slider()->blockSignals(false); - refreshBaseOption(); -} - void KisMyPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, KisMyPaintOpOption::PaintopCategory id) { QString category; diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h index 70c471a1cc5..bd49b3c789c 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h @@ -12,6 +12,8 @@ #include #include +class MyPaintCurveOptionWidget2; + class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget { Q_OBJECT @@ -21,27 +23,9 @@ class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget ~KisMyPaintOpSettingsWidget() override; KisPropertiesConfigurationSP configuration() const override; - void refreshBaseOption(); protected: - void showEvent(QShowEvent *event) override; - void addPaintOpOption(KisPaintOpOption *option, KisMyPaintOpOption::PaintopCategory id); - -private: - KisMyPaintOpOption *m_baseOption; - KisMyPaintCurveOptionWidget *m_radiusWidget; - KisMyPaintCurveOptionWidget *m_hardnessWidget; - KisMyPaintCurveOptionWidget *m_opacityWidget; - -public Q_SLOTS: - void updateBaseOptionRadius(qreal); - void updateBaseOptionHardness(qreal); - void updateBaseOptionOpacity(qreal); - - void updateRadiusOptionOpacity(qreal); - void updateHardnessOptionOpacity(qreal); - void updateOpacityOptionOpacity(qreal); }; #endif From a359055eff1cd635ca7bb392afb99a376ad91f2a Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 18:59:53 +0300 Subject: [PATCH 12/20] Remove old MyPaint classes --- plugins/paintops/mypaint/CMakeLists.txt | 6 - .../paintops/mypaint/MyPaintCurveOption.cpp | 405 --------------- plugins/paintops/mypaint/MyPaintCurveOption.h | 52 -- .../mypaint/MyPaintCurveOptionWidget.cpp | 210 -------- .../mypaint/MyPaintCurveOptionWidget.h | 57 --- .../paintops/mypaint/MyPaintDynamicSensor.cpp | 304 ------------ .../paintops/mypaint/MyPaintDynamicSensor.h | 109 ----- plugins/paintops/mypaint/MyPaintPaintOp.cpp | 7 +- .../mypaint/MyPaintPaintOpFactory.cpp | 1 - .../paintops/mypaint/MyPaintPaintOpOption.cpp | 148 ------ .../paintops/mypaint/MyPaintPaintOpOption.h | 101 ---- .../paintops/mypaint/MyPaintPaintOpPreset.cpp | 60 +-- .../paintops/mypaint/MyPaintPaintOpPreset.h | 5 - .../mypaint/MyPaintPaintOpSettings.cpp | 42 +- .../mypaint/MyPaintPaintOpSettingsWidget.cpp | 460 ++---------------- .../mypaint/MyPaintPaintOpSettingsWidget.h | 7 +- .../paintops/mypaint/MyPaintSensorPack.cpp | 2 - plugins/paintops/mypaint/MyPaintSensorPack.h | 2 + .../mypaint/MyPaintStandardOptionData.h | 368 ++++++++++++++ 19 files changed, 451 insertions(+), 1895 deletions(-) delete mode 100644 plugins/paintops/mypaint/MyPaintCurveOption.cpp delete mode 100644 plugins/paintops/mypaint/MyPaintCurveOption.h delete mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp delete mode 100644 plugins/paintops/mypaint/MyPaintCurveOptionWidget.h delete mode 100644 plugins/paintops/mypaint/MyPaintDynamicSensor.cpp delete mode 100644 plugins/paintops/mypaint/MyPaintDynamicSensor.h delete mode 100644 plugins/paintops/mypaint/MyPaintPaintOpOption.cpp delete mode 100644 plugins/paintops/mypaint/MyPaintPaintOpOption.h create mode 100644 plugins/paintops/mypaint/MyPaintStandardOptionData.h diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index c9aa52684fa..0a5df34cefa 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -14,17 +14,11 @@ set(kritamypaintop_SOURCES MyPaintBasicOptionData.cpp MyPaintBasicOptionModel.cpp MyPaintBasicOptionWidget.cpp - MyPaintPaintOpOption.cpp MyPaintPaintOpSettings.cpp MyPaintPaintOpSettingsWidget.cpp MyPaintSurface.cpp MyPaintPaintOpPreset.cpp MyPaintPaintOpFactory.cpp - MyPaintCurveOptionWidget.cpp - MyPaintDynamicSensor.cpp - MyPaintCurveOption.cpp - ../libpaintop/kis_multi_sensors_selector.cpp - ../libpaintop/kis_multi_sensors_model_p.cpp ) ki18n_wrap_ui(kritamypaintop_SOURCES wdgmypaintoptions.ui wdgmypaintcurveoption.ui) diff --git a/plugins/paintops/mypaint/MyPaintCurveOption.cpp b/plugins/paintops/mypaint/MyPaintCurveOption.cpp deleted file mode 100644 index 74c7995bbbc..00000000000 --- a/plugins/paintops/mypaint/MyPaintCurveOption.cpp +++ /dev/null @@ -1,405 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 Boudewijn Rempt - * SPDX-FileCopyrightText: 2011 Silvio Heinrich - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later -*/ - -#include -#include -#include -#include -#include - -#include -#include - -#include "MyPaintPaintOpPreset.h" -#include "MyPaintPaintOpOption.h" -#include "MyPaintCurveOption.h" - - -struct MyPaintBrush; -KisMyPaintCurveOption::KisMyPaintCurveOption(const KoID &id, KisPaintOpOption::PaintopCategory category, bool checked, qreal value, qreal min, qreal max) - : KisCurveOption(id, category, true, value, min, max) -{ - Q_UNUSED(checked); - m_checkable = false; - m_checked = true; - m_useCurve = true; - m_useSameCurve = false; - m_sensorMap.clear(); - - Q_FOREACH (const DynamicSensorType sensorType, this->sensorsTypes()) { - KisDynamicSensorSP sensor = type2Sensor(sensorType, m_id.id()); - sensor->setActive(false); - replaceSensor(sensor); - } - m_sensorMap[MYPAINT_PRESSURE]->setActive(true); - - setValueRange(min, max); - setValue(value); - - m_commonCurve = defaultCurve(); -} - -KisMyPaintCurveOption::~KisMyPaintCurveOption() -{ -} - -void KisMyPaintCurveOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const -{ - if (m_checkable) { - setting->setProperty("Pressure" + m_id.id(), isChecked()); - } - - QJsonDocument doc = QJsonDocument::fromJson(setting->getProperty(MYPAINT_JSON).toByteArray()); - QJsonObject brush_json = doc.object(); - QVariantMap map = brush_json.toVariantMap(); - QVariantMap settings_map = map["settings"].toMap(); - QVariantMap name_map = settings_map[m_id.id()].toMap(); - QVariantMap inputs_map = name_map["inputs"].toMap(); - - Q_FOREACH(KisDynamicSensorSP val, m_sensorMap.values()) { - - MyPaintDynamicSensor *sensor = dynamic_cast(val.data()); - QVariantList pointsList; - QList curve_points = sensor->getControlPoints(); - - if(!sensor->isActive()){ - inputs_map.remove(sensor->id(sensor->sensorType())); - continue; - } - - for(int i=0; iid(sensor->sensorType())] = pointsList; - } - - if(!m_useCurve || activeSensors().size()==0) - inputs_map.clear(); - - name_map["inputs"] = inputs_map; - settings_map[m_id.id()] = name_map; - map["settings"] = settings_map; - - QJsonObject resultant_json = QJsonObject::fromVariantMap(map); - QJsonDocument doc2(resultant_json); - - setting->setProperty(MYPAINT_JSON, doc2.toJson()); - - setting->setProperty(m_id.id() + "UseCurve", m_useCurve); - setting->setProperty(m_id.id() + "UseSameCurve", m_useSameCurve); - setting->setProperty(m_id.id() + "Value", m_value); - setting->setProperty(m_id.id() + "curveMode", m_curveMode); - setting->setProperty(m_id.id() + "commonCurve", QVariant::fromValue(m_commonCurve)); -} - -void KisMyPaintCurveOption::readOptionSetting(KisPropertiesConfigurationSP setting) -{ - readNamedOptionSetting(m_id.id(), setting); -} - -void KisMyPaintCurveOption::readNamedOptionSetting(const QString& prefix, const KisPropertiesConfigurationSP setting) -{ - if (!setting) return; - - KisCubicCurve commonCurve = m_commonCurve; - - if (m_checkable) { - setChecked(setting->getBool("Pressure" + prefix, false)); - } - - m_sensorMap.clear(); - - Q_FOREACH (const DynamicSensorType sensorType, this->sensorsTypes()) { - replaceSensor(type2Sensor(sensorType, m_id.id())); - } - - MyPaintBrush *brush = mypaint_brush_new(); - mypaint_brush_from_string(brush, setting->getProperty(MYPAINT_JSON).toByteArray()); - - Q_FOREACH(MyPaintBrushInput inp, inputList()) { - - QList points; - for(int i=0; isetCurveFromPoints(points); - } - - if (!setting->getProperty(m_id.id() + sensor->identifier() + "XMIN").isNull()) - sensor->setXRangeMin(setting->getProperty(m_id.id() + sensor->identifier() + "XMIN").toReal()); - - if (!setting->getProperty(m_id.id() + sensor->identifier() + "XMAX").isNull()) - sensor->setXRangeMax(setting->getProperty(m_id.id() + sensor->identifier() + "XMAX").toReal()); - - if (!setting->getProperty(m_id.id() + sensor->identifier() + "YMIN").isNull()) - sensor->setYRangeMin(setting->getProperty(m_id.id() + sensor->identifier() + "YMIN").toReal()); - - if (!setting->getProperty(m_id.id() + sensor->identifier() + "YMAX").isNull()) - sensor->setYRangeMax(setting->getProperty(m_id.id() + sensor->identifier() + "YMAX").toReal()); - - replaceSensor(sensor); - sensor->setActive(points.size()>0); - } - - m_useSameCurve = setting->getBool(m_id.id() + "UseSameCurve", false); - - Q_FOREACH(KisDynamicSensorSP sensor, m_sensorMap.values()) { - commonCurve = sensor->curve(); - } - - m_useCurve = setting->getBool(m_id.id() + "UseCurve", true); - if (m_useSameCurve) { - m_commonCurve = setting->getCubicCurve(prefix + "commonCurve", commonCurve); - } - - if (activeSensors().size() == 0) { - m_useCurve = false; - m_sensorMap[MYPAINT_PRESSURE]->setActive(true); - } - if(!m_useCurve){ - emit unCheckUseCurve(); - } - - firstRead = false; - m_value = setting->getDouble(m_id.id() + "Value", m_maxValue); - m_curveMode = setting->getInt(m_id.id() + "curveMode"); - mypaint_brush_unref(brush); -} - -void KisMyPaintCurveOption::lodLimitations(KisPaintopLodLimitations *l) const { - - if(m_sensorMap[MYPAINT_RANDOM]->isActive()) { - l->blockers << KoID("Random Sensor Active", i18nc("PaintOp instant preview limitation", "Random Sensor Active, consider disabling Instant Preview")); - } - - if (m_id.id() == "offset_by_random" && (m_value > 0.05 || m_value < -0.05)) { - l->blockers << KoID("Offset by Random", i18nc("PaintOp instant preview limitation", "Offset by Random, consider disabling Instant Preview")); - } - - if (m_id.id() == "radius_by_random" && qRound(m_value) >= 0.05) { - l->blockers << KoID("Radius by Random", i18nc("PaintOp instant preview limitation", "Radius by Random, consider disabling Instant Preview")); - } -} - -MyPaintBrushSetting KisMyPaintCurveOption::currentSetting() { - if (m_id.id() == "eraser") - return MYPAINT_BRUSH_SETTING_ERASER; - else if (m_id.id() == "opaque") - return MYPAINT_BRUSH_SETTING_OPAQUE; - else if (m_id.id() == "smudge") - return MYPAINT_BRUSH_SETTING_SMUDGE; - else if (m_id.id() == "color_h") - return MYPAINT_BRUSH_SETTING_COLOR_H; - else if (m_id.id() == "color_s") - return MYPAINT_BRUSH_SETTING_COLOR_S; - else if (m_id.id() == "color_v") - return MYPAINT_BRUSH_SETTING_COLOR_V; - else if (m_id.id() == "colorize") - return MYPAINT_BRUSH_SETTING_COLORIZE; - else if (m_id.id() == "hardness") - return MYPAINT_BRUSH_SETTING_HARDNESS; - else if (m_id.id() == "speed1_gamma") - return MYPAINT_BRUSH_SETTING_SPEED1_GAMMA; - else if (m_id.id() == "speed2_gamma") - return MYPAINT_BRUSH_SETTING_SPEED2_GAMMA; - else if (m_id.id() == "anti_aliasing") - return MYPAINT_BRUSH_SETTING_ANTI_ALIASING; - else if (m_id.id() == "restore_color") - return MYPAINT_BRUSH_SETTING_RESTORE_COLOR; - else if (m_id.id() == "slow_tracking") - return MYPAINT_BRUSH_SETTING_SLOW_TRACKING; - else if (m_id.id() == "smudge_length") - return MYPAINT_BRUSH_SETTING_SMUDGE_LENGTH; - else if (m_id.id() == "snap_to_pixel") - return MYPAINT_BRUSH_SETTING_SNAP_TO_PIXEL; - else if (m_id.id() == "change_color_h") - return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_H; - else if (m_id.id() == "change_color_l") - return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_L; - else if (m_id.id() == "change_color_v") - return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_V; - else if (m_id.id() == "tracking_noise") - return MYPAINT_BRUSH_SETTING_TRACKING_NOISE; - else if (m_id.id() == "dabs_per_second") - return MYPAINT_BRUSH_SETTING_DABS_PER_SECOND; - else if (m_id.id() == "offset_by_speed") - return MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED; - else if (m_id.id() == "opaque_multiply") - return MYPAINT_BRUSH_SETTING_OPAQUE_MULTIPLY; - else if (m_id.id() == "speed1_slowness") - return MYPAINT_BRUSH_SETTING_SPEED1_SLOWNESS; - else if (m_id.id() == "speed2_slowness") - return MYPAINT_BRUSH_SETTING_SPEED2_SLOWNESS; - else if (m_id.id() == "stroke_holdtime") - return MYPAINT_BRUSH_SETTING_STROKE_HOLDTIME; - else if (m_id.id() == "direction_filter") - return MYPAINT_BRUSH_SETTING_DIRECTION_FILTER; - else if (m_id.id() == "offset_by_random") - return MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM; - else if (m_id.id() == "opaque_linearize") - return MYPAINT_BRUSH_SETTING_OPAQUE_LINEARIZE; - else if (m_id.id() == "radius_by_random") - return MYPAINT_BRUSH_SETTING_RADIUS_BY_RANDOM; - else if (m_id.id() == "stroke_threshold") - return MYPAINT_BRUSH_SETTING_STROKE_THRESHOLD; - else if (m_id.id() == "pressure_gain_log") - return MYPAINT_BRUSH_SETTING_PRESSURE_GAIN_LOG; - else if (m_id.id() == "smudge_radius_log") - return MYPAINT_BRUSH_SETTING_SMUDGE_RADIUS_LOG; - else if (m_id.id() == "change_color_hsl_s") - return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSL_S; - else if (m_id.id() == "change_color_hsv_s") - return MYPAINT_BRUSH_SETTING_CHANGE_COLOR_HSV_S; - else if (m_id.id() == "radius_logarithmic") - return MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC; - else if (m_id.id() == "elliptical_dab_angle") - return MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_ANGLE; - else if (m_id.id() == "elliptical_dab_ratio") - return MYPAINT_BRUSH_SETTING_ELLIPTICAL_DAB_RATIO; - else if (m_id.id() == "custom_input_slowness") - return MYPAINT_BRUSH_SETTING_CUSTOM_INPUT_SLOWNESS; - else if (m_id.id() == "custom_input") - return MYPAINT_BRUSH_SETTING_CUSTOM_INPUT; - else if (m_id.id() == "dabs_per_basic_radius") - return MYPAINT_BRUSH_SETTING_DABS_PER_BASIC_RADIUS; - else if (m_id.id() == "slow_tracking_per_dab") - return MYPAINT_BRUSH_SETTING_SLOW_TRACKING_PER_DAB; - else if (m_id.id() == "dabs_per_actual_radius") - return MYPAINT_BRUSH_SETTING_DABS_PER_ACTUAL_RADIUS; - else if (m_id.id() == "offset_by_speed_slowness") - return MYPAINT_BRUSH_SETTING_OFFSET_BY_SPEED_SLOWNESS; - else if (m_id.id() == "stroke_duration_logarithmic") - return MYPAINT_BRUSH_SETTING_STROKE_DURATION_LOGARITHMIC; - - return MYPAINT_BRUSH_SETTING_ERASER; -} - -QList KisMyPaintCurveOption::inputList() { - - QList list; - - list << MYPAINT_BRUSH_INPUT_PRESSURE - << MYPAINT_BRUSH_INPUT_SPEED1 - << MYPAINT_BRUSH_INPUT_SPEED2 - << MYPAINT_BRUSH_INPUT_RANDOM - << MYPAINT_BRUSH_INPUT_STROKE - << MYPAINT_BRUSH_INPUT_DIRECTION - << MYPAINT_BRUSH_INPUT_TILT_DECLINATION - << MYPAINT_BRUSH_INPUT_TILT_ASCENSION - << MYPAINT_BRUSH_INPUT_CUSTOM; - - return list; -} - -QList KisMyPaintCurveOption::sensorsIds() -{ - QList ids; - - ids << Pressure - << FineSpeed - << GrossSpeed - << Random - << Stroke - << Direction - << Declination - << Ascension - << Custom; - - return ids; -} - -DynamicSensorType KisMyPaintCurveOption::id2Type(const KoID &id) -{ - if (id.id() == Pressure.id()) { - return MYPAINT_PRESSURE; - } - else if (id.id() == FineSpeed.id()) { - return MYPAINT_FINE_SPEED; - } - else if (id.id() == GrossSpeed.id()) { - return MYPAINT_GROSS_SPEED; - } - else if (id.id() == Random.id()) { - return MYPAINT_RANDOM; - } - else if (id.id() == Stroke.id()) { - return MYPAINT_STROKE; - } - else if (id.id() == Direction.id()) { - return MYPAINT_DIRECTION; - } - else if (id.id() == Declination.id()) { - return MYPAINT_DECLINATION; - } - else if (id.id() == Ascension.id()) { - return MYPAINT_ASCENSION; - } - else if (id.id() == Custom.id()) { - return MYPAINT_CUSTOM; - } - return UNKNOWN; -} - -KisDynamicSensorSP KisMyPaintCurveOption::id2Sensor(const KoID& id, const QString &parentOptionName) -{ - Q_UNUSED(parentOptionName); - if(id.id()==Pressure.id()) - return new MyPaintDynamicSensor(MYPAINT_PRESSURE); - else if(id.id()==FineSpeed.id()) - return new MyPaintDynamicSensor(MYPAINT_FINE_SPEED); - else if(id.id()==GrossSpeed.id()) - return new MyPaintDynamicSensor(MYPAINT_GROSS_SPEED); - else if(id.id()==Random.id()) - return new MyPaintDynamicSensor(MYPAINT_RANDOM); - else if(id.id()==Stroke.id()) - return new MyPaintDynamicSensor(MYPAINT_STROKE); - else if(id.id()==Direction.id()) - return new MyPaintDynamicSensor(MYPAINT_DIRECTION); - else if(id.id()==Ascension.id()) - return new MyPaintDynamicSensor(MYPAINT_ASCENSION); - else if(id.id()==Declination.id()) - return new MyPaintDynamicSensor(MYPAINT_DECLINATION); - else if(id.id()==Custom.id()) - return new MyPaintDynamicSensor(MYPAINT_CUSTOM); - else { - return 0; - } -} - -QList KisMyPaintCurveOption::sensorsTypes() -{ - QList sensorTypes; - sensorTypes - << MYPAINT_PRESSURE - << MYPAINT_FINE_SPEED - << MYPAINT_GROSS_SPEED - << MYPAINT_RANDOM - << MYPAINT_STROKE - << MYPAINT_DIRECTION - << MYPAINT_DECLINATION - << MYPAINT_ASCENSION - << MYPAINT_CUSTOM; - - return sensorTypes; -} - -KisDynamicSensorSP KisMyPaintCurveOption::type2Sensor(DynamicSensorType sensorType, const QString &parentOptionName) -{ - Q_UNUSED(parentOptionName); - return new MyPaintDynamicSensor(sensorType); -} diff --git a/plugins/paintops/mypaint/MyPaintCurveOption.h b/plugins/paintops/mypaint/MyPaintCurveOption.h deleted file mode 100644 index 0c324f6d971..00000000000 --- a/plugins/paintops/mypaint/MyPaintCurveOption.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 Boudewijn Rempt - * SPDX-FileCopyrightText: 2011 Silvio Heinrich - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ - -#ifndef KIS_MYPAINT_CURVE_OPTION_H -#define KIS_MYPAINT_CURVE_OPTION_H - - -#include -#include - -#include "kis_paintop_option.h" -#include "kis_global.h" -#include "kis_curve_option.h" -#include -#include "kritapaintop_export.h" -#include "MyPaintDynamicSensor.h" -#include "libmypaint/mypaint-brush.h" - -class KisMyPaintCurveOption: public KisCurveOption -{ - Q_OBJECT -public: - KisMyPaintCurveOption(const KoID &id, KisPaintOpOption::PaintopCategory category, bool checked, qreal value = 1.0, qreal min = 0.0, qreal max = 1.0); - - virtual ~KisMyPaintCurveOption(); - - void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; - void readOptionSetting(KisPropertiesConfigurationSP setting) override; - void lodLimitations(KisPaintopLodLimitations *l) const override; - - MyPaintBrushSetting currentSetting(); - QList inputList(); - - QList sensorsIds() override; - DynamicSensorType id2Type(const KoID &id) override; - KisDynamicSensorSP id2Sensor(const KoID &id, const QString &parentOptionName) override; - QList sensorsTypes() override; - KisDynamicSensorSP type2Sensor(DynamicSensorType sensorType, const QString &parentOptionName) override; - -protected: - void readNamedOptionSetting(const QString &prefix, const KisPropertiesConfigurationSP setting) override; - -private: - bool firstRead = true; - -}; - -#endif // KIS_MYPAINT_CURVE_OPTION_H diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp deleted file mode 100644 index b29f18787fc..00000000000 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 Boudewijn Rempt - * SPDX-FileCopyrightText: 2009 Sven Langkamp - * SPDX-FileCopyrightText: 2011 Silvio Heinrich - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "MyPaintCurveOptionWidget.h" - -#include -#include -#include -#include -#include -#include - -#include "MyPaintDynamicSensor.h" -#include "MyPaintCurveOption.h" -#include "MyPaintPaintOpOption.h" -#include "MyPaintPaintOpSettingsWidget.h" -#include "ui_wdgmypaintcurveoption.h" - -KisMyPaintCurveOptionWidget::KisMyPaintCurveOptionWidget(KisMyPaintCurveOption* curveOption, const QString &minLabel, const QString &maxLabel, bool hideSlider, KisMyPaintOpOption *baseOption) - : KisCurveOptionWidget (curveOption, minLabel, maxLabel, hideSlider) -{ - Q_UNUSED(baseOption); - setObjectName("KisMyPaintCurveOptionWidget"); - - strengthToCurveOptionValueScale = 1.0; - hideRangeLabelsAndBoxes(false); - - connect(m_curveOptionWidget->sensorSelector, SIGNAL(highlightedSensorChanged(KisDynamicSensorSP)), SLOT(updateRangeSpinBoxes(KisDynamicSensorSP))); - connect(m_curveOptionWidget->xMinBox, SIGNAL(valueChanged(double)), SLOT(emitSettingChanged())); - connect(m_curveOptionWidget->xMaxBox, SIGNAL(valueChanged(double)), SLOT(emitSettingChanged())); - connect(m_curveOptionWidget->yMinBox, SIGNAL(valueChanged(double)), SLOT(emitSettingChanged())); - connect(m_curveOptionWidget->yMaxBox, SIGNAL(valueChanged(double)), SLOT(emitSettingChanged())); - - m_curveOptionWidget->strengthSlider->setRange(curveOption->minValue(), curveOption->maxValue(), 2); - m_curveOptionWidget->strengthSlider->setSingleStep(0.01); - m_curveOptionWidget->strengthSlider->setValue(curveOption->value()); - m_curveOptionWidget->strengthSlider->setPrefix(i18n("Base Value: ")); - m_curveOptionWidget->strengthSlider->setSuffix(""); - - if (hideSlider) { - m_curveOptionWidget->strengthSlider->hide(); - } - - connect(m_curveOption, SIGNAL(unCheckUseCurve()), SLOT(slotUnCheckUseCurve())); -} - -KisMyPaintCurveOptionWidget::~KisMyPaintCurveOptionWidget() -{ -} - -void KisMyPaintCurveOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setting) const -{ - checkRanges(); - KisDynamicSensorSP dynamicSensor = m_curveOptionWidget->sensorSelector->currentHighlighted(); - MyPaintDynamicSensor* currentSensor = dynamic_cast(m_curveOptionWidget->sensorSelector->currentHighlighted().data()); - KIS_SAFE_ASSERT_RECOVER(dynamicSensor && currentSensor) { } - if (dynamicSensor) { - setting->setProperty(m_curveOption->id().id() + dynamicSensor->identifier() + "XMIN", m_curveOptionWidget->xMinBox->value()); - setting->setProperty(m_curveOption->id().id() + dynamicSensor->identifier() + "XMAX", m_curveOptionWidget->xMaxBox->value()); - setting->setProperty(m_curveOption->id().id() + dynamicSensor->identifier() + "YMIN", m_curveOptionWidget->yMinBox->value()); - setting->setProperty(m_curveOption->id().id() + dynamicSensor->identifier() + "YMAX", m_curveOptionWidget->yMaxBox->value()); - } - if (currentSensor) { - - currentSensor->setXRangeMin(m_curveOptionWidget->xMinBox->value()); - currentSensor->setXRangeMax(m_curveOptionWidget->xMaxBox->value()); - currentSensor->setYRangeMin(m_curveOptionWidget->yMinBox->value()); - currentSensor->setYRangeMax(m_curveOptionWidget->yMaxBox->value()); - } - if (dynamicSensor) { - // don't use currentSensor here, because it would get converted to shared pointer - const_cast(this)->updateSensorCurveLabels(dynamicSensor); - } - setBaseValue(setting, m_curveOptionWidget->strengthSlider->value()); - m_curveOption->writeOptionSetting(setting); -} - -void KisMyPaintCurveOptionWidget::readOptionSetting(const KisPropertiesConfigurationSP setting) -{ - KisCurveOptionWidget::readOptionSetting(setting); - - m_curveOptionWidget->checkBoxUseCurve->setChecked(m_curveOption->isCurveUsed()); - m_curveOptionWidget->strengthSlider->setValue(getBaseValue(setting)); - updateRangeSpinBoxes(m_curveOptionWidget->sensorSelector->currentHighlighted()); -} - -void KisMyPaintCurveOptionWidget::slotUnCheckUseCurve() { - - m_curveOptionWidget->checkBoxUseCurve->setChecked(false); - updateValues(); -} - -void KisMyPaintCurveOptionWidget::updateSensorCurveLabels(KisDynamicSensorSP sensor) -{ - KisCurveOptionWidget::updateSensorCurveLabels(sensor); - MyPaintDynamicSensor* mySensor = dynamic_cast(sensor.data()); - if (mySensor) { - - m_curveOptionWidget->label_xmin->setText(mySensor->minimumXLabel()); - m_curveOptionWidget->label_xmax->setText(mySensor->maximumXLabel()); - m_curveOptionWidget->label_ymin->setText(mySensor->minimumYLabel()); - m_curveOptionWidget->label_ymax->setText(mySensor->maximumYLabel()); - } -} - -void KisMyPaintCurveOptionWidget::updateRangeSpinBoxes(KisDynamicSensorSP sensor) const { - - MyPaintDynamicSensor* mySensor = dynamic_cast(sensor.data()); - m_curveOptionWidget->xMinBox->blockSignals(true); - m_curveOptionWidget->xMaxBox->blockSignals(true); - m_curveOptionWidget->yMinBox->blockSignals(true); - m_curveOptionWidget->yMaxBox->blockSignals(true); - - m_curveOptionWidget->xMinBox->setValue( mySensor->getXRangeMin()); - m_curveOptionWidget->xMaxBox->setValue( mySensor->getXRangeMax()); - m_curveOptionWidget->yMinBox->setValue( mySensor->getYRangeMin()); - m_curveOptionWidget->yMaxBox->setValue( mySensor->getYRangeMax()); - - m_curveOptionWidget->xMinBox->blockSignals(false); - m_curveOptionWidget->xMaxBox->blockSignals(false); - m_curveOptionWidget->yMinBox->blockSignals(false); - m_curveOptionWidget->yMaxBox->blockSignals(false); -} - -float KisMyPaintCurveOptionWidget::getBaseValue(KisPropertiesConfigurationSP setting) { - - KisMyPaintCurveOption *curveOpt = dynamic_cast(m_curveOption); - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC) - return log(setting->getFloat(MYPAINT_DIAMETER)/2); - - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_OPAQUE) - return setting->getFloat(MYPAINT_OPACITY); - - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_HARDNESS) - return setting->getFloat(MYPAINT_HARDNESS); - - MyPaintBrush *brush = mypaint_brush_new(); - mypaint_brush_from_string(brush, setting->getProperty(MYPAINT_JSON).toByteArray()); - - float ret = mypaint_brush_get_base_value(brush, curveOpt->currentSetting()); - - mypaint_brush_unref(brush); - return ret; -} - -void KisMyPaintCurveOptionWidget::setBaseValue(KisPropertiesConfigurationSP setting, float val) const { - - QJsonDocument doc = QJsonDocument::fromJson(setting->getProperty(MYPAINT_JSON).toByteArray()); - QJsonObject brush_json = doc.object(); - QVariantMap map = brush_json.toVariantMap(); - QVariantMap settings_map = map["settings"].toMap(); - QVariantMap name_map = settings_map[m_curveOption->id().id()].toMap(); - double base_val = name_map["base_value"].toDouble(); - Q_UNUSED(base_val); - - name_map["base_value"] = val; - settings_map[m_curveOption->id().id()] = name_map; - map["settings"] = settings_map; - - QJsonObject json_obj = QJsonObject::fromVariantMap(map); - QJsonDocument doc2(json_obj); - - setting->setProperty(MYPAINT_JSON, doc2.toJson()); - - KisMyPaintCurveOption *curveOpt = dynamic_cast(m_curveOption); - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC) - setting->setProperty(MYPAINT_DIAMETER, exp(val)*2); - - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_HARDNESS) - setting->setProperty(MYPAINT_HARDNESS, val); - - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_OPAQUE) - setting->setProperty(MYPAINT_OPACITY, val); - - if(curveOpt->currentSetting() == MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM) - setting->setProperty(MYPAINT_OFFSET_BY_RANDOM, val); -} - -void KisMyPaintCurveOptionWidget::checkRanges() const -{ - if(m_curveOptionWidget->xMinBox->value() >= m_curveOptionWidget->xMaxBox->value()) { - - m_curveOptionWidget->xMinBox->blockSignals(true); - m_curveOptionWidget->xMinBox->setValue(m_curveOptionWidget->xMaxBox->value() - 1); - m_curveOptionWidget->xMinBox->blockSignals(false); - } - - if(m_curveOptionWidget->yMinBox->value() >= m_curveOptionWidget->yMaxBox->value()) { - - m_curveOptionWidget->yMinBox->blockSignals(true); - m_curveOptionWidget->yMinBox->setValue(m_curveOptionWidget->yMaxBox->value() - 1); - m_curveOptionWidget->yMinBox->blockSignals(false); - } -} - -KisDoubleSliderSpinBox* KisMyPaintCurveOptionWidget::slider() { - - return m_curveOptionWidget->strengthSlider; -} - -void KisMyPaintCurveOptionWidget::refresh() { - - emitSettingChanged(); -} diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h b/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h deleted file mode 100644 index 8f2736b220f..00000000000 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 Boudewijn Rempt - * SPDX-FileCopyrightText: 2009 Sven Langkamp - * SPDX-FileCopyrightText: 2011 Silvio Heinrich - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef KIS_MYPAINT_CURVE_OPTION_WIDGET_H -#define KIS_MYPAINT_CURVE_OPTION_WIDGET_H - -#include - -#include -#include -#include -#include -#include - -#include "ui_wdgcurveoption.h" -#include "ui_wdgmypaintcurveoption.h" - -class Ui_WdgMyPaintCurveOption; -class QComboBox; - -class KisMyPaintCurveOptionWidget : public KisCurveOptionWidget -{ - Q_OBJECT -public: - KisMyPaintCurveOptionWidget(KisMyPaintCurveOption* curveOption, const QString &minLabel, const QString &maxLabel, bool hideSlider = false, KisMyPaintOpOption *option = nullptr); - ~KisMyPaintCurveOptionWidget() override; - - void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; - void readOptionSetting(const KisPropertiesConfigurationSP setting) override; - - KisDoubleSliderSpinBox* slider(); - -protected Q_SLOTS: - - void slotUnCheckUseCurve(); - - void updateSensorCurveLabels(KisDynamicSensorSP sensor) override; - void updateRangeSpinBoxes(KisDynamicSensorSP sensor) const; - -public Q_SLOTS: - void refresh(); - -protected: - - void checkRanges() const; - float getBaseValue(KisPropertiesConfigurationSP setting); - void setBaseValue(KisPropertiesConfigurationSP setting, float val) const; - -}; - -#endif // KIS_MYPAINT_CURVE_OPTION_WIDGET_H diff --git a/plugins/paintops/mypaint/MyPaintDynamicSensor.cpp b/plugins/paintops/mypaint/MyPaintDynamicSensor.cpp deleted file mode 100644 index 3a70b05f117..00000000000 --- a/plugins/paintops/mypaint/MyPaintDynamicSensor.cpp +++ /dev/null @@ -1,304 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "MyPaintDynamicSensor.h" - -#include -#include - -#include -#include -#include - - -using namespace std; - -MyPaintDynamicSensor::MyPaintDynamicSensor(DynamicSensorType type) - : KisDynamicSensor (type) -{ - m_type = type; - m_customCurve = false; - m_active = false; - m_length = -1; - m_id = MyPaintDynamicSensor::id(type); -} - -MyPaintDynamicSensor::~MyPaintDynamicSensor() -{ -} - -qreal MyPaintDynamicSensor::value(const KisPaintInformation &info) -{ - if (info.isHoveringMode()) return 1.0; - - const int currentValue = - qMin(info.currentDabSeqNo(), m_length); - - return qreal(currentValue) / m_length; -} - -QString MyPaintDynamicSensor::minimumLabel(DynamicSensorType sensorType) -{ - switch (sensorType) { - default: - return i18n("0.0"); - } -} - -QString MyPaintDynamicSensor::maximumLabel(DynamicSensorType sensorType, int max) -{ - Q_UNUSED(max); - switch (sensorType) { - default: - return i18n("1.0"); - }; -} - -QString MyPaintDynamicSensor::minimumXLabel() { - - return QString::number(curveXMin); -} - -QString MyPaintDynamicSensor::minimumYLabel() { - - return QString::number(curveYMin); -} - -QString MyPaintDynamicSensor::maximumXLabel() { - - return QString::number(curveXMax); -} - -QString MyPaintDynamicSensor::maximumYLabel() { - - return QString::number(curveYMax); -} - -int MyPaintDynamicSensor::minimumValue(DynamicSensorType sensorType) -{ - switch (sensorType) { - - default: - return 0; - } - -} - -int MyPaintDynamicSensor::maximumValue(DynamicSensorType sensorType, int max) -{ - Q_UNUSED(max); - switch (sensorType) { - default: - return 100; - }; -} - -QString MyPaintDynamicSensor::valueSuffix(DynamicSensorType sensorType) -{ - switch (sensorType) { - - default: - return i18n("%"); - }; -} - -DynamicSensorType MyPaintDynamicSensor::typeForInput(MyPaintBrushInput input) -{ - switch(input) { - - case MYPAINT_BRUSH_INPUT_PRESSURE: - return MYPAINT_PRESSURE; - case MYPAINT_BRUSH_INPUT_SPEED1: - return MYPAINT_FINE_SPEED; - case MYPAINT_BRUSH_INPUT_SPEED2: - return MYPAINT_GROSS_SPEED; - case MYPAINT_BRUSH_INPUT_RANDOM: - return MYPAINT_RANDOM; - case MYPAINT_BRUSH_INPUT_STROKE: - return MYPAINT_STROKE; - case MYPAINT_BRUSH_INPUT_DIRECTION: - return MYPAINT_DIRECTION; - case MYPAINT_BRUSH_INPUT_TILT_DECLINATION: - return MYPAINT_DECLINATION; - case MYPAINT_BRUSH_INPUT_TILT_ASCENSION: - return MYPAINT_ASCENSION; - case MYPAINT_BRUSH_INPUT_CUSTOM: - return MYPAINT_CUSTOM; - - default: - return MYPAINT_PRESSURE; - } -} - -MyPaintBrushInput MyPaintDynamicSensor::input() -{ - switch(m_type) { - - case MYPAINT_PRESSURE: - return MYPAINT_BRUSH_INPUT_PRESSURE; - case MYPAINT_FINE_SPEED: - return MYPAINT_BRUSH_INPUT_SPEED1; - case MYPAINT_GROSS_SPEED: - return MYPAINT_BRUSH_INPUT_SPEED2; - case MYPAINT_RANDOM: - return MYPAINT_BRUSH_INPUT_RANDOM; - case MYPAINT_STROKE: - return MYPAINT_BRUSH_INPUT_STROKE; - case MYPAINT_DIRECTION: - return MYPAINT_BRUSH_INPUT_DIRECTION; - case MYPAINT_DECLINATION: - return MYPAINT_BRUSH_INPUT_TILT_DECLINATION; - case MYPAINT_ASCENSION: - return MYPAINT_BRUSH_INPUT_TILT_ASCENSION; - case MYPAINT_CUSTOM: - return MYPAINT_BRUSH_INPUT_CUSTOM; - - default: - return MYPAINT_BRUSH_INPUT_PRESSURE; - } -} - -qreal MyPaintDynamicSensor::getXRangeMin() { - - return curveXMin; -} - -qreal MyPaintDynamicSensor::getXRangeMax() { - - return curveXMax; -} - -qreal MyPaintDynamicSensor::getYRangeMin() { - - return curveYMin; -} - -qreal MyPaintDynamicSensor::getYRangeMax() { - - return curveYMax; -} - -void MyPaintDynamicSensor::setXRangeMin(qreal value) { - - curveXMin = value; -} - -void MyPaintDynamicSensor::setXRangeMax(qreal value) { - - curveXMax = value; -} - -void MyPaintDynamicSensor::setYRangeMin(qreal value) { - - curveYMin = value; -} - -void MyPaintDynamicSensor::setYRangeMax(qreal value) { - - curveYMax = value; -} - - -QString MyPaintDynamicSensor::id(DynamicSensorType sensorType) -{ - switch (sensorType) { - - case MYPAINT_PRESSURE: - return Pressure.id(); - case MYPAINT_FINE_SPEED: - return FineSpeed.id(); - case MYPAINT_GROSS_SPEED: - return GrossSpeed.id(); - case MYPAINT_RANDOM: - return Random.id(); - case MYPAINT_DIRECTION: - return Direction.id(); - case MYPAINT_ASCENSION: - return Ascension.id(); - case MYPAINT_DECLINATION: - return Declination.id(); - case MYPAINT_STROKE: - return Stroke.id(); - case MYPAINT_CUSTOM: - return Custom.id(); - - default: - return QString(); - }; -} - -void MyPaintDynamicSensor::setCurveFromPoints(QList points) { - - setRangeFromPoints(points); - - for (int i=0; i MyPaintDynamicSensor::getControlPoints() { - - QList curvePoints = curve().points(); - for(int i=0; i points) { - - curveXMin = points[0].x(); - curveXMax = points[0].x(); - curveYMin = points[0].y(); - curveYMax = points[0].y(); - - for(int i=1; i - * SPDX-FileCopyrightText: 2011 Silvio Heinrich - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef KIS_MYPAINTBRUSH_OPTION_H -#define KIS_MYPAINTBRUSH_OPTION_H - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class QWidget; -class KisPaintInformation; - -const KoID Pressure("pressure", ki18n("Pressure")); -const KoID FineSpeed("speed1", ki18n("Fine Speed")); -const KoID GrossSpeed("speed2", ki18n("Gross Speed")); -const KoID Random("random", ki18n("Random")); -const KoID Stroke("stroke", ki18nc("The duration of a brush stroke", "Stroke")); -const KoID Direction("direction", ki18nc("Drawing Angle", "Direction")); -const KoID Declination("tilt_declination", ki18nc("Pen tilt declination", "Declination")); -const KoID Ascension("tilt_ascension", ki18nc("Pen tilt ascension", "Ascension")); -const KoID Custom("custom", ki18n("Custom")); - -class MyPaintDynamicSensor : public KisDynamicSensor -{ - -public: - - MyPaintDynamicSensor(DynamicSensorType type); - ~MyPaintDynamicSensor() override; - - qreal value(const KisPaintInformation &info) override; - - QString minimumLabel(DynamicSensorType sensorType) override; - QString maximumLabel(DynamicSensorType sensorType, int max = -1) override; - int minimumValue(DynamicSensorType sensorType) override; - int maximumValue(DynamicSensorType sensorType, int max = -1) override; - QString valueSuffix(DynamicSensorType sensorType) override; - - static DynamicSensorType typeForInput(MyPaintBrushInput input); - - QString id(DynamicSensorType sensorType); - - void setCurveFromPoints(QList points); - - inline DynamicSensorType sensorType() const { return m_type; } - - MyPaintBrushInput input(); - - int length() { return m_length; } - - qreal getXRangeMin(); - qreal getXRangeMax(); - qreal getYRangeMin(); - qreal getYRangeMax(); - - void setXRangeMin(qreal value); - void setXRangeMax(qreal value); - void setYRangeMin(qreal value); - void setYRangeMax(qreal value); - -public: - static inline qreal scalingToAdditive(qreal x) { - return -1.0 + 2.0 * x; - } - - static inline qreal additiveToScaling(qreal x) { - return 0.5 * (1.0 + x); - } - - QList getControlPoints(); - QString minimumXLabel(); - QString minimumYLabel(); - QString maximumXLabel(); - QString maximumYLabel(); - -protected: - - QPointF scaleTo0_1(QPointF point); - QPointF scaleFrom0_1(QPointF point); - qreal scaleToRange(qreal inMin, qreal inMax, qreal outMin, qreal outMax, qreal inValue); - void setRangeFromPoints(QList points); - - qreal curveXMin = 0; - qreal curveXMax = 1; - qreal curveYMin = 0; - qreal curveYMax = 1; - -private: - Q_DISABLE_COPY(MyPaintDynamicSensor) - -}; - -#endif // KIS_MYPAINTBRUSH_OPTION_H diff --git a/plugins/paintops/mypaint/MyPaintPaintOp.cpp b/plugins/paintops/mypaint/MyPaintPaintOp.cpp index 968eaaf6999..96f4f235bcd 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOp.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOp.cpp @@ -22,8 +22,6 @@ #include #include -#include "MyPaintPaintOpOption.h" - KisMyPaintPaintOp::KisMyPaintPaintOp(const KisPaintOpSettingsSP settings, KisPainter *painter, KisNodeSP /*node*/, KisImageSP image) : KisPaintOp (painter) { @@ -51,7 +49,7 @@ KisMyPaintPaintOp::KisMyPaintPaintOp(const KisPaintOpSettingsSP settings, KisPai m_dtime = -1; m_isStrokeStarted = false; - m_radius = settings->getFloat(MYPAINT_DIAMETER)/2; + m_radius = exp(mypaint_brush_get_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC)); } KisMyPaintPaintOp::~KisMyPaintPaintOp() { @@ -64,8 +62,9 @@ KisSpacingInformation KisMyPaintPaintOp::paintAt(const KisPaintInformation& info } const qreal lodScale = KisLodTransform::lodToScale(painter()->device()); - qreal radius = m_radius * lodScale; + qreal radius = m_radius; + radius *= lodScale; mypaint_brush_set_base_value(m_brush->brush(), MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC, log(radius)); m_isStrokeStarted = mypaint_brush_get_state(m_brush->brush(), MYPAINT_BRUSH_STATE_STROKE_STARTED); diff --git a/plugins/paintops/mypaint/MyPaintPaintOpFactory.cpp b/plugins/paintops/mypaint/MyPaintPaintOpFactory.cpp index 8412f77706e..60a3f97dfda 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpFactory.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpFactory.cpp @@ -19,7 +19,6 @@ #include "MyPaintPaintOp.h" #include "MyPaintPaintOpPreset.h" -#include "MyPaintPaintOpOption.h" #include "MyPaintPaintOpSettings.h" #include "MyPaintPaintOpSettingsWidget.h" diff --git a/plugins/paintops/mypaint/MyPaintPaintOpOption.cpp b/plugins/paintops/mypaint/MyPaintPaintOpOption.cpp deleted file mode 100644 index f8e63048c02..00000000000 --- a/plugins/paintops/mypaint/MyPaintPaintOpOption.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "MyPaintPaintOpOption.h" - -#include -#include "ui_wdgmypaintoptions.h" -#include - -class KisMyPaintOpOptionsWidget: public QWidget, public Ui::WdgMyPaintOptions -{ -public: - KisMyPaintOpOptionsWidget(QWidget *parent = 0) - : QWidget(parent) { - - setupUi(this); - } -}; - -KisMyPaintOpOption::KisMyPaintOpOption() - : KisPaintOpOption(i18nc("MyPaint option name", "Basic"), KisPaintOpOption::GENERAL, false) -{ - setObjectName("KisMyPaintOpOption"); - - m_checkable = false; - m_options = new KisMyPaintOpOptionsWidget(); - - m_options->radiusSPBox->setRange(0.01, 7.0, 2); - m_options->radiusSPBox->setSingleStep(0.01); - m_options->radiusSPBox->setValue(radius()); - - m_options->hardnessSPBox->setRange(0.02, 1.0, 2); - m_options->hardnessSPBox->setSingleStep(0.01); - m_options->hardnessSPBox->setValue(hardness()); - - m_options->opacitySPBox->setRange(0.0, 1.0, 2); - m_options->opacitySPBox->setSingleStep(0.01); - m_options->opacitySPBox->setValue(opacity()); - - m_options->eraserBox->setChecked(eraser()); - - connect(m_options->eraserBox, SIGNAL(toggled(bool)), SLOT(emitSettingChanged())); - - setConfigurationPage(m_options); -} - -KisMyPaintOpOption::~KisMyPaintOpOption() -{ - delete m_options; -} - -void KisMyPaintOpOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const -{ - KisMyPaintOptionProperties op; - - op.diameter = 2*exp(m_options->radiusSPBox->value()); - op.hardness = m_options->hardnessSPBox->value(); - op.opacity = m_options->opacitySPBox->value(); - op.eraserMode = m_options->eraserBox->isChecked(); - op.json = this->json; - op.eraser = this->eraserVal; - - op.writeOptionSetting(setting); -} - -void KisMyPaintOpOption::readOptionSetting(const KisPropertiesConfigurationSP setting) -{ - KisMyPaintOptionProperties op; - op.readOptionSetting(setting); - - if(!setting->getProperty(MYPAINT_JSON).isNull()) - this->json = setting->getProperty(MYPAINT_JSON).toByteArray(); - - m_options->radiusSPBox->setValue(op.radius()); - m_options->hardnessSPBox->setValue(op.hardness); - m_options->opacitySPBox->setValue(op.opacity); - m_options->eraserBox->setChecked(op.eraserMode); - this->eraserVal = op.eraser; -} - -void KisMyPaintOpOption::lodLimitations(KisPaintopLodLimitations *l) const { - - Q_UNUSED(l); -} - -void KisMyPaintOpOption::refresh() { - - emitSettingChanged(); -} - -void KisMyPaintOpOption::setEraser(bool isEraser) const -{ - m_options->eraserBox->setChecked(isEraser); -} - -bool KisMyPaintOpOption::eraser() const -{ - return m_options->eraserBox->isChecked(); -} - -void KisMyPaintOpOption::setOpacity(int opacity) const -{ - m_options->opacitySPBox->setValue(opacity); -} - -int KisMyPaintOpOption::opacity() const -{ - return m_options->opacitySPBox->value(); -} - - -void KisMyPaintOpOption::setHardness(int hardness) const -{ - m_options->hardnessSPBox->setValue(hardness); -} - -int KisMyPaintOpOption::hardness() const -{ - return m_options->hardnessSPBox->value(); -} - -void KisMyPaintOpOption::setRadius(int radius) const -{ - m_options->radiusSPBox->setValue(radius); -} - -int KisMyPaintOpOption::radius() const -{ - return m_options->radiusSPBox->value(); -} - -KisDoubleSliderSpinBox* KisMyPaintOpOption::radiusSlider() { - - return m_options->radiusSPBox; -} - -KisDoubleSliderSpinBox* KisMyPaintOpOption::hardnessSlider() { - - return m_options->hardnessSPBox; -} - -KisDoubleSliderSpinBox* KisMyPaintOpOption::opacitySlider() { - - return m_options->opacitySPBox; -} diff --git a/plugins/paintops/mypaint/MyPaintPaintOpOption.h b/plugins/paintops/mypaint/MyPaintPaintOpOption.h deleted file mode 100644 index bb53f9adec9..00000000000 --- a/plugins/paintops/mypaint/MyPaintPaintOpOption.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020 Ashwin Dhakaita - * SPDX-FileCopyrightText: 2021 L. E. Segovia - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef KIS_MY_PAINTOP_OPTION_H -#define KIS_MY_PAINTOP_OPTION_H - -#include -#include -#include -#include - -const QString MYPAINT_DIAMETER = "MyPaint/diameter"; -const QString MYPAINT_HARDNESS = "MyPaint/hardness"; -const QString MYPAINT_OPACITY = "MyPaint/opcity"; -const QString MYPAINT_JSON = "MyPaint/json"; -const QString MYPAINT_BRUSH = "MyPaint/brush"; -const QString MYPAINT_OFFSET_BY_RANDOM = "MyPaint/Offset"; - -class KisMyPaintOpOptionsWidget; - -class KisMyPaintOpOption : public KisPaintOpOption -{ -public: - enum PaintopCategory { BASIC, AIRBRUSH, COLOR, SPEED, DABS, OPACITY, TRACKING, STROKE, SMUDGE, CUSTOM }; - - KisMyPaintOpOption(); - ~KisMyPaintOpOption() override; - - void setRadius(int radius) const; - int radius() const; - - void setHardness(int hardness) const; - int hardness() const; - - void setOpacity(int opacity) const; - int opacity() const; - - void setEraser(bool isEraser) const; - bool eraser() const; - - void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; - void readOptionSetting(const KisPropertiesConfigurationSP setting) override; - void lodLimitations(KisPaintopLodLimitations *l) const override; - - void refresh(); - KisDoubleSliderSpinBox* radiusSlider(); - KisDoubleSliderSpinBox* hardnessSlider(); - KisDoubleSliderSpinBox* opacitySlider(); - -private: - KisMyPaintOpOptionsWidget *m_options {nullptr}; - QByteArray json; - float eraserVal {0.0}; - -}; - -class KisMyPaintOptionProperties: public KisPaintopPropertiesBase -{ -public: - float radius() const { - return log(diameter/2); - } - - void readOptionSettingImpl(const KisPropertiesConfiguration *settings) override { - - hardness = settings->getFloat(MYPAINT_HARDNESS); - eraserMode = settings->getBool("EraserMode"); - opacity = settings->getFloat(MYPAINT_OPACITY); - diameter = settings->getFloat(MYPAINT_DIAMETER); - json = settings->getProperty(MYPAINT_JSON).toByteArray(); - offset = settings->getFloat(MYPAINT_OFFSET_BY_RANDOM); - - } - - void writeOptionSettingImpl(KisPropertiesConfiguration *settings) const override { - - settings->setProperty(MYPAINT_DIAMETER, diameter); - settings->setProperty(MYPAINT_OPACITY, opacity); - settings->setProperty(MYPAINT_HARDNESS, hardness); - settings->setProperty(MYPAINT_JSON, json); - settings->setProperty("EraserMode", eraserMode); - settings->setProperty(MYPAINT_OFFSET_BY_RANDOM, offset); - } - - -public: - float diameter {1.0}; - float hardness {1.0}; - float opacity {1.0}; - float eraser {0.0}; - float offset {0.0}; - bool eraserMode {false}; - QByteArray json; - -}; - -#endif // KIS_MY_PAINTOP_OPTION_H diff --git a/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp b/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp index b85265f7d6c..7d7a2d7a655 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp @@ -17,10 +17,10 @@ #include #include #include -#include #include #include "MyPaintPaintOpSettings.h" +#include "MyPaintSensorPack.h" class KisMyPaintPaintOpPreset::Private { @@ -28,11 +28,6 @@ class KisMyPaintPaintOpPreset::Private { MyPaintBrush *brush; QImage icon; QByteArray json; - float diameter; - float hardness; - float opacity; - float offset; - float isEraser; }; KisMyPaintPaintOpPreset::KisMyPaintPaintOpPreset(const QString &fileName) @@ -95,22 +90,6 @@ void KisMyPaintPaintOpPreset::apply(KisPaintOpSettingsSP settings) { mypaint_brush_from_string(d->brush, ba); } - float diameter = settings->getFloat(MYPAINT_DIAMETER); - d->diameter = diameter; - mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC, log(diameter/2)); - - float hardness = settings->getFloat(MYPAINT_HARDNESS); - d->hardness = hardness; - mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_HARDNESS, hardness); - - float opacity = settings->getFloat(MYPAINT_OPACITY); - d->opacity = opacity; - mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_OPAQUE, opacity); - - float offset = settings->getFloat(MYPAINT_OFFSET_BY_RANDOM); - d->offset = offset; - mypaint_brush_set_base_value(d->brush, MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM, offset); - mypaint_brush_new_stroke(d->brush); } @@ -153,21 +132,13 @@ bool KisMyPaintPaintOpPreset::loadFromDevice(QIODevice *dev, KisResourcesInterfa // if the json is incorrect, the brush will get the default mypaint brush settings // which looks like a round brush with low opacity and high spacing bool success = mypaint_brush_from_string(d->brush, ba); - d->diameter = 2*exp(mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC)); - d->hardness = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_HARDNESS); - d->opacity = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_OPAQUE); - d->offset = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_OFFSET_BY_RANDOM); - d->isEraser = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_ERASER); + const float isEraser = mypaint_brush_get_base_value(d->brush, MYPAINT_BRUSH_SETTING_ERASER); KisPaintOpSettingsSP s = new KisMyPaintOpSettings(resourcesInterface); s->setProperty("paintop", "mypaintbrush"); s->setProperty("filename", this->filename()); s->setProperty(MYPAINT_JSON, this->getJsonData()); - s->setProperty(MYPAINT_DIAMETER, this->getSize()); - s->setProperty(MYPAINT_HARDNESS, this->getHardness()); - s->setProperty(MYPAINT_OPACITY, this->getOpacity()); - s->setProperty(MYPAINT_OFFSET_BY_RANDOM, this->getOffset()); - s->setProperty("EraserMode", qRound(this->isEraser())); + s->setProperty("EraserMode", qRound(isEraser)); if (!metadata().contains("paintopid")) { addMetaData("paintopid", "mypaintbrush"); @@ -194,28 +165,3 @@ QByteArray KisMyPaintPaintOpPreset::getJsonData() { return d->json; } - -float KisMyPaintPaintOpPreset::getSize() { - - return d->diameter; -} - -float KisMyPaintPaintOpPreset::getHardness() { - - return d->hardness; -} - -float KisMyPaintPaintOpPreset::getOpacity() { - - return d->opacity; -} - -float KisMyPaintPaintOpPreset::getOffset() { - - return d->offset; -} - -float KisMyPaintPaintOpPreset::isEraser() { - - return d->isEraser; -} diff --git a/plugins/paintops/mypaint/MyPaintPaintOpPreset.h b/plugins/paintops/mypaint/MyPaintPaintOpPreset.h index c3d73f80aad..98dc649963f 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpPreset.h +++ b/plugins/paintops/mypaint/MyPaintPaintOpPreset.h @@ -39,11 +39,6 @@ class KisMyPaintPaintOpPreset : public KisPaintOpPreset QString thumbnailPath() const override; QByteArray getJsonData(); - float getSize(); - float getHardness(); - float getOpacity(); - float getOffset(); - float isEraser(); private: class Private; diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp index 76ca27d73a8..0311aaa4645 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp @@ -8,9 +8,8 @@ #include #include -#include #include -#include "MyPaintPaintOpOption.h" +#include struct KisMyPaintOpSettings::Private { @@ -31,32 +30,32 @@ KisMyPaintOpSettings::~KisMyPaintOpSettings() void KisMyPaintOpSettings::setPaintOpSize(qreal value) { - KisMyPaintOptionProperties op; - op.readOptionSettingImpl(this); - op.diameter = value; - op.writeOptionSettingImpl(this); + MyPaintRadiusLogarithmicData data; + data.read(this); + data.strengthValue = log(0.5 * value); + data.write(this); } qreal KisMyPaintOpSettings::paintOpSize() const { - KisMyPaintOptionProperties op; - op.readOptionSettingImpl(this); - return op.diameter; + MyPaintRadiusLogarithmicData data; + data.read(this); + return 2 * exp(data.strengthValue); } void KisMyPaintOpSettings::setPaintOpOpacity(qreal value) { - KisMyPaintOptionProperties op; - op.readOptionSettingImpl(this); - op.opacity = value; - op.writeOptionSettingImpl(this); + MyPaintOpacityData data; + data.read(this); + data.strengthValue = value; + data.write(this); } qreal KisMyPaintOpSettings::paintOpOpacity() { - KisMyPaintOptionProperties op; - op.readOptionSettingImpl(this); - return op.opacity; + MyPaintOpacityData data; + data.read(this); + return data.strengthValue; } bool KisMyPaintOpSettings::paintIncremental() @@ -64,19 +63,18 @@ bool KisMyPaintOpSettings::paintIncremental() return true; } - KisOptimizedBrushOutline KisMyPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) { KisOptimizedBrushOutline path; - KisMyPaintOptionProperties op; - op.readOptionSettingImpl(this); - if (mode.isVisible) { qreal finalScale = 1.0; - qreal radius = 0.5 * op.diameter; - qreal offset = op.offset; + MyPaintOffsetByRandomData data; + data.read(this); + const qreal offset = data.strengthValue; + + qreal radius = 0.5 * paintOpSize(); radius = radius + 2 * radius * offset; radius = qBound(3.5, radius, 500.0); diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp index eceb26d689d..12762c01b14 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp @@ -15,363 +15,7 @@ #include #include #include - -struct MyPaintRadiusLogarithmicData : MyPaintCurveOptionData -{ - MyPaintRadiusLogarithmicData() - : MyPaintCurveOptionData(KoID("radius_logarithmic", - i18n("Radius Logarithmic")), - false, true, 0.01, 8.0) - { - } -}; - -struct MyPaintHardnessData : MyPaintCurveOptionData -{ - MyPaintHardnessData() - : MyPaintCurveOptionData(KoID("hardness", i18n("Hardness")), - false, true, 0.02, 1.0) - { - } -}; - -struct MyPaintOpacityData : MyPaintCurveOptionData -{ - MyPaintOpacityData() - : MyPaintCurveOptionData(KoID("opaque", i18n("Opaque")), - false, true, 0.0, 1.0) - { - } -}; - -struct MyPaintRadiusByRandomData : MyPaintCurveOptionData -{ - MyPaintRadiusByRandomData() - : MyPaintCurveOptionData(KoID("radius_by_random", i18n("Radius by Random")), - false, true, 0.0, 1.50) - { - } -}; - -struct MyPaintAntiAliasingData : MyPaintCurveOptionData -{ - MyPaintAntiAliasingData() - : MyPaintCurveOptionData(KoID("anti_aliasing", i18n("Anti Aliasing")), - false, true, 0.0, 1.0) - { - } -}; - -struct MyPaintEllipticalDabAngleData : MyPaintCurveOptionData -{ - MyPaintEllipticalDabAngleData() - : MyPaintCurveOptionData(KoID("elliptical_dab_angle", - i18n("Elliptical Dab Angle")), - false, true, 0.0, 180.0) - { - } -}; - -struct MyPaintEllipticalDabRatioData : MyPaintCurveOptionData -{ - MyPaintEllipticalDabRatioData() - : MyPaintCurveOptionData(KoID("elliptical_dab_ratio", i18n("Elliptical Dab Ratio")), - false, true, 1.0, 10.0) - { - } -}; - - -struct MyPaintDirectionFilterData : MyPaintCurveOptionData -{ - MyPaintDirectionFilterData() - : MyPaintCurveOptionData(KoID("direction_filter", i18n("Direction Filter")), - false, true, 0.0, 10.0) - { - } -}; - -struct MyPaintSnapToPixelsData : MyPaintCurveOptionData -{ - MyPaintSnapToPixelsData() - : MyPaintCurveOptionData(KoID("snap_to_pixel", i18n("Snap To Pixel")), - false, true, 0.0, 10.0) - { - } -}; - - -struct MyPaintPressureGainData : MyPaintCurveOptionData -{ - MyPaintPressureGainData() - : MyPaintCurveOptionData(KoID("pressure_gain_log", i18n("Pressure Gain")), - false, true, -1.8, 1.8) - { - } -}; - - -struct MyPaintChangeColorHData : MyPaintCurveOptionData -{ - MyPaintChangeColorHData() - : MyPaintCurveOptionData(KoID("change_color_h", i18n("Change Color H")), - false, true, -2.0, 2.0) - { - } -}; - -struct MyPaintChangeColorLData : MyPaintCurveOptionData -{ - MyPaintChangeColorLData() - : MyPaintCurveOptionData(KoID("change_color_l", i18n("Change Color L")), - false, true, -2.0, 2.0) - { - } -}; - -struct MyPaintChangeColorVData : MyPaintCurveOptionData -{ - MyPaintChangeColorVData() - : MyPaintCurveOptionData(KoID("change_color_v", i18n("Change Color V")), - false, true, -2.0, 2.0) - { - } -}; - -struct MyPaintChangeColorHSLSData : MyPaintCurveOptionData -{ - MyPaintChangeColorHSLSData() - : MyPaintCurveOptionData(KoID("change_color_hsl_s", i18n("Change Color HSL S")), - false, true, -2.0, 2.0) - { - } -}; - -struct MyPaintChangeColorHSVSData : MyPaintCurveOptionData -{ - MyPaintChangeColorHSVSData() - : MyPaintCurveOptionData(KoID("change_color_hsv_s", i18n("Change Color HSV S")), - false, true, -2.0, 2.0) - { - } -}; - -struct MyPaintColorizeData : MyPaintCurveOptionData -{ - MyPaintColorizeData() - : MyPaintCurveOptionData(KoID("colorize", i18n("Colorize")), - false, true, 0.0, 1.0) - { - } -}; - -struct MyPaintFineSpeedGammaData : MyPaintCurveOptionData -{ - MyPaintFineSpeedGammaData() - : MyPaintCurveOptionData(KoID("speed1_gamma", i18n("Fine Speed Gamma")), - false, true, -8.0, 8.0) - { - } -}; - -struct MyPaintGrossSpeedGammaData : MyPaintCurveOptionData -{ - MyPaintGrossSpeedGammaData() - : MyPaintCurveOptionData(KoID("speed2_gamma", i18n("Gross Speed Gamma")), - false, true, -8.0, 8.0) - { - } -}; - -struct MyPaintFineSpeedSlownessData : MyPaintCurveOptionData -{ - MyPaintFineSpeedSlownessData() - : MyPaintCurveOptionData(KoID("speed1_slowness", i18n("Fine Speed Slowness")), - false, true, -8.0, 8.0) - { - } -}; - -struct MyPaintGrossSpeedSlownessData : MyPaintCurveOptionData -{ - MyPaintGrossSpeedSlownessData() - : MyPaintCurveOptionData(KoID("speed2_slowness", i18n("Gross Speed Slowness")), - false, true, -8.0, 8.0) - { - } -}; - -struct MyPaintOffsetBySpeedData : MyPaintCurveOptionData -{ - MyPaintOffsetBySpeedData() - : MyPaintCurveOptionData(KoID("offset_by_speed", i18n("Offset By Speed")), - false, true, -3.0, 3.0) - { - } -}; - -struct MyPaintOffsetBySpeedFilterData : MyPaintCurveOptionData -{ - MyPaintOffsetBySpeedFilterData() - : MyPaintCurveOptionData(KoID("offset_by_speed_slowness", i18n("Offset by Speed Filter")), - false, true, 0.0, 15.0) - { - } -}; - -struct MyPaintOffsetByRandomData : MyPaintCurveOptionData -{ - MyPaintOffsetByRandomData() - : MyPaintCurveOptionData(KoID("offset_by_random", i18n("Offset By Random")), - false, true, -3.0, 3.0) - { - } -}; - -struct MyPaintDabsPerBasicRadiusData : MyPaintCurveOptionData -{ - MyPaintDabsPerBasicRadiusData() - : MyPaintCurveOptionData(KoID("dabs_per_basic_radius", i18n("Dabs Per Basic Radius")), - false, true, 0.0, 6.0) - { - } -}; - -struct MyPaintDabsPerActualRadiusData : MyPaintCurveOptionData -{ - MyPaintDabsPerActualRadiusData() - : MyPaintCurveOptionData(KoID("dabs_per_actual_radius", i18n("Dabs Per Actual Radius")), - false, true, 0.0, 6.0) - { - } -}; - -struct MyPaintDabsPerSecondData : MyPaintCurveOptionData -{ - MyPaintDabsPerSecondData() - : MyPaintCurveOptionData(KoID("dabs_per_second", i18n("Dabs per Second")), - false, true, 0.0, 80.0) - { - } -}; - - -struct MyPaintOpaqueLinearizeData : MyPaintCurveOptionData -{ - MyPaintOpaqueLinearizeData() - : MyPaintCurveOptionData(KoID("opaque_linearize", i18n("Opaque Linearize")), - false, true, 0.0, 3.0) - { - } -}; - -struct MyPaintOpaqueMultiplyData : MyPaintCurveOptionData -{ - MyPaintOpaqueMultiplyData() - : MyPaintCurveOptionData(KoID("opaque_multiply", i18n("Opaque Multiply")), - false, true, 0.0, 2.0) - { - } -}; - -struct MyPaintSlowTrackingPerDabData : MyPaintCurveOptionData -{ - MyPaintSlowTrackingPerDabData() - : MyPaintCurveOptionData(KoID("slow_tracking_per_dab", i18n("Slow tracking per dab")), - false, true, 0.0, 10.0) - { - } -}; - -struct MyPaintSlowTrackingData : MyPaintCurveOptionData -{ - MyPaintSlowTrackingData() - : MyPaintCurveOptionData(KoID("slow_tracking", i18n("Slow Tracking")), - false, true, 0.0, 10.0) - { - } -}; - -struct MyPaintTrackingNoiseData : MyPaintCurveOptionData -{ - MyPaintTrackingNoiseData() - : MyPaintCurveOptionData(KoID("tracking_noise", i18n("Tracking Noise")), - false, true, 0.0, 12.0) - { - } -}; - -struct MyPaintSmudgeData : MyPaintCurveOptionData -{ - MyPaintSmudgeData() - : MyPaintCurveOptionData(KoID("smudge", i18n("Smudge")), - false, true, 0.0, 1.0) - { - } -}; - -struct MyPaintSmudgeLengthData : MyPaintCurveOptionData -{ - MyPaintSmudgeLengthData() - : MyPaintCurveOptionData(KoID("smudge_length", i18n("Smudge Length")), - false, true, 0.0, 1.0) - { - } -}; - -struct MyPaintSmudgeRadiusLogData : MyPaintCurveOptionData -{ - MyPaintSmudgeRadiusLogData() - : MyPaintCurveOptionData(KoID("smudge_radius_log", i18n("Smudge Radius Log")), - false, true, -1.6, 1.6) - { - } -}; - -struct MyPaintStrokeDurationLogData : MyPaintCurveOptionData -{ - MyPaintStrokeDurationLogData() - : MyPaintCurveOptionData(KoID("stroke_duration_logarithmic", i18n("Stroke Duration log")), - false, true, -1.0, 7.0) - { - } -}; - -struct MyPaintStrokeHoldtimeData : MyPaintCurveOptionData -{ - MyPaintStrokeHoldtimeData() - : MyPaintCurveOptionData(KoID("stroke_holdtime", i18n("Stroke Holdtime")), - false, true, 0.0, 10.0) - { - } -}; - -struct MyPaintStrokeThresholdData : MyPaintCurveOptionData -{ - MyPaintStrokeThresholdData() - : MyPaintCurveOptionData(KoID("stroke_threshold", i18n("Stroke Threshold")), - false, true, 0.0, 0.5) - { - } -}; - -struct MyPaintCustomInputData : MyPaintCurveOptionData -{ - MyPaintCustomInputData() - : MyPaintCurveOptionData(KoID("custom_input", i18n("Custom Input")), - false, true, -5.0, 5.0) - { - } -}; - -struct MyPaintCustomInputSlownessData : MyPaintCurveOptionData -{ - MyPaintCustomInputSlownessData() - : MyPaintCurveOptionData(KoID("custom_input_slowness", i18n("Custom Input Slowness")), - false, true, 0.0, 10.0) - { - } -}; +#include namespace KisPaintOpOptionWidgetUtils { @@ -407,94 +51,94 @@ KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) opacityWidget->strengthValueDenorm())); addPaintOpOption(radiusWidget, - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintRadiusByRandomData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(hardnessWidget, - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintAntiAliasingData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintEllipticalDabAngleData(), "°"), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintEllipticalDabRatioData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDirectionFilterData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSnapToPixelsData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintPressureGainData()), - KisMyPaintOpOption::BASIC); + BASIC); addPaintOpOption(kpowu::createOptionWidget(), - KisMyPaintOpOption::AIRBRUSH); + AIRBRUSH); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorLData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorVData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHSLSData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintChangeColorHSVSData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintColorizeData()), - KisMyPaintOpOption::COLOR); + COLOR); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintFineSpeedGammaData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintGrossSpeedGammaData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintFineSpeedSlownessData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintGrossSpeedSlownessData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetBySpeedData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetBySpeedFilterData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetByRandomData()), - KisMyPaintOpOption::SPEED); + SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerBasicRadiusData()), - KisMyPaintOpOption::DABS); + DABS); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerActualRadiusData()), - KisMyPaintOpOption::DABS); + DABS); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerSecondData()), - KisMyPaintOpOption::DABS); + DABS); addPaintOpOption(opacityWidget, - KisMyPaintOpOption::OPACITY); + OPACITY); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOpaqueLinearizeData()), - KisMyPaintOpOption::OPACITY); + OPACITY); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOpaqueMultiplyData()), - KisMyPaintOpOption::OPACITY); + OPACITY); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSlowTrackingPerDabData()), - KisMyPaintOpOption::TRACKING); + TRACKING); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSlowTrackingData()), - KisMyPaintOpOption::TRACKING); + TRACKING); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintTrackingNoiseData()), - KisMyPaintOpOption::TRACKING); + TRACKING); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeData()), - KisMyPaintOpOption::SMUDGE); + SMUDGE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeLengthData()), - KisMyPaintOpOption::SMUDGE); + SMUDGE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintSmudgeRadiusLogData()), - KisMyPaintOpOption::SMUDGE); + SMUDGE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeDurationLogData()), - KisMyPaintOpOption::STROKE); + STROKE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeHoldtimeData()), - KisMyPaintOpOption::STROKE); + STROKE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintStrokeThresholdData()), - KisMyPaintOpOption::STROKE); + STROKE); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintCustomInputData()), - KisMyPaintOpOption::CUSTOM); + CUSTOM); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintCustomInputSlownessData()), - KisMyPaintOpOption::CUSTOM); + CUSTOM); } KisMyPaintOpSettingsWidget::~ KisMyPaintOpSettingsWidget() @@ -509,39 +153,39 @@ KisPropertiesConfigurationSP KisMyPaintOpSettingsWidget::configuration() const return config; } -void KisMyPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, KisMyPaintOpOption::PaintopCategory id) +void KisMyPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, MyPaintPaintopCategory id) { QString category; switch (id) { - case KisMyPaintOpOption::BASIC: + case BASIC: category = i18nc("Option Category", "Basic"); break; - case KisMyPaintOpOption::AIRBRUSH: + case AIRBRUSH: category = i18n("Airbrush"); break; - case KisMyPaintOpOption::COLOR: + case COLOR: category = i18nc("Option Category", "Color"); break; - case KisMyPaintOpOption::SPEED: + case SPEED: category = i18nc("Option Category", "Speed"); break; - case KisMyPaintOpOption::DABS: + case DABS: category = i18nc("Option Category", "Dabs"); break; - case KisMyPaintOpOption::OPACITY: + case OPACITY: category = i18nc("Option Category", "Opacity"); break; - case KisMyPaintOpOption::TRACKING: + case TRACKING: category = i18nc("Option Category", "Tracking"); break; - case KisMyPaintOpOption::SMUDGE: + case SMUDGE: category = i18nc("Option Category", "Smudge"); break; - case KisMyPaintOpOption::STROKE: + case STROKE: category = i18nc("Option Category", "Stroke"); break; - case KisMyPaintOpOption::CUSTOM: + case CUSTOM: category = i18nc("Option Category", "Custom"); break; } diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h index bd49b3c789c..c74e18c1fd2 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h @@ -9,15 +9,14 @@ #define KIS_MYPAINTOP_SETTINGS_WIDGET_H_ #include -#include -#include class MyPaintCurveOptionWidget2; class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget { Q_OBJECT - +public: + enum MyPaintPaintopCategory { BASIC, AIRBRUSH, COLOR, SPEED, DABS, OPACITY, TRACKING, STROKE, SMUDGE, CUSTOM }; public: KisMyPaintOpSettingsWidget(QWidget* parent = 0); ~KisMyPaintOpSettingsWidget() override; @@ -25,7 +24,7 @@ class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget KisPropertiesConfigurationSP configuration() const override; protected: - void addPaintOpOption(KisPaintOpOption *option, KisMyPaintOpOption::PaintopCategory id); + void addPaintOpOption(KisPaintOpOption *option, MyPaintPaintopCategory id); }; #endif diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.cpp b/plugins/paintops/mypaint/MyPaintSensorPack.cpp index 6acc49b8226..03bbf3d73f3 100644 --- a/plugins/paintops/mypaint/MyPaintSensorPack.cpp +++ b/plugins/paintops/mypaint/MyPaintSensorPack.cpp @@ -19,8 +19,6 @@ #include #include -const QString MYPAINT_JSON = "MyPaint/json"; - namespace detail { struct MyPaintSensorFactoriesRegistrar { diff --git a/plugins/paintops/mypaint/MyPaintSensorPack.h b/plugins/paintops/mypaint/MyPaintSensorPack.h index 6d3bc51dcca..381d6b72e11 100644 --- a/plugins/paintops/mypaint/MyPaintSensorPack.h +++ b/plugins/paintops/mypaint/MyPaintSensorPack.h @@ -12,6 +12,8 @@ #include #include +const QString MYPAINT_JSON = "MyPaint/json"; + const KoID MyPaintPressureId("mypaint_pressure", ki18n("Pressure")); const KoID MyPaintFineSpeedId("mypaint_speed1", ki18n("Fine Speed")); const KoID MyPaintGrossSpeedId("mypaint_speed2", ki18n("Gross Speed")); diff --git a/plugins/paintops/mypaint/MyPaintStandardOptionData.h b/plugins/paintops/mypaint/MyPaintStandardOptionData.h new file mode 100644 index 00000000000..19292a581fc --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintStandardOptionData.h @@ -0,0 +1,368 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef MYPAINTSTANDARDOPTIONDATA_H +#define MYPAINTSTANDARDOPTIONDATA_H + +#include + +struct MyPaintRadiusLogarithmicData : MyPaintCurveOptionData +{ + MyPaintRadiusLogarithmicData() + : MyPaintCurveOptionData(KoID("radius_logarithmic", + i18n("Radius Logarithmic")), + false, true, 0.01, 8.0) + { + } +}; + +struct MyPaintHardnessData : MyPaintCurveOptionData +{ + MyPaintHardnessData() + : MyPaintCurveOptionData(KoID("hardness", i18n("Hardness")), + false, true, 0.02, 1.0) + { + } +}; + +struct MyPaintOpacityData : MyPaintCurveOptionData +{ + MyPaintOpacityData() + : MyPaintCurveOptionData(KoID("opaque", i18n("Opaque")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintRadiusByRandomData : MyPaintCurveOptionData +{ + MyPaintRadiusByRandomData() + : MyPaintCurveOptionData(KoID("radius_by_random", i18n("Radius by Random")), + false, true, 0.0, 1.50) + { + } +}; + +struct MyPaintAntiAliasingData : MyPaintCurveOptionData +{ + MyPaintAntiAliasingData() + : MyPaintCurveOptionData(KoID("anti_aliasing", i18n("Anti Aliasing")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintEllipticalDabAngleData : MyPaintCurveOptionData +{ + MyPaintEllipticalDabAngleData() + : MyPaintCurveOptionData(KoID("elliptical_dab_angle", + i18n("Elliptical Dab Angle")), + false, true, 0.0, 180.0) + { + } +}; + +struct MyPaintEllipticalDabRatioData : MyPaintCurveOptionData +{ + MyPaintEllipticalDabRatioData() + : MyPaintCurveOptionData(KoID("elliptical_dab_ratio", i18n("Elliptical Dab Ratio")), + false, true, 1.0, 10.0) + { + } +}; + + +struct MyPaintDirectionFilterData : MyPaintCurveOptionData +{ + MyPaintDirectionFilterData() + : MyPaintCurveOptionData(KoID("direction_filter", i18n("Direction Filter")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintSnapToPixelsData : MyPaintCurveOptionData +{ + MyPaintSnapToPixelsData() + : MyPaintCurveOptionData(KoID("snap_to_pixel", i18n("Snap To Pixel")), + false, true, 0.0, 10.0) + { + } +}; + + +struct MyPaintPressureGainData : MyPaintCurveOptionData +{ + MyPaintPressureGainData() + : MyPaintCurveOptionData(KoID("pressure_gain_log", i18n("Pressure Gain")), + false, true, -1.8, 1.8) + { + } +}; + + +struct MyPaintChangeColorHData : MyPaintCurveOptionData +{ + MyPaintChangeColorHData() + : MyPaintCurveOptionData(KoID("change_color_h", i18n("Change Color H")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorLData : MyPaintCurveOptionData +{ + MyPaintChangeColorLData() + : MyPaintCurveOptionData(KoID("change_color_l", i18n("Change Color L")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorVData : MyPaintCurveOptionData +{ + MyPaintChangeColorVData() + : MyPaintCurveOptionData(KoID("change_color_v", i18n("Change Color V")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorHSLSData : MyPaintCurveOptionData +{ + MyPaintChangeColorHSLSData() + : MyPaintCurveOptionData(KoID("change_color_hsl_s", i18n("Change Color HSL S")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintChangeColorHSVSData : MyPaintCurveOptionData +{ + MyPaintChangeColorHSVSData() + : MyPaintCurveOptionData(KoID("change_color_hsv_s", i18n("Change Color HSV S")), + false, true, -2.0, 2.0) + { + } +}; + +struct MyPaintColorizeData : MyPaintCurveOptionData +{ + MyPaintColorizeData() + : MyPaintCurveOptionData(KoID("colorize", i18n("Colorize")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintFineSpeedGammaData : MyPaintCurveOptionData +{ + MyPaintFineSpeedGammaData() + : MyPaintCurveOptionData(KoID("speed1_gamma", i18n("Fine Speed Gamma")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintGrossSpeedGammaData : MyPaintCurveOptionData +{ + MyPaintGrossSpeedGammaData() + : MyPaintCurveOptionData(KoID("speed2_gamma", i18n("Gross Speed Gamma")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintFineSpeedSlownessData : MyPaintCurveOptionData +{ + MyPaintFineSpeedSlownessData() + : MyPaintCurveOptionData(KoID("speed1_slowness", i18n("Fine Speed Slowness")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintGrossSpeedSlownessData : MyPaintCurveOptionData +{ + MyPaintGrossSpeedSlownessData() + : MyPaintCurveOptionData(KoID("speed2_slowness", i18n("Gross Speed Slowness")), + false, true, -8.0, 8.0) + { + } +}; + +struct MyPaintOffsetBySpeedData : MyPaintCurveOptionData +{ + MyPaintOffsetBySpeedData() + : MyPaintCurveOptionData(KoID("offset_by_speed", i18n("Offset By Speed")), + false, true, -3.0, 3.0) + { + } +}; + +struct MyPaintOffsetBySpeedFilterData : MyPaintCurveOptionData +{ + MyPaintOffsetBySpeedFilterData() + : MyPaintCurveOptionData(KoID("offset_by_speed_slowness", i18n("Offset by Speed Filter")), + false, true, 0.0, 15.0) + { + } +}; + +struct MyPaintOffsetByRandomData : MyPaintCurveOptionData +{ + MyPaintOffsetByRandomData() + : MyPaintCurveOptionData(KoID("offset_by_random", i18n("Offset By Random")), + false, true, -3.0, 3.0) + { + } +}; + +struct MyPaintDabsPerBasicRadiusData : MyPaintCurveOptionData +{ + MyPaintDabsPerBasicRadiusData() + : MyPaintCurveOptionData(KoID("dabs_per_basic_radius", i18n("Dabs Per Basic Radius")), + false, true, 0.0, 6.0) + { + } +}; + +struct MyPaintDabsPerActualRadiusData : MyPaintCurveOptionData +{ + MyPaintDabsPerActualRadiusData() + : MyPaintCurveOptionData(KoID("dabs_per_actual_radius", i18n("Dabs Per Actual Radius")), + false, true, 0.0, 6.0) + { + } +}; + +struct MyPaintDabsPerSecondData : MyPaintCurveOptionData +{ + MyPaintDabsPerSecondData() + : MyPaintCurveOptionData(KoID("dabs_per_second", i18n("Dabs per Second")), + false, true, 0.0, 80.0) + { + } +}; + + +struct MyPaintOpaqueLinearizeData : MyPaintCurveOptionData +{ + MyPaintOpaqueLinearizeData() + : MyPaintCurveOptionData(KoID("opaque_linearize", i18n("Opaque Linearize")), + false, true, 0.0, 3.0) + { + } +}; + +struct MyPaintOpaqueMultiplyData : MyPaintCurveOptionData +{ + MyPaintOpaqueMultiplyData() + : MyPaintCurveOptionData(KoID("opaque_multiply", i18n("Opaque Multiply")), + false, true, 0.0, 2.0) + { + } +}; + +struct MyPaintSlowTrackingPerDabData : MyPaintCurveOptionData +{ + MyPaintSlowTrackingPerDabData() + : MyPaintCurveOptionData(KoID("slow_tracking_per_dab", i18n("Slow tracking per dab")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintSlowTrackingData : MyPaintCurveOptionData +{ + MyPaintSlowTrackingData() + : MyPaintCurveOptionData(KoID("slow_tracking", i18n("Slow Tracking")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintTrackingNoiseData : MyPaintCurveOptionData +{ + MyPaintTrackingNoiseData() + : MyPaintCurveOptionData(KoID("tracking_noise", i18n("Tracking Noise")), + false, true, 0.0, 12.0) + { + } +}; + +struct MyPaintSmudgeData : MyPaintCurveOptionData +{ + MyPaintSmudgeData() + : MyPaintCurveOptionData(KoID("smudge", i18n("Smudge")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintSmudgeLengthData : MyPaintCurveOptionData +{ + MyPaintSmudgeLengthData() + : MyPaintCurveOptionData(KoID("smudge_length", i18n("Smudge Length")), + false, true, 0.0, 1.0) + { + } +}; + +struct MyPaintSmudgeRadiusLogData : MyPaintCurveOptionData +{ + MyPaintSmudgeRadiusLogData() + : MyPaintCurveOptionData(KoID("smudge_radius_log", i18n("Smudge Radius Log")), + false, true, -1.6, 1.6) + { + } +}; + +struct MyPaintStrokeDurationLogData : MyPaintCurveOptionData +{ + MyPaintStrokeDurationLogData() + : MyPaintCurveOptionData(KoID("stroke_duration_logarithmic", i18n("Stroke Duration log")), + false, true, -1.0, 7.0) + { + } +}; + +struct MyPaintStrokeHoldtimeData : MyPaintCurveOptionData +{ + MyPaintStrokeHoldtimeData() + : MyPaintCurveOptionData(KoID("stroke_holdtime", i18n("Stroke Holdtime")), + false, true, 0.0, 10.0) + { + } +}; + +struct MyPaintStrokeThresholdData : MyPaintCurveOptionData +{ + MyPaintStrokeThresholdData() + : MyPaintCurveOptionData(KoID("stroke_threshold", i18n("Stroke Threshold")), + false, true, 0.0, 0.5) + { + } +}; + +struct MyPaintCustomInputData : MyPaintCurveOptionData +{ + MyPaintCustomInputData() + : MyPaintCurveOptionData(KoID("custom_input", i18n("Custom Input")), + false, true, -5.0, 5.0) + { + } +}; + +struct MyPaintCustomInputSlownessData : MyPaintCurveOptionData +{ + MyPaintCustomInputSlownessData() + : MyPaintCurveOptionData(KoID("custom_input_slowness", i18n("Custom Input Slowness")), + false, true, 0.0, 10.0) + { + } +}; + +#endif // MYPAINTSTANDARDOPTIONDATA_H From e45d038203f1886fcecee65f998cfc169d140236 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Fri, 9 Dec 2022 19:48:43 +0300 Subject: [PATCH 13/20] Fix MyPaint brushes becoming corrupted after the first change We should preserve the JSON since we don't have options for all MyPaint settings. --- libs/image/brushengine/kis_paintop_settings.h | 2 +- plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp | 7 +++++++ plugins/paintops/mypaint/MyPaintPaintOpSettings.h | 1 + plugins/paintops/mypaint/MyPaintSensorPack.cpp | 9 +++++---- plugins/paintops/mypaint/MyPaintStandardOptionData.h | 2 +- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libs/image/brushengine/kis_paintop_settings.h b/libs/image/brushengine/kis_paintop_settings.h index 57c73813737..f5ca2d1c44e 100644 --- a/libs/image/brushengine/kis_paintop_settings.h +++ b/libs/image/brushengine/kis_paintop_settings.h @@ -110,7 +110,7 @@ class KRITAIMAGE_EXPORT KisPaintOpSettings : public KisPropertiesConfiguration * Removes all the settings from the object while keeping the paintop id, * which is loaded to the object by the factory */ - void resetSettings(const QStringList &preserveProperties = QStringList()); + virtual void resetSettings(const QStringList &preserveProperties = QStringList()); /** * @return the node the paintop is working on. diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp index 0311aaa4645..3f1e24c5c69 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettings.cpp @@ -63,6 +63,13 @@ bool KisMyPaintOpSettings::paintIncremental() return true; } +void KisMyPaintOpSettings::resetSettings(const QStringList &preserveProperties) +{ + QStringList allKeys = preserveProperties; + allKeys << MYPAINT_JSON; + KisOutlineGenerationPolicy::resetSettings(allKeys); +} + KisOptimizedBrushOutline KisMyPaintOpSettings::brushOutline(const KisPaintInformation &info, const OutlineMode &mode, qreal alignForZoom) { KisOptimizedBrushOutline path; diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettings.h b/plugins/paintops/mypaint/MyPaintPaintOpSettings.h index 3c7bae740ac..d876e66c06e 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettings.h +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettings.h @@ -35,6 +35,7 @@ class KisMyPaintOpSettings : public KisOutlineGenerationPolicyisActive = true; + data.useCurve = false; + } else { + data.useCurve = true; } data.strengthValue = qreal(mypaint_brush_get_base_value(brush.get(), brushSetting)); - data.useCurve = setting->getBool(data.id.id() + "UseCurve", true); data.useSameCurve = false; // not used in mypaint engine data.commonCurve = DEFAULT_CURVE_STRING; // not used in mypaint engine @@ -389,6 +391,7 @@ void MyPaintSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertie } QJsonDocument doc = QJsonDocument::fromJson(setting->getProperty(MYPAINT_JSON).toByteArray()); + QJsonObject brush_json = doc.object(); QVariantMap map = brush_json.toVariantMap(); QVariantMap settings_map = map["settings"].toMap(); @@ -401,7 +404,7 @@ void MyPaintSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertie const KisSensorData *sensor = *it; const QString sensorJsonId = sensorIdToMyPaintBrushInputJsonKey(sensor->id); - if (!sensor->isActive) { + if (!sensor->isActive || !data.useCurve) { inputs_map.remove(sensorJsonId); } else { KisCubicCurve curve(sensor->curve); @@ -425,8 +428,6 @@ void MyPaintSensorPack::write(const KisCurveOptionDataCommon &data, KisPropertie doc = QJsonDocument(QJsonObject::fromVariantMap(map)); setting->setProperty(MYPAINT_JSON, doc.toJson()); - setting->setProperty(data.id.id() + "UseCurve", data.useCurve); - // not used in mypaint engine setting->setProperty(data.id.id() + "UseSameCurve", false); setting->setProperty(data.id.id() + "commonCurve", DEFAULT_CURVE_STRING); diff --git a/plugins/paintops/mypaint/MyPaintStandardOptionData.h b/plugins/paintops/mypaint/MyPaintStandardOptionData.h index 19292a581fc..57e90d88136 100644 --- a/plugins/paintops/mypaint/MyPaintStandardOptionData.h +++ b/plugins/paintops/mypaint/MyPaintStandardOptionData.h @@ -31,7 +31,7 @@ struct MyPaintOpacityData : MyPaintCurveOptionData { MyPaintOpacityData() : MyPaintCurveOptionData(KoID("opaque", i18n("Opaque")), - false, true, 0.0, 1.0) + false, true, 0.0, 2.0) { } }; From 90821fe0b4eac0719ebd0cf649130cbc622fdb07 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Mon, 12 Dec 2022 16:07:42 +0300 Subject: [PATCH 14/20] Implement lod-limitations for the MyPaint brush engine The patch also implements a few routines that allow automatic creation a widget that provides lod-limitations fetched directly from its data. --- libs/global/KisMpl.h | 37 +++++++++++++++++++ libs/global/KisZug.h | 26 +++++++++++++ libs/image/tests/CMakeLists.txt | 1 + libs/image/tests/KisMplTest.cpp | 37 +++++++++++++++++++ libs/image/tests/KisMplTest.h | 18 +++++++++ libs/ui/kis_paintop_option.cpp | 20 ++++++---- libs/ui/kis_paintop_option.h | 6 ++- libs/ui/kis_paintop_settings_widget.cpp | 12 +++--- .../KisSmudgeOverlayModeOptionWidget.cpp | 2 +- .../KisSmudgeOverlayModeOptionWidget.h | 2 +- .../libpaintop/KisPaintOpOptionWidgetUtils.h | 36 +++++++++++++++++- .../libpaintop/KisSizeOptionWidget.cpp | 2 +- .../paintops/libpaintop/KisSizeOptionWidget.h | 2 +- .../libpaintop/KisTextureOptionWidget.cpp | 2 +- .../libpaintop/KisTextureOptionWidget.h | 2 +- .../libpaintop/kis_brush_option_widget.cpp | 2 +- .../libpaintop/kis_brush_option_widget.h | 2 +- .../mypaint/MyPaintCurveOptionWidget2.cpp | 30 +++++++++++++++ .../mypaint/MyPaintCurveOptionWidget2.h | 4 ++ .../mypaint/MyPaintPaintOpSettingsWidget.cpp | 26 ++++++++++--- .../mypaint/MyPaintPaintOpSettingsWidget.h | 5 +++ .../mypaint/MyPaintStandardOptionData.h | 19 ++++++++++ 22 files changed, 263 insertions(+), 30 deletions(-) create mode 100644 libs/image/tests/KisMplTest.cpp create mode 100644 libs/image/tests/KisMplTest.h diff --git a/libs/global/KisMpl.h b/libs/global/KisMpl.h index 1cc93ed99a2..666e6dd79e1 100644 --- a/libs/global/KisMpl.h +++ b/libs/global/KisMpl.h @@ -137,7 +137,44 @@ struct first_type template using first_type_t = typename first_type::type; +namespace detail { +template +struct fold_optional_impl { + std::optional fold(const std::optional &first) { + return first; + } + + std::optional fold(const std::optional &first, const std::optional &second) { + if (first && second) { + return m_fun(*first, *second); + } else if (first) { + return first; + } else { + return second; + } + } + + template + std::optional fold(const std::optional &first, std::optional const &second, const std::optional &...rest) { + return fold(fold(first, second), rest...); + } + + const Fun m_fun; +}; + +} // namespace detail +/** + * Folds all the valid optional values using the binary function \p fun into one + * optional value. When none optional values are present, an empty optional of the + * specified type is returned. + */ +template ...>::value_type> +std::optional fold_optional(Fun &&fun, Args &&...args) { + return detail::fold_optional_impl{std::forward(fun)}.fold(args...); } +} // namespace kismpl + #endif // KISMPL_H diff --git a/libs/global/KisZug.h b/libs/global/KisZug.h index 343bbe6666e..8286cd5ccdd 100644 --- a/libs/global/KisZug.h +++ b/libs/global/KisZug.h @@ -12,6 +12,7 @@ #include #include #include +#include /** * kiszug is a namespace extending the functionality of @@ -83,6 +84,31 @@ constexpr auto foreach_arg = }); }; +/** + * Fold all valid optional cursors from a set into one by using \p func + * + * Example: + * + * std::optional> brushSize1 = ...; + * std::optional> brushSize2 = ...; + * + * std::optional> maxSize = + * fold_optional_cursors(&std::max, brushSize1, brushSize2); + * + * The resulting reader 'maxSize' will hold the maximum value of the two + * brushes, or nothing if the source readers do not exist. + */ +template ...>::value_type, + typename T = typename FirstCursor::value_type> +std::optional> fold_optional_cursors(const Func &func, Cursors&& ...cursors) { + auto fold_func = [func] (const auto &lhs, const auto &rhs) { + return lager::with(lhs, rhs).map(func); + }; + + return kismpl::fold_optional(fold_func, cursors...); +} + namespace lenses { template auto scale = [] (T multiplier) { diff --git a/libs/image/tests/CMakeLists.txt b/libs/image/tests/CMakeLists.txt index e00745446d6..4c59b4081d6 100644 --- a/libs/image/tests/CMakeLists.txt +++ b/libs/image/tests/CMakeLists.txt @@ -143,6 +143,7 @@ kis_add_tests( kis_mesh_transform_worker_test.cpp KisKeyframeAnimationInterfaceSignalTest.cpp KisOverlayPaintDeviceWrapperTest.cpp + KisMplTest.cpp LINK_LIBRARIES kritaimage Qt5::Test NAME_PREFIX "libs-image-" ) diff --git a/libs/image/tests/KisMplTest.cpp b/libs/image/tests/KisMplTest.cpp new file mode 100644 index 00000000000..c716f7f02ea --- /dev/null +++ b/libs/image/tests/KisMplTest.cpp @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "KisMplTest.h" + +#include + +#include +#include + +#include + + +void KisMplTest::test() +{ + std::optional a(0x1); + std::optional b(0x2); + std::optional c(0x4); + std::optional d; + std::optional e; + + QCOMPARE(kismpl::fold_optional(std::plus{}, a, b, c, d, e), std::optional(7)); + QCOMPARE(kismpl::fold_optional(std::plus{}, e, a, b, c, d), std::optional(7)); + QCOMPARE(kismpl::fold_optional(std::plus{}, d, e, a, b, c), std::optional(7)); + QCOMPARE(kismpl::fold_optional(std::plus{}, c, d, e, a, b), std::optional(7)); + QCOMPARE(kismpl::fold_optional(std::plus{}, b, c, d, e, a), std::optional(7)); + + QCOMPARE(kismpl::fold_optional(std::plus{}, b, c, d, e), std::optional(6)); + QCOMPARE(kismpl::fold_optional(std::plus{}, c, d, e), std::optional(4)); + QCOMPARE(kismpl::fold_optional(std::plus{}, d, e), std::optional()); + QCOMPARE(kismpl::fold_optional(std::plus{}, e), std::optional()); + +} + +SIMPLE_TEST_MAIN(KisMplTest) diff --git a/libs/image/tests/KisMplTest.h b/libs/image/tests/KisMplTest.h new file mode 100644 index 00000000000..fc1acdef48c --- /dev/null +++ b/libs/image/tests/KisMplTest.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef KISMPLTEST_H +#define KISMPLTEST_H + +#include + +class KisMplTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void test(); +}; + +#endif // KISMPLTEST_H diff --git a/libs/ui/kis_paintop_option.cpp b/libs/ui/kis_paintop_option.cpp index 5dc96b8a5b4..a5f316c8624 100644 --- a/libs/ui/kis_paintop_option.cpp +++ b/libs/ui/kis_paintop_option.cpp @@ -130,18 +130,24 @@ void KisPaintOpOption::lodLimitations(KisPaintopLodLimitations *l) const Q_UNUSED(l); } -lager::reader KisPaintOpOption::effectiveLodLimitations() const +KisPaintOpOption::OptionalLodLimitationsReader KisPaintOpOption::effectiveLodLimitations() const { - return lager::with(m_d->pageEnabledReader, lodLimitationsReader()) - .map([](bool enabled, const KisPaintopLodLimitations &l) { - return enabled ? l : KisPaintopLodLimitations(); - }); + OptionalLodLimitationsReader reader = lodLimitationsReader(); + + if (reader) { + reader = lager::with(m_d->pageEnabledReader, *reader) + .map([](bool enabled, const KisPaintopLodLimitations &l) { + return enabled ? l : KisPaintopLodLimitations(); + }); + } + + return reader; } -lager::reader KisPaintOpOption::lodLimitationsReader() const +KisPaintOpOption::OptionalLodLimitationsReader KisPaintOpOption::lodLimitationsReader() const { // no limitations by default - return lager::make_constant(KisPaintopLodLimitations()); + return std::nullopt; } KisPaintOpOption::PaintopCategory KisPaintOpOption::category() const diff --git a/libs/ui/kis_paintop_option.h b/libs/ui/kis_paintop_option.h index 203f6828b22..7773a3e7dca 100644 --- a/libs/ui/kis_paintop_option.h +++ b/libs/ui/kis_paintop_option.h @@ -39,6 +39,8 @@ class KRITAUI_EXPORT KisPaintOpOption : public QObject Q_OBJECT public: + using OptionalLodLimitationsReader = std::optional>; + enum PaintopCategory { GENERAL, COLOR, @@ -82,10 +84,10 @@ class KRITAUI_EXPORT KisPaintOpOption : public QObject QWidget *configurationPage() const; virtual void lodLimitations(KisPaintopLodLimitations *l) const; - lager::reader effectiveLodLimitations() const; + OptionalLodLimitationsReader effectiveLodLimitations() const; protected: - virtual lager::reader lodLimitationsReader() const; + virtual OptionalLodLimitationsReader lodLimitationsReader() const; void setConfigurationPage(QWidget *page); KisResourcesInterfaceSP resourcesInterface() const; diff --git a/libs/ui/kis_paintop_settings_widget.cpp b/libs/ui/kis_paintop_settings_widget.cpp index 930090811d1..913a36d8140 100644 --- a/libs/ui/kis_paintop_settings_widget.cpp +++ b/libs/ui/kis_paintop_settings_widget.cpp @@ -28,12 +28,12 @@ #include #include +#include struct KisPaintOpSettingsWidget::Private { Private() - : lodLimitations(lager::make_constant(KisPaintopLodLimitations())) { } @@ -41,7 +41,7 @@ struct KisPaintOpSettingsWidget::Private KisCategorizedListView* optionsList; KisPaintOpOptionListModel* model; QStackedWidget* optionsStack; - lager::reader lodLimitations; + std::optional> lodLimitations; }; KisPaintOpSettingsWidget::KisPaintOpSettingsWidget(QWidget * parent) @@ -110,10 +110,10 @@ void KisPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, QStrin connect(option, SIGNAL(sigSettingChanged()), SIGNAL(sigConfigurationItemChanged())); m_d->optionsStack->addWidget(option->configurationPage()); m_d->paintOpOptions << option; + m_d->lodLimitations = - lager::with(m_d->lodLimitations, - option->effectiveLodLimitations()) - .map(std::bit_or{}); + kiszug::fold_optional_cursors(std::bit_or{}, m_d->lodLimitations, + option->effectiveLodLimitations()); } void KisPaintOpSettingsWidget::setConfiguration(const KisPropertiesConfigurationSP config) @@ -164,7 +164,7 @@ KisPaintopLodLimitations KisPaintOpSettingsWidget::lodLimitations() const lager::reader KisPaintOpSettingsWidget::lodLimitationsReader() const { - return m_d->lodLimitations; + return m_d->lodLimitations.value_or(lager::make_constant(KisPaintopLodLimitations())); } lager::reader KisPaintOpSettingsWidget::effectiveBrushSize() const diff --git a/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.cpp b/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.cpp index 373b37533d8..8dd9c6e3da7 100644 --- a/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.cpp +++ b/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.cpp @@ -89,7 +89,7 @@ void KisSmudgeOverlayModeOptionWidget::readOptionSetting(const KisPropertiesConf } -lager::reader KisSmudgeOverlayModeOptionWidget::lodLimitationsReader() const +KisPaintOpOption::OptionalLodLimitationsReader KisSmudgeOverlayModeOptionWidget::lodLimitationsReader() const { return m_d->lodLimitations; } diff --git a/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.h b/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.h index ce11f2053d9..827ff46cc0c 100644 --- a/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.h +++ b/plugins/paintops/colorsmudge/KisSmudgeOverlayModeOptionWidget.h @@ -22,7 +22,7 @@ class KisSmudgeOverlayModeOptionWidget : public KisPaintOpOption void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; void readOptionSetting(const KisPropertiesConfigurationSP setting) override; - lager::reader lodLimitationsReader() const override; + OptionalLodLimitationsReader lodLimitationsReader() const override; private: struct Private; diff --git a/plugins/paintops/libpaintop/KisPaintOpOptionWidgetUtils.h b/plugins/paintops/libpaintop/KisPaintOpOptionWidgetUtils.h index 526dfa52064..1a5e5f2c660 100644 --- a/plugins/paintops/libpaintop/KisPaintOpOptionWidgetUtils.h +++ b/plugins/paintops/libpaintop/KisPaintOpOptionWidgetUtils.h @@ -7,9 +7,11 @@ #define KISPAINTOPOPTIONWIDGETUTILS_H #include +#include #include #include #include +#include "kis_paintop_lod_limitations.h" namespace KisPaintOpOptionWidgetUtils { @@ -17,6 +19,7 @@ namespace KisPaintOpOptionWidgetUtils namespace detail { BOOST_TTI_HAS_TYPE(data_type) +BOOST_TTI_HAS_MEMBER_FUNCTION(lodLimitations) template struct DataStorage @@ -84,7 +87,24 @@ struct WidgetWrapper : using BaseClass::BaseClass; }; -} +template +struct WidgetWrapperWithLodLimitations : WidgetWrapper +{ + using BaseClass = WidgetWrapper; + + // reuse c-tor from the base + using BaseClass::BaseClass; + + KisPaintOpOption::OptionalLodLimitationsReader + lodLimitationsReader() const override { + return kiszug::fold_optional_cursors(std::bit_or{}, + BaseClass::lodLimitationsReader(), + KisPaintOpOption::OptionalLodLimitationsReader( + this->m_data.map(&Data::lodLimitations))); + } +}; + +} // namespace detail /** * Creates an option widget and lager::store for its \p Data @@ -106,6 +126,20 @@ Widget* createOptionWidget(Data&& data, Args... args) return new detail::WidgetWrapper(std::forward(data), std::forward(args)...); } +/** + * Same as normal createOptionWidget(), but creates a widget that fetches + * lod limitations directly from the \p Data object by calling + * Data::lodLimitations(). + */ + +template +Widget* createOptionWidgetWithLodLimitations(Data&& data, Args... args) +{ + static_assert(detail::has_member_function_lodLimitations::value, "Data must have Data::lodLomitations() member function defined to use a widget with lod limitaitons generation"); + return new detail::WidgetWrapperWithLodLimitations(std::forward(data), std::forward(args)...); +} + + /** * Creates an option widget and lager::store for its \p Data * type. diff --git a/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp b/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp index f5bd1c6b470..583726db5f5 100644 --- a/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisSizeOptionWidget.cpp @@ -32,7 +32,7 @@ KisSizeOptionWidget::~KisSizeOptionWidget() { } -lager::reader KisSizeOptionWidget::lodLimitationsReader() const +KisPaintOpOption::OptionalLodLimitationsReader KisSizeOptionWidget::lodLimitationsReader() const { return m_d->lodLimitations; } diff --git a/plugins/paintops/libpaintop/KisSizeOptionWidget.h b/plugins/paintops/libpaintop/KisSizeOptionWidget.h index 24407d753ad..bd50ed24c70 100644 --- a/plugins/paintops/libpaintop/KisSizeOptionWidget.h +++ b/plugins/paintops/libpaintop/KisSizeOptionWidget.h @@ -19,7 +19,7 @@ class PAINTOP_EXPORT KisSizeOptionWidget : public KisCurveOptionWidget2 KisSizeOptionWidget(lager::cursor optionData, KisPaintOpOption::PaintopCategory categoryOverride); ~KisSizeOptionWidget(); - lager::reader lodLimitationsReader() const; + OptionalLodLimitationsReader lodLimitationsReader() const override; private: struct Private; diff --git a/plugins/paintops/libpaintop/KisTextureOptionWidget.cpp b/plugins/paintops/libpaintop/KisTextureOptionWidget.cpp index 8aa4dc420b1..4262f461a4f 100644 --- a/plugins/paintops/libpaintop/KisTextureOptionWidget.cpp +++ b/plugins/paintops/libpaintop/KisTextureOptionWidget.cpp @@ -89,7 +89,7 @@ void KisTextureOptionWidget::readOptionSetting(const KisPropertiesConfigurationS m_d->model.optionData.set(data); } -lager::reader KisTextureOptionWidget::lodLimitationsReader() const +KisPaintOpOption::OptionalLodLimitationsReader KisTextureOptionWidget::lodLimitationsReader() const { return m_d->model.optionData.map(&KisTextureOptionData::lodLimitations); } diff --git a/plugins/paintops/libpaintop/KisTextureOptionWidget.h b/plugins/paintops/libpaintop/KisTextureOptionWidget.h index ffdd74174de..edcd1cdf81b 100644 --- a/plugins/paintops/libpaintop/KisTextureOptionWidget.h +++ b/plugins/paintops/libpaintop/KisTextureOptionWidget.h @@ -23,7 +23,7 @@ class PAINTOP_EXPORT KisTextureOptionWidget : public KisPaintOpOption void readOptionSetting(const KisPropertiesConfigurationSP setting) override; protected: - lager::reader lodLimitationsReader() const override; + OptionalLodLimitationsReader lodLimitationsReader() const override; private: struct Private; diff --git a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp index ab3ad1e360b..91cf193437f 100644 --- a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp +++ b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp @@ -143,7 +143,7 @@ lager::reader KisBrushOptionWidget::bakedBrushData() const }); } -lager::reader KisBrushOptionWidget::lodLimitationsReader() const +KisPaintOpOption::OptionalLodLimitationsReader KisBrushOptionWidget::lodLimitationsReader() const { return m_d->brushData.map(&KisBrushModel::brushLodLimitations); } diff --git a/plugins/paintops/libpaintop/kis_brush_option_widget.h b/plugins/paintops/libpaintop/kis_brush_option_widget.h index 426b984b655..b07c57f48e2 100644 --- a/plugins/paintops/libpaintop/kis_brush_option_widget.h +++ b/plugins/paintops/libpaintop/kis_brush_option_widget.h @@ -45,7 +45,7 @@ class PAINTOP_EXPORT KisBrushOptionWidget : public KisPaintOpOption lager::reader bakedBrushData() const; protected: - lager::reader lodLimitationsReader() const override; + OptionalLodLimitationsReader lodLimitationsReader() const override; private: diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp index a11b5674ca3..6d087b6cbf1 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.cpp @@ -10,6 +10,30 @@ #include "MyPaintCurveRangeModel.h" #include "MyPaintCurveOptionRangeControlsStrategy.h" #include "KisCurveOptionInputControlsStrategy.h" +#include "MyPaintSensorPack.h" +#include "kis_paintop_lod_limitations.h" + +namespace { +KisPaintopLodLimitations calcGeneralMyPaintLodLimitations(const MyPaintCurveOptionData &data) +{ + KisPaintopLodLimitations l; + + if (data.sensorStruct().sensorRandom.isActive) { + l.limitations << KoID(QString("Random Sensor Active, %1").arg(data.id.id()), i18nc("PaintOp instant preview limitation", "Random Sensor Active in %1 option, consider disabling Instant Preview", data.id.name())); + } + + return l; +} +} // namespace + +struct MyPaintCurveOptionWidget2::Private +{ + Private(lager::cursor optionData) + : lodLimitations(optionData.map(&calcGeneralMyPaintLodLimitations)) + {} + + lager::reader lodLimitations; +}; MyPaintCurveOptionWidget2::MyPaintCurveOptionWidget2(lager::cursor optionData, qreal maxYRange, @@ -23,9 +47,15 @@ MyPaintCurveOptionWidget2::MyPaintCurveOptionWidget2(lager::cursorlodLimitations; +} diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h index 6d9dcd756f2..2cd3a696afa 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h +++ b/plugins/paintops/mypaint/MyPaintCurveOptionWidget2.h @@ -22,7 +22,11 @@ class MyPaintCurveOptionWidget2 : public KisCurveOptionWidget2 using KisCurveOptionWidget2::strengthValueDenorm; + OptionalLodLimitationsReader lodLimitationsReader() const override; + private: + struct Private; + const QScopedPointer m_d; }; #endif // MYPAINTCURVEOPTIONWIDGET2_H diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp index 12762c01b14..e40722146c4 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.cpp @@ -17,6 +17,8 @@ #include #include +#include + namespace KisPaintOpOptionWidgetUtils { template @@ -26,7 +28,14 @@ MyPaintCurveOptionWidget2* createMyPaintCurveOptionWidget(Data data, const QStri return createOptionWidget(std::move(data), yLimit, yValueSuffix); } -} // namespace +template +MyPaintCurveOptionWidget2* createMyPaintCurveOptionWidgetWithLodLimitations(Data data, const QString &yValueSuffix = "") +{ + const qreal yLimit = qAbs(data.strengthMaxValue - data.strengthMinValue); + return createOptionWidgetWithLodLimitations(std::move(data), yLimit, yValueSuffix); +} + +} // namespace KisPaintOpOptionWidgetUtils KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) @@ -37,7 +46,7 @@ KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) namespace kpowu = KisPaintOpOptionWidgetUtils; - MyPaintCurveOptionWidget2 *radiusWidget = + m_radiusWidget = kpowu::createMyPaintCurveOptionWidget(MyPaintRadiusLogarithmicData()); MyPaintCurveOptionWidget2 *hardnessWidget = kpowu::createMyPaintCurveOptionWidget(MyPaintHardnessData()); @@ -46,13 +55,13 @@ KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) KisPaintOpSettingsWidget::addPaintOpOption( kpowu::createOptionWidget(MyPaintBasicOptionData(), - radiusWidget->strengthValueDenorm(), + m_radiusWidget->strengthValueDenorm(), hardnessWidget->strengthValueDenorm(), opacityWidget->strengthValueDenorm())); - addPaintOpOption(radiusWidget, + addPaintOpOption(m_radiusWidget, BASIC); - addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintRadiusByRandomData()), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidgetWithLodLimitations(MyPaintRadiusByRandomData()), BASIC); addPaintOpOption(hardnessWidget, BASIC); @@ -97,7 +106,7 @@ KisMyPaintOpSettingsWidget:: KisMyPaintOpSettingsWidget(QWidget* parent) SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetBySpeedFilterData()), SPEED); - addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintOffsetByRandomData()), + addPaintOpOption(kpowu::createMyPaintCurveOptionWidgetWithLodLimitations(MyPaintOffsetByRandomData()), SPEED); addPaintOpOption(kpowu::createMyPaintCurveOptionWidget(MyPaintDabsPerBasicRadiusData()), @@ -153,6 +162,11 @@ KisPropertiesConfigurationSP KisMyPaintOpSettingsWidget::configuration() const return config; } +lager::reader KisMyPaintOpSettingsWidget::effectiveBrushSize() const +{ + return m_radiusWidget->strengthValueDenorm().map([] (qreal value) { return 2 * exp(value); }); +} + void KisMyPaintOpSettingsWidget::addPaintOpOption(KisPaintOpOption *option, MyPaintPaintopCategory id) { QString category; diff --git a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h index c74e18c1fd2..1e35f3754c4 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h +++ b/plugins/paintops/mypaint/MyPaintPaintOpSettingsWidget.h @@ -23,8 +23,13 @@ class KisMyPaintOpSettingsWidget : public KisPaintOpSettingsWidget KisPropertiesConfigurationSP configuration() const override; + lager::reader effectiveBrushSize() const override; + protected: void addPaintOpOption(KisPaintOpOption *option, MyPaintPaintopCategory id); + +private: + MyPaintCurveOptionWidget2 *m_radiusWidget {nullptr}; }; #endif diff --git a/plugins/paintops/mypaint/MyPaintStandardOptionData.h b/plugins/paintops/mypaint/MyPaintStandardOptionData.h index 57e90d88136..e8238cfd2b9 100644 --- a/plugins/paintops/mypaint/MyPaintStandardOptionData.h +++ b/plugins/paintops/mypaint/MyPaintStandardOptionData.h @@ -7,6 +7,8 @@ #define MYPAINTSTANDARDOPTIONDATA_H #include +#include + struct MyPaintRadiusLogarithmicData : MyPaintCurveOptionData { @@ -43,6 +45,14 @@ struct MyPaintRadiusByRandomData : MyPaintCurveOptionData false, true, 0.0, 1.50) { } + + KisPaintopLodLimitations lodLimitations() const { + KisPaintopLodLimitations l; + if (qAbs(strengthValue) > 0.05) { + l.limitations << KoID("Radius by Random", i18nc("PaintOp instant preview limitation", "Radius by Random, consider disabling Instant Preview")); + } + return l; + } }; struct MyPaintAntiAliasingData : MyPaintCurveOptionData @@ -218,6 +228,15 @@ struct MyPaintOffsetByRandomData : MyPaintCurveOptionData false, true, -3.0, 3.0) { } + + KisPaintopLodLimitations lodLimitations() const { + KisPaintopLodLimitations l; + if (qAbs(strengthValue) > 0.05) { + l.limitations << KoID("Offset by Random", i18nc("PaintOp instant preview limitation", "Offset by Random, consider disabling Instant Preview")); + } + return l; + } + }; struct MyPaintDabsPerBasicRadiusData : MyPaintCurveOptionData From 12e79c9557a653b0ee45284b3ae90c792dfc9157 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Mon, 12 Dec 2022 18:38:59 +0300 Subject: [PATCH 15/20] Fxi build on Linux --- libs/global/KisMpl.h | 1 + libs/ui/widgets/KisCurveWidgetControlsManager.h | 10 ++-------- .../filters/colorsfilters/kis_cross_channel_filter.cpp | 1 - .../filters/colorsfilters/kis_cross_channel_filter.h | 3 +-- .../filters/colorsfilters/kis_perchannel_filter.cpp | 1 - plugins/filters/colorsfilters/kis_perchannel_filter.h | 2 +- plugins/paintops/libpaintop/kis_curve_option_widget.h | 3 ++- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/libs/global/KisMpl.h b/libs/global/KisMpl.h index 666e6dd79e1..1a477d17c03 100644 --- a/libs/global/KisMpl.h +++ b/libs/global/KisMpl.h @@ -9,6 +9,7 @@ #include #include +#include /** * 'kismpl' stands for kis-meta-program-library diff --git a/libs/ui/widgets/KisCurveWidgetControlsManager.h b/libs/ui/widgets/KisCurveWidgetControlsManager.h index 1197ce5f656..8db412e6b18 100644 --- a/libs/ui/widgets/KisCurveWidgetControlsManager.h +++ b/libs/ui/widgets/KisCurveWidgetControlsManager.h @@ -98,14 +98,8 @@ class KRITAUI_EXPORT_TEMPLATE KisCurveWidgetControlsManager : public KisCurveWid extern template class KisCurveWidgetControlsManager; extern template class KisCurveWidgetControlsManager; -class KisCurveWidgetControlsManagerInt : public KisCurveWidgetControlsManager -{ - using KisCurveWidgetControlsManager::KisCurveWidgetControlsManager; -}; +using KisCurveWidgetControlsManagerInt = KisCurveWidgetControlsManager; +using KisCurveWidgetControlsManagerDouble = KisCurveWidgetControlsManager; -class KisCurveWidgetControlsManagerDouble : public KisCurveWidgetControlsManager -{ - using KisCurveWidgetControlsManager::KisCurveWidgetControlsManager; -}; #endif // KISCURVEWIDGETCONTROLSMANAGER_H diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp index 0e9a7d62894..e0f6754f94c 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.cpp @@ -40,7 +40,6 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include -#include #include "../../color/colorspaceextensions/kis_hsv_adjustment.h" diff --git a/plugins/filters/colorsfilters/kis_cross_channel_filter.h b/plugins/filters/colorsfilters/kis_cross_channel_filter.h index a276ac3d234..1d4b4256b46 100644 --- a/plugins/filters/colorsfilters/kis_cross_channel_filter.h +++ b/plugins/filters/colorsfilters/kis_cross_channel_filter.h @@ -22,8 +22,7 @@ #include "virtual_channel_info.h" #include "kis_multichannel_filter_base.h" - -class KisCurveWidgetControlsManagerInt; +#include /** * Filter which applies a relative adjustment to a (virtual) color channel based on the value of another. diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp index cc7b17938b4..f4fbe3d6628 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.cpp +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.cpp @@ -39,7 +39,6 @@ #include "kis_painter.h" #include "widgets/kis_curve_widget.h" #include -#include #include "kis_multichannel_utils.h" diff --git a/plugins/filters/colorsfilters/kis_perchannel_filter.h b/plugins/filters/colorsfilters/kis_perchannel_filter.h index 1c65b940ff7..6fc6e92d86e 100644 --- a/plugins/filters/colorsfilters/kis_perchannel_filter.h +++ b/plugins/filters/colorsfilters/kis_perchannel_filter.h @@ -20,8 +20,8 @@ #include "virtual_channel_info.h" #include "kis_multichannel_filter_base.h" +#include -class KisCurveWidgetControlsManagerInt; class KisPerChannelFilterConfiguration : public KisMultiChannelFilterConfiguration diff --git a/plugins/paintops/libpaintop/kis_curve_option_widget.h b/plugins/paintops/libpaintop/kis_curve_option_widget.h index 2a0b431bb13..1506ba61f21 100644 --- a/plugins/paintops/libpaintop/kis_curve_option_widget.h +++ b/plugins/paintops/libpaintop/kis_curve_option_widget.h @@ -14,10 +14,11 @@ class Ui_WdgCurveOption; class KisCurveOption; class QComboBox; -class KisCurveWidgetControlsManagerInt; +#include #include + class PAINTOP_EXPORT KisCurveOptionWidget : public KisPaintOpOption { Q_OBJECT From 3162e56d59898128eac5994d13d8ea259a52e9e0 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Mon, 12 Dec 2022 19:58:46 +0300 Subject: [PATCH 16/20] Fix broken spacing when changing an auto brush --- libs/brush/KisBrushModel.cpp | 14 ++++++++++++++ libs/brush/KisBrushModel.h | 1 + .../paintops/libpaintop/KisMaskingBrushOption.cpp | 7 ++++--- .../libpaintop/kis_brush_option_widget.cpp | 14 ++++++++------ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libs/brush/KisBrushModel.cpp b/libs/brush/KisBrushModel.cpp index 05b2699214a..9de4fb35b67 100644 --- a/libs/brush/KisBrushModel.cpp +++ b/libs/brush/KisBrushModel.cpp @@ -141,4 +141,18 @@ qreal effectiveSizeForBrush(const BrushData &brush) return effectiveSizeForBrush(brush.type, brush.autoBrush, brush.predefinedBrush, brush.textBrush); } +void bakeFromModels(BrushData &data, const AutoBrushData &autoBrush, const std::tuple &predefinedBrush) +{ + data.autoBrush = autoBrush; + + CommonData temporaryCommonData; + + std::tie(temporaryCommonData, data.predefinedBrush) = + predefinedBrush; + + if (data.type == Predefined) { + data.common = temporaryCommonData; + } +} + } diff --git a/libs/brush/KisBrushModel.h b/libs/brush/KisBrushModel.h index 23f127e159c..3a4328cbec9 100644 --- a/libs/brush/KisBrushModel.h +++ b/libs/brush/KisBrushModel.h @@ -189,6 +189,7 @@ void BRUSH_EXPORT setEffectiveSizeForBrush(const BrushType type, qreal BRUSH_EXPORT lightnessModeActivated(BrushType type, const PredefinedBrushData &predefinedBrush); +void BRUSH_EXPORT bakeFromModels(BrushData &data, const AutoBrushData &autoBrush, const std::tuple &predefinedBrush); } diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp index 716ddf00e1c..009f15b94af 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp +++ b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp @@ -142,9 +142,10 @@ class MaskingBrushModel : public QObject MaskingBrushData bakedOptionData() const { MaskingBrushData data = m_maskingData.get(); - data.brush.autoBrush = autoBrushModel.bakedOptionData(); - std::tie(data.brush.common, data.brush.predefinedBrush) = - predefinedBrushModel.bakedOptionData(); + + KisBrushModel::bakeFromModels(data.brush, + autoBrushModel.bakedOptionData(), + predefinedBrushModel.bakedOptionData()); return data; } diff --git a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp index 91cf193437f..3561dd32668 100644 --- a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp +++ b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp @@ -90,9 +90,10 @@ void KisBrushOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setti using namespace KisBrushModel; BrushData data = m_d->brushData.get(); - data.autoBrush = m_d->autoBrushModel.bakedOptionData(); - std::tie(data.common, data.predefinedBrush) = - m_d->predefinedBrushModel.bakedOptionData(); + + KisBrushModel::bakeFromModels(data, + m_d->autoBrushModel.bakedOptionData(), + m_d->predefinedBrushModel.bakedOptionData()); data.write(settings.data()); @@ -136,9 +137,10 @@ lager::reader KisBrushOptionWidget::bakedBrushData() const .map([this] (BrushData data, qreal commonBrushSize) { Q_UNUSED(commonBrushSize); // we keep it as a dep only for updates! - data.autoBrush = m_d->autoBrushModel.bakedOptionData(); - std::tie(data.common, data.predefinedBrush) = - m_d->predefinedBrushModel.bakedOptionData(); + + KisBrushModel::bakeFromModels(data, + m_d->autoBrushModel.bakedOptionData(), + m_d->predefinedBrushModel.bakedOptionData()); return data; }); } From 2c7a908183ee649e48020604085b8815df6a8552 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Tue, 13 Dec 2022 14:01:19 +0300 Subject: [PATCH 17/20] One more try to fix brush spacing information being reset by predefined brushes Basically, we should discard the spacing information stored in the brush itself, unless the user presses the "Reset Brush" button. This information is usually stored in the preset, not in the brush resource. --- libs/brush/KisBrushModel.cpp | 14 ------ libs/brush/KisBrushModel.h | 2 - .../libpaintop/KisMaskingBrushOption.cpp | 5 +-- .../libpaintop/KisPredefinedBrushModel.cpp | 43 +++++++++++-------- .../libpaintop/KisPredefinedBrushModel.h | 4 +- .../libpaintop/kis_brush_option_widget.cpp | 11 +++-- .../kis_predefined_brush_chooser.cpp | 6 +-- 7 files changed, 34 insertions(+), 51 deletions(-) diff --git a/libs/brush/KisBrushModel.cpp b/libs/brush/KisBrushModel.cpp index 9de4fb35b67..05b2699214a 100644 --- a/libs/brush/KisBrushModel.cpp +++ b/libs/brush/KisBrushModel.cpp @@ -141,18 +141,4 @@ qreal effectiveSizeForBrush(const BrushData &brush) return effectiveSizeForBrush(brush.type, brush.autoBrush, brush.predefinedBrush, brush.textBrush); } -void bakeFromModels(BrushData &data, const AutoBrushData &autoBrush, const std::tuple &predefinedBrush) -{ - data.autoBrush = autoBrush; - - CommonData temporaryCommonData; - - std::tie(temporaryCommonData, data.predefinedBrush) = - predefinedBrush; - - if (data.type == Predefined) { - data.common = temporaryCommonData; - } -} - } diff --git a/libs/brush/KisBrushModel.h b/libs/brush/KisBrushModel.h index 3a4328cbec9..d02192e843a 100644 --- a/libs/brush/KisBrushModel.h +++ b/libs/brush/KisBrushModel.h @@ -189,8 +189,6 @@ void BRUSH_EXPORT setEffectiveSizeForBrush(const BrushType type, qreal BRUSH_EXPORT lightnessModeActivated(BrushType type, const PredefinedBrushData &predefinedBrush); -void BRUSH_EXPORT bakeFromModels(BrushData &data, const AutoBrushData &autoBrush, const std::tuple &predefinedBrush); - } #endif // KISBRUSHMODEL_H diff --git a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp index 009f15b94af..b09746e6ac6 100644 --- a/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp +++ b/plugins/paintops/libpaintop/KisMaskingBrushOption.cpp @@ -143,9 +143,8 @@ class MaskingBrushModel : public QObject MaskingBrushData bakedOptionData() const { MaskingBrushData data = m_maskingData.get(); - KisBrushModel::bakeFromModels(data.brush, - autoBrushModel.bakedOptionData(), - predefinedBrushModel.bakedOptionData()); + data.brush.autoBrush = autoBrushModel.bakedOptionData(); + data.brush.predefinedBrush = predefinedBrushModel.bakedOptionData(); return data; } diff --git a/plugins/paintops/libpaintop/KisPredefinedBrushModel.cpp b/plugins/paintops/libpaintop/KisPredefinedBrushModel.cpp index e063a713962..6acae594047 100644 --- a/plugins/paintops/libpaintop/KisPredefinedBrushModel.cpp +++ b/plugins/paintops/libpaintop/KisPredefinedBrushModel.cpp @@ -68,26 +68,34 @@ QString calcBrushDetails(PredefinedBrushData data) } auto effectiveResourceData = lager::lenses::getset( - [](const std::tuple &packedData) { - if (std::get<1>(packedData).resourceSignature != KoResourceSignature()) { - return packedData; + [](const PredefinedBrushData &predefinedDataArg) { + if (predefinedDataArg.resourceSignature != KoResourceSignature()) { + return predefinedDataArg; } CommonData commonData; - PredefinedBrushData predefinedData; - std::tie(commonData, predefinedData) = packedData; + + /// NOTE: we cannot just pass the data by value because of the + /// bug in lager: https://github.com/arximboldi/lager/issues/160 + PredefinedBrushData predefinedData = predefinedDataArg; auto source = KisGlobalResourcesInterface::instance()->source(ResourceType::Brushes); KisBrushSP fallbackResource = source.fallbackResource(); - KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(fallbackResource, packedData); + KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(fallbackResource, predefinedData); KisPredefinedBrushFactory::loadFromBrushResource(commonData, predefinedData, fallbackResource); - return std::make_tuple(commonData, predefinedData); + /// NOTE: we discard `commonData` returned from the loaded brush, because + /// we expect spacing and size information to be shared between auto and + /// predefined brushes. If the user wants to load the settings embedded + /// into the brush itself he/she should reset it explicitly via the GUI + /// controls. + + return predefinedData; }, - [](const std::tuple&, - const std::tuple &y) { + [](const PredefinedBrushData&, + const PredefinedBrushData &y) { return y; }); @@ -103,10 +111,7 @@ KisPredefinedBrushModel::KisPredefinedBrushModel(lager::cursor commo m_predefinedBrushData(predefinedBrushData), m_supportsHSLBrushTips(supportsHSLBrushTips), m_commonBrushSizeData(commonBrushSizeData), - m_effectiveBrushData(lager::with(m_commonData, m_predefinedBrushData) - .zoom(effectiveResourceData)), - m_effectiveCommonData(m_effectiveBrushData.zoom(lager::lenses::first)), - m_effectivePredefinedData(m_effectiveBrushData.zoom(lager::lenses::second)), + m_effectivePredefinedData(m_predefinedBrushData.zoom(effectiveResourceData)), LAGER_QT(resourceSignature) {m_effectivePredefinedData[&PredefinedBrushData::resourceSignature]}, LAGER_QT(baseSize) {m_effectivePredefinedData[&PredefinedBrushData::baseSize]}, LAGER_QT(brushSize) {m_commonBrushSizeData}, @@ -122,11 +127,11 @@ KisPredefinedBrushModel::KisPredefinedBrushModel(lager::cursor commo LAGER_QT(contrastAdjustment) {m_effectivePredefinedData[&PredefinedBrushData::contrastAdjustment] .xform(kiszug::map_mupliply(100.0) | kiszug::map_round, kiszug::map_static_cast | kiszug::map_mupliply(0.01))}, - LAGER_QT(angle) {m_effectiveCommonData[&CommonData::angle] + LAGER_QT(angle) {m_commonData[&CommonData::angle] .zoom(kiszug::lenses::scale(180.0 / M_PI))}, - LAGER_QT(spacing) {m_effectiveCommonData[&CommonData::spacing]}, - LAGER_QT(useAutoSpacing) {m_effectiveCommonData[&CommonData::useAutoSpacing]}, - LAGER_QT(autoSpacingCoeff) {m_effectiveCommonData[&CommonData::autoSpacingCoeff]}, + LAGER_QT(spacing) {m_commonData[&CommonData::spacing]}, + LAGER_QT(useAutoSpacing) {m_commonData[&CommonData::useAutoSpacing]}, + LAGER_QT(autoSpacingCoeff) {m_commonData[&CommonData::autoSpacingCoeff]}, LAGER_QT(aggregatedSpacing) {lager::with(LAGER_QT(spacing), LAGER_QT(useAutoSpacing), LAGER_QT(autoSpacingCoeff)) @@ -149,7 +154,7 @@ KisPredefinedBrushModel::KisPredefinedBrushModel(lager::cursor commo } -std::tuple KisPredefinedBrushModel::bakedOptionData() const +PredefinedBrushData KisPredefinedBrushModel::bakedOptionData() const { PredefinedBrushData data = m_effectivePredefinedData.get(); data.application = @@ -157,7 +162,7 @@ std::tuple KisPredefinedBrushModel::bakedOption LAGER_QT(applicationSwitchState)->currentIndex); data.scale = m_commonBrushSizeData.get() / data.baseSize.width(); - return std::make_tuple(m_effectiveCommonData.get(), data); + return data; } diff --git a/plugins/paintops/libpaintop/KisPredefinedBrushModel.h b/plugins/paintops/libpaintop/KisPredefinedBrushModel.h index af42285bf66..dae0b0ccde1 100644 --- a/plugins/paintops/libpaintop/KisPredefinedBrushModel.h +++ b/plugins/paintops/libpaintop/KisPredefinedBrushModel.h @@ -34,8 +34,6 @@ class KisPredefinedBrushModel : public QObject lager::constant m_supportsHSLBrushTips; lager::cursor m_commonBrushSizeData; - lager::cursor> m_effectiveBrushData; - lager::cursor m_effectiveCommonData; lager::cursor m_effectivePredefinedData; @@ -60,7 +58,7 @@ class KisPredefinedBrushModel : public QObject LAGER_QT_READER(QString, brushDetails); LAGER_QT_READER(bool, lightnessModeEnabled); - std::tuple bakedOptionData() const; + PredefinedBrushData bakedOptionData() const; static enumBrushApplication effectiveBrushApplication(PredefinedBrushData predefinedData, bool supportsHSLBrushTips); static qreal effectiveBrushSize(PredefinedBrushData predefinedData); diff --git a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp index 3561dd32668..715c5ef3d62 100644 --- a/plugins/paintops/libpaintop/kis_brush_option_widget.cpp +++ b/plugins/paintops/libpaintop/kis_brush_option_widget.cpp @@ -91,9 +91,8 @@ void KisBrushOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setti BrushData data = m_d->brushData.get(); - KisBrushModel::bakeFromModels(data, - m_d->autoBrushModel.bakedOptionData(), - m_d->predefinedBrushModel.bakedOptionData()); + data.autoBrush = m_d->autoBrushModel.bakedOptionData(); + data.predefinedBrush = m_d->predefinedBrushModel.bakedOptionData(); data.write(settings.data()); @@ -138,9 +137,9 @@ lager::reader KisBrushOptionWidget::bakedBrushData() const Q_UNUSED(commonBrushSize); // we keep it as a dep only for updates! - KisBrushModel::bakeFromModels(data, - m_d->autoBrushModel.bakedOptionData(), - m_d->predefinedBrushModel.bakedOptionData()); + data.autoBrush = m_d->autoBrushModel.bakedOptionData(); + data.predefinedBrush = m_d->predefinedBrushModel.bakedOptionData(); + return data; }); } diff --git a/plugins/paintops/libpaintop/kis_predefined_brush_chooser.cpp b/plugins/paintops/libpaintop/kis_predefined_brush_chooser.cpp index 1191799162e..50d8a46d52a 100644 --- a/plugins/paintops/libpaintop/kis_predefined_brush_chooser.cpp +++ b/plugins/paintops/libpaintop/kis_predefined_brush_chooser.cpp @@ -331,12 +331,10 @@ void KisPredefinedBrushChooser::slotBrushSelected(KoResourceSP resource) { KIS_SAFE_ASSERT_RECOVER_RETURN(resource); - KisBrushModel::CommonData commonBrushData; - KisBrushModel::PredefinedBrushData predefinedBrushData; - std::tie(commonBrushData, predefinedBrushData) = m_d->model->bakedOptionData(); - + KisBrushModel::PredefinedBrushData predefinedBrushData = m_d->model->bakedOptionData(); if (resource->signature() == predefinedBrushData.resourceSignature) return; + KisBrushModel::CommonData commonBrushData; KisPredefinedBrushFactory::loadFromBrushResource(commonBrushData, predefinedBrushData, resource.dynamicCast()); predefinedBrushData.scale = 1.0; From 05f45a73606a69fcd260fbb5e6c1d3f597a92627 Mon Sep 17 00:00:00 2001 From: Freya Lupen Date: Fri, 9 Dec 2022 13:46:21 -0600 Subject: [PATCH 18/20] Port Tangent Normal engine to Lager Refactors kis_tangent_tilt_option file into KisTangentTilt Option/Data/Model/Widget files. --- plugins/paintops/tangentnormal/CMakeLists.txt | 5 +- .../tangentnormal/KisTangentTiltOption.cpp | 114 ++++++++ .../tangentnormal/KisTangentTiltOption.h | 36 +++ .../KisTangentTiltOptionData.cpp | 41 +++ .../tangentnormal/KisTangentTiltOptionData.h | 44 ++++ .../KisTangentTiltOptionModel.cpp | 21 ++ .../tangentnormal/KisTangentTiltOptionModel.h | 31 +++ .../KisTangentTiltOptionWidget.cpp | 102 ++++++++ .../KisTangentTiltOptionWidget.h | 31 +++ .../kis_tangent_normal_paintop.cpp | 44 ++-- .../kis_tangent_normal_paintop.h | 39 +-- ...tangent_normal_paintop_settings_widget.cpp | 55 ++-- .../tangentnormal/kis_tangent_tilt_option.cpp | 245 ------------------ .../tangentnormal/kis_tangent_tilt_option.h | 52 ---- 14 files changed, 484 insertions(+), 376 deletions(-) create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOption.cpp create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOption.h create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionData.cpp create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionData.h create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionModel.cpp create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionModel.h create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.cpp create mode 100644 plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.h delete mode 100644 plugins/paintops/tangentnormal/kis_tangent_tilt_option.cpp delete mode 100644 plugins/paintops/tangentnormal/kis_tangent_tilt_option.h diff --git a/plugins/paintops/tangentnormal/CMakeLists.txt b/plugins/paintops/tangentnormal/CMakeLists.txt index 99cf267a8d2..37e79cec5f1 100644 --- a/plugins/paintops/tangentnormal/CMakeLists.txt +++ b/plugins/paintops/tangentnormal/CMakeLists.txt @@ -2,8 +2,11 @@ set(kritatangentnormalpaintop_SOURCES kis_tangent_normal_paintop_plugin.cpp kis_tangent_normal_paintop.cpp kis_tangent_normal_paintop_settings_widget.cpp - kis_tangent_tilt_option.cpp kis_normal_preview_widget.cpp + KisTangentTiltOption.cpp + KisTangentTiltOptionData.cpp + KisTangentTiltOptionModel.cpp + KisTangentTiltOptionWidget.cpp ) diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOption.cpp b/plugins/paintops/tangentnormal/KisTangentTiltOption.cpp new file mode 100644 index 00000000000..4d4454534a7 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOption.cpp @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#include "KisTangentTiltOption.h" + +#include +namespace kpou = KisPaintOpOptionUtils; + + +KisTangentTiltOption::KisTangentTiltOption(const KisPropertiesConfiguration *setting) + : KisTangentTiltOption(kpou::loadOptionData(setting)) +{ +} + +KisTangentTiltOption::KisTangentTiltOption(const KisTangentTiltOptionData &data) + : m_redChannel(data.redChannel) + , m_greenChannel(data.greenChannel) + , m_blueChannel(data.blueChannel) + , m_directionType(data.directionType) + , m_elevationSensitivity(data.elevationSensitivity) + , m_mixValue(data.mixValue) +{ +} + +void KisTangentTiltOption::swizzleAssign(qreal const horizontal, qreal const vertical, qreal const depth, qreal *component, int index, qreal maxvalue) +{ + switch(index) { + case 0: *component = horizontal; break; + case 1: *component = maxvalue-horizontal; break; + case 2: *component = vertical; break; + case 3: *component = maxvalue-vertical; break; + case 4: *component = depth; break; + case 5: *component = maxvalue-depth; break; + } +} + +void KisTangentTiltOption::apply(const KisPaintInformation& info,qreal *r,qreal *g,qreal *b) +{ + //formula based on https://www.cerebralmeltdown.com/programming_projects/Altitude%20and%20Azimuth%20to%20Vector/index.html + + /* It doesn't make sense of have higher than 8bit color depth. + * Instead we make sure in the paintAt function of kis_tangent_normal_paintop to pick an 8bit space of the current + * color space if the space is an RGB space. If not, it'll pick sRGB 8bit. + */ + qreal halfvalue = 0.5; + qreal maxvalue = 1.0; + + //have the azimuth and altitude in degrees. + qreal direction = KisPaintInformation::tiltDirection(info, true)*360.0; + qreal elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); + + if (m_directionType == TangentTiltDirectionType::Tilt) { + direction = KisPaintInformation::tiltDirection(info, true)*360.0; + elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); + } else if (m_directionType == TangentTiltDirectionType::Direction) { + direction = (0.75 + info.drawingAngle() / (2.0 * M_PI))*360.0; + elevation= 0;//turns out that tablets that don't support tilt just return 90 degrees for elevation. + } else if (m_directionType == TangentTiltDirectionType::Rotation) { + direction = info.rotation(); + elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0);//artpens have tilt-recognition, so this should work. + } else if (m_directionType == TangentTiltDirectionType::Mix) {//mix of tilt+direction + qreal mixamount = m_mixValue/100.0; + direction = (KisPaintInformation::tiltDirection(info, true)*360.0*(1.0-mixamount))+((0.75 + info.drawingAngle() / (2.0 * M_PI))*360.0*(mixamount)); + elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); + } + + //subtract/add the rotation of the canvas. + if (m_directionType != TangentTiltDirectionType::Direction) { + direction = normalizeAngleDegrees(direction - info.canvasRotation()); + } + + //limit the direction/elevation + + //qreal elevationMax = (m_elevationSensitivity*90.0)/100.0; + qreal elevationT = elevation*(m_elevationSensitivity/100.0)+(90-(m_elevationSensitivity*90.0)/100.0); + elevation = static_cast(elevationT); + + //convert to radians. + // Convert this to kis_global's radian function. + direction = kisDegreesToRadians(direction); + elevation = kisDegreesToRadians(elevation); + + //make variables for axes for easy switching later on. + qreal horizontal, vertical, depth; + + //spherical coordinates always center themselves around the origin, leading to values. We need to work around those... + + horizontal = cos(elevation)*sin(direction); + if (horizontal>0.0) { + horizontal= halfvalue+(fabs(horizontal)*halfvalue); + } + else { + horizontal= halfvalue-(fabs(horizontal)*halfvalue); + } + vertical = cos(elevation)*cos(direction); + if (vertical>0.0) { + vertical = halfvalue+(fabs(vertical)*halfvalue); + } + else { + vertical = halfvalue-(fabs(vertical)*halfvalue); + } + + if (info.canvasMirroredH()) {horizontal = maxvalue - horizontal;} + if (info.canvasMirroredV()) {vertical = maxvalue - vertical;} + + depth = sin(elevation)*maxvalue; + + //assign right components to correct axes. + swizzleAssign(horizontal, vertical, depth, r, m_redChannel, maxvalue); + swizzleAssign(horizontal, vertical, depth, g, m_greenChannel, maxvalue); + swizzleAssign(horizontal, vertical, depth, b, m_blueChannel, maxvalue); +} diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOption.h b/plugins/paintops/tangentnormal/KisTangentTiltOption.h new file mode 100644 index 00000000000..0da5f642d91 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOption.h @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#ifndef KISTANGENTTILT_OPTION_H +#define KISTANGENTTILT_OPTION_H + +#include +#include "KisTangentTiltOptionData.h" + +struct KisTangentTiltOptionData; + +class KisTangentTiltOption +{ +public: + KisTangentTiltOption(const KisPropertiesConfiguration *setting); + + /*This assigns the right axis to the component, based on index and maximum value*/ + void swizzleAssign(qreal const horizontal, qreal const vertical, qreal const depth, qreal *component, int index, qreal maxvalue); + + //takes the RGB values and will deform them depending on tilt. + void apply(const KisPaintInformation& info, qreal *r, qreal *g, qreal *b); + +private: + KisTangentTiltOption(const KisTangentTiltOptionData &data); +private: + int m_redChannel; + int m_greenChannel; + int m_blueChannel; + TangentTiltDirectionType m_directionType; + double m_elevationSensitivity; + double m_mixValue; +}; + +#endif // KISTANGENTILT_OPTION_H diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionData.cpp b/plugins/paintops/tangentnormal/KisTangentTiltOptionData.cpp new file mode 100644 index 00000000000..86f22b00cd7 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionData.cpp @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#include "KisTangentTiltOptionData.h" + +#include "kis_properties_configuration.h" + + +const QString TANGENT_RED = "Tangent/swizzleRed"; +const QString TANGENT_GREEN = "Tangent/swizzleGreen"; +const QString TANGENT_BLUE = "Tangent/swizzleBlue"; +const QString TANGENT_TYPE = "Tangent/directionType"; +const QString TANGENT_EV_SEN = "Tangent/elevationSensitivity"; +const QString TANGENT_MIX_VAL = "Tangent/mixValue"; + + +bool KisTangentTiltOptionData::read(const KisPropertiesConfiguration *setting) +{ + redChannel = setting->getInt(TANGENT_RED, 0); + greenChannel = setting->getInt(TANGENT_GREEN, 2); + blueChannel = setting->getInt(TANGENT_BLUE, 4); + + directionType = (TangentTiltDirectionType)setting->getInt(TANGENT_TYPE, 0); + + elevationSensitivity = setting->getDouble(TANGENT_EV_SEN, 100.0); + mixValue = setting->getDouble(TANGENT_MIX_VAL, 50.0); + + return true; +} + +void KisTangentTiltOptionData::write(KisPropertiesConfiguration *setting) const +{ + setting->setProperty(TANGENT_RED, redChannel); + setting->setProperty(TANGENT_GREEN, greenChannel); + setting->setProperty(TANGENT_BLUE, blueChannel); + setting->setProperty(TANGENT_TYPE, directionType); + setting->setProperty(TANGENT_EV_SEN, elevationSensitivity); + setting->setProperty(TANGENT_MIX_VAL, mixValue); +} diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionData.h b/plugins/paintops/tangentnormal/KisTangentTiltOptionData.h new file mode 100644 index 00000000000..180864b9c1e --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionData.h @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#ifndef KIS_TANGENTTILT_OPTION_DATA_H +#define KIS_TANGENTTILT_OPTION_DATA_H + + +#include "kis_types.h" +#include + +class KisPropertiesConfiguration; + +enum TangentTiltDirectionType { + Tilt, + Direction, + Rotation, + Mix +}; + +struct KisTangentTiltOptionData : boost::equality_comparable +{ + inline friend bool operator==(const KisTangentTiltOptionData &lhs, const KisTangentTiltOptionData &rhs) { + return lhs.redChannel == rhs.redChannel + && lhs.greenChannel == rhs.greenChannel + && lhs.blueChannel == rhs.blueChannel + && lhs.directionType == rhs.directionType + && qFuzzyCompare(lhs.elevationSensitivity, rhs.elevationSensitivity) + && qFuzzyCompare(lhs.mixValue, rhs.mixValue); + } + + int redChannel {0}; + int greenChannel {2}; + int blueChannel {4}; + TangentTiltDirectionType directionType {TangentTiltDirectionType::Tilt}; + double elevationSensitivity {100.0}; + double mixValue {50.0}; + + bool read(const KisPropertiesConfiguration *setting); + void write(KisPropertiesConfiguration *setting) const; +}; + +#endif // KIS_TANGENTTILT_OPTION_DATA_H diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.cpp b/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.cpp new file mode 100644 index 00000000000..d2e43d91cd3 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.cpp @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#include "KisTangentTiltOptionModel.h" + +#include + +using namespace KisWidgetConnectionUtils; + +KisTangentTiltOptionModel::KisTangentTiltOptionModel(lager::cursor _optionData) + : optionData(_optionData) + , LAGER_QT(redChannel) {_optionData[&KisTangentTiltOptionData::redChannel]} + , LAGER_QT(greenChannel) {_optionData[&KisTangentTiltOptionData::greenChannel]} + , LAGER_QT(blueChannel) {_optionData[&KisTangentTiltOptionData::blueChannel]} + , LAGER_QT(directionType) {_optionData[&KisTangentTiltOptionData::directionType].zoom(kiszug::lenses::do_static_cast)} + , LAGER_QT(elevationSensitivity) {_optionData[&KisTangentTiltOptionData::elevationSensitivity]} + , LAGER_QT(mixValue) {_optionData[&KisTangentTiltOptionData::mixValue]} +{ +} diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.h b/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.h new file mode 100644 index 00000000000..7fd1575bd45 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionModel.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#ifndef KIS_TANGENTTILT_OPTION_MODEL_H +#define KIS_TANGENTTILT_OPTION_MODEL_H + +#include +#include + +#include "KisTangentTiltOptionData.h" +#include "KisWidgetConnectionUtils.h" + +class KisTangentTiltOptionModel : public QObject +{ + Q_OBJECT +public: + KisTangentTiltOptionModel(lager::cursor optionData); + + lager::cursor optionData; + + LAGER_QT_CURSOR(int, redChannel); + LAGER_QT_CURSOR(int, greenChannel); + LAGER_QT_CURSOR(int, blueChannel); + LAGER_QT_CURSOR(int, directionType); + LAGER_QT_CURSOR(double, elevationSensitivity); + LAGER_QT_CURSOR(double, mixValue); +}; + +#endif // KIS_TANGENTTILT_OPTION_MODEL_H diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.cpp b/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.cpp new file mode 100644 index 00000000000..89e9404d048 --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.cpp @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#include "KisTangentTiltOptionWidget.h" + +#include + +#include +#include "ui_wdgtangenttiltoption.h" + +#include "KisTangentTiltOptionModel.h" + +namespace { + + +class KisTangentTiltWidget: public QWidget, public Ui::WdgTangentTiltOptions +{ +public: + KisTangentTiltWidget(QWidget *parent = 0) + : QWidget(parent) { + setupUi(this); + + sliderElevationSensitivity->setRange(0, 100, 0); + sliderElevationSensitivity->setSuffix(i18n("%")); + + sliderMixValue->setRange(0, 100, 0); + sliderMixValue->setSuffix(i18n("%")); + + sliderMixValue->setVisible(false); + } +}; + + +} + + +struct KisTangentTiltOptionWidget::Private +{ + Private(lager::cursor optionData) + : model(optionData) + { + } + + KisTangentTiltOptionModel model; +}; + + +KisTangentTiltOptionWidget::KisTangentTiltOptionWidget(lager::cursor optionData) + : KisPaintOpOption(i18n("Tangent Tilt"), KisPaintOpOption::GENERAL, true) + , m_d(new Private(optionData)) +{ + + KisTangentTiltWidget *widget = new KisTangentTiltWidget(); + setObjectName("KisTangentTiltOption"); + + m_checkable = false; + + using namespace KisWidgetConnectionUtils; + + connectControl(widget->comboRed, &m_d->model, "redChannel"); + connectControl(widget->comboGreen, &m_d->model, "greenChannel"); + connectControl(widget->comboBlue, &m_d->model, "blueChannel"); + + connect(widget->comboRed, SIGNAL(currentIndexChanged(int)), widget->TangentTiltPreview, SLOT(setRedChannel(int))); + connect(widget->comboGreen, SIGNAL(currentIndexChanged(int)), widget->TangentTiltPreview, SLOT(setGreenChannel(int))); + connect(widget->comboBlue, SIGNAL(currentIndexChanged(int)), widget->TangentTiltPreview, SLOT(setBlueChannel(int))); + + QButtonGroup *group = new QButtonGroup(widget); + group->addButton(widget->optionTilt, static_cast(TangentTiltDirectionType::Tilt)); + group->addButton(widget->optionDirection, static_cast(TangentTiltDirectionType::Direction)); + group->addButton(widget->optionRotation, static_cast(TangentTiltDirectionType::Rotation)); + group->addButton(widget->optionMix, static_cast(TangentTiltDirectionType::Mix)); + group->setExclusive(true); + connectControl(group, &m_d->model, "directionType"); + + connectControl(widget->sliderElevationSensitivity, &m_d->model, "elevationSensitivity"); + connectControl(widget->sliderMixValue, &m_d->model, "mixValue"); + + m_d->model.optionData.bind(std::bind(&KisTangentTiltOptionWidget::emitSettingChanged, this)); + + setConfigurationPage(widget); +} + +KisTangentTiltOptionWidget::~KisTangentTiltOptionWidget() +{ +} + +void KisTangentTiltOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setting) const +{ + KisTangentTiltOptionData data = *m_d->model.optionData; + data.write(setting.data()); +} + +void KisTangentTiltOptionWidget::readOptionSetting(const KisPropertiesConfigurationSP setting) +{ + KisTangentTiltOptionData data = *m_d->model.optionData; + data.read(setting.data()); + m_d->model.optionData.set(data); +} diff --git a/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.h b/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.h new file mode 100644 index 00000000000..35a149a667f --- /dev/null +++ b/plugins/paintops/tangentnormal/KisTangentTiltOptionWidget.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier + * + * SPDX-License-Identifier: LGPL-2.0-or-later + */ +#ifndef KIS_TANGENTTILT_OPTION_WIDGET_H +#define KIS_TANGENTTILT_OPTION_WIDGET_H + +#include +#include +#include + +struct KisTangentTiltOptionData; + +class KisTangentTiltOptionWidget : public KisPaintOpOption +{ +public: + using data_type = KisTangentTiltOptionData; + + KisTangentTiltOptionWidget(lager::cursor optionData); + ~KisTangentTiltOptionWidget(); + + void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; + void readOptionSetting(const KisPropertiesConfigurationSP setting) override; + +private: + struct Private; + const QScopedPointer m_d; +}; + +#endif // KIS_TANGENTTILT_OPTION_WIDGET_H diff --git a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp index 492517dc956..a4ec51dbfdd 100644 --- a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp +++ b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp @@ -22,34 +22,25 @@ #include -KisTangentNormalPaintOp::KisTangentNormalPaintOp(const KisPaintOpSettingsSP settings, KisPainter* painter, KisNodeSP node, KisImageSP image): - KisBrushBasedPaintOp(settings, painter), - m_opacityOption(node), - m_sharpnessOption(settings.data()), - m_tempDev(painter->device()->createCompositionSourceDevice()) +KisTangentNormalPaintOp::KisTangentNormalPaintOp(const KisPaintOpSettingsSP settings, KisPainter* painter, KisNodeSP node, KisImageSP image) + : KisBrushBasedPaintOp(settings, painter) + , m_tangentTiltOption(settings.data()) + , m_opacityOption(settings.data(), node) + , m_flowOption(settings.data()) + , m_sizeOption(settings.data()) + , m_spacingOption(settings.data()) + , m_softnessOption(settings.data()) + , m_sharpnessOption(settings.data()) + , m_scatterOption(settings.data()) + , m_rotationOption(settings.data()) + , m_rateOption(settings.data()) + , m_tempDev(painter->device()->createCompositionSourceDevice()) { Q_UNUSED(image); //Init, read settings, etc// - m_tangentTiltOption.readOptionSetting(settings); - m_airbrushOption.readOptionSetting(settings); - m_sizeOption.readOptionSetting(settings); - m_opacityOption.readOptionSetting(settings); - m_flowOption.readOptionSetting(settings); - m_spacingOption.readOptionSetting(settings); - m_rateOption.readOptionSetting(settings); - m_softnessOption.readOptionSetting(settings); - m_rotationOption.readOptionSetting(settings); - m_scatterOption.readOptionSetting(settings); - - m_sizeOption.resetAllSensors(); - m_opacityOption.resetAllSensors(); - m_flowOption.resetAllSensors(); - m_spacingOption.resetAllSensors(); - m_rateOption.resetAllSensors(); - m_softnessOption.resetAllSensors(); - m_rotationOption.resetAllSensors(); - m_scatterOption.resetAllSensors(); + m_tangentTiltOptionData.read(settings.data()); + m_airbrushData.read(settings.data()); m_dabCache->setSharpnessPostprocessing(&m_sharpnessOption); m_rotationOption.applyFanCornersInfo(this); @@ -143,7 +134,6 @@ KisSpacingInformation KisTangentNormalPaintOp::paintAt(const KisPaintInformation QString oldCompositeOpId = painter()->compositeOpId(); - m_opacityOption.setFlow(m_flowOption.apply(info)); m_opacityOption.apply(painter(), info); //paint with the default color? Copied this from color smudge.// //painter()->setCompositeOp(COMPOSITE_COPY); @@ -167,13 +157,13 @@ KisSpacingInformation KisTangentNormalPaintOp::updateSpacingImpl(const KisPaintI KisTimingInformation KisTangentNormalPaintOp::updateTimingImpl(const KisPaintInformation &info) const { - return KisPaintOpPluginUtils::effectiveTiming(&m_airbrushOption, &m_rateOption, info); + return KisPaintOpPluginUtils::effectiveTiming(&m_airbrushData, &m_rateOption, info); } KisSpacingInformation KisTangentNormalPaintOp::computeSpacing(const KisPaintInformation &info, qreal scale, qreal rotation) const { - return effectiveSpacing(scale, rotation, &m_airbrushOption, &m_spacingOption, info); + return effectiveSpacing(scale, rotation, &m_airbrushData, &m_spacingOption, info); } void KisTangentNormalPaintOp::paintLine(const KisPaintInformation& pi1, const KisPaintInformation& pi2, KisDistanceInformation *currentDistance) diff --git a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h index b83082539e6..18de5d94af1 100644 --- a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h +++ b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h @@ -12,17 +12,16 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include + +#include +#include +#include #include +#include +#include +#include class KisBrushBasedPaintOpSettings; class KisPainter; @@ -52,17 +51,19 @@ class KisTangentNormalPaintOp: public KisBrushBasedPaintOp private: //private functions// - KisPressureSizeOption m_sizeOption; - KisFlowOpacityOption m_opacityOption; - KisPressureSpacingOption m_spacingOption; - KisPressureRateOption m_rateOption; - KisPressureRotationOption m_rotationOption; - KisPressureScatterOption m_scatterOption; KisTangentTiltOption m_tangentTiltOption; - KisAirbrushOptionProperties m_airbrushOption; - KisPressureSoftnessOption m_softnessOption; + KisTangentTiltOptionData m_tangentTiltOptionData; + + KisFlowOpacityOption2 m_opacityOption; + KisFlowOption m_flowOption; + KisSizeOption m_sizeOption; + KisSpacingOption m_spacingOption; + KisSoftnessOption m_softnessOption; KisSharpnessOption m_sharpnessOption; - KisPressureFlowOption m_flowOption; + KisScatterOption m_scatterOption; + KisRotationOption m_rotationOption; + KisAirbrushOptionData m_airbrushData; + KisRateOption m_rateOption; KisFixedPaintDeviceSP m_maskDab; KisPaintDeviceSP m_tempDev; diff --git a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop_settings_widget.cpp b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop_settings_widget.cpp index 06a783293eb..3fe18dd2f83 100644 --- a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop_settings_widget.cpp +++ b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop_settings_widget.cpp @@ -6,30 +6,21 @@ #include "kis_tangent_normal_paintop_settings_widget.h" #include "kis_brush_based_paintop_settings.h" -#include "kis_tangent_tilt_option.h" +#include "KisTangentTiltOptionWidget.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kis_texture_option.h" -#include -#include "kis_pressure_texture_strength_option.h" -#include +#include #include -#include -#include +#include +#include "KisSizeOptionWidget.h" +#include "KisSpacingOptionWidget.h" +#include "KisMirrorOptionWidget.h" +#include "KisSharpnessOptionWidget.h" +#include "KisScatterOptionWidget.h" +#include "KisAirbrushOptionWidget.h" +#include "KisPaintingModeOptionWidget.h" +#include KisTangentNormalPaintOpSettingsWidget::KisTangentNormalPaintOpSettingsWidget(QWidget* parent, KisResourcesInterfaceSP resourcesInterface, KoCanvasResourcesInterfaceSP canvasResourcesInterface): KisBrushBasedPaintopOptionWidget(KisBrushOptionWidgetFlag::SupportsPrecision | @@ -41,25 +32,25 @@ KisTangentNormalPaintOpSettingsWidget::KisTangentNormalPaintOpSettingsWidget(QWi setObjectName("brush option widget"); addPaintOpOption(kpowu::createOptionWidget()); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureOpacityOption(), i18n("Transparent"), i18n("Opaque"))); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureFlowOption(), i18n("0%"), i18n("100%"))); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureSizeOption(), i18n("0%"), i18n("100%"))); + addPaintOpOption(kpowu::createOpacityOptionWidget()); + addPaintOpOption(kpowu::createFlowOptionWidget()); + addPaintOpOption(kpowu::createOptionWidget()); - addPaintOpOption(new KisTangentTiltOption()); + addPaintOpOption(kpowu::createOptionWidget()); - addPaintOpOption(new KisPressureSpacingOptionWidget()); - addPaintOpOption(new KisPressureMirrorOptionWidget()); + addPaintOpOption(kpowu::createOptionWidget()); + addPaintOpOption(kpowu::createOptionWidget()); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureSoftnessOption(), i18n("Soft"), i18n("Hard"))); - addPaintOpOption(new KisPressureSharpnessOptionWidget()); - addPaintOpOption(new KisPressureScatterOptionWidget()); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureRotationOption(), i18n("-180°"), i18n("180°"))); + addPaintOpOption(kpowu::createSoftnessOptionWidget()); + addPaintOpOption(kpowu::createOptionWidget()); + addPaintOpOption(kpowu::createOptionWidget()); + addPaintOpOption(kpowu::createRotationOptionWidget()); addPaintOpOption(kpowu::createOptionWidget()); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureRateOption(), i18n("0%"), i18n("100%"))); + addPaintOpOption(kpowu::createRateOptionWidget()); addPaintOpOption(kpowu::createOptionWidget()); addPaintOpOption(kpowu::createOptionWidget(KisTextureOptionData(), resourcesInterface)); - addPaintOpOption(new KisCurveOptionWidget(new KisPressureTextureStrengthOption(), i18n("Weak"), i18n("Strong"))); + addPaintOpOption(kpowu::createStrengthOptionWidget()); } KisTangentNormalPaintOpSettingsWidget::~KisTangentNormalPaintOpSettingsWidget() { } diff --git a/plugins/paintops/tangentnormal/kis_tangent_tilt_option.cpp b/plugins/paintops/tangentnormal/kis_tangent_tilt_option.cpp deleted file mode 100644 index 985790d94fd..00000000000 --- a/plugins/paintops/tangentnormal/kis_tangent_tilt_option.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* This file is part of the KDE project - * - * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ - - -#include "kis_tangent_tilt_option.h" -#include -#include -#include - -#include "ui_wdgtangenttiltoption.h" - -#include "kis_global.h" - -class KisTangentTiltOptionWidget: public QWidget, public Ui::WdgTangentTiltOptions -{ -public: - KisTangentTiltOptionWidget(QWidget *parent = 0) - : QWidget(parent) { - setupUi(this); - } -}; - -KisTangentTiltOption::KisTangentTiltOption() - : KisPaintOpOption(i18n("Tangent Tilt"), KisPaintOpOption::GENERAL, false) -{ - m_checkable = false; - m_options = new KisTangentTiltOptionWidget(); - //Setup tangent tilt. - m_options->comboRed->setCurrentIndex(0); - m_options->comboGreen->setCurrentIndex(2); - m_options->comboBlue->setCurrentIndex(4); - - m_options->sliderElevationSensitivity->setRange(0, 100, 0); - m_options->sliderElevationSensitivity->setValue(100); - m_options->sliderElevationSensitivity->setSuffix(i18n("%")); - - m_options->sliderMixValue->setRange(0, 100, 0); - m_options->sliderMixValue->setValue(50); - m_options->sliderMixValue->setSuffix(i18n("%")); - - connect(m_options->comboRed, SIGNAL(currentIndexChanged(int)), SLOT(emitSettingChanged())); - connect(m_options->comboGreen, SIGNAL(currentIndexChanged(int)), SLOT(emitSettingChanged())); - connect(m_options->comboBlue, SIGNAL(currentIndexChanged(int)), SLOT(emitSettingChanged())); - connect(m_options->comboRed, SIGNAL(currentIndexChanged(int)), m_options->TangentTiltPreview, SLOT(setRedChannel(int))); - connect(m_options->comboGreen, SIGNAL(currentIndexChanged(int)), m_options->TangentTiltPreview, SLOT(setGreenChannel(int))); - connect(m_options->comboBlue, SIGNAL(currentIndexChanged(int)), m_options->TangentTiltPreview, SLOT(setBlueChannel(int))); - - connect(m_options->optionTilt, SIGNAL(toggled(bool)), SLOT(emitSettingChanged())); - connect(m_options->optionDirection, SIGNAL(toggled(bool)), SLOT(emitSettingChanged())); - connect(m_options->optionRotation, SIGNAL(toggled(bool)), SLOT(emitSettingChanged())); - connect(m_options->optionMix, SIGNAL(toggled(bool)), SLOT(emitSettingChanged())); - - connect(m_options->sliderElevationSensitivity, SIGNAL(valueChanged(qreal)), SLOT(emitSettingChanged())); - connect(m_options->sliderMixValue, SIGNAL(valueChanged(qreal)), SLOT(emitSettingChanged())); - m_options->sliderMixValue->setVisible(false); - - setConfigurationPage(m_options); - -} - -KisTangentTiltOption::~KisTangentTiltOption() -{ - delete m_options; -} - -//options -int KisTangentTiltOption::redChannel() const -{ - return m_options->comboRed->currentIndex(); -} -int KisTangentTiltOption::greenChannel() const -{ - return m_options->comboGreen->currentIndex(); -} -int KisTangentTiltOption::blueChannel() const -{ - return m_options->comboBlue->currentIndex(); -} - -int KisTangentTiltOption::directionType() const -{ - int type=0; - - if (m_options->optionTilt->isChecked()==true) { - type=0; - } - else if (m_options->optionDirection->isChecked()==true) { - type=1; - } - else if (m_options->optionRotation->isChecked()==true) { - type=2; - } - else if (m_options->optionMix->isChecked()==true) { - type=3; - } - else { - warnKrita<<"There's something odd with the radio buttons. We'll use Tilt"; - } - - return type; -} - -double KisTangentTiltOption::elevationSensitivity() const -{ - return m_options->sliderElevationSensitivity->value(); -} - -double KisTangentTiltOption::mixValue() const -{ - return m_options->sliderMixValue->value(); -} - -void KisTangentTiltOption::swizzleAssign(qreal const horizontal, qreal const vertical, qreal const depth, qreal *component, int index, qreal maxvalue) -{ - switch(index) { - case 0: *component = horizontal; break; - case 1: *component = maxvalue-horizontal; break; - case 2: *component = vertical; break; - case 3: *component = maxvalue-vertical; break; - case 4: *component = depth; break; - case 5: *component = maxvalue-depth; break; - } -} - -void KisTangentTiltOption::apply(const KisPaintInformation& info,qreal *r,qreal *g,qreal *b) -{ - //formula based on https://www.cerebralmeltdown.com/programming_projects/Altitude%20and%20Azimuth%20to%20Vector/index.html - - /* It doesn't make sense of have higher than 8bit color depth. - * Instead we make sure in the paintAt function of kis_tangent_normal_paintop to pick an 8bit space of the current - * color space if the space is an RGB space. If not, it'll pick sRGB 8bit. - */ - qreal halfvalue = 0.5; - qreal maxvalue = 1.0; - - //have the azimuth and altitude in degrees. - qreal direction = KisPaintInformation::tiltDirection(info, true)*360.0; - qreal elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); - - if (directionType() == 0) { - direction = KisPaintInformation::tiltDirection(info, true)*360.0; - elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); - } else if (directionType() == 1) { - direction = (0.75 + info.drawingAngle() / (2.0 * M_PI))*360.0; - elevation= 0;//turns out that tablets that don't support tilt just return 90 degrees for elevation. - } else if (directionType() == 2) { - direction = info.rotation(); - elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0);//artpens have tilt-recognition, so this should work. - } else if (directionType() == 3) {//mix of tilt+direction - qreal mixamount = mixValue()/100.0; - direction = (KisPaintInformation::tiltDirection(info, true)*360.0*(1.0-mixamount))+((0.75 + info.drawingAngle() / (2.0 * M_PI))*360.0*(mixamount)); - elevation= (info.tiltElevation(info, 60.0, 60.0, true)*90.0); - } - - //subtract/add the rotation of the canvas. - if (directionType() != 1) { - direction = normalizeAngleDegrees(direction - info.canvasRotation()); - } - - //limit the direction/elevation - - //qreal elevationMax = (elevationSensitivity()*90.0)/100.0; - qreal elevationT = elevation*(elevationSensitivity()/100.0)+(90-(elevationSensitivity()*90.0)/100.0); - elevation = static_cast(elevationT); - - //convert to radians. - // Convert this to kis_global's radian function. - direction = kisDegreesToRadians(direction); - elevation = kisDegreesToRadians(elevation); - - //make variables for axes for easy switching later on. - qreal horizontal, vertical, depth; - - //spherical coordinates always center themselves around the origin, leading to values. We need to work around those... - - horizontal = cos(elevation)*sin(direction); - if (horizontal>0.0) { - horizontal= halfvalue+(fabs(horizontal)*halfvalue); - } - else { - horizontal= halfvalue-(fabs(horizontal)*halfvalue); - } - vertical = cos(elevation)*cos(direction); - if (vertical>0.0) { - vertical = halfvalue+(fabs(vertical)*halfvalue); - } - else { - vertical = halfvalue-(fabs(vertical)*halfvalue); - } - - if (info.canvasMirroredH()) {horizontal = maxvalue - horizontal;} - if (info.canvasMirroredV()) {vertical = maxvalue - vertical;} - - depth = sin(elevation)*maxvalue; - - //assign right components to correct axes. - swizzleAssign(horizontal, vertical, depth, r, redChannel(), maxvalue); - swizzleAssign(horizontal, vertical, depth, g, greenChannel(), maxvalue); - swizzleAssign(horizontal, vertical, depth, b, blueChannel(), maxvalue); - -} - -/*settings*/ -void KisTangentTiltOption::writeOptionSetting(KisPropertiesConfigurationSP setting) const -{ - setting->setProperty(TANGENT_RED, redChannel()); - setting->setProperty(TANGENT_GREEN, greenChannel()); - setting->setProperty(TANGENT_BLUE, blueChannel()); - setting->setProperty(TANGENT_TYPE, directionType()); - setting->setProperty(TANGENT_EV_SEN, elevationSensitivity()); - setting->setProperty(TANGENT_MIX_VAL, mixValue()); -} - -void KisTangentTiltOption::readOptionSetting(const KisPropertiesConfigurationSP setting) -{ - m_options->comboRed->setCurrentIndex(setting->getInt(TANGENT_RED, 0)); - m_options->comboGreen->setCurrentIndex(setting->getInt(TANGENT_GREEN, 2)); - m_options->comboBlue->setCurrentIndex(setting->getInt(TANGENT_BLUE, 4)); - - //The comboboxes are connected to the TangentTiltPreview, so that gets automatically updated by them. - - if (setting->getInt(TANGENT_TYPE)== 0){ - m_options->optionTilt->setChecked(true); - m_options->sliderMixValue->setVisible(false); - } - else if (setting->getInt(TANGENT_TYPE)== 1) { - m_options->optionDirection->setChecked(true); - m_options->sliderMixValue->setVisible(false); - } - else if (setting->getInt(TANGENT_TYPE)== 2) { - m_options->optionRotation->setChecked(true); - m_options->sliderMixValue->setVisible(false); - } - else if (setting->getInt(TANGENT_TYPE)== 3) { - m_options->optionMix->setChecked(true); - m_options->sliderMixValue->setVisible(true); - } - - m_options->sliderElevationSensitivity->setValue(setting->getDouble(TANGENT_EV_SEN, 100)); - m_options->sliderMixValue->setValue(setting->getDouble(TANGENT_MIX_VAL, 50)); -} diff --git a/plugins/paintops/tangentnormal/kis_tangent_tilt_option.h b/plugins/paintops/tangentnormal/kis_tangent_tilt_option.h deleted file mode 100644 index c68d1a9572e..00000000000 --- a/plugins/paintops/tangentnormal/kis_tangent_tilt_option.h +++ /dev/null @@ -1,52 +0,0 @@ -/* This file is part of the KDE project - * - * SPDX-FileCopyrightText: 2015 Wolthera van Hövell tot Westerflier - * - * SPDX-License-Identifier: LGPL-2.0-or-later - */ - -#ifndef KIS_TANGENT_TILT_OPTION_H -#define KIS_TANGENT_TILT_OPTION_H - -#include -#include - -#include - -const QString TANGENT_RED = "Tangent/swizzleRed"; -const QString TANGENT_GREEN = "Tangent/swizzleGreen"; -const QString TANGENT_BLUE = "Tangent/swizzleBlue"; -const QString TANGENT_TYPE = "Tangent/directionType"; -const QString TANGENT_EV_SEN = "Tangent/elevationSensitivity"; -const QString TANGENT_MIX_VAL = "Tangent/mixValue"; -//const QString TANGENT_DIR_MIN = "Tangent/directionMinimum"; -//const QString TANGENT_DIR_MAX = "Tangent/directionMaximum"; - -class KisPropertiesConfiguration; -class KisTangentTiltOptionWidget; - -class KisTangentTiltOption: public KisPaintOpOption //not really// -{ -public: - KisTangentTiltOption(); - ~KisTangentTiltOption() override; - /*These three give away which the index of the combobox for a given channel*/ - int redChannel() const; - int greenChannel() const; - int blueChannel() const; - int directionType() const; - double elevationSensitivity() const; - double mixValue() const; - /*This assigns the right axis to the component, based on index and maximum value*/ - void swizzleAssign(qreal const horizontal, qreal const vertical, qreal const depth, qreal *component, int index, qreal maxvalue); - - //takes the RGB values and will deform them depending on tilt. - void apply(const KisPaintInformation& info, qreal *r, qreal *g, qreal *b); - - void writeOptionSetting(KisPropertiesConfigurationSP setting) const override; - void readOptionSetting(const KisPropertiesConfigurationSP setting) override; -private: - KisTangentTiltOptionWidget * m_options; -}; - -#endif // KIS_TANGENT_TILT_OPTION_H From 7724c1ad6c5d616dad71298747f95c9678aef7c1 Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Tue, 13 Dec 2022 15:49:18 +0300 Subject: [PATCH 19/20] Remove unused data object --- plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp | 1 - plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp index a4ec51dbfdd..ac3bc96eba2 100644 --- a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp +++ b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.cpp @@ -39,7 +39,6 @@ KisTangentNormalPaintOp::KisTangentNormalPaintOp(const KisPaintOpSettingsSP sett { Q_UNUSED(image); //Init, read settings, etc// - m_tangentTiltOptionData.read(settings.data()); m_airbrushData.read(settings.data()); m_dabCache->setSharpnessPostprocessing(&m_sharpnessOption); diff --git a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h index 18de5d94af1..0bd0f3327d0 100644 --- a/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h +++ b/plugins/paintops/tangentnormal/kis_tangent_normal_paintop.h @@ -52,7 +52,6 @@ class KisTangentNormalPaintOp: public KisBrushBasedPaintOp private: //private functions// KisTangentTiltOption m_tangentTiltOption; - KisTangentTiltOptionData m_tangentTiltOptionData; KisFlowOpacityOption2 m_opacityOption; KisFlowOption m_flowOption; From c4a009f56850a4df292a42b1b2b73a8644f4ae3e Mon Sep 17 00:00:00 2001 From: Dmitry Kazakov Date: Wed, 14 Dec 2022 13:42:33 +0300 Subject: [PATCH 20/20] Make sure MyPaint presets saved in Krita 5.2 can still be open in Krita 5.1 That form of compatibility should be removed in the future, but for now we can just save the values needed by previous verisons of Krita. --- plugins/paintops/mypaint/CMakeLists.txt | 1 + .../mypaint/MyPaintCurveOptionData.cpp | 25 ++++-- .../paintops/mypaint/MyPaintCurveOptionData.h | 12 ++- .../paintops/mypaint/MyPaintPaintOpPreset.cpp | 22 +++++ .../mypaint/MyPaintStandardOptionData.cpp | 90 +++++++++++++++++++ .../mypaint/MyPaintStandardOptionData.h | 19 +--- 6 files changed, 145 insertions(+), 24 deletions(-) create mode 100644 plugins/paintops/mypaint/MyPaintStandardOptionData.cpp diff --git a/plugins/paintops/mypaint/CMakeLists.txt b/plugins/paintops/mypaint/CMakeLists.txt index 0a5df34cefa..cf42a77b434 100644 --- a/plugins/paintops/mypaint/CMakeLists.txt +++ b/plugins/paintops/mypaint/CMakeLists.txt @@ -19,6 +19,7 @@ set(kritamypaintop_SOURCES MyPaintSurface.cpp MyPaintPaintOpPreset.cpp MyPaintPaintOpFactory.cpp + MyPaintStandardOptionData.cpp ) ki18n_wrap_ui(kritamypaintop_SOURCES wdgmypaintoptions.ui wdgmypaintcurveoption.ui) diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp index f1dc63860b3..841eb87fbb3 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.cpp @@ -12,13 +12,13 @@ MyPaintCurveOptionData::MyPaintCurveOptionData(const QString &prefix, bool isChecked, qreal minValue, qreal maxValue) - : KisCurveOptionDataCommon(prefix, - id, - isCheckable, - isChecked, - minValue, - maxValue, - new MyPaintSensorPack()) + : MyPaintCurveOptionData(prefix, + id, + isCheckable, + isChecked, + minValue, + maxValue, + new MyPaintSensorPack()) { } @@ -31,6 +31,17 @@ MyPaintCurveOptionData::MyPaintCurveOptionData(const KoID &id, { } +MyPaintCurveOptionData::MyPaintCurveOptionData(const QString &prefix, const KoID &id, bool isCheckable, bool isChecked, qreal minValue, qreal maxValue, MyPaintSensorPack *sensorInterface) + : KisCurveOptionDataCommon(prefix, + id, + isCheckable, + isChecked, + minValue, + maxValue, + sensorInterface) +{ +} + MyPaintSensorData &MyPaintCurveOptionData::sensorStruct() { return dynamic_cast(sensorData.data())->sensorsStruct(); diff --git a/plugins/paintops/mypaint/MyPaintCurveOptionData.h b/plugins/paintops/mypaint/MyPaintCurveOptionData.h index aebca59d55c..fac533de01c 100644 --- a/plugins/paintops/mypaint/MyPaintCurveOptionData.h +++ b/plugins/paintops/mypaint/MyPaintCurveOptionData.h @@ -25,7 +25,17 @@ struct MyPaintCurveOptionData : KisCurveOptionDataCommon bool isChecked = false, qreal minValue = 0.0, qreal maxValue = 1.0); - + +protected: + MyPaintCurveOptionData(const QString &prefix, + const KoID &id, + bool isCheckable, + bool isChecked, + qreal minValue, + qreal maxValue, + MyPaintSensorPack *sensorInterface); +public: + MyPaintSensorData& sensorStruct(); const MyPaintSensorData& sensorStruct() const; }; diff --git a/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp b/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp index 7d7a2d7a655..fda88ce29d1 100644 --- a/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp +++ b/plugins/paintops/mypaint/MyPaintPaintOpPreset.cpp @@ -21,6 +21,7 @@ #include "MyPaintPaintOpSettings.h" #include "MyPaintSensorPack.h" +#include "MyPaintStandardOptionData.h" class KisMyPaintPaintOpPreset::Private { @@ -140,6 +141,27 @@ bool KisMyPaintPaintOpPreset::loadFromDevice(QIODevice *dev, KisResourcesInterfa s->setProperty(MYPAINT_JSON, this->getJsonData()); s->setProperty("EraserMode", qRound(isEraser)); + + { + /** + * See a comment in `namespace deprecated_remove_after_krita6` in + * MyPaintStandardOptionData.cpp + */ + + auto recoverDeprecatedProperty = [] (auto data, KisPaintOpSettingsSP settings) { + /// we just round-trip the save operation to save the property + /// out ot json object + + data.read(settings.data()); + data.write(settings.data()); + }; + + recoverDeprecatedProperty(MyPaintRadiusLogarithmicData(), s); + recoverDeprecatedProperty(MyPaintOpacityData(), s); + recoverDeprecatedProperty(MyPaintHardnessData(), s); + } + + if (!metadata().contains("paintopid")) { addMetaData("paintopid", "mypaintbrush"); } diff --git a/plugins/paintops/mypaint/MyPaintStandardOptionData.cpp b/plugins/paintops/mypaint/MyPaintStandardOptionData.cpp new file mode 100644 index 00000000000..2c03ce376b8 --- /dev/null +++ b/plugins/paintops/mypaint/MyPaintStandardOptionData.cpp @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: 2022 Dmitry Kazakov + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include + +namespace deprecated_remove_after_krita6 { + +/** + * Before Krita 5.2 MyPaint brushes saved into .kpp files used to have + * separate properties for hardness, opacity and diameter. They are gone + * with Krita 5.2, but to make sure new brush presets can be open with the + * older versions of Krita, we should keep them for some time. + */ + +const QString MYPAINT_HARDNESS = "MyPaint/hardness"; +const QString MYPAINT_OPACITY = "MyPaint/opcity"; +const QString MYPAINT_DIAMETER = "MyPaint/diameter"; + +class SensorPackOpacity : public MyPaintSensorPack +{ +public: + KisSensorPackInterface * clone() const override + { + return new SensorPackOpacity(*this); + } + + void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const override + { + MyPaintSensorPack::write(data, setting); + setting->setProperty(MYPAINT_OPACITY, data.strengthValue); + } +}; + +class SensorPackHardness : public MyPaintSensorPack +{ +public: + KisSensorPackInterface * clone() const override + { + return new SensorPackHardness(*this); + } + void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const override + { + MyPaintSensorPack::write(data, setting); + setting->setProperty(MYPAINT_HARDNESS, data.strengthValue); + } +}; + + +class SensorPackRadiusLogarithmic : public MyPaintSensorPack +{ +public: + KisSensorPackInterface * clone() const override { + return new SensorPackRadiusLogarithmic(*this); + } + void write(const KisCurveOptionDataCommon &data, KisPropertiesConfiguration *setting) const override + { + MyPaintSensorPack::write(data, setting); + setting->setProperty(MYPAINT_DIAMETER, 2.0 * exp(data.strengthValue)); + } +}; + +} // namespace deprecated_remove_after_krita6 + +MyPaintRadiusLogarithmicData::MyPaintRadiusLogarithmicData() + : MyPaintCurveOptionData("", + KoID("radius_logarithmic", + i18n("Radius Logarithmic")), + false, true, 0.01, 8.0, + new deprecated_remove_after_krita6::SensorPackRadiusLogarithmic()) +{ +} + +MyPaintHardnessData::MyPaintHardnessData() + : MyPaintCurveOptionData("", + KoID("hardness", i18n("Hardness")), + false, true, 0.02, 1.0, + new deprecated_remove_after_krita6::SensorPackHardness()) +{ +} + +MyPaintOpacityData::MyPaintOpacityData() + : MyPaintCurveOptionData("", + KoID("opaque", i18n("Opaque")), + false, true, 0.0, 2.0, + new deprecated_remove_after_krita6::SensorPackOpacity()) +{ +} diff --git a/plugins/paintops/mypaint/MyPaintStandardOptionData.h b/plugins/paintops/mypaint/MyPaintStandardOptionData.h index e8238cfd2b9..b015892dc8f 100644 --- a/plugins/paintops/mypaint/MyPaintStandardOptionData.h +++ b/plugins/paintops/mypaint/MyPaintStandardOptionData.h @@ -12,30 +12,17 @@ struct MyPaintRadiusLogarithmicData : MyPaintCurveOptionData { - MyPaintRadiusLogarithmicData() - : MyPaintCurveOptionData(KoID("radius_logarithmic", - i18n("Radius Logarithmic")), - false, true, 0.01, 8.0) - { - } + MyPaintRadiusLogarithmicData(); }; struct MyPaintHardnessData : MyPaintCurveOptionData { - MyPaintHardnessData() - : MyPaintCurveOptionData(KoID("hardness", i18n("Hardness")), - false, true, 0.02, 1.0) - { - } + MyPaintHardnessData(); }; struct MyPaintOpacityData : MyPaintCurveOptionData { - MyPaintOpacityData() - : MyPaintCurveOptionData(KoID("opaque", i18n("Opaque")), - false, true, 0.0, 2.0) - { - } + MyPaintOpacityData(); }; struct MyPaintRadiusByRandomData : MyPaintCurveOptionData