X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_routes.cc;h=025633b0909af55e7cf73aaf7dcc50ec99ae313a;hb=c028d223dff472bcadce3cbe9d000f20053de763;hp=10f2c3f5ed924945d2dd35bf4dc15539da30dbf3;hpb=580520b12f90251e38d94a1a5d6a199b76142b0b;p=ardour.git diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index 10f2c3f5ed..025633b090 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -53,6 +53,7 @@ using namespace std; using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; using namespace PBD; using namespace Gtk; using namespace Gtkmm2ext; @@ -70,6 +71,7 @@ EditorRoutes::EditorRoutes (Editor* e) , _ignore_reorder (false) , _no_redisplay (false) , _adding_routes (false) + , _route_deletion_in_progress (false) , _menu (0) , old_focus (0) , selection_countdown (0) @@ -222,6 +224,7 @@ EditorRoutes::EditorRoutes (Editor* e) _display.set_headers_visible (true); _display.get_selection()->set_mode (SELECTION_SINGLE); _display.get_selection()->set_select_function (sigc::mem_fun (*this, &EditorRoutes::selection_filter)); + _display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::selection_changed)); _display.set_reorderable (true); _display.set_name (X_("EditGroupList")); _display.set_rules_hint (true); @@ -270,7 +273,7 @@ EditorRoutes::EditorRoutes (Editor* e) active_col->set_fixed_width (30); active_col->set_alignment (ALIGN_CENTER); - _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::route_deleted)); + _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::row_deleted)); _model->signal_rows_reordered().connect (sigc::mem_fun (*this, &EditorRoutes::reordered)); _display.signal_button_press_event().connect (sigc::mem_fun (*this, &EditorRoutes::button_press), false); @@ -284,7 +287,7 @@ EditorRoutes::EditorRoutes (Editor* e) _display.set_enable_search (false); - Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_order_keys, this, _1), gui_context()); + Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_order_keys, this), gui_context()); } bool @@ -518,7 +521,6 @@ EditorRoutes::redisplay () /* show or hide the TimeAxisView */ if (visible) { position += tv->show_at (position, n, &_editor->edit_controls_vbox); - // SHOWTRACKS } else { tv->hide (); } @@ -546,18 +548,31 @@ EditorRoutes::redisplay () } void -EditorRoutes::route_deleted (Gtk::TreeModel::Path const &) +EditorRoutes::row_deleted (Gtk::TreeModel::Path const &) { - /* this happens as the second step of a DnD within the treeview as well - as when a row/route is actually deleted. + /* this happens as the second step of a DnD within the treeview, and + when a route is actually removed. we don't differentiate between + the two cases. + + note that the sync_orders_keys() step may not actually change any + RID's (e.g. the last track may be removed, so all other tracks keep + the same RID), which means that no redisplay would happen. so we + have to force a redisplay. */ + DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n"); + + DisplaySuspender ds; sync_order_keys_from_treeview (); } void EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/) { + /* reordering implies that RID's will change, so sync_order_keys() will + cause a redisplay. + */ + DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n"); sync_order_keys_from_treeview (); } @@ -569,6 +584,7 @@ EditorRoutes::visible_changed (std::string const & path) return; } + DisplaySuspender ds; TreeIter iter; if ((iter = _model->get_iter (path))) { @@ -599,10 +615,25 @@ EditorRoutes::active_changed (std::string const & path) void EditorRoutes::routes_added (list routes) { - TreeModel::Row row; PBD::Unwinder at (_adding_routes, true); - suspend_redisplay (); + bool from_scratch = (_model->children().size() == 0); + Gtk::TreeModel::Children::iterator insert_iter = _model->children().end(); + + for (Gtk::TreeModel::Children::iterator it = _model->children().begin(); it != _model->children().end(); ++it) { + boost::shared_ptr r = (*it)[_columns.route]; + + if (r->order_key() == (routes.front()->route()->order_key() + routes.size())) { + insert_iter = it; + break; + } + } + + if(!from_scratch) { + _editor->selection->tracks.clear(); + } + + DisplaySuspender ds; _display.set_model (Glib::RefPtr()); @@ -610,7 +641,7 @@ EditorRoutes::routes_added (list routes) boost::shared_ptr midi_trk = boost::dynamic_pointer_cast ((*x)->route()); - row = *(_model->append ()); + TreeModel::Row row = *(_model->insert (insert_iter)); row[_columns.text] = (*x)->route()->name(); row[_columns.visible] = (*x)->marked_for_display(); @@ -634,6 +665,10 @@ EditorRoutes::routes_added (list routes) row[_columns.solo_safe_state] = (*x)->route()->solo_safe(); row[_columns.name_editable] = true; + if (!from_scratch) { + _editor->selection->add(*x); + } + boost::weak_ptr wr ((*x)->route()); (*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context()); @@ -667,7 +702,6 @@ EditorRoutes::routes_added (list routes) update_input_active_display (); update_active_display (); - resume_redisplay (); _display.set_model (_model); /* now update route order keys from the treeview/track display order */ @@ -701,10 +735,13 @@ EditorRoutes::route_removed (TimeAxisView *tv) TreeModel::Children rows = _model->children(); TreeModel::Children::iterator ri; + bool found = false; for (ri = rows.begin(); ri != rows.end(); ++ri) { if ((*ri)[_columns.tv] == tv) { + PBD::Unwinder uw (_route_deletion_in_progress, true); _model->erase (ri); + found = true; break; } } @@ -759,7 +796,7 @@ EditorRoutes::update_visibility () TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - suspend_redisplay (); + DisplaySuspender ds (); for (i = rows.begin(); i != rows.end(); ++i) { TimeAxisView *tv = (*i)[_columns.tv]; @@ -770,8 +807,6 @@ EditorRoutes::update_visibility () */ sync_order_keys_from_treeview (); - - resume_redisplay (); } void @@ -810,7 +845,7 @@ EditorRoutes::show_track_in_display (TimeAxisView& tv) void EditorRoutes::reset_remote_control_ids () { - if (Config->get_remote_model() != EditorOrdered || !_session || _session->deletion_in_progress()) { + if (Config->get_remote_model() == UserOrdered || !_session || _session->deletion_in_progress()) { return; } @@ -839,7 +874,7 @@ EditorRoutes::reset_remote_control_ids () uint32_t new_rid = (visible ? rid : invisible_key--); if (new_rid != route->remote_control_id()) { - route->set_remote_control_id_from_order_key (EditorSort, new_rid); + route->set_remote_control_id_explicit (new_rid); rid_change = true; } @@ -885,20 +920,20 @@ EditorRoutes::sync_order_keys_from_treeview () boost::shared_ptr route = (*ri)[_columns.route]; bool visible = (*ri)[_columns.visible]; - uint32_t old_key = route->order_key (EditorSort); + uint32_t old_key = route->order_key (); if (order != old_key) { - route->set_order_key (EditorSort, order); + route->set_order_key (order); changed = true; } - if ((Config->get_remote_model() == EditorOrdered) && !route->is_master() && !route->is_monitor()) { + if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) { uint32_t new_rid = (visible ? rid : invisible_key--); if (new_rid != route->remote_control_id()) { - route->set_remote_control_id_from_order_key (EditorSort, new_rid); + route->set_remote_control_id_explicit (new_rid); rid_change = true; } @@ -913,7 +948,7 @@ EditorRoutes::sync_order_keys_from_treeview () if (changed) { /* tell the world that we changed the editor sort keys */ - _session->sync_order_keys (EditorSort); + _session->sync_order_keys (); } if (rid_change) { @@ -923,37 +958,17 @@ EditorRoutes::sync_order_keys_from_treeview () } void -EditorRoutes::sync_treeview_from_order_keys (RouteSortOrderKey src) +EditorRoutes::sync_treeview_from_order_keys () { - /* Some route order key(s) for `src' has been changed, make sure that + /* Some route order key(s) have been changed, make sure that we update out tree/list model and GUI to reflect the change. */ - if (!_session || _session->deletion_in_progress()) { + if (_ignore_reorder || !_session || _session->deletion_in_progress()) { return; } - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("editor sync model from order keys, src = %1\n", enum_2_string (src))); - - if (src == MixerSort) { - - if (!Config->get_sync_all_route_ordering()) { - /* mixer sort keys changed - we don't care */ - return; - } - - DEBUG_TRACE (DEBUG::OrderKeys, "reset editor order key to match mixer\n"); - - /* mixer sort keys were changed, update the editor sort - * keys since "sync mixer+editor order" is enabled. - */ - - boost::shared_ptr r = _session->get_routes (); - - for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { - (*i)->sync_order_keys (src); - } - } + DEBUG_TRACE (DEBUG::OrderKeys, "editor sync model from order keys.\n"); /* we could get here after either a change in the Mixer or Editor sort * order, but either way, the mixer order keys reflect the intended @@ -973,7 +988,7 @@ EditorRoutes::sync_treeview_from_order_keys (RouteSortOrderKey src) for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { boost::shared_ptr route = (*ri)[_columns.route]; - sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key (EditorSort))); + sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key ())); } SortByNewDisplayOrder cmp; @@ -1009,7 +1024,7 @@ EditorRoutes::hide_all_tracks (bool /*with_select*/) TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - suspend_redisplay (); + DisplaySuspender ds; for (i = rows.begin(); i != rows.end(); ++i) { @@ -1022,14 +1037,6 @@ EditorRoutes::hide_all_tracks (bool /*with_select*/) row[_columns.visible] = false; } - - resume_redisplay (); - - /* XXX this seems like a hack and half, but its not clear where to put this - otherwise. - */ - - //reset_scrolling_region (); } void @@ -1038,7 +1045,7 @@ EditorRoutes::set_all_tracks_visibility (bool yn) TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - suspend_redisplay (); + DisplaySuspender ds; for (i = rows.begin(); i != rows.end(); ++i) { @@ -1057,8 +1064,6 @@ EditorRoutes::set_all_tracks_visibility (bool yn) */ sync_order_keys_from_treeview (); - - resume_redisplay (); } void @@ -1067,7 +1072,7 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn) TreeModel::Children rows = _model->children(); TreeModel::Children::iterator i; - suspend_redisplay (); + DisplaySuspender ds; for (i = rows.begin(); i != rows.end(); ++i) { @@ -1119,8 +1124,6 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn) */ sync_order_keys_from_treeview (); - - resume_redisplay (); } void @@ -1295,27 +1298,46 @@ EditorRoutes::button_press (GdkEventButton* ev) //Scroll editor canvas to selected track if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - // Get the model row. Gtk::TreeModel::Row row = *_model->get_iter (path); - TimeAxisView *tv = row[_columns.tv]; - int y_pos = tv->y_position(); - - //Clamp the y pos so that we do not extend beyond the canvas full height. - if (_editor->_full_canvas_height - y_pos < _editor->_visible_canvas_height){ - y_pos = _editor->_full_canvas_height - _editor->_visible_canvas_height; - } - - //Only scroll to if the track is visible - if(y_pos != -1){ - _editor->reset_y_origin (y_pos); + if (tv) { + _editor->ensure_time_axis_view_is_visible (*tv, true); } } return false; } +void +EditorRoutes::selection_changed () +{ + if (_display.get_selection()->count_selected_rows() > 0) { + + TreeIter iter; + TreeView::Selection::ListHandle_Path rows = _display.get_selection()->get_selected_rows (); + TrackViewList selected; + + _editor->get_selection().clear_regions (); + + for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) { + + if ((iter = _model->get_iter (*i))) { + + TimeAxisView* tv = (*iter)[_columns.tv]; + selected.push_back (tv); + } + + } + + _editor->get_selection().set (selected); + _editor->ensure_time_axis_view_is_visible (*(selected.front()), true); + + } else { + _editor->get_selection().clear_tracks (); + } +} + bool EditorRoutes::selection_filter (Glib::RefPtr const &, TreeModel::Path const&, bool /*selected*/) { @@ -1339,18 +1361,17 @@ struct EditorOrderRouteSorter { /* everything else before master */ return false; } - return a->order_key (EditorSort) < b->order_key (EditorSort); + return a->order_key () < b->order_key (); } }; void EditorRoutes::initial_display () { - suspend_redisplay (); + DisplaySuspender ds; _model->clear (); if (!_session) { - resume_redisplay (); return; } @@ -1377,8 +1398,6 @@ EditorRoutes::initial_display () _editor->add_routes (r); } - - resume_redisplay (); } void @@ -1499,7 +1518,7 @@ EditorRoutes::move_selected_tracks (bool up) } for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) { - uint32_t order = leading->second->order_key (EditorSort); + uint32_t order = leading->second->order_key (); neworder.push_back (order); } @@ -1687,14 +1706,11 @@ EditorRoutes::show_tracks_with_regions_at_playhead () } } - suspend_redisplay (); + DisplaySuspender ds; TreeModel::Children rows = _model->children (); for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) { TimeAxisView* tv = (*i)[_columns.tv]; (*i)[_columns.visible] = (show.find (tv) != show.end()); } - - resume_redisplay (); } -