mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-26 16:37:44 +01:00
add move-selected-tracks-{up,down} commands
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3879 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
c021a56672
commit
0d173fdccd
7 changed files with 258 additions and 1 deletions
|
|
@ -140,8 +140,10 @@
|
|||
|
||||
(gtk_accel_path "<Actions>/Editor/select-prev-route" "uparrow")
|
||||
(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow")
|
||||
(gtk_accel_path "<Actions>/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow")
|
||||
(gtk_accel_path "<Actions>/Editor/select-next-route" "downarrow")
|
||||
(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow")
|
||||
(gtk_accel_path "<Actions>/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow")
|
||||
|
||||
;; keypad
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,8 @@
|
|||
<menuitem action='zoom-to-region'/>
|
||||
<menuitem action='toggle-zoom'/>
|
||||
</menu>
|
||||
<menu action="move-selected-tracks-up"/>
|
||||
<menu action="move-selected-tracks-down"/>
|
||||
<menu action="ScrollMenu">
|
||||
<menuitem action='scroll-tracks-down'/>
|
||||
<menuitem action='scroll-tracks-up'/>
|
||||
|
|
|
|||
|
|
@ -336,6 +336,8 @@
|
|||
<menuitem action="toggle-cd-marker-ruler"/>
|
||||
<menuitem action="toggle-marker-ruler"/>
|
||||
</menu>
|
||||
<menu action="move-selected-tracks-up"/>
|
||||
<menu action="move-selected-tracks-down"/>
|
||||
<menu action="ScrollMenu">
|
||||
<menuitem action='scroll-tracks-down'/>
|
||||
<menuitem action='scroll-tracks-up'/>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -614,3 +614,245 @@ Editor::foreach_time_axis_view (sigc::slot<void,TimeAxisView&> 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<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
|
||||
list<ViewRoute> view_routes;
|
||||
vector<int> 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> route = (*ri)[route_display_columns.route];
|
||||
|
||||
view_routes.push_back (ViewRoute (tv, route));
|
||||
}
|
||||
|
||||
list<ViewRoute>::iterator trailing;
|
||||
list<ViewRoute>::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<ViewRoute>::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<boost::shared_ptr<Route> > selected_block;
|
||||
boost::shared_ptr<Route> target_unselected_route;
|
||||
bool last_track_was_selected = false;
|
||||
vector<int> 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> 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<boost::shared_ptr<Route> >::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<boost::shared_ptr<Route> >::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
|
||||
|
|
|
|||
|
|
@ -114,10 +114,12 @@
|
|||
(gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
|
||||
(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow")
|
||||
(gtk_accel_path "<Actions>/Editor/select-prev-route" "<%SECONDARY%>uparrow")
|
||||
(gtk_accel_path "<Actions>/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow")
|
||||
|
||||
(gtk_accel_path "<Actions>/Editor/step-tracks-down" "downarrow")
|
||||
(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow")
|
||||
(gtk_accel_path "<Actions>/Editor/select-next-route" "<%SECONDARY%>downarrow")
|
||||
(gtk_accel_path "<Actions>/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow")
|
||||
|
||||
(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "leftarrow")
|
||||
(gtk_accel_path "<Actions>/Editor/tab-to-transient-backwards" "<%PRIMARY%>leftarrow")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue