Sort tracks in the port matrix according to editor order. Fixes #2966.

git-svn-id: svn://localhost/ardour2/branches/3.0@7458 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-07-21 02:17:57 +00:00
parent f58a810af8
commit 1fd56c5476
7 changed files with 87 additions and 23 deletions

View file

@ -272,7 +272,7 @@ PortGroupList::~PortGroupList()
void void
PortGroupList::maybe_add_processor_to_list ( PortGroupList::maybe_add_processor_to_list (
boost::weak_ptr<Processor> wp, list<boost::shared_ptr<Bundle> >* route_bundles, bool inputs, set<boost::shared_ptr<IO> >& used_io boost::weak_ptr<Processor> wp, list<boost::shared_ptr<IO> >* route_ios, bool inputs, set<boost::shared_ptr<IO> >& used_io
) )
{ {
boost::shared_ptr<Processor> p (wp.lock()); boost::shared_ptr<Processor> p (wp.lock());
@ -288,12 +288,28 @@ PortGroupList::maybe_add_processor_to_list (
boost::shared_ptr<IO> io = inputs ? iop->input() : iop->output(); boost::shared_ptr<IO> io = inputs ? iop->input() : iop->output();
if (io && used_io.find (io) == used_io.end()) { if (io && used_io.find (io) == used_io.end()) {
route_bundles->push_back (io->bundle ()); route_ios->push_back (io);
used_io.insert (io); used_io.insert (io);
} }
} }
} }
struct RouteIOs {
RouteIOs (boost::shared_ptr<Route> r, boost::shared_ptr<IO> i) {
route = r;
ios.push_back (i);
}
boost::shared_ptr<Route> route;
std::list<boost::shared_ptr<IO> > ios;
};
class RouteIOsComparator {
public:
bool operator() (RouteIOs const & a, RouteIOs const & b) {
return a.route->order_key (X_("editor")) < b.route->order_key (X_("editor"));
}
};
/** Gather bundles from around the system and put them in this PortGroupList. /** Gather bundles from around the system and put them in this PortGroupList.
* @param type Type of bundles to collect, or NIL for all types. * @param type Type of bundles to collect, or NIL for all types.
@ -313,16 +329,16 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
boost::shared_ptr<PortGroup> ardour (new PortGroup (_("Ardour"))); boost::shared_ptr<PortGroup> ardour (new PortGroup (_("Ardour")));
boost::shared_ptr<PortGroup> other (new PortGroup (_("Other"))); boost::shared_ptr<PortGroup> other (new PortGroup (_("Other")));
/* Find the bundles for routes. We use the RouteBundle class to join /* Find the IOs which have bundles for routes and their processors. We store
the route's input/output and processor bundles together so that they these IOs in a RouteIOs class so that we can then sort the results by route
are presented as one bundle in the matrix. */ order key.
*/
boost::shared_ptr<RouteList> routes = session->get_routes (); boost::shared_ptr<RouteList> routes = session->get_routes ();
list<RouteIOs> route_ios;
for (RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) { for (RouteList::const_iterator i = routes->begin(); i != routes->end(); ++i) {
list<boost::shared_ptr<Bundle> > route_bundles;
/* keep track of IOs that we have taken bundles from, /* keep track of IOs that we have taken bundles from,
so that we can avoid taking the same IO from both so that we can avoid taking the same IO from both
Route::output() and the main_outs Delivery */ Route::output() and the main_outs Delivery */
@ -331,24 +347,32 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
boost::shared_ptr<IO> io = inputs ? (*i)->input() : (*i)->output(); boost::shared_ptr<IO> io = inputs ? (*i)->input() : (*i)->output();
used_io.insert (io); used_io.insert (io);
route_bundles.push_back (io->bundle ()); RouteIOs rb (*i, io);
(*i)->foreach_processor (boost::bind (&PortGroupList::maybe_add_processor_to_list, this, _1, &rb.ios, inputs, used_io));
(*i)->foreach_processor (boost::bind (&PortGroupList::maybe_add_processor_to_list, this, _1, &route_bundles, inputs, used_io)); route_ios.push_back (rb);
}
/* Work out which group to put these bundles in */ /* Sort RouteIOs by the routes' editor order keys */
route_ios.sort (RouteIOsComparator ());
/* Now put the bundles that belong to these sorted RouteIOs into the PortGroup */
for (list<RouteIOs>::iterator i = route_ios.begin(); i != route_ios.end(); ++i) {
TimeAxisView* tv = PublicEditor::instance().axis_view_from_route (i->route);
/* Work out which group to put these IOs' bundles in */
boost::shared_ptr<PortGroup> g; boost::shared_ptr<PortGroup> g;
if (boost::dynamic_pointer_cast<Track> (*i)) { if (boost::dynamic_pointer_cast<Track> (i->route)) {
g = track; g = track;
} else { } else {
g = bus; g = bus;
} }
TimeAxisView* tv = PublicEditor::instance().axis_view_from_route (*i); for (list<boost::shared_ptr<IO> >::iterator j = i->ios.begin(); j != i->ios.end(); ++j) {
for (list<boost::shared_ptr<Bundle> >::iterator i = route_bundles.begin(); i != route_bundles.end(); ++i) {
if (tv) { if (tv) {
g->add_bundle (*i, io, tv->color ()); g->add_bundle ((*j)->bundle(), *j, tv->color ());
} else { } else {
g->add_bundle (*i, io); g->add_bundle ((*j)->bundle(), *j);
} }
} }
} }

View file

@ -40,7 +40,6 @@ namespace ARDOUR {
} }
class PortMatrix; class PortMatrix;
class RouteBundle;
class PublicEditor; class PublicEditor;
/** A list of bundles grouped by some aspect of their type e.g. busses, tracks, system. /** A list of bundles grouped by some aspect of their type e.g. busses, tracks, system.
@ -145,7 +144,7 @@ class PortGroupList : public sigc::trackable
void emit_bundle_changed (ARDOUR::Bundle::Change); void emit_bundle_changed (ARDOUR::Bundle::Change);
boost::shared_ptr<ARDOUR::Bundle> make_bundle_from_ports (std::vector<std::string> const &, ARDOUR::DataType, bool) const; boost::shared_ptr<ARDOUR::Bundle> make_bundle_from_ports (std::vector<std::string> const &, ARDOUR::DataType, bool) const;
void maybe_add_processor_to_list ( void maybe_add_processor_to_list (
boost::weak_ptr<ARDOUR::Processor>, std::list<boost::shared_ptr<ARDOUR::Bundle> > *, bool, std::set<boost::shared_ptr<ARDOUR::IO> > & boost::weak_ptr<ARDOUR::Processor>, std::list<boost::shared_ptr<ARDOUR::IO> > *, bool, std::set<boost::shared_ptr<ARDOUR::IO> > &
); );
mutable PortGroup::BundleList _bundles; mutable PortGroup::BundleList _bundles;

View file

@ -151,6 +151,8 @@ PortMatrix::init ()
/* and also ports */ /* and also ports */
_session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context()); _session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
/* watch for route order keys changing, which changes the order of things in our global ports list(s) */
_session->RouteOrderKeyChanged.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
/* Part 3: other stuff */ /* Part 3: other stuff */

View file

@ -257,6 +257,7 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
PBD::Signal0<void> meter_change; PBD::Signal0<void> meter_change;
PBD::Signal0<void> signal_latency_changed; PBD::Signal0<void> signal_latency_changed;
PBD::Signal0<void> initial_delay_changed; PBD::Signal0<void> initial_delay_changed;
PBD::Signal0<void> order_key_changed;
/* gui's call this for their own purposes. */ /* gui's call this for their own purposes. */

View file

@ -774,6 +774,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void send_mmc_locate (nframes64_t); void send_mmc_locate (nframes64_t);
int send_full_time_code (nframes64_t); int send_full_time_code (nframes64_t);
PBD::Signal0<void> RouteOrderKeyChanged;
protected: protected:
friend class AudioEngine; friend class AudioEngine;
void set_block_size (nframes_t nframes); void set_block_size (nframes_t nframes);
@ -1416,6 +1418,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void setup_midi_machine_control (); void setup_midi_machine_control ();
void cleanup_stubfiles (); void cleanup_stubfiles ();
void route_order_key_changed ();
}; };
} // namespace ARDOUR } // namespace ARDOUR

View file

@ -227,15 +227,32 @@ Route::order_key (std::string const & name) const
void void
Route::set_order_key (std::string const & name, long n) Route::set_order_key (std::string const & name, long n)
{ {
order_keys[name] = n; bool changed = false;
/* This method looks more complicated than it should, but
it's important that we don't emit order_key_changed unless
it actually has, as expensive things happen on receipt of that
signal.
*/
if (order_keys.find(name) == order_keys.end() || order_keys[name] != n) {
order_keys[name] = n;
changed = true;
}
if (Config->get_sync_all_route_ordering()) { if (Config->get_sync_all_route_ordering()) {
for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) { for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
x->second = n; if (x->second != n) {
x->second = n;
changed = true;
}
} }
} }
_session.set_dirty (); if (changed) {
order_key_changed (); /* EMIT SIGNAL */
_session.set_dirty ();
}
} }
/** Set all order keys to be the same as that for `base', if such a key /** Set all order keys to be the same as that for `base', if such a key
@ -263,8 +280,17 @@ Route::sync_order_keys (std::string const & base)
i = order_keys.begin(); i = order_keys.begin();
} }
bool changed = false;
for (; i != order_keys.end(); ++i) { for (; i != order_keys.end(); ++i) {
i->second = key; if (i->second != key) {
i->second = key;
changed = true;
}
}
if (changed) {
order_key_changed (); /* EMIT SIGNAL */
} }
} }

View file

@ -1911,6 +1911,7 @@ Session::add_routes (RouteList& new_routes, bool save)
r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1)); r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2)); r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1)); r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
r->order_key_changed.connect_same_thread (*this, boost::bind (&Session::route_order_key_changed, this));
if (r->is_master()) { if (r->is_master()) {
_master_out = r; _master_out = r;
@ -3898,3 +3899,10 @@ Session::add_session_range_location (nframes_t start, nframes_t end)
_session_range_location = new Location (start, end, _("session"), Location::IsSessionRange); _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
_locations.add (_session_range_location); _locations.add (_session_range_location);
} }
/** Called when one of our routes' order keys has changed */
void
Session::route_order_key_changed ()
{
RouteOrderKeyChanged (); /* EMIT SIGNAL */
}