X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_selection.cc;h=227eaa4a63247da4d083976930b16885bdbd7850;hb=6b1b72a247bf04c81292fc41af4f69c9b7f90379;hp=82c9020e9ae2bb8d882da68dbb4f5a5886ff2087;hpb=eb3f50e15c9f9ed1880c59fecd6f8b3edcc05820;p=ardour.git diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 82c9020e9a..227eaa4a63 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -30,6 +30,7 @@ #include "ardour/route_group.h" #include "ardour/selection.h" #include "ardour/session.h" +#include "ardour/vca.h" #include "editor.h" #include "editor_drag.h" @@ -190,6 +191,8 @@ Editor::set_selected_track_as_side_effect (Selection::Operation op) return; } + PBD::Unwinder uw (_editor_track_selection_change_without_scroll, true); + RouteGroup* group = NULL; if (clicked_routeview) { group = clicked_routeview->route()->route_group(); @@ -396,7 +399,7 @@ Editor::mapover_tracks (sigc::slot sl, TimeA RouteGroup* group = route_basis->route()->route_group(); - if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) { + if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id)) { /* the basis is a member of an active route group, with the appropriate properties; find other members */ @@ -440,7 +443,7 @@ Editor::mapover_tracks_with_unique_playlists (sigc::slotroute()->route_group(); // could be null, not a problem - if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) { + if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id)) { /* the basis is a member of an active route group, with the appropriate properties; find other members */ @@ -666,24 +669,24 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) } else if (op == Selection::Extend) { list results; - framepos_t last_frame; - framepos_t first_frame; + samplepos_t last_sample; + samplepos_t first_sample; bool same_track = false; /* 1. find the last selected regionview in the track that was clicked in */ - last_frame = 0; - first_frame = max_framepos; + last_sample = 0; + first_sample = max_samplepos; for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) { - if ((*x)->region()->last_frame() > last_frame) { - last_frame = (*x)->region()->last_frame(); + if ((*x)->region()->last_sample() > last_sample) { + last_sample = (*x)->region()->last_sample(); } - if ((*x)->region()->first_frame() < first_frame) { - first_frame = (*x)->region()->first_frame(); + if ((*x)->region()->first_sample() < first_sample) { + first_sample = (*x)->region()->first_sample(); } same_track = true; @@ -694,34 +697,34 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) /* 2. figure out the boundaries for our search for new objects */ - switch (clicked_regionview->region()->coverage (first_frame, last_frame)) { + switch (clicked_regionview->region()->coverage (first_sample, last_sample)) { case Evoral::OverlapNone: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); + if (last_sample < clicked_regionview->region()->first_sample()) { + first_sample = last_sample; + last_sample = clicked_regionview->region()->last_sample(); } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + last_sample = first_sample; + first_sample = clicked_regionview->region()->first_sample(); } break; case Evoral::OverlapExternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); + if (last_sample < clicked_regionview->region()->first_sample()) { + first_sample = last_sample; + last_sample = clicked_regionview->region()->last_sample(); } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + last_sample = first_sample; + first_sample = clicked_regionview->region()->first_sample(); } break; case Evoral::OverlapInternal: - if (last_frame < clicked_regionview->region()->first_frame()) { - first_frame = last_frame; - last_frame = clicked_regionview->region()->last_frame(); + if (last_sample < clicked_regionview->region()->first_sample()) { + first_sample = last_sample; + last_sample = clicked_regionview->region()->last_sample(); } else { - last_frame = first_frame; - first_frame = clicked_regionview->region()->first_frame(); + last_sample = first_sample; + first_sample = clicked_regionview->region()->first_sample(); } break; @@ -741,15 +744,15 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) */ - first_frame = clicked_regionview->region()->position(); - last_frame = clicked_regionview->region()->last_frame(); + first_sample = clicked_regionview->region()->position(); + last_sample = clicked_regionview->region()->last_sample(); for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { - if ((*i)->region()->position() < first_frame) { - first_frame = (*i)->region()->position(); + if ((*i)->region()->position() < first_sample) { + first_sample = (*i)->region()->position(); } - if ((*i)->region()->last_frame() + 1 > last_frame) { - last_frame = (*i)->region()->last_frame(); + if ((*i)->region()->last_sample() + 1 > last_sample) { + last_sample = (*i)->region()->last_sample(); } } } @@ -862,7 +865,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op) */ for (set::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) { - (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results); + (*t)->get_selectables (first_sample, last_sample, -1.0, -1.0, results); } /* 4. convert to a vector of regions */ @@ -980,34 +983,25 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* /*ev*/, StreamView* return true; } -struct SelectionOrderSorter { - bool operator() (TimeAxisView const * const a, TimeAxisView const * const b) const { - boost::shared_ptr sa = a->stripable (); - boost::shared_ptr sb = b->stripable (); - if (!sa && !sb) { - return a < b; - } - if (!sa) { - return false; - } - if (!sb) { - return true; - } - return sa->presentation_info().selection_cnt() < sb->presentation_info().selection_cnt(); - } -}; - void Editor::presentation_info_changed (PropertyChange const & what_changed) { + uint32_t n_tracks = 0; + uint32_t n_busses = 0; + uint32_t n_vcas = 0; + uint32_t n_routes = 0; + uint32_t n_stripables = 0; + /* We cannot ensure ordering of the handlers for * PresentationInfo::Changed, so we have to do everything in order * here, as a single handler. */ - for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - (*i)->set_selected (false); - (*i)->hide_selection (); + if (what_changed.contains (Properties::selected)) { + for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { + (*i)->set_selected (false); + (*i)->hide_selection (); + } } /* STEP 1: set the GUI selection state (in which TimeAxisViews for the @@ -1019,10 +1013,6 @@ Editor::presentation_info_changed (PropertyChange const & what_changed) /* STEP 2: update TimeAxisView's knowledge of their selected state */ - - PropertyChange pc; - pc.add (Properties::selected); - if (what_changed.contains (Properties::selected)) { StripableNotificationListPtr stripables (new StripableNotificationList); @@ -1032,7 +1022,7 @@ Editor::presentation_info_changed (PropertyChange const & what_changed) break; default: set_selected_mixer_strip (*(selection->tracks.back())); - if (!_track_selection_change_without_scroll) { + if (!_track_selection_change_without_scroll && !_editor_track_selection_change_without_scroll) { ensure_time_axis_view_is_visible (*(selection->tracks.back()), false); } break; @@ -1049,9 +1039,22 @@ Editor::presentation_info_changed (PropertyChange const & what_changed) continue; } + n_stripables++; + + if (boost::dynamic_pointer_cast ((*i).stripable)) { + n_tracks++; + n_routes++; + } else if (boost::dynamic_pointer_cast ((*i).stripable)) { + n_busses++; + n_routes++; + } else if (boost::dynamic_pointer_cast ((*i).stripable)) { + n_vcas++; + } + TimeAxisView* tav = dynamic_cast (av); if (!tav) { + assert (0); continue; /* impossible */ } @@ -1083,7 +1086,11 @@ Editor::presentation_info_changed (PropertyChange const & what_changed) stripables->push_back ((*i).stripable); } - ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty()); + ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, (n_stripables > 0)); + ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, (n_tracks > 0)); + ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, (n_busses > 0)); + ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, (n_routes > 0)); + ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, (n_vcas > 0)); sensitize_the_right_region_actions (false); @@ -1131,6 +1138,17 @@ Editor::presentation_info_changed (PropertyChange const & what_changed) } } +void +Editor::track_selection_changed () +{ + /* reset paste count, so the plaste location doesn't get incremented + * if we want to paste in the same place, but different track. */ + paste_count = 0; + + if ( _session->solo_selection_active() ) + play_solo_selection(false); +} + void Editor::time_selection_changed () { @@ -1164,7 +1182,7 @@ Editor::time_selection_changed () if (_session && !_drags->active()) { if (selection->time.length() != 0) { - _session->set_range_selection (selection->time.start(), selection->time.end_frame()); + _session->set_range_selection (selection->time.start(), selection->time.end_sample()); } else { _session->clear_range_selection (); } @@ -1229,7 +1247,7 @@ Editor::sensitize_the_right_region_actions (bool because_canvas_crossing) } } else { RegionSelection at_edit_point; - framepos_t const where = get_preferred_edit_position (Editing::EDIT_IGNORE_NONE, false, !within_track_canvas); + samplepos_t const where = get_preferred_edit_position (Editing::EDIT_IGNORE_NONE, false, !within_track_canvas); get_regions_at (at_edit_point, where, selection->tracks); if (!at_edit_point.empty()) { have_edit_point = true; @@ -1547,12 +1565,26 @@ Editor::region_selection_changed () if (_session) { if (!selection->regions.empty()) { - _session->set_object_selection (selection->regions.start(), selection->regions.end_frame()); + _session->set_object_selection (selection->regions.start(), selection->regions.end_sample()); } else { _session->clear_object_selection (); } } + if (_session->solo_selection_active()) { + play_solo_selection(false); + } + + /* set nudge button color */ + if (! get_regions_from_selection_and_entered().empty()) { + /* nudge regions */ + nudge_forward_button.set_name ("nudge button"); + nudge_backward_button.set_name ("nudge button"); + } else { + /* nudge marker or playhead */ + nudge_forward_button.set_name ("generic button"); + nudge_backward_button.set_name ("generic button"); + } } void @@ -1574,7 +1606,7 @@ Editor::select_all_in_track (Selection::Operation op) begin_reversible_selection_op (X_("Select All in Track")); - clicked_routeview->get_selectables (0, max_framepos, 0, DBL_MAX, touched); + clicked_routeview->get_selectables (0, max_samplepos, 0, DBL_MAX, touched); switch (op) { case Selection::Toggle: @@ -1637,7 +1669,7 @@ Editor::select_all_objects (Selection::Operation op) if ((*iter)->hidden()) { continue; } - (*iter)->get_selectables (0, max_framepos, 0, DBL_MAX, touched); + (*iter)->get_selectables (0, max_samplepos, 0, DBL_MAX, touched); } begin_reversible_selection_op (X_("select all")); @@ -1676,7 +1708,6 @@ Editor::invert_selection_in_track () void Editor::invert_selection () { - list touched; if (internal_editing()) { for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { @@ -1688,27 +1719,46 @@ Editor::invert_selection () return; } - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; + if (!selection->tracks.empty()) { + + TrackViewList inverted; + + for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { + if (!(*iter)->selected()) { + inverted.push_back (*iter); + } } - (*iter)->get_inverted_selectables (*selection, touched); - } - begin_reversible_selection_op (X_("Invert Selection")); - selection->set (touched); - commit_reversible_selection_op (); + begin_reversible_selection_op (X_("Invert Track Selection")); + selection->set (inverted); + commit_reversible_selection_op (); + + } else { + + list touched; + + for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { + if ((*iter)->hidden()) { + continue; + } + (*iter)->get_inverted_selectables (*selection, touched); + } + + begin_reversible_selection_op (X_("Invert ObjectSelection")); + selection->set (touched); + commit_reversible_selection_op (); + } } -/** @param start Start time in session frames. - * @param end End time in session frames. +/** @param start Start time in session samples. + * @param end End time in session samples. * @param top Top (lower) y limit in trackview coordinates (ie 0 at the top of the track view) * @param bottom Bottom (higher) y limit in trackview coordinates (ie 0 at the top of the track view) * @param preserve_if_selected true to leave the current selection alone if we're adding to the selection and all of the selectables * within the region are already selected. */ void -Editor::select_all_within (framepos_t start, framepos_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op, bool preserve_if_selected) +Editor::select_all_within (samplepos_t start, samplepos_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op, bool preserve_if_selected) { list found; @@ -1777,13 +1827,13 @@ Editor::set_selection_from_region () /* select range (this will clear the region selection) */ - selection->set (selection->regions.start(), selection->regions.end_frame()); + selection->set (selection->regions.start(), selection->regions.end_sample()); /* and select the tracks */ selection->set (tvl); - if (!get_smart_mode () || !mouse_mode == Editing::MouseObject) { + if (!get_smart_mode () || !(mouse_mode == Editing::MouseObject) ) { set_mouse_mode (Editing::MouseRange, false); } } @@ -1815,7 +1865,15 @@ void Editor::set_selection_from_range (Location& loc) { begin_reversible_selection_op (X_("set selection from range")); + selection->set (loc.start(), loc.end()); + + // if no tracks are selected, enable all tracks + // (_something_ has to be selected for any range selection, otherwise the user won't see anything) + if (selection->tracks.empty()) { + select_all_tracks(); + } + commit_reversible_selection_op (); if (!get_smart_mode () || mouse_mode != Editing::MouseObject) { @@ -1832,8 +1890,8 @@ Editor::select_all_selectables_using_time_selection () return; } - framepos_t start = selection->time[clicked_selection].start; - framepos_t end = selection->time[clicked_selection].end; + samplepos_t start = selection->time[clicked_selection].start; + samplepos_t end = selection->time[clicked_selection].end; if (end - start < 1) { return; @@ -1925,17 +1983,17 @@ Editor::select_all_selectables_using_loop() void Editor::select_all_selectables_using_cursor (EditorCursor *cursor, bool after) { - framepos_t start; - framepos_t end; + samplepos_t start; + samplepos_t end; list touched; if (after) { - start = cursor->current_frame(); - end = _session->current_end_frame(); + start = cursor->current_sample(); + end = _session->current_end_sample(); } else { - if (cursor->current_frame() > 0) { + if (cursor->current_sample() > 0) { start = 0; - end = cursor->current_frame() - 1; + end = cursor->current_sample() - 1; } else { return; } @@ -1978,13 +2036,13 @@ Editor::select_all_selectables_using_cursor (EditorCursor *cursor, bool after) void Editor::select_all_selectables_using_edit (bool after, bool from_context_menu) { - framepos_t start; - framepos_t end; + samplepos_t start; + samplepos_t end; list touched; if (after) { start = get_preferred_edit_position(EDIT_IGNORE_NONE, from_context_menu); - end = _session->current_end_frame(); + end = _session->current_end_sample(); } else { if ((end = get_preferred_edit_position(EDIT_IGNORE_NONE, from_context_menu)) > 1) { start = 0; @@ -2029,8 +2087,8 @@ Editor::select_all_selectables_using_edit (bool after, bool from_context_menu) void Editor::select_all_selectables_between (bool within) { - framepos_t start; - framepos_t end; + samplepos_t start; + samplepos_t end; list touched; if (!get_edit_op_range (start, end)) { @@ -2068,10 +2126,10 @@ Editor::select_all_selectables_between (bool within) void Editor::select_range_between () { - framepos_t start; - framepos_t end; + samplepos_t start; + samplepos_t end; - if ( !selection->time.empty() ) { + if (!selection->time.empty()) { selection->clear_time (); } @@ -2089,17 +2147,17 @@ Editor::select_range_between () } bool -Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const +Editor::get_edit_op_range (samplepos_t& start, samplepos_t& end) const { -// framepos_t m; +// samplepos_t m; // bool ignored; /* if an explicit range exists, use it */ - if ( (mouse_mode == MouseRange || get_smart_mode() ) && !selection->time.empty()) { + if ((mouse_mode == MouseRange || get_smart_mode()) && !selection->time.empty()) { /* we know that these are ordered */ start = selection->time.start(); - end = selection->time.end_frame(); + end = selection->time.end_sample(); return true; } else { start = 0; @@ -2107,7 +2165,7 @@ Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const return false; } -// if (!mouse_frame (m, ignored)) { +// if (!mouse_sample (m, ignored)) { // /* mouse is not in a canvas, try playhead+selected marker. // this is probably most true when using menus. // */ @@ -2117,7 +2175,7 @@ Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const // } // start = selection->markers.front()->position(); -// end = _session->audible_frame(); +// end = _session->audible_sample(); // } else { @@ -2126,10 +2184,10 @@ Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const // if (selection->markers.empty()) { // /* use mouse + playhead */ // start = m; -// end = _session->audible_frame(); +// end = _session->audible_sample(); // } else { // /* use playhead + selected marker */ -// start = _session->audible_frame(); +// start = _session->audible_sample(); // end = selection->markers.front()->position(); // } // break; @@ -2138,7 +2196,7 @@ Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const // /* use mouse + selected marker */ // if (selection->markers.empty()) { // start = m; -// end = _session->audible_frame(); +// end = _session->audible_sample(); // } else { // start = selection->markers.front()->position(); // end = m; @@ -2198,7 +2256,7 @@ Editor::deselect_all () } long -Editor::select_range (framepos_t s, framepos_t e) +Editor::select_range (samplepos_t s, samplepos_t e) { begin_reversible_selection_op (X_("Select Range")); selection->add (clicked_axisview);