Issue 2147: white balance slider now non-linear
This commit is contained in:
@@ -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;
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user