From 07a58ffd62f834780eb5dada7c1713e31c2e425a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 13 Aug 2011 20:19:39 +0000 Subject: Stop bundles disappearing from the port matrix when they have no channels (#4209). Also fix the remove all channels menu option. git-svn-id: svn://localhost/ardour2/branches/3.0@9986 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/global_port_matrix.cc | 4 +++ gtk2_ardour/port_group.cc | 41 +++++++------------------- gtk2_ardour/port_matrix.cc | 49 +++++++++++++++++++++----------- gtk2_ardour/port_matrix.h | 3 ++ gtk2_ardour/port_matrix_body.cc | 2 +- gtk2_ardour/port_matrix_column_labels.cc | 6 ++-- gtk2_ardour/port_matrix_component.cc | 6 ++-- gtk2_ardour/port_matrix_component.h | 1 + gtk2_ardour/port_matrix_grid.cc | 38 ++++++++++++++++++------- gtk2_ardour/port_matrix_row_labels.cc | 25 ++++++++-------- 10 files changed, 99 insertions(+), 76 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/global_port_matrix.cc b/gtk2_ardour/global_port_matrix.cc index df22424520..565def896e 100644 --- a/gtk2_ardour/global_port_matrix.cc +++ b/gtk2_ardour/global_port_matrix.cc @@ -90,6 +90,10 @@ GlobalPortMatrix::get_state (BundleChannel c[2]) const return PortMatrixNode::NOT_ASSOCIATED; } + if (c[0].bundle->nchannels() == ChanCount::ZERO || c[1].bundle->nchannels() == ChanCount::ZERO) { + return PortMatrixNode::NOT_ASSOCIATED; + } + Bundle::PortList const & in_ports = c[IN].bundle->channel_ports (c[IN].channel); Bundle::PortList const & out_ports = c[OUT].bundle->channel_ports (c[OUT].channel); if (in_ports.empty() || out_ports.empty()) { diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index d164c17782..7523e8beea 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -389,12 +389,10 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp for (list >::iterator j = i->ios.begin(); j != i->ios.end(); ++j) { boost::shared_ptr b = bundle_for_type ((*j)->bundle(), type); - if (b->nchannels() != ChanCount::ZERO) { - if (tv) { - g->add_bundle (b, *j, tv->color ()); - } else { - g->add_bundle (b, *j); - } + if (tv) { + g->add_bundle (b, *j, tv->color ()); + } else { + g->add_bundle (b, *j); } } } @@ -408,18 +406,14 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) && (*i)->ports_are_inputs() == inputs) { boost::shared_ptr b = bundle_for_type (*i, type); - if (b->nchannels() != ChanCount::ZERO) { - system->add_bundle (b, allow_dups); - } + system->add_bundle (b, allow_dups); } } for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) == 0 && (*i)->ports_are_inputs() == inputs) { boost::shared_ptr b = bundle_for_type (*i, type); - if (b->nchannels() != ChanCount::ZERO) { - system->add_bundle (b, allow_dups); - } + system->add_bundle (b, allow_dups); } } @@ -427,14 +421,10 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp if (!inputs) { boost::shared_ptr b = bundle_for_type (session->the_auditioner()->output()->bundle(), type); - if (b->nchannels() != ChanCount::ZERO) { - ardour->add_bundle (b); - } + ardour->add_bundle (b); b = bundle_for_type (session->click_io()->bundle(), type); - if (b->nchannels() != ChanCount::ZERO) { - ardour->add_bundle (b); - } + ardour->add_bundle (b); } /* Ardour's surfaces */ @@ -570,9 +560,7 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp if (!extra_system[*i].empty()) { boost::shared_ptr b = make_bundle_from_ports (extra_system[*i], *i, inputs); boost::shared_ptr bt = bundle_for_type (b, type); - if (bt->nchannels() != ChanCount::ZERO) { - system->add_bundle (bt); - } + system->add_bundle (bt); } } @@ -580,9 +568,7 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp if (!extra_other[*i].empty()) { boost::shared_ptr b = make_bundle_from_ports (extra_other[*i], *i, inputs); boost::shared_ptr bt = bundle_for_type (b, type); - if (bt->nchannels() != ChanCount::ZERO) { - other->add_bundle (bt); - } + other->add_bundle (bt); } } @@ -789,12 +775,7 @@ PortGroupList::io_from_bundle (boost::shared_ptr b) const bool PortGroupList::empty () const { - List::const_iterator i = _groups.begin (); - while (i != _groups.end() && (*i)->total_channels() == ChanCount::ZERO) { - ++i; - } - - return (i == _groups.end()); + return _groups.empty (); } /** Take a bundle, and either return it, if it contains only ports of type \a t, diff --git a/gtk2_ardour/port_matrix.cc b/gtk2_ardour/port_matrix.cc index d537dd18a1..35cfea651f 100644 --- a/gtk2_ardour/port_matrix.cc +++ b/gtk2_ardour/port_matrix.cc @@ -289,8 +289,8 @@ void PortMatrix::select_arrangement () { uint32_t const N[2] = { - count_of_our_type (_ports[0].total_channels()), - count_of_our_type (_ports[1].total_channels()) + count_of_our_type_min_1 (_ports[0].total_channels()), + count_of_our_type_min_1 (_ports[1].total_channels()) }; /* XXX: shirley there's an easier way than this */ @@ -407,14 +407,11 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t) boost::weak_ptr w (bc[dim].bundle); - bool can_add_or_rename = false; - /* Start off with options for the `natural' port type */ for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) { if (should_show (*i)) { snprintf (buf, sizeof (buf), _("Add %s %s"), (*i).to_i18n_string(), channel_noun().c_str()); sub.push_back (MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::add_channel_proxy), w, *i))); - can_add_or_rename = true; } } @@ -423,7 +420,6 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t) if (!should_show (*i)) { snprintf (buf, sizeof (buf), _("Add %s %s"), (*i).to_i18n_string(), channel_noun().c_str()); sub.push_back (MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::add_channel_proxy), w, *i))); - can_add_or_rename = true; } } @@ -438,17 +434,12 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t) sigc::bind (sigc::mem_fun (*this, &PortMatrix::rename_channel_proxy), w, bc[dim].channel) ) ); - can_add_or_rename = true; - } - - if (can_add_or_rename) { - sub.push_back (SeparatorElem ()); } if (can_remove_channels (bc[dim].bundle)) { if (bc[dim].channel != -1) { add_remove_option (sub, w, bc[dim].channel); - } else { + } else if (bc[dim].bundle->nchannels() != ARDOUR::ChanCount::ZERO) { snprintf (buf, sizeof (buf), _("Remove all")); sub.push_back ( @@ -465,7 +456,8 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t) } } - if (_show_only_bundles || count_of_our_type (bc[dim].bundle->nchannels()) <= 1) { + uint32_t c = count_of_our_type (bc[dim].bundle->nchannels ()); + if ((_show_only_bundles && c > 0) || c == 1) { snprintf (buf, sizeof (buf), _("%s all"), disassociation_verb().c_str()); sub.push_back ( MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_channel), w, bc[dim].channel, dim)) @@ -475,7 +467,7 @@ PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t) if (bc[dim].channel != -1) { add_disassociate_option (sub, w, dim, bc[dim].channel); - } else { + } else if (count_of_our_type (bc[dim].bundle->nchannels()) != 0) { snprintf (buf, sizeof (buf), _("%s all"), disassociation_verb().c_str()); sub.push_back ( MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_bundle), w, dim)) @@ -722,7 +714,10 @@ PortMatrix::remove_all_channels (boost::weak_ptr w) return; } - for (uint32_t i = 0; i < b->nchannels().n_total(); ++i) { + /* Remove channels backwards so that we don't renumber channels + that we are about to remove. + */ + for (int i = (b->nchannels().n_total() - 1); i >= 0; --i) { if (should_show (b->channel_type(i))) { remove_channel (ARDOUR::BundleChannel (b, i)); } @@ -856,7 +851,9 @@ PortMatrix::body_dimensions_changed () resize_window_to_proportion_of_monitor (_parent, m.first, m.second); } - +/** @return The PortGroup that is currently visible (ie selected by + * the notebook) along a given axis. + */ boost::shared_ptr PortMatrix::visible_ports (int d) const { @@ -942,6 +939,20 @@ PortMatrix::count_of_our_type (ChanCount c) const return c.get (_type); } +/** @return The number of ports of our type in the given channel count, + * but returning 1 if there are no ports. + */ +uint32_t +PortMatrix::count_of_our_type_min_1 (ChanCount c) const +{ + uint32_t n = count_of_our_type (c); + if (n == 0) { + n = 1; + } + + return n; +} + PortMatrixNode::State PortMatrix::get_association (PortMatrixNode node) const { @@ -1007,3 +1018,9 @@ PortMatrix::get_association (PortMatrixNode node) const return PortMatrixNode::NOT_ASSOCIATED; } +/** @return true if b is a non-zero pointer and the bundle it points to has some channels */ +bool +PortMatrix::bundle_with_channels (boost::shared_ptr b) +{ + return b && b->nchannels() != ARDOUR::ChanCount::ZERO; +} diff --git a/gtk2_ardour/port_matrix.h b/gtk2_ardour/port_matrix.h index 01fb67c0ae..75b2abf279 100644 --- a/gtk2_ardour/port_matrix.h +++ b/gtk2_ardour/port_matrix.h @@ -126,6 +126,7 @@ public: bool should_show (ARDOUR::DataType) const; uint32_t count_of_our_type (ARDOUR::ChanCount) const; + uint32_t count_of_our_type_min_1 (ARDOUR::ChanCount) const; PortMatrixNode::State get_association (PortMatrixNode) const; @@ -159,6 +160,8 @@ public: sigc::signal Finished; + static bool bundle_with_channels (boost::shared_ptr); + protected: /** We have two port group lists. One will be presented on the rows of the matrix, diff --git a/gtk2_ardour/port_matrix_body.cc b/gtk2_ardour/port_matrix_body.cc index 2b12ed092a..5d7bb0c4b6 100644 --- a/gtk2_ardour/port_matrix_body.cc +++ b/gtk2_ardour/port_matrix_body.cc @@ -458,7 +458,7 @@ PortMatrixBody::highlight_associated_channels (int dim, ARDOUR::BundleChannel h) ARDOUR::BundleChannel bc[2]; bc[dim] = h; - if (!bc[dim].bundle) { + if (!PortMatrix::bundle_with_channels (bc[dim].bundle)) { return; } diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc index f9b5b6aef8..eba2fffddf 100644 --- a/gtk2_ardour/port_matrix_column_labels.cc +++ b/gtk2_ardour/port_matrix_column_labels.cc @@ -149,7 +149,7 @@ PortMatrixColumnLabels::render (cairo_t* cr) if (_matrix->show_only_bundles()) { x += grid_spacing(); } else { - x += _matrix->count_of_our_type ((*i)->bundle->nchannels()) * grid_spacing(); + x += _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()) * grid_spacing(); } ++N; @@ -214,7 +214,7 @@ PortMatrixColumnLabels::mouseover_changed (list const &) ARDOUR::BundleChannel c = i->column; ARDOUR::BundleChannel r = i->row; - if (c.bundle && r.bundle) { + if (PortMatrix::bundle_with_channels (c.bundle) && PortMatrix::bundle_with_channels (r.bundle)) { add_channel_highlight (c); } else if (c.bundle) { _body->highlight_associated_channels (_matrix->column_index(), c); @@ -273,7 +273,7 @@ PortMatrixColumnLabels::render_bundle_name ( if (_matrix->show_only_bundles()) { w = grid_spacing (); } else { - w = _matrix->count_of_our_type (b->nchannels()) * grid_spacing(); + w = _matrix->count_of_our_type_min_1 (b->nchannels()) * grid_spacing(); } double x_ = xoff; diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc index 38a07479b0..166488bef0 100644 --- a/gtk2_ardour/port_matrix_component.cc +++ b/gtk2_ardour/port_matrix_component.cc @@ -132,7 +132,7 @@ PortMatrixComponent::group_size (boost::shared_ptr g) const s = bundles.size(); } else { for (PortGroup::BundleList::const_iterator i = bundles.begin(); i != bundles.end(); ++i) { - s += _matrix->count_of_our_type ((*i)->bundle->nchannels()); + s += _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()); } } @@ -169,7 +169,7 @@ PortMatrixComponent::channel_to_position (ARDOUR::BundleChannel bc, boost::share if (_matrix->show_only_bundles()) { p += 1; } else { - p += _matrix->count_of_our_type ((*i)->bundle->nchannels()); + p += _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()); } } @@ -195,7 +195,7 @@ PortMatrixComponent::position_to_channel (double p, double, boost::shared_ptrcount_of_our_type ((*j)->bundle->nchannels()); + uint32_t const s = _matrix->count_of_our_type_min_1 ((*j)->bundle->nchannels()); if (p < s) { return ARDOUR::BundleChannel ((*j)->bundle, p); } else { diff --git a/gtk2_ardour/port_matrix_component.h b/gtk2_ardour/port_matrix_component.h index 3fdd26394a..a574d20341 100644 --- a/gtk2_ardour/port_matrix_component.h +++ b/gtk2_ardour/port_matrix_component.h @@ -31,6 +31,7 @@ class PortGroup; class PortGroupList; namespace ARDOUR { + class Bundle; class BundleChannel; } diff --git a/gtk2_ardour/port_matrix_grid.cc b/gtk2_ardour/port_matrix_grid.cc index 4a2f569d5c..b87f560984 100644 --- a/gtk2_ardour/port_matrix_grid.cc +++ b/gtk2_ardour/port_matrix_grid.cc @@ -81,7 +81,7 @@ PortMatrixGrid::render (cairo_t* cr) if (!_matrix->show_only_bundles()) { cairo_set_line_width (cr, thin_grid_line_width()); - for (uint32_t j = 0; j < _matrix->count_of_our_type ((*i)->bundle->nchannels()); ++j) { + for (uint32_t j = 0; j < _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()); ++j) { x += grid_spacing (); cairo_move_to (cr, x, 0); cairo_line_to (cr, x, _height); @@ -97,6 +97,12 @@ PortMatrixGrid::render (cairo_t* cr) ++N; } + if (_matrix->show_only_bundles ()) { + cairo_move_to (cr, x, 0); + cairo_line_to (cr, x, _height); + cairo_stroke (cr); + } + uint32_t y = 0; /* HORIZONTAL GRID LINES */ @@ -111,7 +117,7 @@ PortMatrixGrid::render (cairo_t* cr) if (!_matrix->show_only_bundles()) { cairo_set_line_width (cr, thin_grid_line_width()); - for (uint32_t j = 0; j < _matrix->count_of_our_type ((*i)->bundle->nchannels()); ++j) { + for (uint32_t j = 0; j < _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()); ++j) { y += grid_spacing (); cairo_move_to (cr, 0, y); cairo_line_to (cr, _width, y); @@ -127,6 +133,12 @@ PortMatrixGrid::render (cairo_t* cr) ++N; } + if (_matrix->show_only_bundles ()) { + cairo_move_to (cr, 0, y); + cairo_line_to (cr, _width, y); + cairo_stroke (cr); + } + /* ASSOCIATION INDICATORS and NON-CONNECTABLE INDICATORS */ /* we draw a grey square in a matrix box if the two ports that intersect at that box @@ -173,14 +185,10 @@ PortMatrixGrid::render (cairo_t* cr) for (PortGroup::BundleList::const_iterator j = row_bundles.begin(); j != row_bundles.end(); ++j) { x = bx; - for (uint32_t k = 0; k < (*i)->bundle->nchannels().n_total(); ++k) { + for (uint32_t k = 0; k < _matrix->count_of_our_type ((*i)->bundle->nchannels()); ++k) { y = by; - for (uint32_t l = 0; l < (*j)->bundle->nchannels().n_total(); ++l) { - - if (!_matrix->should_show ((*i)->bundle->channel_type(k)) || !_matrix->should_show ((*j)->bundle->channel_type(l))) { - continue; - } + for (uint32_t l = 0; l < _matrix->count_of_our_type ((*j)->bundle->nchannels()); ++l) { ARDOUR::BundleChannel c[2]; c[_matrix->column_index()] = ARDOUR::BundleChannel ((*i)->bundle, k); @@ -209,13 +217,21 @@ PortMatrixGrid::render (cairo_t* cr) y += grid_spacing(); } + if ((*j)->bundle->nchannels() == ARDOUR::ChanCount::ZERO) { + draw_non_connectable_indicator (cr, x, y); + } + x += grid_spacing(); } - by += _matrix->count_of_our_type ((*j)->bundle->nchannels()) * grid_spacing(); + if ((*i)->bundle->nchannels() == ARDOUR::ChanCount::ZERO) { + draw_non_connectable_indicator (cr, x, y); + } + + by += _matrix->count_of_our_type_min_1 ((*j)->bundle->nchannels()) * grid_spacing(); } - bx += _matrix->count_of_our_type ((*i)->bundle->nchannels()) * grid_spacing(); + bx += _matrix->count_of_our_type_min_1 ((*i)->bundle->nchannels()) * grid_spacing(); } } } @@ -402,7 +418,7 @@ PortMatrixGrid::draw_extra (cairo_t* cr) double const x = component_to_parent_x (channel_to_position (i->column, _matrix->visible_columns()) * grid_spacing()) + grid_spacing() / 2; double const y = component_to_parent_y (channel_to_position (i->row, _matrix->visible_rows()) * grid_spacing()) + grid_spacing() / 2; - if (i->row.bundle && i->column.bundle) { + if (PortMatrix::bundle_with_channels (i->row.bundle) && PortMatrix::bundle_with_channels (i->column.bundle)) { cairo_move_to (cr, x, y); if (_matrix->arrangement() == PortMatrix::LEFT_TO_BOTTOM) { diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc index bc6e2a2fa1..8c8dcd4dff 100644 --- a/gtk2_ardour/port_matrix_row_labels.cc +++ b/gtk2_ardour/port_matrix_row_labels.cc @@ -115,17 +115,18 @@ PortMatrixRowLabels::render (cairo_t* cr) render_bundle_name (cr, background_colour (), (*i)->has_colour ? (*i)->colour : get_a_bundle_colour (N), 0, y, (*i)->bundle); if (!_matrix->show_only_bundles()) { - for (uint32_t j = 0; j < (*i)->bundle->nchannels().n_total(); ++j) { - - if (!_matrix->should_show ((*i)->bundle->channel_type(j))) { - continue; - } - + uint32_t const N = _matrix->count_of_our_type ((*i)->bundle->nchannels()); + for (uint32_t j = 0; j < N; ++j) { Gdk::Color c = (*i)->has_colour ? (*i)->colour : get_a_bundle_colour (M); render_channel_name (cr, background_colour (), c, 0, y, ARDOUR::BundleChannel ((*i)->bundle, j)); y += grid_spacing(); ++M; } + + if (N == 0) { + y += grid_spacing (); + } + } else { y += grid_spacing(); } @@ -215,7 +216,7 @@ PortMatrixRowLabels::render_bundle_name ( { double const x = bundle_name_x (); - int const n = _matrix->show_only_bundles() ? 1 : _matrix->count_of_our_type (b->nchannels()); + int const n = _matrix->show_only_bundles() ? 1 : _matrix->count_of_our_type_min_1 (b->nchannels()); set_source_rgb (cr, bg_colour); cairo_rectangle (cr, xoff + x, yoff, _longest_bundle_name + name_pad() * 2, grid_spacing() * n); cairo_fill_preserve (cr); @@ -244,15 +245,15 @@ PortMatrixRowLabels::render_channel_name ( cairo_set_line_width (cr, label_border_width ()); cairo_stroke (cr); - cairo_text_extents_t ext; - cairo_text_extents (cr, bc.bundle->channel_name(bc.channel).c_str(), &ext); - double const off = (grid_spacing() - ext.height) / 2; - if (_matrix->count_of_our_type (bc.bundle->nchannels()) > 1) { /* only plot the name if the bundle has more than one channel; the name of a single channel is assumed to be redundant */ + cairo_text_extents_t ext; + cairo_text_extents (cr, bc.bundle->channel_name(bc.channel).c_str(), &ext); + double const off = (grid_spacing() - ext.height) / 2; + set_source_rgb (cr, text_colour()); cairo_move_to (cr, port_name_x() + xoff + name_pad(), yoff + name_pad() + off); cairo_show_text (cr, bc.bundle->channel_name(bc.channel).c_str()); @@ -304,7 +305,7 @@ PortMatrixRowLabels::mouseover_changed (list const &) ARDOUR::BundleChannel c = i->column; ARDOUR::BundleChannel r = i->row; - if (c.bundle && r.bundle) { + if (PortMatrix::bundle_with_channels (c.bundle) && PortMatrix::bundle_with_channels (r.bundle)) { add_channel_highlight (r); } else if (r.bundle) { _body->highlight_associated_channels (_matrix->row_index(), r); -- cgit v1.2.3