From 0d173fdccda3d5662d80cb3eb56d38e47a949c77 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 7 Oct 2008 21:46:42 +0000 Subject: [PATCH] add move-selected-tracks-{up,down} commands git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3879 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/SAE-de.bindings.in | 2 + gtk2_ardour/ardour-sae.menus | 2 + gtk2_ardour/ardour.menus | 2 + gtk2_ardour/editor.h | 4 +- gtk2_ardour/editor_actions.cc | 5 + gtk2_ardour/editor_route_list.cc | 242 ++++++++++++++++++++++++++++ gtk2_ardour/mnemonic-us.bindings.in | 2 + 7 files changed, 258 insertions(+), 1 deletion(-) diff --git a/gtk2_ardour/SAE-de.bindings.in b/gtk2_ardour/SAE-de.bindings.in index a1dedef2f9..aeec05aae6 100644 --- a/gtk2_ardour/SAE-de.bindings.in +++ b/gtk2_ardour/SAE-de.bindings.in @@ -140,8 +140,10 @@ (gtk_accel_path "/Editor/select-prev-route" "uparrow") (gtk_accel_path "/Transport/TransitionToRoll" "<%PRIMARY%>uparrow") +(gtk_accel_path "/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow") (gtk_accel_path "/Editor/select-next-route" "downarrow") (gtk_accel_path "/Transport/TransitionToReverse" "<%PRIMARY%>downarrow") +(gtk_accel_path "/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow") ;; keypad diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus index 96033d8b76..ef05f41f8a 100644 --- a/gtk2_ardour/ardour-sae.menus +++ b/gtk2_ardour/ardour-sae.menus @@ -251,6 +251,8 @@ + + diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index dcab5156ee..b062201297 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -336,6 +336,8 @@ + + diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 7052d32287..d5cc180d97 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -354,6 +354,8 @@ class Editor : public PublicEditor void scroll_tracks_down_line (); void scroll_tracks_up_line (); + void move_selected_tracks (bool up); + bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; } void prepare_for_cleanup (); void finish_cleanup (); @@ -525,7 +527,7 @@ class Editor : public PublicEditor void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false); void select_all_tracks (); - + bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false); void set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false); void set_selected_track_as_side_effect (bool force = false); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index a700b9e754..b119b4f213 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -301,6 +301,11 @@ Editor::register_actions () act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state)); ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), bind (mem_fun(*this, &Editor::move_selected_tracks), true)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), bind (mem_fun(*this, &Editor::move_selected_tracks), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), mem_fun(*this, &Editor::scroll_tracks_up)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "scroll-tracks-down", _("Scroll Tracks Down"), mem_fun(*this, &Editor::scroll_tracks_down)); diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index 6862425da5..9a355977de 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -614,3 +614,245 @@ Editor::foreach_time_axis_view (sigc::slot theslot) theslot (**i); } } + +static uint32_t +compute_new_key (uint32_t old_key, bool up, uint32_t distance, uint32_t limit) +{ + uint32_t new_key; + + if (up) { + if (old_key >= distance) { + new_key = old_key - distance; // towards top + } else { + new_key = old_key; // already at top + } + } else { + if (old_key >= limit - distance) { + new_key = old_key; // already at bottom + } else { + new_key = old_key + distance; // towards bottom + } + } + + return new_key; +} + +void +Editor::move_selected_tracks (bool up) +{ + if (selection->tracks.empty()) { + return; + } + + typedef pair > ViewRoute; + list view_routes; + vector neworder; + TreeModel::Children rows = route_display_model->children(); + TreeModel::Children::iterator ri; + + for (ri = rows.begin(); ri != rows.end(); ++ri) { + TimeAxisView* tv = (*ri)[route_display_columns.tv]; + boost::shared_ptr route = (*ri)[route_display_columns.route]; + + view_routes.push_back (ViewRoute (tv, route)); + } + + list::iterator trailing; + list::iterator leading; + + if (up) { + + trailing = view_routes.begin(); + leading = view_routes.begin(); + + ++leading; + + while (leading != view_routes.end()) { + if (selection->selected (leading->first)) { + view_routes.insert (trailing, ViewRoute (leading->first, leading->second)); + leading = view_routes.erase (leading); + } else { + ++leading; + ++trailing; + } + } + + } else { + + /* 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. + */ + + trailing = view_routes.end(); + leading = view_routes.end(); + + --leading; if (leading == view_routes.begin()) { return; } + --leading; + --trailing; + + while (1) { + + if (selection->selected (leading->first)) { + list::iterator tmp; + + /* need to insert *after* trailing, not *before* it, + which is what insert (iter, val) normally does. + */ + + tmp = trailing; + tmp++; + + view_routes.insert (tmp, ViewRoute (leading->first, leading->second)); + + /* can't use iter = cont.erase (iter); form here, because + we need iter to move backwards. + */ + + tmp = leading; + --tmp; + + bool done = false; + + if (leading == view_routes.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; + } + + view_routes.erase (leading); + + if (done) { + break; + } + + leading = tmp; + + } else { + if (leading == view_routes.begin()) { + break; + } + --leading; + --trailing; + } + }; + } + + for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) { + neworder.push_back (leading->second->order_key (_order_key)); + } + + route_display_model->reorder (neworder); +} + +#if 0 + vector > selected_block; + boost::shared_ptr target_unselected_route; + bool last_track_was_selected = false; + vector neworder; + TreeModel::Children rows = route_display_model->children(); + TreeModel::Children::iterator ri; + uint32_t old_key; + uint32_t new_key; + int n; + + /* preload "neworder" with the current order */ + + for (n = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++n) { + neworder.push_back (n); + } + + for (ri = rows.begin(); ri != rows.end(); ++ri) { + + TimeAxisView* tv = (*ri)[route_display_columns.tv]; + boost::shared_ptr route = (*ri)[route_display_columns.route]; + + if (selection->selected (tv)) { + + selected_block.push_back (route); + cerr << "--SAVE as SELECTED " << route->name() << endl; + last_track_was_selected = true; + continue; + + } else { + + if (!last_track_was_selected) { + /* keep moving through unselected tracks, but save this + one in case we need it later as the one that will + move *down* as the selected block moves up. + */ + target_unselected_route = route; + cerr << "--pre-SAVE as UNSELECTED " << route->name() << endl; + continue; + } + + last_track_was_selected = false; + + if (!up) { + /* this is the track immediately after a selected block, + and this is the one that will move *up* as + the selected block moves down. + */ + + target_unselected_route = route; + cerr << "--post-SAVE as UNSELECTED " << route->name() << endl; + } else { + cerr << "--(up) plan to use existing unselected target\n"; + } + } + + cerr << "TRANSITION: sel = " << selected_block.size() << " unsel = " << target_unselected_route << endl; + + /* transitioned between selected/not-selected */ + + uint32_t distance; + + for (vector >::iterator x = selected_block.begin(); x != selected_block.end(); ++x) { + old_key = (*x)->order_key (_order_key); + new_key = compute_new_key (old_key, up, 1, rows.size()); + neworder[new_key] = old_key; + cerr << "--SELECTED, reorder from " << old_key << " => " << new_key << endl; + } + + /* now move the unselected tracks in the opposite direction */ + + if (!selected_block.empty() && target_unselected_route) { + distance = selected_block.size(); + old_key = target_unselected_route->order_key (_order_key); + new_key = compute_new_key (old_key, !up, distance, rows.size()); + neworder[new_key] = old_key; + cerr << "--UNSELECTED, reorder from " << old_key << " => " << new_key << endl; + } + + selected_block.clear (); + target_unselected_route.reset (); + } + + cerr << "when done ... sel = " << selected_block.size() << " unsel = " << target_unselected_route << endl; + + if (!selected_block.empty() || target_unselected_route) { + + /* left over blocks */ + + uint32_t distance; + + for (vector >::iterator x = selected_block.begin(); x != selected_block.end(); ++x) { + old_key = (*x)->order_key (_order_key); + new_key = compute_new_key (old_key, up, 1, rows.size()); + neworder[new_key] = old_key; + cerr << "--SELECTED, reorder from " << old_key << " => " << new_key << endl; + } + + if (!selected_block.empty() && target_unselected_route) { + distance = selected_block.size(); + old_key = target_unselected_route->order_key (_order_key); + new_key = compute_new_key (old_key, !up, distance, rows.size()); + neworder[new_key] = old_key; + cerr << "--UNSELECTED, reorder from " << old_key << " => " << new_key << endl; + } + } + + route_display_model->reorder (neworder); +#endif diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in index ce704d1159..15beadc189 100644 --- a/gtk2_ardour/mnemonic-us.bindings.in +++ b/gtk2_ardour/mnemonic-us.bindings.in @@ -114,10 +114,12 @@ (gtk_accel_path "/Editor/step-tracks-up" "uparrow") (gtk_accel_path "/Transport/TransitionToRoll" "<%PRIMARY%>uparrow") (gtk_accel_path "/Editor/select-prev-route" "<%SECONDARY%>uparrow") +(gtk_accel_path "/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow") (gtk_accel_path "/Editor/step-tracks-down" "downarrow") (gtk_accel_path "/Transport/TransitionToReverse" "<%PRIMARY%>downarrow") (gtk_accel_path "/Editor/select-next-route" "<%SECONDARY%>downarrow") +(gtk_accel_path "/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow") (gtk_accel_path "/Editor/playhead-to-previous-region-boundary" "leftarrow") (gtk_accel_path "/Editor/tab-to-transient-backwards" "<%PRIMARY%>leftarrow")