From 64524c0ba40b9f69f06a395f8763615700244fda Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 20 May 2009 13:28:30 +0000 Subject: Make pan double-click entry work in percentage left or right. Write pan position to the panner as text (except when centered). Use a virtual function rather than a signal for BarController labels. git-svn-id: svn://localhost/ardour2/branches/3.0@5104 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/automation_controller.cc | 24 ++++--- gtk2_ardour/automation_controller.h | 5 +- gtk2_ardour/latency_gui.cc | 16 +++-- gtk2_ardour/latency_gui.h | 3 +- gtk2_ardour/panner.cc | 127 +++++++++++++++++++++++++++++++---- gtk2_ardour/panner.h | 6 ++ gtk2_ardour/panner_ui.cc | 19 +----- gtk2_ardour/panner_ui.h | 1 - 8 files changed, 149 insertions(+), 52 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/automation_controller.cc b/gtk2_ardour/automation_controller.cc index cf79eb4d48..90c6279f17 100644 --- a/gtk2_ardour/automation_controller.cc +++ b/gtk2_ardour/automation_controller.cc @@ -18,6 +18,7 @@ */ +#include #include "pbd/error.h" #include "ardour/automation_list.h" #include "ardour/automation_control.h" @@ -35,7 +36,7 @@ using namespace Gtk; AutomationController::AutomationController(boost::shared_ptr ac, Adjustment* adj) - : BarController(*adj, ac) + : BarController (*adj, ac) , _ignore_change(false) , _controllable(ac) , _adjustment(adj) @@ -44,8 +45,6 @@ AutomationController::AutomationController(boost::shared_ptr set_style (BarController::LeftToRight); set_use_parent (true); - label_callback = sigc::mem_fun(this, &AutomationController::update_label); - StartGesture.connect (mem_fun(*this, &AutomationController::start_touch)); StopGesture.connect (mem_fun(*this, &AutomationController::end_touch)); @@ -78,16 +77,19 @@ AutomationController::create( return boost::shared_ptr(new AutomationController(ac, adjustment)); } -void -AutomationController::update_label(char* label, int label_len) +std::string +AutomationController::get_label (int&) { - if (label && label_len) { - // Hack to display CC rounded to int - if (_controllable->parameter().type() == MidiCCAutomation) - snprintf(label, label_len, "%d", (int)_controllable->get_value()); - else - snprintf(label, label_len, "%.3f", _controllable->get_value()); + std::stringstream s; + + // Hack to display CC rounded to int + if (_controllable->parameter().type() == MidiCCAutomation) { + s << (int)_controllable->get_value(); + } else { + s << std::fixed << std::setprecision(3) << _controllable->get_value(); } + + return s.str (); } void diff --git a/gtk2_ardour/automation_controller.h b/gtk2_ardour/automation_controller.h index 767c4ced00..6217aa10d2 100644 --- a/gtk2_ardour/automation_controller.h +++ b/gtk2_ardour/automation_controller.h @@ -46,12 +46,13 @@ public: Gtk::Adjustment* adjustment() { return _adjustment; } - void update_label(char* label, int label_len); void display_effective_value(); void value_adjusted(); private: - AutomationController(boost::shared_ptr ac, Gtk::Adjustment* adj); + AutomationController (boost::shared_ptr ac, Gtk::Adjustment* adj); + std::string get_label (int&); + void start_touch(); void end_touch(); diff --git a/gtk2_ardour/latency_gui.cc b/gtk2_ardour/latency_gui.cc index 1f3ae38da4..3b4e3b4222 100644 --- a/gtk2_ardour/latency_gui.cc +++ b/gtk2_ardour/latency_gui.cc @@ -1,6 +1,7 @@ #define __STDC_FORMAT_MACROS 1 #include +#include #include "ardour/latent.h" #include @@ -24,16 +25,19 @@ static const gchar *_unit_strings[] = { std::vector LatencyGUI::unit_strings; -void -LatencyGUI::latency_printer (char *buf, unsigned int bufsize) +std::string +LatencyGUI::get_label (int&) { - double nframes = adjustment.get_value(); + double const nframes = adjustment.get_value(); + std::stringstream s; if (nframes < (sample_rate / 1000.0)) { - snprintf (buf, bufsize, "%" PRId64 " samples", (nframes64_t) rint (nframes)); + s << ((nframes64_t) rint (nframes)) << " samples"; } else { - snprintf (buf, bufsize, "%.2g msecs" , nframes / (sample_rate / 1000.0)); + s << std::fixed << std::setprecision (2) << (nframes / (sample_rate / 1000.0)) << " msecs"; } + + return s.str (); } LatencyGUI::LatencyGUI (Latent& l, nframes64_t sr, nframes64_t psz) @@ -44,7 +48,7 @@ LatencyGUI::LatencyGUI (Latent& l, nframes64_t sr, nframes64_t psz) ignored (new PBD::IgnorableControllable()), /* max 1 second, step by frames, page by msecs */ adjustment (initial_value, 0.0, sample_rate, 1.0, sample_rate / 1000.0f), - bc (adjustment, ignored, sigc::mem_fun (*this, &LatencyGUI::latency_printer)), + bc (adjustment, ignored), reset_button (_("Reset")) { Widget* w; diff --git a/gtk2_ardour/latency_gui.h b/gtk2_ardour/latency_gui.h index 2e350762ec..35fad9e296 100644 --- a/gtk2_ardour/latency_gui.h +++ b/gtk2_ardour/latency_gui.h @@ -31,6 +31,8 @@ class LatencyGUI : public Gtk::VBox void refresh (); private: + std::string get_label (int&); + ARDOUR::Latent& _latent; nframes64_t initial_value; nframes64_t sample_rate; @@ -48,7 +50,6 @@ class LatencyGUI : public Gtk::VBox Gtk::ComboBoxText units_combo; void change_latency_from_button (int dir); - void latency_printer (char* buf, unsigned int bufsize); static std::vector unit_strings; }; diff --git a/gtk2_ardour/panner.cc b/gtk2_ardour/panner.cc index 975f1e6b3b..80b401acfe 100644 --- a/gtk2_ardour/panner.cc +++ b/gtk2_ardour/panner.cc @@ -18,24 +18,19 @@ */ #include - +#include +#include +#include "ardour/panner.h" #include "panner.h" +#include "i18n.h" using namespace std; +using namespace Gtk; static const int triangle_size = 5; -static void -null_label_callback (char* buf, unsigned int bufsize) -{ - /* no label */ - - buf[0] = '\0'; -} - - -PannerBar::PannerBar (Gtk::Adjustment& adj, boost::shared_ptr c) - : BarController (adj, c, sigc::ptr_fun (null_label_callback)) +PannerBar::PannerBar (Adjustment& adj, boost::shared_ptr c) + : BarController (adj, c) { set_style (BarController::Line); } @@ -118,6 +113,112 @@ PannerBar::button_press (GdkEventButton* ev) bool PannerBar::button_release (GdkEventButton* ev) { - return BarController::button_release (ev); + bool const r = BarController::button_release (ev); + + /* get rid of any `C' labels that may exist */ + queue_draw (); + return r; +} + +bool +PannerBar::entry_input (double *new_value) +{ + Entry* e = dynamic_cast (&spinner); + string const text = e->get_text (); + + string digits; + string letters; + + string const L = _("L"); + string const C = _("C"); + string const R = _("R"); + + for (string::size_type i = 0; i < text.length(); ++i) { + if (isdigit (text[i])) { + digits += text[i]; + } else if (text[i] != '%') { + letters += text[i]; + } + } + + if (letters.empty()) { + /* no letter specified, so take any number as a percentage where + * 0 is left and 100 right */ + *new_value = digits.empty() ? 0.5 : (atoi (digits.c_str()) / 100.0); + } else { + /* letter given, so value is a percentage to the extreme + * (e.g. 100L is full left, 1L is slightly left */ + if (letters[0] == L[0] || letters[0] == tolower (L[0])) { + *new_value = digits.empty() ? 0 : (0.5 - atoi (digits.c_str()) / 200.0); + } else if (letters[0] == R[0] || letters[0] == tolower (R[0])) { + *new_value = digits.empty() ? 1 : 0.5 + atoi (digits.c_str()) / 200.0; + } else if (letters[0] == C[0] || letters[0] == tolower (C[0])) { + *new_value = 0.5; + } + } + + return true; +} + +bool +PannerBar::entry_output () +{ + Entry* e = dynamic_cast (&spinner); + e->set_text (value_as_string (spinner.get_adjustment()->get_value())); + return true; } +string +PannerBar::value_as_string (double v) const +{ + if (ARDOUR::Panner::equivalent (v, 0.5)) { + return _("C"); + } else if (ARDOUR::Panner::equivalent (v, 0)) { + return _("L"); + } else if (ARDOUR::Panner::equivalent (v, 1)) { + return _("R"); + } else if (v < 0.5) { + std::stringstream s; + s << fixed << setprecision (0) << _("L") << ((0.5 - v) * 200) << "%"; + return s.str(); + } else if (v > 0.5) { + std::stringstream s; + s << fixed << setprecision (0) << _("R") << ((v -0.5) * 200) << "%"; + return s.str (); + } + + return ""; +} + +std::string +PannerBar::get_label (int& x) +{ + double const value = spinner.get_adjustment()->get_value (); + + if (ARDOUR::Panner::equivalent (value, 0.5)) { + + /* centre: only display text during a drag */ + + if (!grabbed) { + return ""; + } + + } else { + + /* non-centre: display text on the side of the panner which has more space */ + + Glib::RefPtr p = get_pango_context (); + Glib::RefPtr l = Pango::Layout::create (p); + l->set_text (value_as_string (value)); + + Pango::Rectangle const ext = l->get_ink_extents (); + + if (value < 0.5) { + x = (darea.get_width() - 4 - ext.get_width() / Pango::SCALE); + } else { + x = 4; + } + } + + return value_as_string (value); +} diff --git a/gtk2_ardour/panner.h b/gtk2_ardour/panner.h index 21f984aa7c..a553e97f30 100644 --- a/gtk2_ardour/panner.h +++ b/gtk2_ardour/panner.h @@ -33,6 +33,12 @@ class PannerBar : public Gtkmm2ext::BarController bool expose (GdkEventExpose*); bool button_press (GdkEventButton*); bool button_release (GdkEventButton*); + bool entry_input (double *); + bool entry_output (); + + private: + std::string get_label (int&); + std::string value_as_string (double v) const; }; #endif /* __gtk_ardour_panner_h__ */ diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc index 3ffec0ab05..b35ebe5f22 100644 --- a/gtk2_ardour/panner_ui.cc +++ b/gtk2_ardour/panner_ui.cc @@ -393,7 +393,7 @@ PannerUI::setup_pan () x = rx; } - pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1)); + pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.005, 0.05)); bc = new PannerBar (*pan_adjustments[asz], boost::static_pointer_cast( _io->panner()->pan_control( asz )) ); @@ -696,23 +696,6 @@ PannerUI::update_pan_bars (bool only_if_aplay) in_pan_update = false; } -void -PannerUI::pan_printer (char *buf, uint32_t len, Adjustment* adj) -{ - float val = adj->get_value(); - - if (val == 0.0f) { - snprintf (buf, len, X_("L")); - } else if (val == 1.0f) { - snprintf (buf, len, X_("R")); - } else if (Panner::equivalent (val, 0.5f)) { - snprintf (buf, len, X_("C")); - } else { - /* don't print anything */ - buf[0] = '\0'; - } -} - void PannerUI::update_pan_sensitive () { diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h index fa0b7ce2e8..602164d7a9 100644 --- a/gtk2_ardour/panner_ui.h +++ b/gtk2_ardour/panner_ui.h @@ -119,7 +119,6 @@ class PannerUI : public Gtk::HBox void pan_adjustment_changed (uint32_t which); void pan_value_changed (uint32_t which); - void pan_printer (char* buf, uint32_t, Gtk::Adjustment*); void update_pan_bars (bool only_if_aplay); void update_pan_linkage (); void update_pan_state (); -- cgit v1.2.3