47 gboolean
qt (gboolean, gint, gint, gboolean, Gtk::Tooltip*, gpointer)
54 , binding_proxy (_controllable)
71 set_flags (CAN_FOCUS);
72 add_events (Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
73 set_size_request (85, 20);
74 set_name (
X_(
"ShuttleControl"));
79 g_signal_connect ((GObject*) gobj(),
"query-tooltip", G_CALLBACK (
qt), NULL);
85 cairo_pattern_destroy (
pattern);
92 SessionHandlePtr::set_session (s);
106 cairo_pattern_destroy (
pattern);
115 pattern = cairo_pattern_create_linear (0, 0, 0, alloc.get_height());
119 cairo_pattern_add_color_stop_rgb (
pattern, 0.0, r/400.0, g/400.0, b/400.0);
120 cairo_pattern_add_color_stop_rgb (
pattern, 0.4, r/255.0, g/255.0, b/255.0);
121 cairo_pattern_add_color_stop_rgb (
pattern, 1.0, r/512.0, g/512.0, b/512.0);
124 shine_pattern = cairo_pattern_create_linear (0.0, 0.0, 0.0, 10);
125 cairo_pattern_add_color_stop_rgba (
shine_pattern, 0, 1,1,1,0.0);
126 cairo_pattern_add_color_stop_rgba (
shine_pattern, 0.2, 1,1,1,0.4);
127 cairo_pattern_add_color_stop_rgba (
shine_pattern, 1, 1,1,1,0.1);
144 if (fabs(speed) <= (2*DBL_EPSILON)) {
162 using namespace Menu_Helpers;
167 Menu* speed_menu = manage (
new Menu());
168 MenuList& speed_items = speed_menu->items();
170 Menu* units_menu = manage (
new Menu);
171 MenuList& units_items = units_menu->items();
172 RadioMenuItem::Group units_group;
176 static_cast<RadioMenuItem*
>(&units_items.back())->
set_active();
180 static_cast<RadioMenuItem*
>(&units_items.back())->
set_active();
182 items.push_back (MenuElem (
_(
"Units"), *units_menu));
184 Menu* style_menu = manage (
new Menu);
185 MenuList& style_items = style_menu->items();
186 RadioMenuItem::Group style_group;
190 static_cast<RadioMenuItem*
>(&style_items.back())->
set_active();
194 static_cast<RadioMenuItem*
>(&style_items.back())->
set_active();
197 items.push_back (MenuElem (
_(
"Mode"), *style_menu));
199 RadioMenuItem::Group speed_group;
203 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
207 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
211 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
215 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
219 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
223 static_cast<RadioMenuItem*
>(&speed_items.back())->
set_active ();
226 items.push_back (MenuElem (
_(
"Maximum speed"), *speed_menu));
258 if (Keyboard::is_context_menu_event (ev)) {
263 switch (ev->button) {
265 if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
274 gdk_pointer_grab(ev->window,
false,
275 GdkEventMask( Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK |Gdk::BUTTON_RELEASE_MASK),
296 switch (ev->button) {
300 remove_modal_grab ();
301 gdk_pointer_ungrab (GDK_CURRENT_TIME);
344 switch (ev->direction) {
346 case GDK_SCROLL_RIGHT:
359 case GDK_SCROLL_DOWN:
360 case GDK_SCROLL_LEFT:
387 switch (ev->direction) {
389 case GDK_SCROLL_RIGHT:
392 case GDK_SCROLL_DOWN:
393 case GDK_SCROLL_LEFT:
421 double const center = get_width() / 2.0;
422 double distance_from_center = x - center;
424 if (distance_from_center > 0) {
425 distance_from_center = min (distance_from_center, center);
427 distance_from_center = max (distance_from_center, -center);
450 assert (speed != 0.0);
454 return (
int) round (12.0 *
fast_log2 (-speed));
457 return (
int) round (12.0 *
fast_log2 (speed));
465 return -pow (2.0, (semi / 12.0));
467 return pow (2.0, (semi / 12.0));
481 assert (fract != 0.0);
527 cairo_text_extents_t extents;
530 cairo_set_source_rgb (cr, 0, 0.0, 0.0);
542 float marker_size = get_height() - 5.0;
543 float avail_width = get_width() - marker_size - 4;
544 float x = get_width() * 0.5 + visual_fraction * avail_width * 0.5;
546 cairo_set_source (cr,
pattern);
548 cairo_move_to( cr, x, 2.5);
549 cairo_line_to( cr, x + marker_size * .577, 2.5 + marker_size * 0.5);
550 cairo_line_to( cr, x, 2.5 + marker_size);
551 cairo_close_path(cr);
552 }
else if ( speed ==0.0 )
555 cairo_arc (cr, x, 2.5 + marker_size * .5, marker_size * 0.47, 0, 2.0 * M_PI);
556 cairo_set_line_width (cr, 1.75);
568 snprintf (buf,
sizeof (buf),
"%s",
_(
"Playing"));
571 snprintf (buf,
sizeof (buf),
"<<< %.1f%%", -speed * 100.
f);
573 snprintf (buf,
sizeof (buf),
">>> %.1f%%", speed * 100.
f);
583 snprintf (buf,
sizeof (buf),
_(
"<<< %+d semitones"), semi);
585 snprintf (buf,
sizeof (buf),
_(
">>> %+d semitones"), semi);
590 snprintf (buf,
sizeof (buf),
"%s",
_(
"Stopped"));
596 cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
597 cairo_set_font_size (cr, 13.0);
598 cairo_text_extents (cr,
"0|", &extents);
599 const float text_ypos = (get_height() + extents.height - 1.) * .5;
601 cairo_move_to (cr, 10, text_ypos);
602 cairo_show_text (cr, buf);
607 switch (
Config->get_shuttle_behaviour()) {
609 snprintf (buf,
sizeof (buf),
"%s",
_(
"Sprung"));
612 snprintf (buf,
sizeof (buf),
"%s",
_(
"Wheel"));
616 cairo_text_extents (cr, buf, &extents);
617 cairo_move_to (cr, get_width() - (fabs(extents.x_advance) + 5), text_ypos);
618 cairo_show_text (cr, buf);
623 cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
641 Config->set_shuttle_behaviour (s);
647 Config->set_shuttle_units (s);
671 if (p ==
"shuttle-behaviour") {
672 switch (
Config->get_shuttle_behaviour ()) {
698 }
else if (p ==
"shuttle-units") {
713 return CairoWidget::on_enter_notify_event (ev);
725 return CairoWidget::on_leave_notify_event (ev);
bool transport_rolling() const
void use_shuttle_fract(bool force, bool zero_ok=false)
ArdourCanvas::Color color(const std::string &, bool *failed=0) const
LIBGTKMM2EXT_API Gtk::Widget * get_widget(const char *name)
void request_transport_speed_nonzero(double, bool as_default=false)
float last_speed_displayed
void on_size_allocate(Gtk::Allocation &)
int fract_as_semitones(float, bool &)
double transport_speed() const
BindingProxy binding_proxy
gint mouse_shuttle(double x, bool force)
void set_shuttle_units(ARDOUR::ShuttleUnits)
static ARDOUR_UI * instance()
double get_value(void) const
Gtk::Menu * shuttle_unit_menu
bool on_button_release_event(GdkEventButton *)
bool on_scroll_event(GdkEventScroll *)
cairo_pattern_t * pattern
#define UINT_TO_RGBA(u, r, g, b, a)
int speed_as_semitones(float, bool &)
bool on_query_tooltip(int, int, bool, const Glib::RefPtr< Gtk::Tooltip > &)
LIBARDOUR_API microseconds_t get_microseconds()
static float fast_log2(float val)
void set_shuttle_max_speed(float)
PBD::ScopedConnection parameter_connection
LIBGTKMM2EXT_API void set_sensitive(std::vector< Glib::RefPtr< Gtk::Action > > &actions, bool)
void show_shuttle_context_menu()
LIBARDOUR_API RCConfiguration * Config
gboolean qt(gboolean, gint, gint, gboolean, Gtk::Tooltip *, gpointer)
void request_transport_speed(double speed, bool as_default=false)
Gtk::Menu * shuttle_style_menu
void add_controllable(boost::shared_ptr< PBD::Controllable >)
bool button_press_handler(GdkEventButton *)
void set_shuttle_fract(double, bool zero_ok=false)
PBD::Signal1< void, std::string > ParameterChanged
bool on_button_press_event(GdkEventButton *)
void shuttle_unit_clicked()
void set_tip(Gtk::Widget &w, const gchar *tip)
Gtk::Menu * shuttle_context_menu
void map_transport_state()
void parameter_changed(std::string)
cairo_pattern_t * shine_pattern
void set_session(ARDOUR::Session *)
ShuttleControllable(ShuttleControl &)
void render(cairo_t *, cairo_rectangle_t *)
boost::shared_ptr< ShuttleControllable > _controllable
bool on_leave_notify_event(GdkEventCrossing *)
static UIConfiguration * config()
ARDOUR::microseconds_t last_shuttle_request
LIBGTKMM2EXT_API void rounded_rectangle(Cairo::RefPtr< Cairo::Context > context, double x, double y, double w, double h, double r=10)
float semitones_as_fract(int, bool)
bool on_motion_notify_event(GdkEventMotion *)
float semitones_as_speed(int, bool)
#define MISSING_INVALIDATOR
bool on_enter_notify_event(GdkEventCrossing *)
ARDOUR::Session * _session
void set_shuttle_style(ARDOUR::ShuttleBehaviour)
void build_shuttle_context_menu()
double shuttle_speed_on_grab