Commit 43c2bad8 authored by Agata Cacko's avatar Agata Cacko

Replace cache with a new variable in curve option

Before this commit, "Use the same curve" (precisely,
"Share curve across all settings") was done using
(1) rewriting values in sensors to the selected curve
(2) cached curves for all the sensors in case the user changes
their mind and wants the previous ones.

This behaviour brings confusion and is hard to debug, hence
the change.

This commit adds a new separate variable that keeps the
"common curve", so all sensors has their own curves.
There is no need for caching or restoring, it just needs
to be clear that when the Use The Same Curve checkbox is
checked, the value from the common curve needs to be taken
instead of the curve from the sensor in question.
parent 78ea95b5
......@@ -41,6 +41,13 @@ KisCurveOption::KisCurveOption(const QString& name, KisPaintOpOption::PaintopCat
setValueRange(min, max);
setValue(value);
QList<QPointF> points;
points.push_back(QPointF(0,1));
points.push_back(QPointF(0.25,0.9));
points.push_back(QPointF(0.75,0.1));
points.push_back(QPointF(1,0));
m_commonCurve = KisCubicCurve(points);
}
KisCurveOption::~KisCurveOption()
......@@ -257,6 +264,11 @@ int KisCurveOption::getCurveMode() const
return m_curveMode;
}
KisCubicCurve KisCurveOption::getCommonCurve() const
{
return m_commonCurve;
}
void KisCurveOption::setSeparateCurveValue(bool separateCurveValue)
{
m_separateCurveValue = separateCurveValue;
......@@ -287,14 +299,17 @@ void KisCurveOption::setCurveMode(int mode)
m_curveMode = mode;
}
void KisCurveOption::setCommonCurve(KisCubicCurve curve)
{
m_commonCurve = curve;
}
void KisCurveOption::setCurve(DynamicSensorType sensorType, bool useSameCurve, const KisCubicCurve &curve)
{
// No switch in state, don't mess with the cache
if (useSameCurve == m_useSameCurve) {
if (useSameCurve) {
Q_FOREACH (KisDynamicSensorSP s, m_sensorMap.values()) {
s->setCurve(curve);
}
m_commonCurve = curve;
}
else {
KisDynamicSensorSP s = sensor(sensorType, false);
......@@ -311,8 +326,8 @@ void KisCurveOption::setCurve(DynamicSensorType sensorType, bool useSameCurve, c
m_curveCache.clear();
Q_FOREACH (KisDynamicSensorSP s, m_sensorMap.values()) {
m_curveCache[s->sensorType()] = s->curve();
s->setCurve(curve);
}
m_commonCurve = curve;
}
else { //if (m_useSameCurve && !useSameCurve)
// Restore the cached curves
......@@ -324,7 +339,6 @@ void KisCurveOption::setCurve(DynamicSensorType sensorType, bool useSameCurve, c
else {
s = KisDynamicSensor::type2Sensor(sensorType, m_name);
}
s->setCurve(m_curveCache[sensorType]);
m_sensorMap[sensorType] = s;
}
s = 0;
......@@ -334,7 +348,6 @@ void KisCurveOption::setCurve(DynamicSensorType sensorType, bool useSameCurve, c
}
if (s) {
s->setCurve(curve);
s->setCurve(m_curveCache[sensorType]);
}
}
......@@ -364,14 +377,15 @@ KisCurveOption::ValueComponents KisCurveOption::computeValueComponents(const Kis
KisDynamicSensorSP s(i.value());
if (s->isActive()) {
qreal valueFromCurve = m_useSameCurve ? s->parameter(info, m_commonCurve, true) : s->parameter(info);
if (s->isAdditive()) {
components.additive += s->parameter(info);
components.additive += valueFromCurve;
components.hasAdditive = true;
} else if (s->isAbsoluteRotation()) {
components.absoluteOffset = s->parameter(info);
components.absoluteOffset = valueFromCurve;
components.hasAbsoluteOffset =true;
} else {
sensorValues << s->parameter(info);
sensorValues << valueFromCurve;
components.hasScaling = true;
}
}
......
......@@ -85,6 +85,12 @@ public:
int getCurveMode() const;
/**
* Returns the curve that is being used instead of sensor ones
* in case "Use the same curve" is checked.
*/
KisCubicCurve getCommonCurve() const;
void setSeparateCurveValue(bool separateCurveValue);
void setChecked(bool checked);
......@@ -93,6 +99,12 @@ public:
void setValue(qreal value);
void setCurveMode(int mode);
/**
* Sets the curve that is being used instead of sensor ones
* in case "Use the same curve" is checked.
*/
void setCommonCurve(KisCubicCurve curve);
struct ValueComponents {
ValueComponents()
......@@ -198,6 +210,12 @@ protected:
bool m_useSameCurve;
bool m_separateCurveValue;
/**
* Curve that is being used instead of sensors' internal ones
* in case "Use the same curve" is checked.
*/
KisCubicCurve m_commonCurve;
int m_curveMode;
QMap<DynamicSensorType, KisDynamicSensorSP> m_sensorMap;
......
......@@ -123,12 +123,11 @@ void KisCurveOptionWidget::readOptionSetting(const KisPropertiesConfigurationSP
m_curveOptionWidget->sensorSelector->reload();
m_curveOptionWidget->sensorSelector->setCurrent(m_curveOption->activeSensors().first());
updateSensorCurveLabels(m_curveOptionWidget->sensorSelector->currentHighlighted());
updateCurve(m_curveOptionWidget->sensorSelector->currentHighlighted());
if (m_curveOption->isSameCurveUsed()) {
// make sure the curve is transfered to all sensors to avoid updating from a wrong curve later
transferCurve();
m_curveOption->setCommonCurve(m_curveOptionWidget->sensorSelector->currentHighlighted()->curve());
}
updateCurve(m_curveOptionWidget->sensorSelector->currentHighlighted());
}
void KisCurveOptionWidget::lodLimitations(KisPaintopLodLimitations *l) const
......@@ -204,7 +203,8 @@ void KisCurveOptionWidget::updateCurve(KisDynamicSensorSP sensor)
{
if (sensor) {
bool blockSignal = m_curveOptionWidget->curveWidget->blockSignals(true);
m_curveOptionWidget->curveWidget->setCurve(sensor->curve());
KisCubicCurve curve = m_curveOption->isSameCurveUsed() ? m_curveOption->getCommonCurve() : sensor->curve();
m_curveOptionWidget->curveWidget->setCurve(curve);
m_curveOptionWidget->curveWidget->blockSignals(blockSignal);
}
}
......
......@@ -514,12 +514,17 @@ void KisDynamicSensor::fromXML(const QDomElement& e)
}
qreal KisDynamicSensor::parameter(const KisPaintInformation& info)
{
return parameter(info, m_curve, m_customCurve);
}
qreal KisDynamicSensor::parameter(const KisPaintInformation& info, const KisCubicCurve curve, const bool customCurve)
{
const qreal val = value(info);
if (m_customCurve) {
if (customCurve) {
qreal scaledVal = isAdditive() ? additiveToScaling(val) : val;
const QVector<qreal> transfer = m_curve.floatTransfer(256);
const QVector<qreal> transfer = curve.floatTransfer(256);
scaledVal = KisCubicCurve::interpolateLinear(scaledVal, transfer);
return isAdditive() ? scalingToAdditive(scaledVal) : scaledVal;
......
......@@ -114,6 +114,13 @@ public:
* @return the value of this sensor for the given KisPaintInformation
*/
qreal parameter(const KisPaintInformation& info);
/**
* @return the value of this sensor for the given KisPaintInformation
* curve -- a custom, temporary curve that should be used instead of the one for the sensor
* customCurve -- if it's a new curve or not; should always be true if the function is called from outside
* (aka not in parameter(info) function)
*/
qreal parameter(const KisPaintInformation& info, const KisCubicCurve curve, const bool customCurve);
/**
* This function is call before beginning a stroke to reset the sensor.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment