diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 6ff757c1b7..ea74b2d970 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -5332,7 +5332,7 @@ Editor::add_stripables (StripableList& sl) TrackViewList new_selection; bool from_scratch = (track_views.size() == 0); - sl.sort (StripablePresentationInfoSorter()); + sl.sort (Stripable::Sorter()); for (StripableList::iterator s = sl.begin(); s != sl.end(); ++s) { diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 419e48da21..c9604b13df 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -546,9 +546,11 @@ Drag::add_midi_region (MidiTimeAxisView* view, bool commit) return boost::shared_ptr(); } -struct PresentationInfoTimeAxisViewSorter { - bool operator() (TimeAxisView* a, TimeAxisView* b) { - return a->stripable()->presentation_info().order() < b->stripable()->presentation_info().order(); +struct TimeAxisViewStripableSorter { + bool operator() (TimeAxisView* tav_a, TimeAxisView* tav_b) { + boost::shared_ptr const& a = tav_a->stripable (); + boost::shared_ptr const& b = tav_b->stripable (); + return ARDOUR::Stripable::Sorter () (a, b); } }; @@ -564,7 +566,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, listtrack_views; - track_views.sort (PresentationInfoTimeAxisViewSorter ()); + track_views.sort (TimeAxisViewStripableSorter ()); for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { _time_axis_views.push_back (*i); diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index 487f3aff2b..aaa7daf80f 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -1006,82 +1006,37 @@ EditorRoutes::sync_presentation_info_from_treeview () TreeModel::Children::iterator ri; bool change = false; PresentationInfo::order_t order = 0; - bool master_is_first = false; - uint32_t count = 0; - OrderingKeys sorted; - const size_t cmp_max = rows.size (); + TreeOrderKeys sorted; PresentationInfo::ChangeSuspender cs; - // special case master if it's got PI order 0 lets keep it there - if (_session->master_out() && (_session->master_out()->presentation_info().order() == 0)) { - order++; - master_is_first = true; - } - for (ri = rows.begin(); ri != rows.end(); ++ri) { - boost::shared_ptr stripable = (*ri)[_columns.stripable]; bool visible = (*ri)[_columns.visible]; - /* Monitor and Auditioner do not get their presentation - * info reset here. - */ - +#ifndef NDEBUG // these should not exist in the treeview if (stripable->is_monitor() || stripable->is_auditioner()) { + assert (0); continue; } +#endif stripable->presentation_info().set_hidden (!visible); - /* special case master if it's got PI order 0 lets keep it there - * but still allow master to move if first non-master route has - * presentation order 1 - */ - if ((count == 0) && master_is_first && (stripable->presentation_info().order() == 1)) { - master_is_first = false; // someone has moved master - order = 0; - } - - if (stripable->is_master() && master_is_first) { - if (count) { - continue; - } else { - count++; - continue; - } - } - if (order != stripable->presentation_info().order()) { stripable->set_presentation_order (order); change = true; } - sorted.push_back (OrderKeys (order, stripable, cmp_max)); - + sorted.push_back (TreeOrderKey (order, stripable)); ++order; - ++count; } - if (!change) { - // VCA (and Mixbus) special cases according to SortByNewDisplayOrder - uint32_t n = 0; - SortByNewDisplayOrder cmp; - sort (sorted.begin(), sorted.end(), cmp); - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { - if (sr->old_display_order != n) { - change = true; - } - } - if (change) { - n = 0; - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { - if (sr->stripable->presentation_info().order() != n) { - sr->stripable->set_presentation_order (n); - } - } - } + change |= _session->ensure_stripable_sort_order (); + + if (change) { + _session->set_dirty(); } } @@ -1114,23 +1069,21 @@ EditorRoutes::sync_treeview_from_presentation_info (PropertyChange const & what_ return; } - OrderingKeys sorted; - const size_t cmp_max = rows.size (); - + TreeOrderKeys sorted; for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { boost::shared_ptr stripable = (*ri)[_columns.stripable]; /* use global order */ - sorted.push_back (OrderKeys (old_order, stripable, cmp_max)); + sorted.push_back (TreeOrderKey (old_order, stripable)); } - SortByNewDisplayOrder cmp; + TreeOrderKeySorter cmp; sort (sorted.begin(), sorted.end(), cmp); neworder.assign (sorted.size(), 0); uint32_t n = 0; - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { + for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { neworder[n] = sr->old_display_order; @@ -1543,27 +1496,6 @@ EditorRoutes::selection_filter (Glib::RefPtr const& model, TreeModel: return true; } -struct PresentationInfoRouteSorter -{ - bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - if (a->is_master()) { - /* master before everything else */ - return true; - } else if (b->is_master()) { - /* everything else before master */ - return false; - } - return a->presentation_info().order () < b->presentation_info().order (); - } -}; - -struct PresentationInfoVCASorter -{ - bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - return a->presentation_info().order () < b->presentation_info().order (); - } -}; - void EditorRoutes::initial_display () { @@ -1627,7 +1559,7 @@ EditorRoutes::move_selected_tracks (bool up) return; } - sl.sort (Stripable::PresentationOrderSorter()); + sl.sort (Stripable::Sorter()); std::list view_stripables; diff --git a/gtk2_ardour/export_channel_selector.cc b/gtk2_ardour/export_channel_selector.cc index acbed62030..347882501c 100644 --- a/gtk2_ardour/export_channel_selector.cc +++ b/gtk2_ardour/export_channel_selector.cc @@ -121,7 +121,7 @@ PortExportChannelSelector::fill_route_list () channel_view.add_route (master); } - routes.sort (Stripable::PresentationOrderSorter ()); + routes.sort (Stripable::Sorter ()); for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) { if ((*it)->is_master () || (*it)->is_monitor ()) { diff --git a/gtk2_ardour/group_tabs.cc b/gtk2_ardour/group_tabs.cc index 8f076fe84e..17667da650 100644 --- a/gtk2_ardour/group_tabs.cc +++ b/gtk2_ardour/group_tabs.cc @@ -679,12 +679,12 @@ void GroupTabs::collect (RouteGroup* g) { boost::shared_ptr group_routes = g->route_list (); - group_routes->sort (Stripable::PresentationOrderSorter()); + group_routes->sort (Stripable::Sorter()); int const N = group_routes->size (); RouteList::iterator i = group_routes->begin (); boost::shared_ptr routes = _session->get_routes (); - routes->sort (Stripable::PresentationOrderSorter()); + routes->sort (Stripable::Sorter()); RouteList::const_iterator j = routes->begin (); int diff = 0; diff --git a/gtk2_ardour/meterbridge.cc b/gtk2_ardour/meterbridge.cc index 09ad83350d..69006eda57 100644 --- a/gtk2_ardour/meterbridge.cc +++ b/gtk2_ardour/meterbridge.cc @@ -408,22 +408,6 @@ Meterbridge::on_scroll() metrics_right.set_metric_mode(mm_right, mt_right); } -struct PresentationInfoRouteSorter -{ - bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - if (a->is_master() || a->is_monitor()) { - /* "a" is a special route (master, monitor, etc), and comes - * last in the mixer ordering - */ - return false; - } else if (b->is_master() || b->is_monitor()) { - /* everything comes before b */ - return true; - } - return a->presentation_info().order() < b->presentation_info().order(); - } -}; - void Meterbridge::set_session (Session* s) { @@ -449,7 +433,7 @@ Meterbridge::set_session (Session* s) boost::shared_ptr routes = _session->get_routes(); RouteList copy (*routes); - copy.sort (PresentationInfoRouteSorter()); + copy.sort (Stripable::Sorter (true)); add_strips (copy); _session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Meterbridge::add_strips, this, _1), gui_context()); diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 11bc38609b..6a156d7d8b 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -498,7 +498,7 @@ Mixer_UI::add_stripables (StripableList& slist) bool from_scratch = (track_model->children().size() == 0); uint32_t nroutes = 0; - slist.sort (StripablePresentationInfoSorter()); + slist.sort (Stripable::Sorter()); for (Gtk::TreeModel::Children::iterator it = track_model->children().begin(); it != track_model->children().end(); ++it) { boost::shared_ptr s = (*it)[stripable_columns.stripable]; @@ -509,6 +509,7 @@ Mixer_UI::add_stripables (StripableList& slist) nroutes++; + // XXX what does this special case do? if (s->presentation_info().order() == (slist.front()->presentation_info().order() + slist.size())) { insert_iter = it; break; @@ -722,15 +723,12 @@ Mixer_UI::sync_presentation_info_from_treeview () TreeModel::Children::iterator ri; bool change = false; - uint32_t order = 0; - OrderingKeys sorted; - const size_t cmp_max = rows.size (); + PresentationInfo::order_t master_key = _session->master_order_key (); + PresentationInfo::order_t order = 0; + uint32_t count = 0; - // special case master if it's got PI order 0 lets keep it there - if (_session->master_out() && (_session->master_out()->presentation_info().order() == 0)) { - order++; - } + TreeOrderKeys sorted; PresentationInfo::ChangeSuspender cs; @@ -738,27 +736,26 @@ Mixer_UI::sync_presentation_info_from_treeview () bool visible = (*ri)[stripable_columns.visible]; boost::shared_ptr stripable = (*ri)[stripable_columns.stripable]; +#ifndef NDEBUG // these should not exist in the mixer's treeview if (!stripable) { + assert (0); continue; } - - /* Monitor and Auditioner do not get their presentation - * info reset here. - */ - if (stripable->is_monitor() || stripable->is_auditioner()) { + assert (0); continue; } - - /* Master also doesn't get set here but since the editor allows - * it to be reordered, we need to preserve its ordering. - */ + if (stripable->is_master()) { + assert (0); + continue; + } +#endif stripable->presentation_info().set_hidden (!visible); - // master may not get set here, but if it is zero keep it there - if (stripable->is_master() && (stripable->presentation_info().order() == 0)) { - continue; + // leave master where it is. + if (order == master_key) { + ++order; } if (order != stripable->presentation_info().order()) { @@ -766,37 +763,12 @@ Mixer_UI::sync_presentation_info_from_treeview () change = true; } - sorted.push_back (OrderKeys (order, stripable, cmp_max)); - + sorted.push_back (TreeOrderKey (count, stripable)); ++order; + ++count; } - if (!change) { - // VCA (and Mixbus) special cases according to SortByNewDisplayOrder - uint32_t n = 0; - SortByNewDisplayOrder cmp; - sort (sorted.begin(), sorted.end(), cmp); - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { - if (_session->master_out() && (_session->master_out()->presentation_info().order() == n)) { - ++n; - } - if (sr->old_display_order != n) { - change = true; - break; - } - } - if (change) { - n = 0; - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { - if (_session->master_out() && (_session->master_out()->presentation_info().order() == n)) { - ++n; - } - if (sr->stripable->presentation_info().order() != n) { - sr->stripable->set_presentation_order (n); - } - } - } - } + change |= _session->ensure_stripable_sort_order (); if (change) { DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from mixer GUI\n"); @@ -827,22 +799,20 @@ Mixer_UI::sync_treeview_from_presentation_info (PropertyChange const & what_chan return; } - OrderingKeys sorted; - const size_t cmp_max = rows.size (); - + TreeOrderKeys sorted; for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { boost::shared_ptr stripable = (*ri)[stripable_columns.stripable]; - sorted.push_back (OrderKeys (old_order, stripable, cmp_max)); + sorted.push_back (TreeOrderKey (old_order, stripable)); } - SortByNewDisplayOrder cmp; + TreeOrderKeySorter cmp; sort (sorted.begin(), sorted.end(), cmp); neworder.assign (sorted.size(), 0); uint32_t n = 0; - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { + for (TreeOrderKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { neworder[n] = sr->old_display_order; @@ -926,6 +896,15 @@ Mixer_UI::axis_view_by_control (boost::shared_ptr c) const return 0; } +struct MixerStripSorter { + bool operator() (const MixerStrip* ms_a, const MixerStrip* ms_b) + { + boost::shared_ptr const& a = ms_a->stripable (); + boost::shared_ptr const& b = ms_b->stripable (); + return ARDOUR::Stripable::Sorter(true)(a, b); + } +}; + bool Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip) { @@ -949,16 +928,10 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip) bool accumulate = false; bool found_another = false; - OrderingKeys sorted; - const size_t cmp_max = strips.size (); - for (list::iterator i = strips.begin(); i != strips.end(); ++i) { - sorted.push_back (OrderKeys (-1, (*i)->stripable(), cmp_max)); - } - SortByNewDisplayOrder cmp; - sort (sorted.begin(), sorted.end(), cmp); + strips.sort (MixerStripSorter()); - for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr) { - MixerStrip* ms = strip_by_stripable (sr->stripable); + for (list::iterator i = strips.begin(); i != strips.end(); ++i) { + MixerStrip* ms = *i; assert (ms); if (ms == strip) { diff --git a/gtk2_ardour/route_sorter.h b/gtk2_ardour/route_sorter.h index bf054b1ad4..fb7f574d72 100644 --- a/gtk2_ardour/route_sorter.h +++ b/gtk2_ardour/route_sorter.h @@ -26,44 +26,29 @@ #include "ardour/stripable.h" -struct OrderKeys { +/* This is used to keep numerical tree-order in sync + * with Stripable ordering (mixer_ui.cc editor_routes.cc) + */ + +struct TreeOrderKey { uint32_t old_display_order; - uint32_t new_display_order; - uint32_t compare_order; boost::shared_ptr stripable; - OrderKeys (uint32_t ok, boost::shared_ptr s, uint32_t cmp_max) + TreeOrderKey (uint32_t ok, boost::shared_ptr s) : old_display_order (ok) , stripable (s) + {} +}; + +typedef std::vector TreeOrderKeys; + +struct TreeOrderKeySorter +{ + bool operator() (const TreeOrderKey& ok_a, const TreeOrderKey& ok_b) { - new_display_order = s->presentation_info().order(); - compare_order = new_display_order; - - if (s->presentation_info().flags () & ARDOUR::PresentationInfo::VCA) { - compare_order += 2 * cmp_max; - } -#ifdef MIXBUS - if (s->presentation_info().flags () & ARDOUR::PresentationInfo::Mixbus || s->mixbus()) { - compare_order += cmp_max; - } - if (s->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut) { - compare_order += 3 * cmp_max; - } -#endif - } -}; - -typedef std::vector OrderingKeys; - -struct SortByNewDisplayOrder { - bool operator() (const OrderKeys& a, const OrderKeys& b) { - return a.compare_order < b.compare_order; - } -}; - -struct StripablePresentationInfoSorter { - bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - return a->presentation_info().order () < b->presentation_info().order (); + boost::shared_ptr const& a = ok_a.stripable; + boost::shared_ptr const& b = ok_b.stripable; + return ARDOUR::Stripable::Sorter () (a, b); } }; diff --git a/gtk2_ardour/stripable_treemodel.cc b/gtk2_ardour/stripable_treemodel.cc index 197683577c..8b31d80996 100644 --- a/gtk2_ardour/stripable_treemodel.cc +++ b/gtk2_ardour/stripable_treemodel.cc @@ -129,7 +129,7 @@ StripableTreeModel::iter_next_vfunc (const iterator& iter, iterator& iter_next) if (sl.empty()) { return false; } - sl.sort (Stripable::PresentationOrderSorter()); + sl.sort (Stripable::Sorter()); for (StripableList::const_iterator s = sl.begin(); s != sl.end(); ++s) { @@ -199,7 +199,7 @@ StripableTreeModel::iter_nth_root_child_vfunc(int n, iterator& iter) const return false; } - sl.sort (Stripable::PresentationOrderSorter()); + sl.sort (Stripable::Sorter()); StripableList::const_iterator s;