diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 852587896e..06a67aca08 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -178,34 +178,44 @@ LadspaPlugin::default_value (uint32_t port) ret = prh[port].LowerBound; bounds_given = true; sr_scaling = true; - earlier_hint = true; } /* FIXME: add support for logarithmic defaults */ else if (LADSPA_IS_HINT_DEFAULT_LOW(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f; + if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) { + ret = exp(log(prh[port].LowerBound) * 0.75f + log(prh[port].UpperBound) * 0.25f); + } + else { + ret = prh[port].LowerBound * 0.75f + prh[port].UpperBound * 0.25f; + } bounds_given = true; sr_scaling = true; - earlier_hint = true; } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.50f + prh[port].UpperBound * 0.50f; + if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) { + ret = exp(log(prh[port].LowerBound) * 0.5f + log(prh[port].UpperBound) * 0.5f); + } + else { + ret = prh[port].LowerBound * 0.5f + prh[port].UpperBound * 0.5f; + } bounds_given = true; sr_scaling = true; - earlier_hint = true; } else if (LADSPA_IS_HINT_DEFAULT_HIGH(prh[port].HintDescriptor)) { - ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f; + if (LADSPA_IS_HINT_LOGARITHMIC(prh[port].HintDescriptor)) { + ret = exp(log(prh[port].LowerBound) * 0.25f + log(prh[port].UpperBound) * 0.75f); + } + else { + ret = prh[port].LowerBound * 0.25f + prh[port].UpperBound * 0.75f; + } bounds_given = true; sr_scaling = true; - earlier_hint = true; } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(prh[port].HintDescriptor)) { ret = prh[port].UpperBound; bounds_given = true; sr_scaling = true; - earlier_hint = true; } else if (LADSPA_IS_HINT_DEFAULT_0(prh[port].HintDescriptor)) { ret = 0.0f; diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc index 53d642ce23..5cce612056 100644 --- a/libs/gtkmm2ext/barcontroller.cc +++ b/libs/gtkmm2ext/barcontroller.cc @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -48,6 +49,7 @@ BarController::BarController (Gtk::Adjustment& adj, switching = false; switch_on_release = false; use_parent = false; + logarithmic = false; layout = darea.create_pango_layout(""); @@ -76,6 +78,7 @@ BarController::BarController (Gtk::Adjustment& adj, spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input)); spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output)); spinner.set_digits (3); + spinner.set_numeric (true); add (darea); show_all (); @@ -422,13 +425,6 @@ BarController::switch_to_spinner () void BarController::entry_activated () { - string text = spinner.get_text (); - float val; - - if (sscanf (text.c_str(), "%f", &val) == 1) { - adjustment.set_value (val); - } - switch_to_bar (); } @@ -453,16 +449,84 @@ BarController::set_sensitive (bool yn) darea.set_sensitive (yn); } -bool -BarController::entry_input (double* /*v*/) +/* + This is called when we need to update the adjustment with the value + from the spinner's text entry. + + We need to use Gtk::Entry::get_text to avoid recursive nastiness :) + + If we're not in logarithmic mode we can return false to use the + default conversion. + + In theory we should check for conversion errors but set numeric + mode to true on the spinner prevents invalid input. +*/ +int +BarController::entry_input (double* new_value) { - return false; + if (!logarithmic) { + return false; + } + + // extract a double from the string and take its log + Entry *entry = dynamic_cast(&spinner); + stringstream stream(entry->get_text()); + stream.imbue(std::locale("")); + + double value; + stream >> value; + + *new_value = log(value); + return true; } +/* + This is called when we need to update the spinner's text entry + with the value of the adjustment. + + We need to use Gtk::Entry::set_text to avoid recursive nastiness :) + + If we're not in logarithmic mode we can return false to use the + default conversion. +*/ bool BarController::entry_output () { - return false; + if (!logarithmic) { + return false; + } + + // generate the exponential and turn it into a string + // convert to correct locale. + + stringstream stream; + string str; + size_t found; + + // Gtk.Entry does not like the thousands separator, so we have to + // remove it after conversion from float to string. + + stream.imbue(std::locale("")); + stream.precision(spinner.get_digits()); + + stream << fixed << exp(spinner.get_adjustment()->get_value()); + + str=stream.str(); + + // find thousands separators, remove them + found = str.find(use_facet >(std::locale("")).thousands_sep()); + while(found != str.npos) { + str.erase(found,1); + + //find next + found = str.find(use_facet >(std::locale("")).thousands_sep()); + } + + Entry *entry = dynamic_cast(&spinner); + entry->set_text(str); + + return true; } + diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h index e5c01c7191..176580dece 100644 --- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h +++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h @@ -48,6 +48,8 @@ class BarController : public Gtk::Frame void set_use_parent (bool yn); void set_sensitive (bool yn); + + void set_logarithmic (bool yn) { logarithmic = yn; } sigc::signal StartGesture; sigc::signal StopGesture; @@ -73,6 +75,7 @@ class BarController : public Gtk::Frame GdkWindow* grab_window; Gtk::SpinButton spinner; bool use_parent; + bool logarithmic; virtual std::string get_label (int& /*x*/) { return ""; @@ -94,6 +97,9 @@ class BarController : public Gtk::Frame void entry_activated (); void drop_grab (); + + int entry_input (double* new_value); + bool entry_output (); };