View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0002675 | ardour | bugs | public | 2009-05-15 16:33 | 2010-04-24 10:33 |
| Reporter | oofus | Assigned To | cth103 | ||
| Priority | normal | Severity | tweak | Reproducibility | always |
| Status | closed | Resolution | fixed | ||
| Platform | Dell D830 core2duo T9300 2.5GHz | OS | Mandriva | OS Version | 2009.0 |
| Product Version | SVN/2.0-ongoing | ||||
| Summary | 0002675: Pan readouts should be in percentage left or right. | ||||
| Description | Pan readouts should be in percentage. Either 50|50 when in the center and then 100|0 for full left and 0|100 for full right. Or, C when centred and then a single percentage to indicate the amount left or right. ie 37% L or 59% R. with 100% indicating full left or right. This could be shown in a tool tip when panning. double clicking and entering a value is of little use I think. The current 0.xxx readout is meaningless and unreadable. | ||||
| Tags | No tags attached. | ||||
|
|
I believe I mentioned a similar thing about a year ago (?) Can not find it again. You want something like the hdspmixer shows for the HDSP card channels. I fully agree :) |
|
2009-05-19 23:25
|
panner-percentage.patch (5,863 bytes)
diff --git a/gtk2_ardour/panner.cc b/gtk2_ardour/panner.cc
index 975f1e6..e1ce802 100644
--- a/gtk2_ardour/panner.cc
+++ b/gtk2_ardour/panner.cc
@@ -19,9 +19,12 @@
#include <iostream>
+#include "ardour/panner.h"
#include "panner.h"
+#include "i18n.h"
using namespace std;
+using namespace Gtk;
static const int triangle_size = 5;
@@ -34,7 +37,7 @@ null_label_callback (char* buf, unsigned int bufsize)
}
-PannerBar::PannerBar (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
+PannerBar::PannerBar (Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
: BarController (adj, c, sigc::ptr_fun (null_label_callback))
{
set_style (BarController::Line);
@@ -121,3 +124,66 @@ PannerBar::button_release (GdkEventButton* ev)
return BarController::button_release (ev);
}
+bool
+PannerBar::entry_input (double *new_value)
+{
+ Entry* e = dynamic_cast<Entry*> (&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<Entry*> (&spinner);
+ double const v = spinner.get_adjustment()->get_value();
+ if (ARDOUR::Panner::equivalent (v, 0.5)) {
+ e->set_text (_("C"));
+ } else if (ARDOUR::Panner::equivalent (v, 0)) {
+ e->set_text (_("L"));
+ } else if (ARDOUR::Panner::equivalent (v, 1)) {
+ e->set_text (_("R"));
+ } else if (v < 0.5) {
+ std::stringstream s;
+ s << _("L") << ((0.5 - v) * 200) << "%";
+ e->set_text (s.str ());
+ } else if (v > 0.5) {
+ std::stringstream s;
+ s << _("R") << ((v -0.5) * 200) << "%";
+ e->set_text (s.str ());
+ }
+
+ return true;
+}
diff --git a/gtk2_ardour/panner.h b/gtk2_ardour/panner.h
index 21f984a..2103966 100644
--- a/gtk2_ardour/panner.h
+++ b/gtk2_ardour/panner.h
@@ -33,6 +33,8 @@ class PannerBar : public Gtkmm2ext::BarController
bool expose (GdkEventExpose*);
bool button_press (GdkEventButton*);
bool button_release (GdkEventButton*);
+ bool entry_input (double *);
+ bool entry_output ();
};
#endif /* __gtk_ardour_panner_h__ */
diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc
index 3ffec0a..208ff6e 100644
--- a/gtk2_ardour/panner_ui.cc
+++ b/gtk2_ardour/panner_ui.cc
@@ -697,23 +697,6 @@ PannerUI::update_pan_bars (bool only_if_aplay)
}
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 ()
{
bool sensitive = !(_io->panner()->automation_state() & Play);
diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h
index fa0b7ce..602164d 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 ();
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index 90954e5..53414d8 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -76,6 +76,8 @@ BarController::BarController (Gtk::Adjustment& adj,
spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
+ spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input));
+ spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output));
spinner.set_digits (3);
add (darea);
@@ -467,3 +469,17 @@ BarController::set_sensitive (bool yn)
Frame::set_sensitive (yn);
darea.set_sensitive (yn);
}
+
+bool
+BarController::entry_input (double* v)
+{
+ return false;
+}
+
+bool
+BarController::entry_output ()
+{
+ return false;
+}
+
+
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index 2c0ca94..a01007f 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -55,8 +55,6 @@ class BarController : public Gtk::Frame
void set_sensitive (bool yn);
- Gtk::SpinButton& get_spin_button() { return spinner; }
-
sigc::signal<void> StartGesture;
sigc::signal<void> StopGesture;
@@ -90,6 +88,8 @@ class BarController : public Gtk::Frame
virtual bool expose (GdkEventExpose *);
virtual bool scroll (GdkEventScroll *);
virtual bool entry_focus_out (GdkEventFocus*);
+ virtual bool entry_input (double *);
+ virtual bool entry_output ();
gint mouse_control (double x, GdkWindow* w, double scaling);
|
|
|
The attached patch implements percentages in the double-click entry. Any thoughts? I suppose you could put the percentage figure actually within the pan control... hmm... |
|
2009-05-20 00:16
|
panner-percentage.2.patch (6,801 bytes)
diff --git a/gtk2_ardour/panner.cc b/gtk2_ardour/panner.cc
index 975f1e6..022c78e 100644
--- a/gtk2_ardour/panner.cc
+++ b/gtk2_ardour/panner.cc
@@ -18,10 +18,14 @@
*/
#include <iostream>
+#include <iomanip>
+#include "ardour/panner.h"
#include "panner.h"
+#include "i18n.h"
using namespace std;
+using namespace Gtk;
static const int triangle_size = 5;
@@ -34,7 +38,7 @@ null_label_callback (char* buf, unsigned int bufsize)
}
-PannerBar::PannerBar (Gtk::Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
+PannerBar::PannerBar (Adjustment& adj, boost::shared_ptr<PBD::Controllable> c)
: BarController (adj, c, sigc::ptr_fun (null_label_callback))
{
set_style (BarController::Line);
@@ -95,6 +99,27 @@ PannerBar::expose (GdkEventExpose* ev)
gdk_draw_polygon (win->gobj(), gc->gobj(), true, points, 3);
+ double const value = spinner.get_adjustment()->get_value ();
+ if (!ARDOUR::Panner::equivalent (value, 0.5)) {
+
+ Glib::RefPtr<Pango::Context> p = get_pango_context ();
+ Glib::RefPtr<Pango::Layout> l = Pango::Layout::create (p);
+ l->set_text (value_as_string (value));
+
+ Pango::Rectangle const ext = l->get_ink_extents ();
+
+ int x = 0;
+ if (value < 0.5) {
+ x = (darea.get_width() - 4 - ext.get_width() / Pango::SCALE);
+ } else {
+ x = 4;
+ }
+
+ int const y = (darea.get_height() - ext.get_height() / Pango::SCALE) / 2;
+
+ win->draw_layout (gc, x, y, l);
+ }
+
return true;
}
@@ -121,3 +146,72 @@ PannerBar::button_release (GdkEventButton* ev)
return BarController::button_release (ev);
}
+bool
+PannerBar::entry_input (double *new_value)
+{
+ Entry* e = dynamic_cast<Entry*> (&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<Entry*> (&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 "";
+}
diff --git a/gtk2_ardour/panner.h b/gtk2_ardour/panner.h
index 21f984a..2d1d351 100644
--- a/gtk2_ardour/panner.h
+++ b/gtk2_ardour/panner.h
@@ -33,6 +33,11 @@ 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 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 3ffec0a..208ff6e 100644
--- a/gtk2_ardour/panner_ui.cc
+++ b/gtk2_ardour/panner_ui.cc
@@ -697,23 +697,6 @@ PannerUI::update_pan_bars (bool only_if_aplay)
}
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 ()
{
bool sensitive = !(_io->panner()->automation_state() & Play);
diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h
index fa0b7ce..602164d 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 ();
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index 90954e5..53414d8 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -76,6 +76,8 @@ BarController::BarController (Gtk::Adjustment& adj,
spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
+ spinner.signal_input().connect (mem_fun (*this, &BarController::entry_input));
+ spinner.signal_output().connect (mem_fun (*this, &BarController::entry_output));
spinner.set_digits (3);
add (darea);
@@ -467,3 +469,17 @@ BarController::set_sensitive (bool yn)
Frame::set_sensitive (yn);
darea.set_sensitive (yn);
}
+
+bool
+BarController::entry_input (double* v)
+{
+ return false;
+}
+
+bool
+BarController::entry_output ()
+{
+ return false;
+}
+
+
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index 2c0ca94..a01007f 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -55,8 +55,6 @@ class BarController : public Gtk::Frame
void set_sensitive (bool yn);
- Gtk::SpinButton& get_spin_button() { return spinner; }
-
sigc::signal<void> StartGesture;
sigc::signal<void> StopGesture;
@@ -90,6 +88,8 @@ class BarController : public Gtk::Frame
virtual bool expose (GdkEventExpose *);
virtual bool scroll (GdkEventScroll *);
virtual bool entry_focus_out (GdkEventFocus*);
+ virtual bool entry_input (double *);
+ virtual bool entry_output ();
gint mouse_control (double x, GdkWindow* w, double scaling);
|
|
|
The second patch (to be applied instead of the first patch) fixes some problems with precision and writes the pan string into the pan control itself (except when the panner is at centre). Any thoughts welcome! |
|
|
Tested the second patch and I think that it's really good. I like the use of the space, in as much as you write the percentage on the opposite side to the pan direction. Subtle, but great. The only comment I might have is that the sensitivity is to low, I only seem to be able to drag the pan in 3% (and sometimes 6%) steps. This could of course be down to my mouse settings, but it would be nice if I could drag in single percent increments, especially as I don't seem to be able to accurately drag back to the centre, it keeps skipping over it. Also, maybe, whilst dragging show 'C' as you pass through the centre, but then cancel it when dragging stops. A 'C' under the panner permanently wouldn't look right. |
|
|
I have not tried the patch yet but I feel a 1% increment as you drag is a good thing too. Now, would that be too much to add a "pan-dead-center-from-wherever-the-panner-is-located" mouse action, e.g. a single click with the middle button (or scroll-wheel button) ? |
|
|
Usually short-cut for 'reset to default position' is ctrl-click, hope to have it in Ardour also both for panners and faders. But for stereo panners it would be dead-left and dead-right. Were you talking about mono tracks? |
|
|
You can set the panner to be full left, full right or centre by clicking the white triangles. I think this is quicker than a key combination. Also there is a right click menu option to reset. |
|
|
Shift click appears to reset panners at present. You can change the drag sensitivity by holding down Shift, Ctrl or both while dragging. Other changes have been committed to SVN. |
|
|
implemented |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2009-05-15 16:33 | oofus | New Issue | |
| 2009-05-18 13:00 | thorgal | Note Added: 0006012 | |
| 2009-05-19 23:25 | cth103 | File Added: panner-percentage.patch | |
| 2009-05-19 23:28 | cth103 | Note Added: 0006015 | |
| 2009-05-19 23:28 | cth103 | Status | new => feedback |
| 2009-05-20 00:16 | cth103 | File Added: panner-percentage.2.patch | |
| 2009-05-20 00:18 | cth103 | Note Added: 0006016 | |
| 2009-05-20 11:53 | oofus | Note Added: 0006017 | |
| 2009-05-20 12:01 | thorgal | Note Added: 0006018 | |
| 2009-05-20 14:41 | agorka | Note Added: 0006019 | |
| 2009-05-20 17:23 | oofus | Note Added: 0006020 | |
| 2009-05-20 17:59 | cth103 | cost | => 0.00 |
| 2009-05-20 17:59 | cth103 | Note Added: 0006021 | |
| 2009-05-20 17:59 | cth103 | Status | feedback => resolved |
| 2009-05-20 17:59 | cth103 | Fixed in Version | => SVN 3.0 |
| 2009-05-20 17:59 | cth103 | Resolution | open => fixed |
| 2009-05-20 17:59 | cth103 | Assigned To | => cth103 |
| 2009-10-29 23:45 | oofus | Status | resolved => feedback |
| 2009-10-29 23:45 | oofus | Resolution | fixed => reopened |
| 2009-10-29 23:45 | oofus | Note Added: 0006977 | |
| 2009-10-29 23:45 | oofus | Status | feedback => closed |
| 2009-10-29 23:45 | oofus | Resolution | reopened => fixed |
| 2010-04-24 10:28 | cth103 | Category | bugs => bugs2 |
| 2010-04-24 10:33 | cth103 | Category | bugs2 => bugs |