diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2017-02-13 22:09:55 +0100 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2017-02-13 22:10:18 +0100 |
commit | bd7507590eec08146a5cc1a291a1f6217cd9e7e6 (patch) | |
tree | 383ba454913e002063e8338e7837c5fd4ee8afcd /gtk2_ardour/editor_routes.cc | |
parent | 0f7ccb8adb77b1a9586999cb2dc00a658daf57d9 (diff) |
new implementation of move-selected-tracks
This does not modify the editor treeview/treemodel at all
but instead works directly on the PresentationInfo order
data. Likely needs more testing etc.
Diffstat (limited to 'gtk2_ardour/editor_routes.cc')
-rw-r--r-- | gtk2_ardour/editor_routes.cc | 173 |
1 files changed, 65 insertions, 108 deletions
diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index 2c39190758..687e929550 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -1167,8 +1167,10 @@ EditorRoutes::sync_treeview_from_presentation_info (PropertyChange const & what_ * The rows (stripables) are not actually removed from the model, * but only from the display in the DnDTreeView. * ->reorder() will fail to find the row_path. - * (re-order drag -> remove row -> rync PI from TV -> notify -> sync TV from PI -> crash) + * (re-order drag -> remove row -> sync PI from TV -> notify -> sync TV from PI -> crash) */ + Unwinder<bool> uw2 (_ignore_selection_change, true); + _display.unset_model(); _model->reorder (neworder); _display.set_model (_model); @@ -1195,7 +1197,6 @@ EditorRoutes::sync_treeview_from_presentation_info (PropertyChange const & what_ } /* step two: set the Selection (for stripables/routes) */ - _editor->get_selection().set (tvl); } @@ -1622,153 +1623,109 @@ EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& contex struct ViewStripable { TimeAxisView* tav; boost::shared_ptr<Stripable> stripable; - uint32_t old_order; - ViewStripable (TimeAxisView* t, boost::shared_ptr<Stripable> s, uint32_t n) - : tav (t), stripable (s), old_order (n) {} + ViewStripable (TimeAxisView* t, boost::shared_ptr<Stripable> s) + : tav (t), stripable (s) {} }; void EditorRoutes::move_selected_tracks (bool up) { - if (_editor->selection->tracks.empty()) { + StripableList sl; + _session->get_stripables (sl); + + if (sl.size() < 2) { + /* nope */ return; } + sl.sort (Stripable::PresentationOrderSorter()); + std::list<ViewStripable> view_stripables; - std::vector<int> neworder; - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator ri; - TreeModel::Children::size_type n; - for (n = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++n) { - TimeAxisView* tv = (*ri)[_columns.tv]; - boost::shared_ptr<Stripable> stripable = (*ri)[_columns.stripable]; - view_stripables.push_back (ViewStripable (tv, stripable, n)); + /* build a list that includes time axis view information */ + + for (StripableList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) { + TimeAxisView* tv = _editor->axis_view_from_stripable (*sli); + view_stripables.push_back (ViewStripable (tv, *sli)); } - list<ViewStripable>::iterator trailing; - list<ViewStripable>::iterator leading; + /* for each selected stripable, move it above or below the adjacent + * stripable that has a time-axis view representation here. If there's + * no such representation, then + */ - TimeAxisView* scroll_to = NULL; + list<ViewStripable>::iterator unselected_neighbour; + list<ViewStripable>::iterator vsi; - if (up) { + { + PresentationInfo::ChangeSuspender cs; - trailing = view_stripables.begin(); - leading = view_stripables.begin(); + if (up) { + unselected_neighbour = view_stripables.end (); + vsi = view_stripables.begin(); + ++vsi; - ++leading; + while (vsi != view_stripables.end()) { - while (leading != view_stripables.end()) { - if (_editor->selection->selected (leading->tav)) { - view_stripables.insert (trailing, ViewStripable (*leading)); - if (!scroll_to) { - scroll_to = leading->tav; - } - leading = view_stripables.erase (leading); - } else { - ++leading; - ++trailing; - } - } + if (vsi->stripable->presentation_info().selected()) { - } else { + if (unselected_neighbour != view_stripables.end()) { - /* if we could use reverse_iterator in list::insert, this code - would be a beautiful reflection of the code above. but we can't - and so it looks like a bit of a mess. - */ + PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order(); + PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order(); - trailing = view_stripables.end(); - leading = view_stripables.end(); + unselected_neighbour->stripable->set_presentation_order (my_order); + vsi->stripable->set_presentation_order (unselected_neighbour_order); + } - --leading; if (leading == view_stripables.begin()) { return; } - --leading; - --trailing; + } else { - while (1) { + if (vsi->tav) { + unselected_neighbour = vsi; + } - if (_editor->selection->selected (leading->tav)) { - if (!scroll_to) { - scroll_to = leading->tav; } - list<ViewStripable>::iterator tmp; - /* need to insert *after* trailing, not *before* it, - which is what insert (iter, val) normally does. - */ + ++vsi; + } - tmp = trailing; - tmp++; + } else { - view_stripables.insert (tmp, ViewStripable (*leading)); + unselected_neighbour = view_stripables.end(); + vsi = unselected_neighbour; + --vsi; - /* can't use iter = cont.erase (iter); form here, because - we need iter to move backwards. - */ + do { - tmp = leading; - --tmp; + if (vsi->stripable->presentation_info().selected()) { - bool done = false; + if (unselected_neighbour != view_stripables.end()) { - if (leading == view_stripables.begin()) { - /* the one we've just inserted somewhere else - was the first in the list. erase this copy, - and then break, because we're done. - */ - done = true; - } + PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order(); + PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order(); - view_stripables.erase (leading); + unselected_neighbour->stripable->set_presentation_order (my_order); + vsi->stripable->set_presentation_order (unselected_neighbour_order); + } - if (done) { - break; - } + } else { - leading = tmp; + if (vsi->tav) { + unselected_neighbour = vsi; + } - } else { - if (leading == view_stripables.begin()) { - break; } - --leading; - --trailing; - } - }; - } - bool changed = false; - unsigned int i = 0; - for (leading = view_stripables.begin(); leading != view_stripables.end(); ++leading, ++i) { - if (leading->old_order != i) { - changed = true; - } - neworder.push_back (leading->old_order); -#ifndef NDEBUG - if (leading->old_order != neworder.size() - 1) { - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("move %1 to %2\n", leading->old_order, neworder.size() - 1)); - } -#endif - } + --vsi; - if (!changed) { - return; - } - -#ifndef NDEBUG - DEBUG_TRACE (DEBUG::OrderKeys, "New order after moving tracks:\n"); - for (vector<int>::iterator i = neworder.begin(); i != neworder.end(); ++i) { - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("\t%1\n", *i)); + } while (vsi != view_stripables.begin()); + } } - DEBUG_TRACE (DEBUG::OrderKeys, "-------\n"); -#endif - _model->reorder (neworder); - - if (scroll_to) { - _editor->ensure_time_axis_view_is_visible (*scroll_to, false); - } +// if (scroll_to) { +// _editor->ensure_time_axis_view_is_visible (*scroll_to, false); +// } } |