several tweaks/fixes to the shuttle control

git-svn-id: svn://localhost/ardour2/branches/3.0@9395 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2011-04-20 22:53:41 +00:00
parent 458db0525c
commit 80e9eb09dd
2 changed files with 78 additions and 59 deletions

View file

@ -61,6 +61,8 @@ ShuttleControl::ShuttleControl ()
set_name (X_("ShuttleControl")); set_name (X_("ShuttleControl"));
Config->ParameterChanged.connect (parameter_connection, MISSING_INVALIDATOR, ui_bind (&ShuttleControl::parameter_changed, this, _1), gui_context()); Config->ParameterChanged.connect (parameter_connection, MISSING_INVALIDATOR, ui_bind (&ShuttleControl::parameter_changed, this, _1), gui_context());
signal_query_tooltip().connect (sigc::mem_fun (*this, &ShuttleControl::on_query_tooltip));
} }
ShuttleControl::~ShuttleControl () ShuttleControl::~ShuttleControl ()
@ -106,7 +108,11 @@ ShuttleControl::map_transport_state ()
float speed = _session->transport_speed (); float speed = _session->transport_speed ();
if (speed != 0.0) { if (speed != 0.0) {
shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ if (Config->get_shuttle_units() == Semitones) {
shuttle_fract = speed/2.0;
} else {
shuttle_fract = speed/shuttle_max_speed;
}
} else { } else {
shuttle_fract = 0; shuttle_fract = 0;
} }
@ -125,35 +131,6 @@ ShuttleControl::build_shuttle_context_menu ()
Menu* speed_menu = manage (new Menu()); Menu* speed_menu = manage (new Menu());
MenuList& speed_items = speed_menu->items(); MenuList& speed_items = speed_menu->items();
RadioMenuItem::Group group;
speed_items.push_back (RadioMenuElem (group, "8", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 8.0f)));
if (shuttle_max_speed == 8.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (group, "6", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 6.0f)));
if (shuttle_max_speed == 6.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (group, "4", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 4.0f)));
if (shuttle_max_speed == 4.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (group, "3", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 3.0f)));
if (shuttle_max_speed == 3.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (group, "2", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 2.0f)));
if (shuttle_max_speed == 2.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (group, "1.5", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 1.5f)));
if (shuttle_max_speed == 1.5) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
items.push_back (MenuElem (_("Maximum speed"), *speed_menu));
Menu* units_menu = manage (new Menu); Menu* units_menu = manage (new Menu);
MenuList& units_items = units_menu->items(); MenuList& units_items = units_menu->items();
RadioMenuItem::Group units_group; RadioMenuItem::Group units_group;
@ -182,6 +159,36 @@ ShuttleControl::build_shuttle_context_menu ()
} }
items.push_back (MenuElem (_("Mode"), *style_menu)); items.push_back (MenuElem (_("Mode"), *style_menu));
RadioMenuItem::Group speed_group;
speed_items.push_back (RadioMenuElem (speed_group, "8", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 8.0f)));
if (shuttle_max_speed == 8.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (speed_group, "6", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 6.0f)));
if (shuttle_max_speed == 6.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (speed_group, "4", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 4.0f)));
if (shuttle_max_speed == 4.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (speed_group, "3", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 3.0f)));
if (shuttle_max_speed == 3.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (speed_group, "2", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 2.0f)));
if (shuttle_max_speed == 2.0) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
speed_items.push_back (RadioMenuElem (speed_group, "1.5", sigc::bind (sigc::mem_fun (*this, &ShuttleControl::set_shuttle_max_speed), 1.5f)));
if (shuttle_max_speed == 1.5) {
static_cast<RadioMenuItem*>(&speed_items.back())->set_active ();
}
items.push_back (MenuElem (_("Maximum speed"), *speed_menu));
} }
void void
@ -277,23 +284,31 @@ ShuttleControl::on_button_release_event (GdkEventButton* ev)
return true; return true;
} }
bool
ShuttleControl::on_query_tooltip (int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&)
{
std::cerr << "OQT!\n";
return false;
}
bool bool
ShuttleControl::on_scroll_event (GdkEventScroll* ev) ShuttleControl::on_scroll_event (GdkEventScroll* ev)
{ {
if (!_session) { if (!_session || Config->get_shuttle_behaviour() != Wheel) {
return true; return true;
} }
switch (ev->direction) { switch (ev->direction) {
case GDK_SCROLL_UP: case GDK_SCROLL_UP:
case GDK_SCROLL_RIGHT:
shuttle_fract += 0.005; shuttle_fract += 0.005;
break; break;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
case GDK_SCROLL_LEFT:
shuttle_fract -= 0.005; shuttle_fract -= 0.005;
break; break;
default: default:
/* scroll left/right */
return false; return false;
} }
@ -354,21 +369,11 @@ ShuttleControl::use_shuttle_fract (bool force)
double speed = 0; double speed = 0;
if (Config->get_shuttle_units() == Semitones) { if (Config->get_shuttle_units() == Semitones) {
double const step = 1.0 / 24.0; // range is 24 semitones up & down double const step = 1.0 / 24.0; // range is 24 semitones up & down
double const semitones = round (shuttle_fract / step); double const semitones = round (shuttle_fract / step);
speed = pow (2.0, (semitones / 12.0)); speed = pow (2.0, (semitones / 12.0));
} else { } else {
speed = shuttle_max_speed * shuttle_fract;
bool const neg = (shuttle_fract < 0.0);
double fract = 1 - sqrt (1 - (shuttle_fract * shuttle_fract)); // Formula A1
if (neg) {
fract = -fract;
}
speed = shuttle_max_speed * fract;
} }
_session->request_transport_speed_nonzero (speed); _session->request_transport_speed_nonzero (speed);
@ -390,9 +395,16 @@ ShuttleControl::on_expose_event (GdkEventExpose* event)
cairo_set_source_rgb (cr, 0, 0, 0.0); cairo_set_source_rgb (cr, 0, 0, 0.0);
cairo_stroke (cr); cairo_stroke (cr);
float speed = 0.0;
if (_session) {
speed = _session->transport_speed ();
}
/* Marker */ /* Marker */
double x = (get_width() / 2.0) + (0.5 * (get_width() * shuttle_fract)); double visual_fraction = std::min (1.0f, speed/shuttle_max_speed);
double x = (get_width() / 2.0) + (0.5 * (get_width() * visual_fraction));
cairo_move_to (cr, x, 0); cairo_move_to (cr, x, 0);
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
cairo_line_to (cr, x, get_height()); cairo_line_to (cr, x, get_height());
@ -401,20 +413,18 @@ ShuttleControl::on_expose_event (GdkEventExpose* event)
/* speed text */ /* speed text */
char buf[32]; char buf[32];
float speed = 0.0;
if (_session) {
speed = _session->transport_speed ();
}
if (speed != 0) { if (speed != 0) {
if (Config->get_shuttle_units() == Percentage) { if (Config->get_shuttle_units() == Percentage) {
snprintf (buf, sizeof (buf), "%d%%", (int) round (speed * 100)); if (speed == 1.0) {
snprintf (buf, sizeof (buf), _("Playing"));
} else {
snprintf (buf, sizeof (buf), "%d%%", (int) round (speed * 100));
}
} else { } else {
if (speed < 0) { if (speed < 0) {
snprintf (buf, sizeof (buf), "< %d semitones", (int) round (12.0 * fast_log2 (-speed))); snprintf (buf, sizeof (buf), "-%d semitones", (int) round (12.0 * fast_log2 (-speed)));
} else { } else {
snprintf (buf, sizeof (buf), "> %d semitones", (int) round (12.0 * fast_log2 (speed))); snprintf (buf, sizeof (buf), "+%d semitones", (int) round (12.0 * fast_log2 (speed)));
} }
} }
} else { } else {
@ -521,18 +531,26 @@ ShuttleControl::parameter_changed (std::string p)
if (p == "shuttle-behaviour") { if (p == "shuttle-behaviour") {
switch (Config->get_shuttle_behaviour ()) { switch (Config->get_shuttle_behaviour ()) {
case Sprung: case Sprung:
shuttle_fract = 0.0; /* back to Sprung - reset to speed = 1.0 if playing
*/
if (_session) { if (_session) {
if (_session->transport_rolling()) { if (_session->transport_rolling()) {
shuttle_fract = SHUTTLE_FRACT_SPEED1; if (_session->transport_speed() == 1.0) {
_session->request_transport_speed (1.0); queue_draw ();
} } else {
_session->request_transport_speed (1.0);
/* redraw when speed changes */
}
} else {
queue_draw ();
}
} }
break; break;
case Wheel: case Wheel:
queue_draw ();
break; break;
} }
queue_draw ();
} else if (p == "shuttle-units") { } else if (p == "shuttle-units") {
queue_draw (); queue_draw ();

View file

@ -82,6 +82,7 @@ class ShuttleControl : public Gtk::DrawingArea, public ARDOUR::SessionHandlePtr
bool on_motion_notify_event(GdkEventMotion*); bool on_motion_notify_event(GdkEventMotion*);
bool on_expose_event(GdkEventExpose*); bool on_expose_event(GdkEventExpose*);
void on_size_allocate (Gtk::Allocation&); void on_size_allocate (Gtk::Allocation&);
bool on_query_tooltip (int, int, bool, const Glib::RefPtr<Gtk::Tooltip>&);
gint mouse_shuttle (double x, bool force); gint mouse_shuttle (double x, bool force);
void use_shuttle_fract (bool force); void use_shuttle_fract (bool force);