diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc index 66e618d21..a5311530a 100644 --- a/rtgui/adjuster.cc +++ b/rtgui/adjuster.cc @@ -27,7 +27,9 @@ #define MIN_RESET_BUTTON_HEIGHT 17 -Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon) { +static double one2one(double val) { return val; } + +Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon, double2double_fun slider2value_, double2double_fun value2slider_) { Gtk::HBox *hbox2=NULL; @@ -37,6 +39,8 @@ Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep automatic = NULL; eventPending = false; + slider2value = slider2value_ ? slider2value_ : one2one; + value2slider = value2slider_ ? value2slider_ : one2one; vMin = vmin; vMax = vmax; vStep = vstep; @@ -224,14 +228,14 @@ void Adjuster::resetValue (bool toInitial) { afterReset = true; if (toInitial) { // resetting to the initial editing value, when the image has been loaded - slider->set_value (defaultVal); + slider->set_value (addMode ? defaultVal : value2slider(defaultVal)); } else { // resetting to the slider default value if (addMode) slider->set_value (0.); else - slider->set_value (ctorDefaultVal); + slider->set_value (value2slider(ctorDefaultVal)); } } @@ -261,8 +265,8 @@ void Adjuster::setLimits (double vmin, double vmax, double vstep, double vdefaul spin->set_value (shapeValue(vdefault)); slider->set_digits (digits); slider->set_increments (vstep, 2.0*vstep); - slider->set_range (vmin, vmax); - slider->set_value (shapeValue(vdefault)); + slider->set_range (addMode ? vmin : value2slider(vmin), addMode ? vmax : value2slider(vmax)); + slider->set_value (addMode ? shapeValue(vdefault) : value2slider(shapeValue(vdefault))); //defaultVal = shapeValue (vdefault); sliderChange.block (false); spinChange.block (false); @@ -271,6 +275,7 @@ void Adjuster::setLimits (double vmin, double vmax, double vstep, double vdefaul void Adjuster::setAddMode(bool addM) { if (addM != addMode) { // Switching the Adjuster to the new mode + addMode = addM; if (addM) { // Switching to the relative mode double range = -vMin + vMax; @@ -281,7 +286,6 @@ void Adjuster::setAddMode(bool addM) { // Switching to the absolute mode setLimits(vMin, vMax, vStep, defaultVal); } - addMode = addM; } } @@ -291,7 +295,7 @@ void Adjuster::spinChanged () { delayConnection.disconnect (); sliderChange.block (true); - slider->set_value (spin->get_value ()); + slider->set_value (addMode ? spin->get_value () : value2slider(spin->get_value ())); sliderChange.block (false); if (delay==0) { @@ -326,7 +330,7 @@ void Adjuster::sliderChanged () { delayConnection.disconnect (); spinChange.block (true); - spin->set_value (slider->get_value ()); + spin->set_value (addMode ? slider->get_value () : slider2value(slider->get_value ())); spinChange.block (false); if (delay==0 || afterReset) { @@ -360,7 +364,7 @@ void Adjuster::setValue (double a) { spinChange.block (true); sliderChange.block (true); spin->set_value (shapeValue (a)); - slider->set_value (shapeValue (a)); + slider->set_value (addMode ? shapeValue(a) : value2slider(shapeValue (a))); sliderChange.block (false); spinChange.block (false); afterReset = false; diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index 9b5181f68..e4005d159 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -32,6 +32,7 @@ class AdjusterListener { virtual void adjusterAutoToggled (Adjuster* a, bool newval) {} }; +typedef double(*double2double_fun)(double val); class Adjuster : public Gtk::VBox { @@ -70,12 +71,13 @@ class Adjuster : public Gtk::VBox { double shapeValue (double a); void refreshLabelStyle (); + double2double_fun value2slider, slider2value; public: int delay; - Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon=NULL); + Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon=NULL, double2double_fun slider2value=NULL, double2double_fun value2slider=NULL); virtual ~Adjuster (); // Add an "Automatic" checkbox next to the reset button. diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc index 4f2a754ef..d125ba5d6 100755 --- a/rtgui/whitebalance.cc +++ b/rtgui/whitebalance.cc @@ -24,6 +24,7 @@ #define MINTEMP 1500 //1200 #define MAXTEMP 60000 //12000 +#define CENTERTEMP 4750 #define MINGREEN 0.02 #define MAXGREEN 5.0 #define MINEQUAL 0.8 @@ -61,6 +62,59 @@ void WhiteBalance::cleanup () { } } +static double wbSlider2Temp(double sval) { + + // slider range: 0 - 10000 + double temp; + if (sval <= 5000) { + // linear below center-temp + temp = MINTEMP + (sval / 5000.0) * (CENTERTEMP - MINTEMP); + } else { + const double slope = (double)(CENTERTEMP - MINTEMP) / (MAXTEMP - CENTERTEMP); + double x = (sval - 5000) / 5000; // x 0..1 + double y = x * slope + (1.0 - slope)*pow(x, 4.0); + //double y = pow(x, 4.0); + temp = CENTERTEMP + y * (MAXTEMP - CENTERTEMP); + } + if (temp < MINTEMP) temp = MINTEMP; + if (temp > MAXTEMP) temp = MAXTEMP; + return temp; +} + +static double wbTemp2Slider(double temp) { + + double sval; + if (temp <= CENTERTEMP) { + sval = ((temp - MINTEMP) / (CENTERTEMP - MINTEMP)) * 5000.0; + } else { + const double slope = (double)(CENTERTEMP - MINTEMP) / (MAXTEMP - CENTERTEMP); + const double y = (temp - CENTERTEMP) / (MAXTEMP - CENTERTEMP); + double x = pow(y, 0.25); // rough guess of x, will be a little lower + double y1; + double k = 0.1; + bool add = true; + // the y=f(x) function is a mess to invert, therefore we have this trial-refinement loop instead. + // from tests, worst case is about 20 iterations, ie no problem + for (;;) { + y1 = x * slope + (1.0 - slope)*pow(x, 4.0); + if (5000 * fabs(y1 - y) < 0.1) break; + if (y1 < y) { + if (!add) k /= 2; + x += k; + add = true; + } else { + if (add) k /= 2; + x -= k; + add = false; + } + } + sval = 5000.0 + x * 5000.0; + } + if (sval < 0) sval = 0; + if (sval > 10000) sval = 10000; + return sval; +} + WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL), wblistener(NULL) { set_border_width(4); @@ -181,7 +235,7 @@ WhiteBalance::WhiteBalance () : Gtk::VBox(), FoldableToolPanel(this), wbp(NULL), pack_start (*spotbox, Gtk::PACK_SHRINK, 4); - temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, 4750)); + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, CENTERTEMP, NULL, &wbSlider2Temp, &wbTemp2Slider)); green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0)); equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0)); cache_customTemp (0);