X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fshuttle_control.cc;h=938ba08c51fe3a35f9a51ba094082b686514ce83;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=1d150f73d67511ff8a60ab838e0820a3376e601c;hpb=d15fda6d751a465d278f477923075d4783f3b1ca;p=ardour.git diff --git a/gtk2_ardour/shuttle_control.cc b/gtk2_ardour/shuttle_control.cc index 1d150f73d6..938ba08c51 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); @@ -113,7 +133,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()->get_canvasvar_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 +145,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 +159,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 +252,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 +266,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 @@ -262,8 +312,8 @@ ShuttleControl::on_button_press_event (GdkEventButton* ev) shuttle_speed_on_grab = _session->transport_speed (); 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 +339,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 +414,7 @@ ShuttleControl::on_scroll_event (GdkEventScroll* ev) default: return false; } - + if (semis) { float lower_side_of_dead_zone = semitones_as_fract (-24, true); @@ -512,15 +563,37 @@ ShuttleControl::use_shuttle_fract (bool force, bool zero_ok) } void -ShuttleControl::render (cairo_t* cr) +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_preserve (cr); -// cairo_stroke (cr); cairo_fill (cr); float speed = 0.0; @@ -530,23 +603,22 @@ ShuttleControl::render (cairo_t* cr) } /* Marker */ - float visual_fraction = std::min (1.0f, speed/shuttle_max_speed); - float marker_size = get_height()-4; - float avail_width = get_width() - marker_size; - float x = get_width()*0.5 + visual_fraction * avail_width*0.5; - float offset = x - marker_size*0.5; + float visual_fraction = std::min (1.0f, speed / shuttle_max_speed); + float marker_size = get_height() - 5.0; + float avail_width = get_width() - marker_size - 4; + float x = get_width() * 0.5 + visual_fraction * avail_width * 0.5; // cairo_set_source_rgb (cr, 0, 1, 0.0); cairo_set_source (cr, pattern); if (speed == 1.0) { - cairo_move_to( cr, offset-4, 2); - cairo_line_to( cr, offset+4, 2+marker_size*0.5); - cairo_line_to( cr, offset-4, 2+marker_size); - cairo_line_to( cr, offset-4, 2); + cairo_move_to( cr, x, 2.5); + cairo_line_to( cr, x + marker_size * .577, 2.5 + marker_size * 0.5); + cairo_line_to( cr, x, 2.5 + marker_size); + cairo_close_path(cr); } else if ( speed ==0.0 ) - rounded_rectangle (cr, offset, 4, marker_size-2, marker_size-2, 1); + rounded_rectangle (cr, x, 2.5, marker_size, marker_size, 1); else - cairo_arc (cr, offset + marker_size*0.5, 2 + marker_size*0.5, marker_size*0.5, 0, 360); - cairo_set_line_width (cr, 2); + cairo_arc (cr, x, 2.5 + marker_size * .5, marker_size * 0.47, 0, 2.0 * M_PI); + cairo_set_line_width (cr, 1.75); cairo_stroke (cr); /* speed text */ @@ -561,9 +633,9 @@ ShuttleControl::render (cairo_t* cr) snprintf (buf, sizeof (buf), "%s", _("Playing")); } else { if (speed < 0.0) { - snprintf (buf, sizeof (buf), "<<< %d%%", (int) round (-speed * 100)); + snprintf (buf, sizeof (buf), "<<< %.1f%%", -speed * 100.f); } else { - snprintf (buf, sizeof (buf), ">>> %d%%", (int) round (speed * 100)); + snprintf (buf, sizeof (buf), ">>> %.1f%%", speed * 100.f); } } @@ -585,14 +657,14 @@ ShuttleControl::render (cairo_t* cr) last_speed_displayed = speed; - cairo_set_source_rgb (cr, 0.6, 0.6, 0.6); - cairo_text_extents (cr, buf, &extents); - cairo_move_to (cr, 10, extents.height + 4); - cairo_set_font_size (cr, 13.0); - cairo_show_text (cr, buf); + const float top_text_margin = 3.0f; + const float side_text_margin = 5.0f; - /* style text */ + 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: @@ -603,22 +675,15 @@ ShuttleControl::render (cairo_t* cr) break; } - cairo_text_extents (cr, buf, &extents); - cairo_move_to (cr, get_width() - (fabs(extents.x_advance) + 5), extents.height + 4); - cairo_show_text (cr, buf); - - float _corner_radius = 4.0; + 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()); -/* //reflection - float rheight = 10.0; - Gtkmm2ext::rounded_rectangle (cr, 2, 1, get_width()-4, rheight, _corner_radius); - cairo_set_source (cr, shine_pattern); - cairo_fill (cr); -*/ - if (ARDOUR::Config->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { if (_hovering) { - rounded_rectangle (cr, 1, 1, get_width()-2, get_height()-2, _corner_radius); - cairo_set_source_rgba (cr, 1, 1, 1, 0.2); + rounded_rectangle (cr, 1, 1, get_width()-2, get_height()-2, 4.0); + cairo_set_source_rgba (cr, 1, 1, 1, 0.15); cairo_fill (cr); } } @@ -645,14 +710,6 @@ ShuttleControl::set_shuttle_units (ShuttleUnits s) Config->set_shuttle_units (s); } -void -ShuttleControl::update_speed_display () -{ - if (_session->transport_speed() != last_speed_displayed) { - queue_draw (); - } -} - ShuttleControl::ShuttleControllable::ShuttleControllable (ShuttleControl& s) : PBD::Controllable (X_("Shuttle")) , sc (s) @@ -660,7 +717,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); } @@ -712,7 +769,7 @@ ShuttleControl::on_enter_notify_event (GdkEventCrossing* ev) { _hovering = true; - if (ARDOUR::Config->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { queue_draw (); } @@ -724,7 +781,7 @@ ShuttleControl::on_leave_notify_event (GdkEventCrossing* ev) { _hovering = false; - if (ARDOUR::Config->get_widget_prelight()) { + if (UIConfiguration::instance().get_widget_prelight()) { queue_draw (); }