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