From bdd6eec95c2840f0ff9956562f80c275a9c99bb4 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 22 Jun 2024 04:46:09 +0200 Subject: [PATCH] Constrain height of group-tab to the editor's height Previously the group-tab extended all the way down to the last track. Potentially with a widget height of > 2^15 px. This caused issues with gtk widgets (notably on Windows) ``` unhandled exception (type std::exception) in signal handler: what: invalid value (typically too big) for the size of the input (surface, pattern, etc.) ``` This also prepares for Mixer Tab-Group to use the same separation between visible and total extent. --- gtk2_ardour/editor.cc | 16 ++++++++-------- gtk2_ardour/editor_canvas.cc | 7 ++----- gtk2_ardour/editor_group_tabs.cc | 25 ++++++++++++++++--------- gtk2_ardour/editor_group_tabs.h | 7 ++++--- gtk2_ardour/group_tabs.cc | 23 +++++++++++++++++++++++ gtk2_ardour/group_tabs.h | 18 ++++++++++++++---- gtk2_ardour/mixer_group_tabs.h | 3 ++- gtk2_ardour/recorder_group_tabs.cc | 2 +- gtk2_ardour/recorder_group_tabs.h | 2 +- 9 files changed, 71 insertions(+), 32 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index c226c14089..32811a5de8 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -591,11 +591,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"); @@ -609,6 +606,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()); @@ -641,15 +640,16 @@ 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 /* 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 7685dc38df..f873b00ddf 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -347,11 +347,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. */ @@ -381,6 +376,7 @@ Editor::reset_controls_layout_height (int32_t h) controls_layout.property_height() = h; + _group_tabs->set_extent (h); } bool @@ -1016,6 +1012,7 @@ Editor::tie_vertical_scrolling () _region_peak_cursor->hide (); _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 b6f300f8c8..42abbf7b8a 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) { add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK); UIConfiguration::instance().ColorsChanged.connect (sigc::mem_fun (*this, &GroupTabs::queue_draw)); @@ -82,6 +84,27 @@ GroupTabs::set_session (Session* s) } } +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 29656cf247..4b7f5a6864 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; @@ -162,6 +170,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; /** colors that have been used for new route group tabs */ static std::list _used_colors; 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; };