X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fport_group.cc;h=8dc91edb3b46ee7af4db96c42c42626ddc36b802;hb=dab0dacc66dcc190b4408ba75e3807973582cbd6;hp=da908cc01f32dd44c1f79558cfdd3f274172d0b6;hpb=abd80d0f64a4b32c3a8cce01c9aa1d6bc7ee64bb;p=ardour.git diff --git a/gtk2_ardour/port_group.cc b/gtk2_ardour/port_group.cc index da908cc01f..8dc91edb3b 100644 --- a/gtk2_ardour/port_group.cc +++ b/gtk2_ardour/port_group.cc @@ -30,6 +30,7 @@ #include "ardour/session.h" #include "ardour/auditioner.h" +#include "gui_thread.h" #include "port_group.h" #include "port_matrix.h" #include "time_axis_view.h" @@ -50,6 +51,14 @@ PortGroup::PortGroup (std::string const & n) } +PortGroup::~PortGroup() +{ + for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { + delete *i; + } + _bundles.clear (); +} + /** Add a bundle to a group. * @param b Bundle. * @param allow_dups true to allow the group to contain more than one bundle with the same port, otherwise false. @@ -80,6 +89,14 @@ PortGroup::add_bundle (boost::shared_ptr b, boost::shared_ptr io, Gd add_bundle_internal (b, io, true, c, false); } +PortGroup::BundleRecord::BundleRecord (boost::shared_ptr b, boost::shared_ptr iop, Gdk::Color c, bool has_c) + : bundle (b) + , io (iop) + , colour (c) + , has_colour (has_c) +{ +} + void PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptr io, bool has_colour, Gdk::Color colour, bool allow_dups) { @@ -90,7 +107,7 @@ PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptrhas_same_ports (i->bundle) == false) { + while (i != _bundles.end() && b->has_same_ports ((*i)->bundle) == false) { ++i; } @@ -99,14 +116,9 @@ PortGroup::add_bundle_internal (boost::shared_ptr b, boost::shared_ptrChanged.connect (sigc::mem_fun (*this, &PortGroup::bundle_changed)); - - _bundles.push_back (r); + BundleRecord* br = new BundleRecord (b, io, colour, has_colour); + b->Changed.connect (br->changed_connection, invalidator (*this), ui_bind (&PortGroup::bundle_changed, this, _1), gui_context()); + _bundles.push_back (br); Changed (); } @@ -117,7 +129,7 @@ PortGroup::remove_bundle (boost::shared_ptr b) assert (b.get()); BundleList::iterator i = _bundles.begin (); - while (i != _bundles.end() && i->bundle != b) { + while (i != _bundles.end() && (*i)->bundle != b) { ++i; } @@ -125,7 +137,7 @@ PortGroup::remove_bundle (boost::shared_ptr b) return; } - i->changed_connection.disconnect (); + delete *i; _bundles.erase (i); Changed (); @@ -142,7 +154,7 @@ void PortGroup::clear () { for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - i->changed_connection.disconnect (); + delete *i; } _bundles.clear (); @@ -153,7 +165,7 @@ bool PortGroup::has_port (std::string const& p) const { for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - if (i->bundle->offers_port_alone (p)) { + if ((*i)->bundle->offers_port_alone (p)) { return true; } } @@ -165,7 +177,7 @@ boost::shared_ptr PortGroup::only_bundle () { assert (_bundles.size() == 1); - return _bundles.front().bundle; + return _bundles.front()->bundle; } @@ -174,7 +186,7 @@ PortGroup::total_channels () const { uint32_t n = 0; for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { - n += i->bundle->nchannels (); + n += (*i)->bundle->nchannels (); } return n; @@ -184,7 +196,7 @@ boost::shared_ptr PortGroup::io_from_bundle (boost::shared_ptr b) const { BundleList::const_iterator i = _bundles.begin (); - while (i != _bundles.end() && i->bundle != b) { + while (i != _bundles.end() && (*i)->bundle != b) { ++i; } @@ -192,7 +204,56 @@ PortGroup::io_from_bundle (boost::shared_ptr b) const return boost::shared_ptr (); } - return i->io; + return (*i)->io; +} + +/** Remove bundles whose channels are already represented by other, larger bundles */ +void +PortGroup::remove_duplicates () +{ + BundleList::iterator i = _bundles.begin(); + while (i != _bundles.end()) { + + BundleList::iterator tmp = i; + ++tmp; + + bool remove = false; + + for (BundleList::iterator j = _bundles.begin(); j != _bundles.end(); ++j) { + + if ((*j)->bundle->nchannels() > (*i)->bundle->nchannels()) { + /* this bundle is larger */ + + uint32_t k = 0; + while (k < (*i)->bundle->nchannels()) { + /* see if this channel on *i has an equivalent on *j */ + uint32_t l = 0; + while (l < (*j)->bundle->nchannels() && (*i)->bundle->channel_ports (k) != (*j)->bundle->channel_ports (l)) { + ++l; + } + + if (l == (*j)->bundle->nchannels()) { + /* it does not */ + break; + } + + ++k; + } + + if (k == (*i)->bundle->nchannels ()) { + /* all channels on *i are represented by the larger bundle *j, so remove *i */ + remove = true; + break; + } + } + } + + if (remove) { + _bundles.erase (i); + } + + i = tmp; + } } @@ -204,6 +265,11 @@ PortGroupList::PortGroupList () } +PortGroupList::~PortGroupList() +{ + /* XXX need to clean up bundles, but ownership shared with PortGroups */ +} + void PortGroupList::set_type (DataType t) { @@ -245,12 +311,10 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) if (session == 0) { return; } - + boost::shared_ptr bus (new PortGroup (_("Bus"))); boost::shared_ptr track (new PortGroup (_("Track"))); - boost::shared_ptr system_mono (new PortGroup (_("System (mono)"))); - boost::shared_ptr system_stereo (new PortGroup (_("System (stereo)"))); - boost::shared_ptr system_other (new PortGroup (_("System (other)"))); + boost::shared_ptr system (new PortGroup (_("System"))); boost::shared_ptr ardour (new PortGroup (_("Ardour"))); boost::shared_ptr other (new PortGroup (_("Other"))); @@ -274,7 +338,7 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) route_bundles.push_back (io->bundle ()); - (*i)->foreach_processor (bind (mem_fun (*this, &PortGroupList::maybe_add_processor_to_list), &route_bundles, inputs, used_io)); + (*i)->foreach_processor (boost::bind (&PortGroupList::maybe_add_processor_to_list, this, _1, &route_bundles, inputs, used_io)); /* Work out which group to put these bundles in */ boost::shared_ptr g; @@ -298,7 +362,7 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) if (g) { - TimeAxisView* tv = PublicEditor::instance().axis_view_from_route (i->get()); + TimeAxisView* tv = PublicEditor::instance().axis_view_from_route (*i); for (list >::iterator i = route_bundles.begin(); i != route_bundles.end(); ++i) { if (tv) { g->add_bundle (*i, io, tv->color ()); @@ -317,25 +381,13 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) && (*i)->ports_are_inputs() == inputs && (*i)->type() == _type) { - if ((*i)->nchannels() == 1) { - system_mono->add_bundle (*i, allow_dups); - } else if ((*i)->nchannels() == 2) { - system_stereo->add_bundle (*i, allow_dups); - } else { - system_other->add_bundle (*i, allow_dups); - } + system->add_bundle (*i, allow_dups); } } for (BundleList::iterator i = b->begin(); i != b->end(); ++i) { if (boost::dynamic_pointer_cast (*i) == 0 && (*i)->ports_are_inputs() == inputs && (*i)->type() == _type) { - if ((*i)->nchannels() == 1) { - system_mono->add_bundle (*i, allow_dups); - } else if ((*i)->nchannels() == 2) { - system_stereo->add_bundle (*i, allow_dups); - } else { - system_other->add_bundle (*i, allow_dups); - } + system->add_bundle (*i, allow_dups); } } @@ -365,9 +417,7 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) std::string const p = ports[n]; - if (!system_mono->has_port(p) && - !system_stereo->has_port(p) && - !system_other->has_port(p) && + if (!system->has_port(p) && !bus->has_port(p) && !track->has_port(p) && !ardour->has_port(p) && @@ -390,26 +440,22 @@ PortGroupList::gather (ARDOUR::Session* session, bool inputs, bool allow_dups) if (!extra_system.empty()) { boost::shared_ptr b = make_bundle_from_ports (extra_system, inputs); - if (b->nchannels() == 1) { - system_mono->add_bundle (b); - } else if (b->nchannels() == 2) { - system_stereo->add_bundle (b); - } else { - system_other->add_bundle (b); - } + system->add_bundle (b); } if (!extra_other.empty()) { other->add_bundle (make_bundle_from_ports (extra_other, inputs)); } - add_group_if_not_empty (system_mono); - add_group_if_not_empty (system_stereo); - add_group_if_not_empty (system_other); + if (!allow_dups) { + system->remove_duplicates (); + } + + add_group_if_not_empty (other); add_group_if_not_empty (bus); add_group_if_not_empty (track); add_group_if_not_empty (ardour); - add_group_if_not_empty (other); + add_group_if_not_empty (system); emit_changed (); } @@ -487,13 +533,7 @@ void PortGroupList::clear () { _groups.clear (); - - for (std::vector::iterator i = _bundle_changed_connections.begin(); i != _bundle_changed_connections.end(); ++i) { - i->disconnect (); - } - - _bundle_changed_connections.clear (); - + _bundle_changed_connections.drop_connections (); emit_changed (); } @@ -535,11 +575,8 @@ PortGroupList::add_group (boost::shared_ptr g) { _groups.push_back (g); - g->Changed.connect (sigc::mem_fun (*this, &PortGroupList::emit_changed)); - - _bundle_changed_connections.push_back ( - g->BundleChanged.connect (sigc::mem_fun (*this, &PortGroupList::emit_bundle_changed)) - ); + g->Changed.connect (_changed_connections, invalidator (*this), boost::bind (&PortGroupList::emit_changed, this), gui_context()); + g->BundleChanged.connect (_bundle_changed_connections, invalidator (*this), ui_bind (&PortGroupList::emit_bundle_changed, this, _1), gui_context()); emit_changed (); }