1 /** -*- C++ -*-
2  *
3  *  This file is part of RawTherapee.
4  *
5  *  Copyright (c) 2017 Alberto Griggio <alberto.griggio@gmail.com>
6  *
7  *  RawTherapee is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  RawTherapee is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with RawTherapee.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 #include <cmath>
21 #include <iomanip>
22 
23 #include "localcontrast.h"
24 
25 #include "eventmapper.h"
26 
27 #include "../rtengine/procparams.h"
28 
29 using namespace rtengine;
30 using namespace rtengine::procparams;
31 
LocalContrast()32 LocalContrast::LocalContrast(): FoldableToolPanel(this, "localcontrast", M("TP_LOCALCONTRAST_LABEL"), false, true)
33 {
34     auto m = ProcEventMapper::getInstance();
35     EvLocalContrastEnabled = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_ENABLED");
36     EvLocalContrastRadius = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_RADIUS");
37     EvLocalContrastAmount = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_AMOUNT");
38     EvLocalContrastDarkness = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_DARKNESS");
39     EvLocalContrastLightness = m->newEvent(RGBCURVE, "HISTORY_MSG_LOCALCONTRAST_LIGHTNESS");
40 
41     radius = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 20., 200., 1., 80.));
42     amount = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_AMOUNT"), 0., 1., 0.01, 0.2));
43     darkness = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_DARKNESS"), 0., 3., 0.01, 1.));
44     lightness = Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_LIGHTNESS"), 0., 3., 0.01, 1.));
45 
46     radius->setAdjusterListener(this);
47     amount->setAdjusterListener(this);
48     darkness->setAdjusterListener(this);
49     lightness->setAdjusterListener(this);
50 
51     radius->show();
52     amount->show();
53     darkness->show();
54     lightness->show();
55 
56     pack_start(*radius);
57     pack_start(*amount);
58     pack_start(*darkness);
59     pack_start(*lightness);
60 }
61 
62 
read(const ProcParams * pp,const ParamsEdited * pedited)63 void LocalContrast::read(const ProcParams *pp, const ParamsEdited *pedited)
64 {
65     disableListener();
66 
67     if (pedited) {
68         radius->setEditedState(pedited->localContrast.radius ? Edited : UnEdited);
69         amount->setEditedState(pedited->localContrast.amount ? Edited : UnEdited);
70         darkness->setEditedState(pedited->localContrast.darkness ? Edited : UnEdited);
71         lightness->setEditedState(pedited->localContrast.lightness ? Edited : UnEdited);
72         set_inconsistent(multiImage && !pedited->localContrast.enabled);
73     }
74 
75     setEnabled(pp->localContrast.enabled);
76     radius->setValue(pp->localContrast.radius);
77     amount->setValue(pp->localContrast.amount);
78     darkness->setValue(pp->localContrast.darkness);
79     lightness->setValue(pp->localContrast.lightness);
80 
81     enableListener();
82 }
83 
84 
write(ProcParams * pp,ParamsEdited * pedited)85 void LocalContrast::write(ProcParams *pp, ParamsEdited *pedited)
86 {
87     pp->localContrast.radius = radius->getValue();
88     pp->localContrast.amount = amount->getValue();
89     pp->localContrast.darkness = darkness->getValue();
90     pp->localContrast.lightness = lightness->getValue();
91     pp->localContrast.enabled = getEnabled();
92 
93     if (pedited) {
94         pedited->localContrast.radius = radius->getEditedState();
95         pedited->localContrast.amount = amount->getEditedState();
96         pedited->localContrast.darkness = darkness->getEditedState();
97         pedited->localContrast.lightness = lightness->getEditedState();
98         pedited->localContrast.enabled = !get_inconsistent();
99     }
100 }
101 
setDefaults(const ProcParams * defParams,const ParamsEdited * pedited)102 void LocalContrast::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited)
103 {
104     radius->setDefault(defParams->localContrast.radius);
105     amount->setDefault(defParams->localContrast.amount);
106     darkness->setDefault(defParams->localContrast.darkness);
107     lightness->setDefault(defParams->localContrast.lightness);
108 
109     if (pedited) {
110         radius->setDefaultEditedState(pedited->localContrast.radius ? Edited : UnEdited);
111         amount->setDefaultEditedState(pedited->localContrast.amount ? Edited : UnEdited);
112         darkness->setDefaultEditedState(pedited->localContrast.darkness ? Edited : UnEdited);
113         lightness->setDefaultEditedState(pedited->localContrast.lightness ? Edited : UnEdited);
114     } else {
115         radius->setDefaultEditedState(Irrelevant);
116         amount->setDefaultEditedState(Irrelevant);
117         darkness->setDefaultEditedState(Irrelevant);
118         lightness->setDefaultEditedState(Irrelevant);
119     }
120 }
121 
adjusterChanged(Adjuster * a,double newval)122 void LocalContrast::adjusterChanged(Adjuster* a, double newval)
123 {
124     if (listener && getEnabled()) {
125         if (a == radius) {
126             listener->panelChanged(EvLocalContrastRadius, a->getTextValue());
127         } else if (a == amount) {
128             listener->panelChanged(EvLocalContrastAmount, a->getTextValue());
129         } else if (a == darkness) {
130             listener->panelChanged(EvLocalContrastDarkness, a->getTextValue());
131         } else if (a == lightness) {
132             listener->panelChanged(EvLocalContrastLightness, a->getTextValue());
133         }
134     }
135 }
136 
enabledChanged()137 void LocalContrast::enabledChanged ()
138 {
139     if (listener) {
140         if (get_inconsistent()) {
141             listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_UNCHANGED"));
142         } else if (getEnabled()) {
143             listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_ENABLED"));
144         } else {
145             listener->panelChanged(EvLocalContrastEnabled, M("GENERAL_DISABLED"));
146         }
147     }
148 }
149 
150 
setBatchMode(bool batchMode)151 void LocalContrast::setBatchMode(bool batchMode)
152 {
153     ToolPanel::setBatchMode(batchMode);
154 
155     radius->showEditedCB();
156     amount->showEditedCB();
157     darkness->showEditedCB();
158     lightness->showEditedCB();
159 }
160 
161 
setAdjusterBehavior(bool radiusAdd,bool amountAdd,bool darknessAdd,bool lightnessAdd)162 void LocalContrast::setAdjusterBehavior(bool radiusAdd, bool amountAdd, bool darknessAdd, bool lightnessAdd)
163 {
164     radius->setAddMode(radiusAdd);
165     amount->setAddMode(amountAdd);
166     darkness->setAddMode(darknessAdd);
167     lightness->setAddMode(lightnessAdd);
168 }
169 
170