13
0

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.
This commit is contained in:
Robin Gareus 2024-06-22 04:46:09 +02:00
parent c94ca79798
commit bdd6eec95c
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
9 changed files with 71 additions and 32 deletions

View File

@ -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);

View File

@ -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

View File

@ -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<Pango::Layout> 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

View File

@ -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__

View File

@ -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

View File

@ -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<ARDOUR::RouteList>);
@ -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<Gdk::Color> _used_colors;

View File

@ -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();
}

View File

@ -39,7 +39,7 @@ RecorderGroupTabs::primary_coordinate (double, double y) const
}
double
RecorderGroupTabs::extent () const
RecorderGroupTabs::visible_extent () const
{
return get_height ();
}

View File

@ -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;
};