Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / tonecurve.cc
blobb56c0c332b46e322bd37c2eb75037eb5faa4f016
1 /*
2 * This file is part of RawTherapee.
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * RawTherapee is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
19 #include <tonecurve.h>
20 #include <adjuster.h>
21 #include <sigc++/class_slot.h>
22 #include <iomanip>
23 #include <guiutils.h>
25 using namespace rtengine;
26 using namespace rtengine::procparams;
28 ToneCurve::ToneCurve () : ToolPanel(), expAdd(false), blackAdd(false), brAdd(false), contrAdd(false) {
30 //----------- Auto Levels ----------------------------------
31 abox = Gtk::manage (new Gtk::HBox ());
32 abox->set_border_width (2);
34 autolevels = Gtk::manage (new Gtk::ToggleButton (M("TP_EXPOSURE_AUTOLEVELS")));
35 autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) );
37 sclip = Gtk::manage (new Gtk::SpinButton ());
38 sclip->set_range (0.0, 0.9999);
39 sclip->set_increments (0.0001, 0.01);
40 sclip->set_value (0.002);
41 sclip->set_digits (4);
42 sclip->signal_value_changed().connect( sigc::mem_fun(*this, &ToneCurve::clip_changed) );
44 abox->pack_start (*autolevels);
45 abox->pack_end (*sclip);
46 abox->pack_end (*Gtk::manage (new Gtk::Label (M("TP_EXPOSURE_CLIP"))));
47 pack_start (*abox);
49 pack_start (*Gtk::manage (new Gtk::HSeparator()));
51 //----------- Exposure Compensation ------------------------
52 expcomp = new Adjuster (M("TP_EXPOSURE_EXPCOMP"), -5, 5, 0.01, 0);
53 pack_start (*expcomp);
54 hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 150, 1, 0));
55 pack_start (*hlcompr);
57 //----------- Black Level ----------------------------------
58 black = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BLACKLEVEL"), 0, 32768, 1, 0));
59 pack_start (*black);
60 shcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRSHADOWS"), 0, 150, 1, 0));
61 pack_start (*shcompr);
63 pack_start (*Gtk::manage (new Gtk::HSeparator()));
65 //---------Brightness / Contrast -------------------------
66 brightness = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BRIGHTNESS"), -100, 100, 1, 0));
67 pack_start (*brightness);
68 contrast = Gtk::manage (new Adjuster (M("TP_EXPOSURE_CONTRAST"), -100, 100, 1, 0));
69 pack_start (*contrast);
71 /*
72 //----------- Curve ------------------------------
73 pack_start (*Gtk::manage (new Gtk::HSeparator()));
75 shape = Gtk::manage (new CurveEditor ());
76 shape->setCurveListener (this);
77 curvexp = Gtk::manage (new Gtk::Expander (M("TP_EXPOSURE_CURVEEDITOR")));
78 curvexp->add (*shape);
80 pack_start (*curvexp, Gtk::PACK_SHRINK, 4);
82 // --------- Set Up Listeners -------------
83 expcomp->setAdjusterListener (this);
84 brightness->setAdjusterListener (this);
85 black->setAdjusterListener (this);
86 hlcompr->setAdjusterListener (this);
87 shcompr->setAdjusterListener (this);
88 contrast->setAdjusterListener (this);
91 ToneCurve::~ToneCurve () {
93 delete expcomp;
96 void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) {
98 disableListener ();
100 if (pedited) {
101 expcomp->setEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited);
102 black->setEditedState (pedited->toneCurve.black ? Edited : UnEdited);
103 hlcompr->setEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited);
104 shcompr->setEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited);
105 brightness->setEditedState (pedited->toneCurve.brightness ? Edited : UnEdited);
106 contrast->setEditedState (pedited->toneCurve.contrast ? Edited : UnEdited);
107 autolevels->set_inconsistent (!pedited->toneCurve.autoexp);
108 clipDirty = pedited->toneCurve.clip;
111 autoconn.block (true);
112 autolevels->set_active (pp->toneCurve.autoexp);
113 autoconn.block (false);
114 lastAuto = pp->toneCurve.autoexp;
115 sclip->set_value (pp->toneCurve.clip);
117 expcomp->setValue (pp->toneCurve.expcomp);
118 black->setValue (pp->toneCurve.black);
119 hlcompr->setValue (pp->toneCurve.hlcompr);
120 shcompr->setValue (pp->toneCurve.shcompr);
121 brightness->setValue (pp->toneCurve.brightness);
122 contrast->setValue (pp->toneCurve.contrast);
123 // shape->setCurve (pp->toneCurve.curve);
125 enableListener ();
128 void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) {
130 pp->toneCurve.autoexp = autolevels->get_active();
131 pp->toneCurve.clip = sclip->get_value ();
132 pp->toneCurve.expcomp = expcomp->getValue ();
133 pp->toneCurve.black = (int)black->getValue ();
134 pp->toneCurve.hlcompr = (int)hlcompr->getValue ();
135 pp->toneCurve.shcompr = (int)shcompr->getValue ();
136 pp->toneCurve.brightness = (int)brightness->getValue ();
137 pp->toneCurve.contrast = (int)contrast->getValue ();
138 // pp->toneCurve.curve = shape->getCurve ();
140 if (pedited) {
141 pedited->toneCurve.expcomp = expcomp->getEditedState ();
142 pedited->toneCurve.black = black->getEditedState ();
143 pedited->toneCurve.hlcompr = hlcompr->getEditedState ();
144 pedited->toneCurve.shcompr = shcompr->getEditedState ();
145 pedited->toneCurve.brightness = brightness->getEditedState ();
146 pedited->toneCurve.contrast = contrast->getEditedState ();
147 pedited->toneCurve.autoexp = !autolevels->get_inconsistent();
148 pedited->toneCurve.clip = clipDirty;
152 void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
154 expcomp->setDefault (defParams->toneCurve.expcomp);
155 brightness->setDefault (defParams->toneCurve.brightness);
156 black->setDefault (defParams->toneCurve.black);
157 hlcompr->setDefault (defParams->toneCurve.hlcompr);
158 shcompr->setDefault (defParams->toneCurve.shcompr);
159 contrast->setDefault (defParams->toneCurve.contrast);
161 if (pedited) {
162 expcomp->setDefaultEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited);
163 black->setDefaultEditedState (pedited->toneCurve.black ? Edited : UnEdited);
164 hlcompr->setDefaultEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited);
165 shcompr->setDefaultEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited);
166 brightness->setDefaultEditedState (pedited->toneCurve.brightness ? Edited : UnEdited);
167 contrast->setDefaultEditedState (pedited->toneCurve.contrast ? Edited : UnEdited);
169 else {
170 expcomp->setDefaultEditedState (Irrelevant);
171 black->setDefaultEditedState (Irrelevant);
172 hlcompr->setDefaultEditedState (Irrelevant);
173 shcompr->setDefaultEditedState (Irrelevant);
174 brightness->setDefaultEditedState (Irrelevant);
175 contrast->setDefaultEditedState (Irrelevant);
179 /*void ToneCurve::curveChanged () {
181 if (listener) {
182 listener->panelChanged (EvToneCurve, M("HISTORY_CUSTOMCURVE"));
186 void ToneCurve::adjusterChanged (Adjuster* a, double newval) {
188 if (autolevels->get_active() && (a==expcomp || a==black || a==hlcompr || a==shcompr)) {
189 autolevels->set_active (false);
190 autolevels->set_inconsistent (false);
193 if (!listener)
194 return;
196 Glib::ustring costr;
197 if (a==expcomp)
198 costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
199 else
200 costr = Glib::ustring::format ((int)a->getValue());
202 if (a==expcomp)
203 listener->panelChanged (EvExpComp, costr);
204 else if (a==brightness)
205 listener->panelChanged (EvBrightness, costr);
206 else if (a==black)
207 listener->panelChanged (EvBlack, costr);
208 else if (a==contrast)
209 listener->panelChanged (EvContrast, costr);
210 else if (a==hlcompr)
211 listener->panelChanged (EvHLCompr, costr);
212 else if (a==shcompr)
213 listener->panelChanged (EvSHCompr, costr);
216 void ToneCurve::autolevels_toggled () {
218 if (batchMode) {
219 if (autolevels->get_inconsistent()) {
220 autolevels->set_inconsistent (false);
221 autoconn.block (true);
222 autolevels->set_active (false);
223 autoconn.block (false);
225 else if (lastAuto)
226 autolevels->set_inconsistent (true);
228 lastAuto = autolevels->get_active ();
231 if (!batchMode && autolevels->get_active() && listener) {
232 listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
233 waitForAutoExp ();
236 if (batchMode) {
237 expcomp->setEditedState (UnEdited);
238 black->setEditedState (UnEdited);
239 if (expAdd)
240 expcomp->setValue (0);
241 if (blackAdd)
242 black->setValue (0);
243 listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED"));
247 void ToneCurve::clip_changed () {
249 clipDirty = true;
250 if (autolevels->get_active() && listener)
251 Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::clip_changed_));
254 bool ToneCurve::clip_changed_ () {
256 if (listener) {
257 listener->panelChanged (EvClip, Glib::ustring::format (std::setprecision(5), sclip->get_value()));
258 if (!batchMode)
259 waitForAutoExp ();
261 return false;
264 void ToneCurve::waitForAutoExp () {
266 sclip->set_sensitive (false);
267 expcomp->setEnabled (false);
268 brightness->setEnabled (false);
269 black->setEnabled (false);
270 hlcompr->setEnabled (false);
271 shcompr->setEnabled (false);
272 contrast->setEnabled (false);
273 // shape->set_sensitive (false);
276 int aexpcomputed (void* data) {
278 gdk_threads_enter();
279 ((ToneCurve*)data)->autoExpComputed_ ();
280 gdk_threads_leave();
281 return 0;
284 void ToneCurve::autoExpChanged (double br, int bl) {
286 nextBl = bl;
287 nextBr = br;
288 g_idle_add (aexpcomputed, this);
291 // Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::autoExpComputed_));
294 void ToneCurve::enableAll () {
296 sclip->set_sensitive (true);
297 expcomp->setEnabled (true);
298 brightness->setEnabled (true);
299 black->setEnabled (true);
300 hlcompr->setEnabled (true);
301 shcompr->setEnabled (true);
302 contrast->setEnabled (true);
303 // shape->set_sensitive (true);
306 bool ToneCurve::autoExpComputed_ () {
308 disableListener ();
309 enableAll ();
310 expcomp->setValue (nextBr);
311 black->setValue (nextBl);
312 enableListener ();
314 return false;
318 void ToneCurve::expandCurve (bool isExpanded) {
320 curvexp->set_expanded (isExpanded);
323 bool ToneCurve::isCurveExpanded () {
325 return curvexp->get_expanded ();
329 void ToneCurve::setBatchMode (bool batchMode) {
331 removeIfThere (abox, autolevels, false);
332 autolevels = Gtk::manage (new Gtk::CheckButton (M("TP_EXPOSURE_AUTOLEVELS")));
333 autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) );
334 abox->pack_start (*autolevels);
336 ToolPanel::setBatchMode (batchMode);
337 expcomp->showEditedCB ();
338 black->showEditedCB ();
339 hlcompr->showEditedCB ();
340 shcompr->showEditedCB ();
341 brightness->showEditedCB ();
342 contrast->showEditedCB ();
345 void ToneCurve::setAdjusterBehavior (bool expadd, bool bradd, bool blackadd, bool contradd) {
347 if (!expAdd && expadd || expAdd && !expadd)
348 expcomp->setLimits (-5, 5, 0.01, 0);
349 if (!blackAdd && blackadd)
350 black->setLimits (0, 16384, 1, 0);
351 else if (blackAdd && !blackadd)
352 black->setLimits (0, 32768, 1, 0);
353 if (!brAdd && bradd || brAdd && !bradd)
354 brightness->setLimits (-100, 100, 0.01, 0);
355 if (!contrAdd && contradd || contrAdd && !contradd)
356 contrast->setLimits (-100, 100, 0.01, 0);
358 expAdd = expadd;
359 blackAdd = blackadd;
360 brAdd = bradd;
361 contrAdd = contradd;