diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 120fff9ecb..45c144c2f4 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -607,11 +607,8 @@ Editor::Editor () vertical_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &Editor::tie_vertical_scrolling), true); _track_canvas->signal_map_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_map_handler)); - HBox* h = manage (new HBox); _group_tabs = new EditorGroupTabs (this); - h->pack_start (*_group_tabs, PACK_SHRINK); - h->pack_start (edit_controls_vbox); - controls_layout.add (*h); + controls_layout.add (edit_controls_vbox); HSeparator* separator = manage (new HSeparator()); separator->set_name("TrackSeparator"); @@ -625,6 +622,8 @@ Editor::Editor () controls_layout.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::edit_controls_button_event)); controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false); + _group_tabs->signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false); + _cursors = new MouseCursors; _cursors->set_cursor_set (UIConfiguration::instance().get_icon_set()); @@ -703,16 +702,17 @@ Editor::Editor () axis_view_shadow->set_name("EditorWindow"); axis_view_shadow->show(); - edit_packer.attach (*axis_view_shadow, 0, 1, 0, 2, FILL, FILL|EXPAND, 0, 0); + edit_packer.attach (*axis_view_shadow, 0, 1, 0, 2, FILL, FILL|EXPAND, 0, 0); #endif #endif /* labels for the time bars */ - edit_packer.attach (time_bars_event_box, 1, 2, 0, 1, FILL, SHRINK, 0, 0); + edit_packer.attach (time_bars_event_box, 1, 3, 0, 1, FILL, SHRINK, 0, 0); /* track controls */ - edit_packer.attach (controls_layout, 1, 2, 1, 2, FILL, FILL|EXPAND, 0, 0); + edit_packer.attach (*_group_tabs, 1, 2, 1, 2, FILL, FILL|EXPAND, 0, 0); + edit_packer.attach (controls_layout, 2, 3, 1, 2, FILL, FILL|EXPAND, 0, 0); /* canvas */ - edit_packer.attach (*_track_canvas_viewport, 2, 3, 0, 2, FILL|EXPAND, FILL|EXPAND, 0, 0); + edit_packer.attach (*_track_canvas_viewport, 3, 4, 0, 2, FILL|EXPAND, FILL|EXPAND, 0, 0); bottom_hbox.set_border_width (2); bottom_hbox.set_spacing (3); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 4707d11ff9..e204f9bf14 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -350,11 +350,6 @@ Editor::reset_controls_layout_width () req = edit_controls_vbox.size_request (); w = req.width; - if (_group_tabs->get_visible()) { - req = _group_tabs->size_request (); - w += req.width; - } - /* the controls layout has no horizontal scrolling, its visible width is always equal to the total width of its contents. */ @@ -384,6 +379,7 @@ Editor::reset_controls_layout_height (int32_t h) controls_layout.property_height() = h; + _group_tabs->set_extent (h); } bool @@ -1021,6 +1017,7 @@ Editor::tie_vertical_scrolling () _summary->set_overlays_dirty (); } } + _group_tabs->set_offset (vertical_adjustment.get_value ()); } void diff --git a/gtk2_ardour/editor_group_tabs.cc b/gtk2_ardour/editor_group_tabs.cc index 08e29a145d..03f3566fcc 100644 --- a/gtk2_ardour/editor_group_tabs.cc +++ b/gtk2_ardour/editor_group_tabs.cc @@ -87,6 +87,13 @@ EditorGroupTabs::compute_tabs () const void EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) { + const double from = tab.from - offset (); + const double to = tab.to - offset (); + + if (from > visible_extent () || to < 0) { + return; + } + double const arc_radius = get_width(); double r, g, b, a; @@ -99,14 +106,14 @@ EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) a = 1.0; cairo_set_source_rgba (cr, r, g, b, a); - cairo_move_to (cr, 0, tab.from + arc_radius); - cairo_arc (cr, get_width(), tab.from + arc_radius, arc_radius, M_PI, 3 * M_PI / 2); - cairo_line_to (cr, get_width(), tab.to); - cairo_arc (cr, get_width(), tab.to - arc_radius, arc_radius, M_PI / 2, M_PI); - cairo_line_to (cr, 0, tab.from + arc_radius); + cairo_move_to (cr, 0, from + arc_radius); + cairo_arc (cr, get_width(), from + arc_radius, arc_radius, M_PI, 3 * M_PI / 2); + cairo_line_to (cr, get_width(), to); + cairo_arc (cr, get_width(), to - arc_radius, arc_radius, M_PI / 2, M_PI); + cairo_line_to (cr, 0, from + arc_radius); cairo_fill (cr); - if (tab.group && (tab.to - tab.from) > arc_radius) { + if (tab.group && (to - from) > arc_radius) { int text_width, text_height; Glib::RefPtr layout; @@ -114,10 +121,10 @@ EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) layout->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); layout->set_text (tab.group->name ()); - layout->set_width ((tab.to - tab.from - arc_radius) * PANGO_SCALE); + layout->set_width ((to - from - arc_radius) * PANGO_SCALE); layout->get_pixel_size (text_width, text_height); - cairo_move_to (cr, (get_width() - text_height) * .5, (text_width + tab.to + tab.from) * .5); + cairo_move_to (cr, (get_width() - text_height) * .5, (text_width + to + from) * .5); Gtkmm2ext::Color c = Gtkmm2ext::contrasting_text_color (Gtkmm2ext::rgba_to_color (r, g, b, a)); Gtkmm2ext::color_to_rgba (c, r, g, b, a); @@ -133,7 +140,7 @@ EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) double EditorGroupTabs::primary_coordinate (double, double y) const { - return y; + return y + offset (); } RouteList diff --git a/gtk2_ardour/editor_group_tabs.h b/gtk2_ardour/editor_group_tabs.h index 63fbc13e51..f2eb5ca7be 100644 --- a/gtk2_ardour/editor_group_tabs.h +++ b/gtk2_ardour/editor_group_tabs.h @@ -35,11 +35,12 @@ private: void draw_tab (cairo_t *, Tab const &); double primary_coordinate (double, double) const; ARDOUR::RouteList routes_for_tab (Tab const *) const; - double extent () const { - return get_height(); - } void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *); ARDOUR::RouteList selected_routes () const; + + double visible_extent () const { + return get_height(); + } }; #endif // __gtk_ardour_editor_group_tabs_h__ diff --git a/gtk2_ardour/group_tabs.cc b/gtk2_ardour/group_tabs.cc index 2a55aa82d2..1b00447cff 100644 --- a/gtk2_ardour/group_tabs.cc +++ b/gtk2_ardour/group_tabs.cc @@ -52,6 +52,8 @@ GroupTabs::GroupTabs () : _menu (0) , _dragging (0) , _dragging_new_tab (0) + , _extent (-1) + , _offset (0) , _hovering (false) { add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK); @@ -92,7 +94,7 @@ GroupTabs::on_enter_notify_event (GdkEventCrossing* ev) queue_draw (); } - get_window()->set_cursor (Gdk::Cursor( primary_coordinate(1,0) ? Gdk::SB_H_DOUBLE_ARROW : Gdk::SB_V_DOUBLE_ARROW)); + get_window()->set_cursor (Gdk::Cursor (offset () != primary_coordinate (1, 0) ? Gdk::SB_H_DOUBLE_ARROW : Gdk::SB_V_DOUBLE_ARROW)); return CairoWidget::on_enter_notify_event (ev); } @@ -111,6 +113,28 @@ GroupTabs::on_leave_notify_event (GdkEventCrossing* ev) return CairoWidget::on_leave_notify_event (ev); } +void +GroupTabs::set_extent (double extent) +{ + if (_extent == extent) { + return; + } + _extent = extent; + set_dirty (); + queue_draw (); +} + +void +GroupTabs::set_offset (double offset) +{ + if (_offset == offset) { + return; + } + _offset = offset; + set_dirty (); + queue_draw (); +} + /** Handle a size request. * @param req GTK requisition */ diff --git a/gtk2_ardour/group_tabs.h b/gtk2_ardour/group_tabs.h index f46be82a83..a5f6dabe57 100644 --- a/gtk2_ardour/group_tabs.h +++ b/gtk2_ardour/group_tabs.h @@ -65,6 +65,9 @@ public: void run_new_group_dialog (ARDOUR::RouteList const *, bool with_master); + void set_extent (double); + void set_offset (double); + static void set_group_color (ARDOUR::RouteGroup *, uint32_t); static std::string group_gui_id (ARDOUR::RouteGroup *); static uint32_t group_color (ARDOUR::RouteGroup *); @@ -80,6 +83,15 @@ protected: ARDOUR::RouteGroup* group; ///< route group }; + /** @return Size of the widget along the primary axis */ + virtual double visible_extent () const = 0; + + /** @return Size of all contained strips along the primary axis */ + double extent () const { return _extent < 0 ? visible_extent () : _extent; } + + /** @return Scroll offset of \ref visible_extent along the primary axis */ + double offset () const { return _offset; } + private: static void emit_gui_changed_for_members (std::shared_ptr); @@ -102,10 +114,6 @@ private: virtual double primary_coordinate (double x, double y) const = 0; virtual ARDOUR::RouteList routes_for_tab (Tab const * t) const = 0; - - /** @return Size of the widget along the primary axis */ - virtual double extent () const = 0; - virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {} virtual ARDOUR::RouteList selected_routes () const = 0; @@ -165,6 +173,8 @@ private: double _drag_min; ///< minimum position for drag double _drag_max; ///< maximum position for drag double _drag_first; ///< first mouse pointer position during drag + double _extent; + double _offset; bool _hovering; diff --git a/gtk2_ardour/mixer_group_tabs.h b/gtk2_ardour/mixer_group_tabs.h index 7da9f7020d..daf9426231 100644 --- a/gtk2_ardour/mixer_group_tabs.h +++ b/gtk2_ardour/mixer_group_tabs.h @@ -34,7 +34,8 @@ private: void draw_tab (cairo_t *, Tab const &); double primary_coordinate (double, double) const; ARDOUR::RouteList routes_for_tab (Tab const *) const; - double extent () const { + + double visible_extent () const { return get_width(); } diff --git a/gtk2_ardour/recorder_group_tabs.cc b/gtk2_ardour/recorder_group_tabs.cc index 9fc8b41548..2e2e0ea84e 100644 --- a/gtk2_ardour/recorder_group_tabs.cc +++ b/gtk2_ardour/recorder_group_tabs.cc @@ -39,7 +39,7 @@ RecorderGroupTabs::primary_coordinate (double, double y) const } double -RecorderGroupTabs::extent () const +RecorderGroupTabs::visible_extent () const { return get_height (); } diff --git a/gtk2_ardour/recorder_group_tabs.h b/gtk2_ardour/recorder_group_tabs.h index 033b071653..04a9641b28 100644 --- a/gtk2_ardour/recorder_group_tabs.h +++ b/gtk2_ardour/recorder_group_tabs.h @@ -34,7 +34,7 @@ private: ARDOUR::RouteList routes_for_tab (Tab const*) const; ARDOUR::RouteList selected_routes () const; double primary_coordinate (double, double) const; - double extent () const; + double visible_extent () const; RecorderUI* _recorder; };