X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fshuttle_control.cc;h=fec3547e1ea8cb2cfee1699f09608b8489554f32;hb=cd5a319e4842862fa6e84f35e3781fce73e129cf;hp=654785d435a4ed4c26632d6c8dbcaec54c76743f;hpb=2e82aa2743623cf4734e54f7cd37933439bfbbe6;p=ardour.git diff --git a/gtk2_ardour/shuttle_control.cc b/gtk2_ardour/shuttle_control.cc index 654785d435..fec3547e1e 100644 --- a/gtk2_ardour/shuttle_control.cc +++ b/gtk2_ardour/shuttle_control.cc @@ -32,15 +32,16 @@ #include "gtkmm2ext/rgb_macros.h" #include "actions.h" -#include "ardour_ui.h" #include "rgb_macros.h" #include "shuttle_control.h" +#include "tooltips.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace Gtk; using namespace Gtkmm2ext; using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using std::min; using std::max; @@ -52,8 +53,15 @@ gboolean qt (gboolean, gint, gint, gboolean, Gtk::Tooltip*, gpointer) ShuttleControl::ShuttleControl () : _controllable (new ShuttleControllable (*this)) , binding_proxy (_controllable) + , text_color (0) { - ARDOUR_UI::instance()->set_tip (*this, _("Shuttle speed control (Context-click for options)")); + left_text = Pango::Layout::create (get_pango_context()); + right_text = Pango::Layout::create (get_pango_context()); + + right_text->set_attributes (text_attributes); + left_text->set_attributes (text_attributes); + + set_tooltip (*this, _("Shuttle speed control (Context-click for options)")); pattern = 0; shine_pattern = 0; @@ -73,7 +81,19 @@ ShuttleControl::ShuttleControl () set_size_request (85, 20); set_name (X_("ShuttleControl")); + shuttle_max_speed = Config->get_shuttle_max_speed(); + + if (shuttle_max_speed >= 8.f) { shuttle_max_speed = 8.0f; } + else if (shuttle_max_speed >= 6.f) { shuttle_max_speed = 6.0f; } + else if (shuttle_max_speed >= 4.f) { shuttle_max_speed = 4.0f; } + else if (shuttle_max_speed >= 3.f) { shuttle_max_speed = 3.0f; } + else if (shuttle_max_speed >= 2.f) { shuttle_max_speed = 2.0f; } + else { shuttle_max_speed = 1.5f; } + Config->ParameterChanged.connect (parameter_connection, MISSING_INVALIDATOR, boost::bind (&ShuttleControl::parameter_changed, this, _1), gui_context()); + UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &ShuttleControl::set_colors)); + + set_colors (); /* gtkmm 2.4: the C++ wrapper doesn't work */ g_signal_connect ((GObject*) gobj(), "query-tooltip", G_CALLBACK (qt), NULL); @@ -84,6 +104,7 @@ ShuttleControl::~ShuttleControl () { cairo_pattern_destroy (pattern); cairo_pattern_destroy (shine_pattern); + delete text_color; } void @@ -113,7 +134,7 @@ ShuttleControl::on_size_allocate (Gtk::Allocation& alloc) //background pattern = cairo_pattern_create_linear (0, 0, 0, alloc.get_height()); - uint32_t col = ARDOUR_UI::config()->color ("shuttle"); + uint32_t col = UIConfiguration::instance().color ("shuttle"); int r,b,g,a; UINT_TO_RGBA(col, &r, &g, &b, &a); cairo_pattern_add_color_stop_rgb (pattern, 0.0, r/400.0, g/400.0, b/400.0); @@ -125,6 +146,13 @@ ShuttleControl::on_size_allocate (Gtk::Allocation& alloc) cairo_pattern_add_color_stop_rgba (shine_pattern, 0, 1,1,1,0.0); cairo_pattern_add_color_stop_rgba (shine_pattern, 0.2, 1,1,1,0.4); cairo_pattern_add_color_stop_rgba (shine_pattern, 1, 1,1,1,0.1); + + Pango::AttrFontDesc* font_attr; + + font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (UIConfiguration::instance().get_NormalBoldFont())); + text_attributes.change (*font_attr); + + delete font_attr; } void @@ -132,6 +160,15 @@ ShuttleControl::map_transport_state () { float speed = _session->transport_speed (); + if ( (fabsf( speed - last_speed_displayed) < 0.005f) // dead-zone + && !( speed == 1.f && last_speed_displayed != 1.f) + && !( speed == 0.f && last_speed_displayed != 0.f) + ) + { + return; // nothing to see here, move along. + } + + // Q: is there a good reason why we re-calculate this every time? if (fabs(speed) <= (2*DBL_EPSILON)) { shuttle_fract = 0; } else { @@ -216,6 +253,8 @@ ShuttleControl::build_shuttle_context_menu () items.push_back (MenuElem (_("Maximum speed"), *speed_menu)); + items.push_back (SeparatorElem ()); + items.push_back (MenuElem (_("Reset to 100%"), sigc::mem_fun (*this, &ShuttleControl::reset_speed))); } void @@ -228,10 +267,22 @@ ShuttleControl::show_shuttle_context_menu () shuttle_context_menu->popup (1, gtk_get_current_event_time()); } +void +ShuttleControl::reset_speed () +{ + if (_session->transport_rolling()) { + _session->request_transport_speed (1.0, true); + } else { + _session->request_transport_speed (0.0, true); + } +} + void ShuttleControl::set_shuttle_max_speed (float speed) { + Config->set_shuttle_max_speed (speed); shuttle_max_speed = speed; + last_speed_displayed = -99999999; } bool @@ -260,10 +311,11 @@ ShuttleControl::on_button_press_event (GdkEventButton* ev) add_modal_grab (); shuttle_grabbed = true; shuttle_speed_on_grab = _session->transport_speed (); + requested_speed = shuttle_speed_on_grab; mouse_shuttle (ev->x, true); gdk_pointer_grab(ev->window,false, - GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), - NULL,NULL,ev->time); + GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK), + NULL,NULL,ev->time); } break; @@ -289,12 +341,13 @@ ShuttleControl::on_button_release_event (GdkEventButton* ev) shuttle_grabbed = false; remove_modal_grab (); gdk_pointer_ungrab (GDK_CURRENT_TIME); - + if (Config->get_shuttle_behaviour() == Sprung) { if (shuttle_speed_on_grab == 0 ) { - _session->request_transport_speed (1.0); + _session->request_stop (); + } else { + _session->request_transport_speed (shuttle_speed_on_grab); } - _session->request_transport_speed (shuttle_speed_on_grab); } else { mouse_shuttle (ev->x, true); } @@ -363,7 +416,7 @@ ShuttleControl::on_scroll_event (GdkEventScroll* ev) default: return false; } - + if (semis) { float lower_side_of_dead_zone = semitones_as_fract (-24, true); @@ -504,6 +557,7 @@ ShuttleControl::use_shuttle_fract (bool force, bool zero_ok) speed = shuttle_max_speed * shuttle_fract; } + requested_speed = speed; if (zero_ok) { _session->request_transport_speed (speed, Config->get_shuttle_behaviour() == Wheel); } else { @@ -512,19 +566,48 @@ ShuttleControl::use_shuttle_fract (bool force, bool zero_ok) } void -ShuttleControl::render (cairo_t* cr, cairo_rectangle_t*) +ShuttleControl::set_colors () { - cairo_text_extents_t extents; + int r, g, b, a; + + uint32_t bg_color = UIConfiguration::instance().color (X_("shuttle bg")); + uint32_t text = UIConfiguration::instance().color (X_("shuttle text")); + + UINT_TO_RGBA (bg_color, &r, &g, &b, &a); + bg_r = r/255.0; + bg_g = g/255.0; + bg_b = b/255.0; + + UINT_TO_RGBA (text, &r, &g, &b, &a); + + /* rescale for Pango colors ... sigh */ + + r = lrint (r * 65535.0); + g = lrint (g * 65535.0); + b = lrint (b * 65535.0); + delete text_color; + text_color = new Pango::AttrColor (Pango::Attribute::create_attr_foreground (r, g, b)); + text_attributes.change (*text_color); +} + +void +ShuttleControl::render (cairo_t* cr, cairo_rectangle_t*) +{ //black border - cairo_set_source_rgb (cr, 0, 0.0, 0.0); + cairo_set_source_rgb (cr, bg_r, bg_g, bg_b); rounded_rectangle (cr, 0, 0, get_width(), get_height(), 4); cairo_fill (cr); float speed = 0.0; + float acutal_speed = 0.0; if (_session) { speed = _session->transport_speed (); + acutal_speed = speed; + if (shuttle_grabbed) { + speed = requested_speed; + } } /* Marker */ @@ -550,24 +633,24 @@ ShuttleControl::render (cairo_t* cr, cairo_rectangle_t*) char buf[32]; - if (speed != 0) { + if (acutal_speed != 0) { if (Config->get_shuttle_units() == Percentage) { - if (speed == 1.0) { + if (acutal_speed == 1.0) { snprintf (buf, sizeof (buf), "%s", _("Playing")); } else { - if (speed < 0.0) { - snprintf (buf, sizeof (buf), "<<< %d%%", (int) round (-speed * 100)); + if (acutal_speed < 0.0) { + snprintf (buf, sizeof (buf), "<<< %.1f%%", -acutal_speed * 100.f); } else { - snprintf (buf, sizeof (buf), ">>> %d%%", (int) round (speed * 100)); + snprintf (buf, sizeof (buf), ">>> %.1f%%", acutal_speed * 100.f); } } } else { bool reversed; - int semi = speed_as_semitones (speed, reversed); + int semi = speed_as_semitones (acutal_speed, reversed); if (reversed) { snprintf (buf, sizeof (buf), _("<<< %+d semitones"), semi); @@ -580,20 +663,17 @@ ShuttleControl::render (cairo_t* cr, cairo_rectangle_t*) snprintf (buf, sizeof (buf), "%s", _("Stopped")); } - last_speed_displayed = speed; + last_speed_displayed = acutal_speed; - // TODO use a proper pango layout, scale font - cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); - cairo_set_font_size (cr, 13.0); - cairo_text_extents (cr, "0|", &extents); // note the descender - const float text_ypos = (get_height() + extents.height - 1.) * .5; + const float top_text_margin = 3.0f; + const float side_text_margin = 5.0f; - cairo_move_to (cr, 10, text_ypos); - cairo_show_text (cr, buf); + left_text->set_text (buf); + cairo_move_to (cr, side_text_margin, top_text_margin); + pango_cairo_show_layout (cr, left_text->gobj()); /* style text */ - switch (Config->get_shuttle_behaviour()) { case Sprung: snprintf (buf, sizeof (buf), "%s", _("Sprung")); @@ -603,14 +683,15 @@ ShuttleControl::render (cairo_t* cr, cairo_rectangle_t*) break; } - cairo_text_extents (cr, buf, &extents); - cairo_move_to (cr, get_width() - (fabs(extents.x_advance) + 5), text_ypos); - cairo_show_text (cr, buf); + right_text->set_text (buf); + Pango::Rectangle r = right_text->get_ink_extents (); + cairo_move_to (cr, get_width() - ((r.get_width()/PANGO_SCALE) + side_text_margin), top_text_margin); + pango_cairo_show_layout (cr, right_text->gobj()); - if (ARDOUR_UI::config()->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { if (_hovering) { rounded_rectangle (cr, 1, 1, get_width()-2, get_height()-2, 4.0); - cairo_set_source_rgba (cr, 1, 1, 1, 0.2); + cairo_set_source_rgba (cr, 1, 1, 1, 0.15); cairo_fill (cr); } } @@ -637,19 +718,6 @@ ShuttleControl::set_shuttle_units (ShuttleUnits s) Config->set_shuttle_units (s); } -void -ShuttleControl::update_speed_display () -{ - const float speed = _session->transport_speed(); - if ( (fabsf( speed - last_speed_displayed) > 0.009f) // dead-zone just below 1%, except.. - || ( speed == 1.f && last_speed_displayed != 1.f) - || ( speed == 0.f && last_speed_displayed != 0.f) - ) - { - queue_draw (); - } -} - ShuttleControl::ShuttleControllable::ShuttleControllable (ShuttleControl& s) : PBD::Controllable (X_("Shuttle")) , sc (s) @@ -657,7 +725,7 @@ ShuttleControl::ShuttleControllable::ShuttleControllable (ShuttleControl& s) } void -ShuttleControl::ShuttleControllable::set_value (double val) +ShuttleControl::ShuttleControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/) { sc.set_shuttle_fract ((val - lower()) / (upper() - lower()), true); } @@ -709,7 +777,7 @@ ShuttleControl::on_enter_notify_event (GdkEventCrossing* ev) { _hovering = true; - if (ARDOUR_UI::config()->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { queue_draw (); } @@ -721,7 +789,7 @@ ShuttleControl::on_leave_notify_event (GdkEventCrossing* ev) { _hovering = false; - if (ARDOUR_UI::config()->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { queue_draw (); }