From 1a447016437727452fdf00e7c762f339c796f736 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 7 Dec 2009 00:41:50 +0000 Subject: [PATCH] Fix a couple of crashes with empty matrices. Some small optimisations. Correctly handle descenders on text when plotting labels. Minor layout improvements. Add some drawings of what's going on in the port matrix so that I don't keep losing them. git-svn-id: svn://localhost/ardour2/branches/3.0@6319 d708f5d6-7413-0410-9779-e7cbd77b26cf --- doc/port_matrix/cairo_text.svg | 341 +++++++++ doc/port_matrix/top_column_bundle_name.svg | 801 +++++++++++++++++++++ doc/port_matrix/top_column_port_name.svg | 670 +++++++++++++++++ gtk2_ardour/ardour3_ui_dark.rc.in | 1 + gtk2_ardour/port_matrix.cc | 42 +- gtk2_ardour/port_matrix.h | 3 + gtk2_ardour/port_matrix_body.cc | 35 +- gtk2_ardour/port_matrix_body.h | 10 +- gtk2_ardour/port_matrix_column_labels.cc | 52 +- gtk2_ardour/port_matrix_column_labels.h | 3 +- gtk2_ardour/port_matrix_grid.cc | 12 +- gtk2_ardour/port_matrix_row_labels.cc | 9 +- 12 files changed, 1926 insertions(+), 53 deletions(-) create mode 100644 doc/port_matrix/cairo_text.svg create mode 100644 doc/port_matrix/top_column_bundle_name.svg create mode 100644 doc/port_matrix/top_column_port_name.svg diff --git a/doc/port_matrix/cairo_text.svg b/doc/port_matrix/cairo_text.svg new file mode 100644 index 0000000000..d623ccc01e --- /dev/null +++ b/doc/port_matrix/cairo_text.svg @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + ABCjpq + + + y + + + + + + origin + + + + y_bearing + + height + ABCjpq + + + + origin + + cairo_rotate (c, - M_PI / 4); + + diff --git a/doc/port_matrix/top_column_bundle_name.svg b/doc/port_matrix/top_column_bundle_name.svg new file mode 100644 index 0000000000..d5669c3e8d --- /dev/null +++ b/doc/port_matrix/top_column_bundle_name.svg @@ -0,0 +1,801 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Bundle name (top) + ϑ + + + h + + y + + + g + + x + + + p + + ϑ + + d + + q + Port name (bottom) + + + + f + + diff --git a/doc/port_matrix/top_column_port_name.svg b/doc/port_matrix/top_column_port_name.svg new file mode 100644 index 0000000000..0a05f15b85 --- /dev/null +++ b/doc/port_matrix/top_column_port_name.svg @@ -0,0 +1,670 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Column name (top) + ϑ + + + g + + h + + + y + + x + + p + + ϑ + + d + + q + Bundle name (bottom) + + diff --git a/gtk2_ardour/ardour3_ui_dark.rc.in b/gtk2_ardour/ardour3_ui_dark.rc.in index 393ce3c841..0e81e576e9 100644 --- a/gtk2_ardour/ardour3_ui_dark.rc.in +++ b/gtk2_ardour/ardour3_ui_dark.rc.in @@ -1669,3 +1669,4 @@ widget "*OddPortGroups" style:highest "odd_port_groups" widget "*EvenPortGroups" style:highest "even_port_groups" widget "*MidiListView*" style:highest "white_tree_view" widget "*ProcessorSelector*" style:highest "processor_list_display" +widget "*PortMatrixLabel*" style:highest "small_text" \ No newline at end of file diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc index 3fe27b4fdf..58c8a099bd 100644 --- a/gtk2_ardour/port_matrix.cc +++ b/gtk2_ardour/port_matrix.cc @@ -60,33 +60,41 @@ PortMatrix::PortMatrix (Window* parent, Session* session, DataType type) _ignore_notebook_page_selected (false) { _body = new PortMatrixBody (this); + _body->DimensionsChanged.connect (mem_fun (*this, &PortMatrix::body_dimensions_changed)); - _vbox.pack_start (_vnotebook); - _vbox.pack_start (_vlabel); - _hbox.pack_start (_hnotebook); - _hbox.pack_start (_hlabel); + _vbox.pack_start (_vspacer, false, false); + _vbox.pack_start (_vnotebook, false, false); + _vbox.pack_start (_vlabel, true, true); + _hbox.pack_start (_hspacer, false, false); + _hbox.pack_start (_hnotebook, false, false); + _hbox.pack_start (_hlabel, true, true); _vnotebook.signal_switch_page().connect (mem_fun (*this, &PortMatrix::v_page_selected)); _vnotebook.property_tab_border() = 4; + _vnotebook.set_name (X_("PortMatrixLabel")); _hnotebook.signal_switch_page().connect (mem_fun (*this, &PortMatrix::h_page_selected)); _hnotebook.property_tab_border() = 4; + _hnotebook.set_name (X_("PortMatrixLabel")); for (int i = 0; i < 2; ++i) { _ports[i].set_type (type); } _vlabel.set_use_markup (); - _vlabel.set_alignment (0.5, 0); + _vlabel.set_alignment (1, 1); _vlabel.set_padding (4, 16); + _vlabel.set_name (X_("PortMatrixLabel")); _hlabel.set_use_markup (); - _hlabel.set_alignment (0, 0.5); + _hlabel.set_alignment (1, 0.5); _hlabel.set_padding (16, 4); + _hlabel.set_name (X_("PortMatrixLabel")); _body->show (); _vbox.show (); _hbox.show (); _vlabel.show (); _hlabel.show (); + _hspacer.show (); } PortMatrix::~PortMatrix () @@ -106,7 +114,6 @@ void PortMatrix::init () { select_arrangement (); - setup_notebooks (); if (!_ports[0].empty()) { _visible_ports[0] = *_ports[0].begin(); @@ -674,15 +681,15 @@ PortMatrix::setup_notebooks () } if (_hnotebook.get_n_pages() <= 1) { - _hnotebook.hide (); + _hbox.hide (); } else { - _hnotebook.show (); + _vbox.show (); } if (_vnotebook.get_n_pages() <= 1) { - _vnotebook.hide (); + _vbox.hide (); } else { - _vnotebook.show (); + _vbox.show (); } } @@ -751,3 +758,16 @@ PortMatrix::session_going_away () { _session = 0; } + +void +PortMatrix::body_dimensions_changed () +{ + _hspacer.set_size_request (_body->column_labels_border_x (), -1); + if (_arrangement == TOP_TO_RIGHT) { + _vspacer.set_size_request (-1, _body->column_labels_height ()); + _vspacer.show (); + } else { + _vspacer.hide (); + } + +} diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h index 268c898684..f228a4101f 100644 --- a/gtk2_ardour/port_matrix.h +++ b/gtk2_ardour/port_matrix.h @@ -179,6 +179,7 @@ private: void v_page_selected (GtkNotebookPage *, guint); void h_page_selected (GtkNotebookPage *, guint); void route_processors_changed (ARDOUR::RouteProcessorChange); + void body_dimensions_changed (); void session_going_away (); Gtk::Window* _parent; @@ -196,6 +197,8 @@ private: Gtk::Label _hlabel; Gtk::VBox _vbox; Gtk::HBox _hbox; + Gtk::Label _hspacer; + Gtk::Label _vspacer; Gtk::Menu* _menu; Arrangement _arrangement; int _row_index; diff --git a/gtk2_ardour/port_matrix_body.cc b/gtk2_ardour/port_matrix_body.cc index 41faaa31ef..72da040ed7 100644 --- a/gtk2_ardour/port_matrix_body.cc +++ b/gtk2_ardour/port_matrix_body.cc @@ -34,6 +34,8 @@ PortMatrixBody::PortMatrixBody (PortMatrix* p) _alloc_height (0), _xoffset (0), _yoffset (0), + _column_labels_border_x (0), + _column_labels_height (0), _ignore_component_size_changed (false) { _column_labels = new PortMatrixColumnLabels (p, this); @@ -58,7 +60,10 @@ PortMatrixBody::~PortMatrixBody () bool PortMatrixBody::on_expose_event (GdkEventExpose* event) { - if (_matrix->visible_columns()->bundles().empty() || _matrix->visible_rows()->bundles().empty()) { + if ( + _matrix->visible_columns() == 0 || _matrix->visible_rows() == 0 || + _matrix->visible_columns()->bundles().empty() || _matrix->visible_rows()->bundles().empty() + ) { /* nothing to connect */ @@ -171,7 +176,7 @@ PortMatrixBody::compute_rectangles () { /* full sizes of components */ pair const col = _column_labels->dimensions (); - uint32_t col_overhang = _column_labels->overhang (); + uint32_t const col_overhang = _column_labels->overhang (); pair const row = _row_labels->dimensions (); pair const grid = _grid->dimensions (); @@ -182,6 +187,7 @@ PortMatrixBody::compute_rectangles () if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) { col_rect.set_x (0); + _column_labels_border_x = col_overhang; col_rect.set_y (0); grid_rect.set_x (0); @@ -222,13 +228,17 @@ PortMatrixBody::compute_rectangles () col_rect.set_width (grid_rect.get_width () + col_overhang); col_rect.set_x (row_rect.get_width() + grid_rect.get_width() - col_rect.get_width()); + _column_labels_border_x = col_rect.get_x () >= 0 ? col_rect.get_x () : 0; col_rect.set_y (row_rect.get_height()); - } + _column_labels_height = col_rect.get_height (); + _row_labels->set_parent_rectangle (row_rect); _column_labels->set_parent_rectangle (col_rect); _grid->set_parent_rectangle (grid_rect); + + DimensionsChanged (); /* EMIT SIGNAL */ } void @@ -243,7 +253,7 @@ PortMatrixBody::setup () /* Connect to bundles so that we find out when their names change */ - PortGroup::BundleList r = _matrix->rows()->bundles (); + PortGroup::BundleList r = _matrix->visible_rows()->bundles (); for (PortGroup::BundleList::iterator i = r.begin(); i != r.end(); ++i) { _bundle_connections.push_back ( @@ -252,7 +262,7 @@ PortMatrixBody::setup () } - PortGroup::BundleList c = _matrix->columns()->bundles (); + PortGroup::BundleList c = _matrix->visible_columns()->bundles (); for (PortGroup::BundleList::iterator i = c.begin(); i != c.end(); ++i) { _bundle_connections.push_back ( i->bundle->Changed.connect (sigc::hide (sigc::mem_fun (*this, &PortMatrixBody::rebuild_and_draw_column_labels))) @@ -295,6 +305,7 @@ PortMatrixBody::alloc_scroll_height () return _grid->parent_rectangle().get_height(); } +/** Set x offset (for scrolling) */ void PortMatrixBody::set_xoffset (uint32_t xo) { @@ -302,6 +313,7 @@ PortMatrixBody::set_xoffset (uint32_t xo) queue_draw (); } +/** Set y offset (for scrolling) */ void PortMatrixBody::set_yoffset (uint32_t yo) { @@ -494,3 +506,16 @@ PortMatrixBody::max_size () const return make_pair (std::max (row.first, _column_labels->overhang()) + grid.first, col.second + grid.second); } + +/** @return x position at which the column labels meet the border of the matrix */ +uint32_t +PortMatrixBody::column_labels_border_x () const +{ + return _column_labels_border_x; +} + +uint32_t +PortMatrixBody::column_labels_height () const +{ + return _column_labels_height; +} diff --git a/gtk2_ardour/port_matrix_body.h b/gtk2_ardour/port_matrix_body.h index c8dc0cce29..0b8facda45 100644 --- a/gtk2_ardour/port_matrix_body.h +++ b/gtk2_ardour/port_matrix_body.h @@ -67,6 +67,11 @@ public: void component_size_changed (); std::pair max_size () const; + uint32_t column_labels_border_x () const; + uint32_t column_labels_height () const; + + sigc::signal DimensionsChanged; + protected: bool on_expose_event (GdkEventExpose *); void on_size_request (Gtk::Requisition *); @@ -91,11 +96,10 @@ private: uint32_t _alloc_width; ///< allocated width uint32_t _alloc_height; ///< allocated height - Gdk::Rectangle _column_labels_rect; - Gdk::Rectangle _row_labels_rect; - Gdk::Rectangle _grid_rect; uint32_t _xoffset; uint32_t _yoffset; + uint32_t _column_labels_border_x; + uint32_t _column_labels_height; std::list _mouseover; bool _ignore_component_size_changed; diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc index 2aeb084b9f..c10bb01a2b 100644 --- a/gtk2_ardour/port_matrix_column_labels.cc +++ b/gtk2_ardour/port_matrix_column_labels.cc @@ -45,10 +45,6 @@ PortMatrixColumnLabels::compute_dimensions () _longest_bundle_name = 0; /* width of the longest channel name */ _longest_channel_name = 0; - /* height of highest bit of text (apart from group names) */ - _highest_text = 0; - /* width of the whole thing */ - _width = 0; /* Compute dimensions using all port groups, so that we allow for the largest and hence we can change between visible groups without the size of the labels jumping around. @@ -64,10 +60,6 @@ PortMatrixColumnLabels::compute_dimensions () _longest_bundle_name = ext.width; } - if (ext.height > _highest_text) { - _highest_text = ext.height; - } - for (uint32_t k = 0; k < j->bundle->nchannels (); ++k) { cairo_text_extents ( @@ -79,14 +71,21 @@ PortMatrixColumnLabels::compute_dimensions () if (ext.width > _longest_channel_name) { _longest_channel_name = ext.width; } - - if (ext.height > _highest_text) { - _highest_text = ext.height; - } } } + } - _width += group_size (*i) * grid_spacing (); + /* height metrics */ + cairo_text_extents_t ext; + cairo_text_extents (cr, X_("AQRjpy"), &ext); + _text_height = ext.height; + _descender_height = ext.height + ext.y_bearing; + + /* width of the whole thing */ + if (_matrix->visible_columns()) { + _width = group_size (_matrix->visible_columns()) * grid_spacing (); + } else { + _width = 0; } cairo_destroy (cr); @@ -99,7 +98,7 @@ PortMatrixColumnLabels::compute_dimensions () a += _longest_channel_name; } - _height = a * sin (angle()) + _highest_text * cos (angle()); + _height = a * sin (angle()) + _text_height * cos (angle()); _overhang = _height / tan (angle ()); _width += _overhang; } @@ -108,7 +107,7 @@ double PortMatrixColumnLabels::basic_text_x_pos (int) const { return grid_spacing() / 2 + - _highest_text / (2 * sin (angle ())); + _text_height / (2 * sin (angle ())); } void @@ -278,6 +277,8 @@ PortMatrixColumnLabels::render_bundle_name ( set_source_rgb (cr, text_colour()); + double const q = ((grid_spacing() * sin (angle())) - _text_height) / 2 + _descender_height; + if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) { double rl = 0; @@ -288,16 +289,16 @@ PortMatrixColumnLabels::render_bundle_name ( } cairo_move_to ( cr, - xoff + basic_text_x_pos (0) + rl * cos (angle()), - yoff + _height - rl * sin (angle()) + xoff + grid_spacing() - q * sin (angle ()) + rl * cos (angle()), + yoff + _height - q * cos (angle ()) - rl * sin (angle()) ); } else { cairo_move_to ( cr, - xoff + basic_text_x_pos (0) + name_pad() * cos (angle ()), - yoff + _height - name_pad() * sin (angle()) + xoff + grid_spacing() - q * sin (angle ()), + yoff + _height - q * cos (angle ()) ); } @@ -328,21 +329,24 @@ PortMatrixColumnLabels::render_channel_name ( set_source_rgb (cr, text_colour()); + double const q = ((grid_spacing() * sin (angle())) - _text_height) / 2 + _descender_height; + if (_matrix->arrangement() == PortMatrix::TOP_TO_RIGHT) { cairo_move_to ( cr, - xoff + basic_text_x_pos(bc.channel), - yoff + _height - name_pad() * sin (angle()) + xoff + grid_spacing() - q * sin (angle ()), + yoff + _height - q * cos (angle ()) ); + } else { double const rl = 3 * name_pad() + _longest_bundle_name; cairo_move_to ( cr, - xoff + basic_text_x_pos(bc.channel) + rl * cos (angle ()), - yoff + _height - rl * sin (angle()) + xoff + grid_spacing() - q * sin (angle ()) + rl * cos (angle ()), + yoff + _height - q * cos (angle ()) - rl * sin (angle()) ); } @@ -453,7 +457,7 @@ PortMatrixColumnLabels::motion (double x, double y) return; } - uint32_t const bh = _longest_channel_name * sin (angle ()) + _highest_text / cos (angle ()); + uint32_t const bh = _longest_channel_name * sin (angle ()) + _text_height / cos (angle ()); if ( (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM && y > bh) || diff --git a/gtk2_ardour/port_matrix_column_labels.h b/gtk2_ardour/port_matrix_column_labels.h index 0c725a0803..9ff59ec33b 100644 --- a/gtk2_ardour/port_matrix_column_labels.h +++ b/gtk2_ardour/port_matrix_column_labels.h @@ -64,7 +64,8 @@ private: double _longest_bundle_name; double _longest_channel_name; - double _highest_text; + double _text_height; + double _descender_height; uint32_t _overhang; }; diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc index 5136285e48..3e5d171690 100644 --- a/gtk2_ardour/port_matrix_grid.cc +++ b/gtk2_ardour/port_matrix_grid.cc @@ -41,16 +41,16 @@ PortMatrixGrid::PortMatrixGrid (PortMatrix* m, PortMatrixBody* b) void PortMatrixGrid::compute_dimensions () { - if (_matrix->visible_columns() == 0) { - _width = 0; - } else { + if (_matrix->visible_columns()) { _width = group_size (_matrix->visible_columns()) * grid_spacing (); + } else { + _width = 0; } - if (_matrix->visible_rows() == 0) { - _height = 0; - } else { + if (_matrix->visible_rows()) { _height = group_size (_matrix->visible_rows()) * grid_spacing (); + } else { + _height = 0; } } diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc index 6528f31d76..9878dc23dd 100644 --- a/gtk2_ardour/port_matrix_row_labels.cc +++ b/gtk2_ardour/port_matrix_row_labels.cc @@ -44,7 +44,6 @@ PortMatrixRowLabels::compute_dimensions () _longest_port_name = 0; _longest_bundle_name = 0; - _height = 0; /* Compute maximum dimensions using all port groups, so that we allow for the largest and hence we can change between visible groups without the size of the labels jumping around. @@ -71,8 +70,12 @@ PortMatrixRowLabels::compute_dimensions () } } - - _height += group_size (_matrix->visible_rows()) * grid_spacing (); + + if (_matrix->visible_rows()) { + _height = group_size (_matrix->visible_rows()) * grid_spacing (); + } else { + _height = 0; + } cairo_destroy (cr); gdk_pixmap_unref (pm);