Issue 2147: white balance slider now non-linear

This commit is contained in:
torger
2013-12-24 14:51:35 +01:00
parent e4e689c06f
commit 5970935529
3 changed files with 71 additions and 11 deletions

View File

@@ -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;

View File

@@ -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.

View File

@@ -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);