unify BarController with Slider/Pixfader.
[ardour.git] / gtk2_ardour / selection.cc
index 395ceda1696ad95aa00b814d292bca6bb473653f..4ebd3a583a706c089054342c2f83f7c863623090 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <algorithm>
 #include <sigc++/bind.h>
+
 #include "pbd/error.h"
 #include "pbd/stacktrace.h"
 
@@ -119,13 +120,15 @@ Selection::clear_objects ()
        clear_playlists ();
        clear_midi_notes ();
        clear_midi_regions ();
-       clear_markers ();
 }
 
 void
 Selection::clear_tracks ()
 {
        if (!tracks.empty()) {
+               for (TrackViewList::iterator x = tracks.begin(); x != tracks.end(); ++x) {
+                       (*x)->set_selected (false);
+               }
                tracks.clear ();
                if (!_no_tracks_changed) {
                        TracksChanged();
@@ -157,9 +160,6 @@ Selection::clear_regions ()
        if (!regions.empty()) {
                regions.clear_all ();
                RegionsChanged();
-               if (Config->get_link_region_and_track_selection()) {
-                       clear_tracks ();
-               }
        }
 }
 
@@ -223,6 +223,7 @@ void
 Selection::toggle (boost::shared_ptr<Playlist> pl)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        
        PlaylistSelection::iterator i;
 
@@ -250,8 +251,10 @@ Selection::toggle (TimeAxisView* track)
        TrackSelection::iterator i;
 
        if ((i = find (tracks.begin(), tracks.end(), track)) == tracks.end()) {
+               track->set_selected (true);
                tracks.push_back (track);
        } else {
+               track->set_selected (false);
                tracks.erase (i);
        }
 
@@ -264,6 +267,7 @@ void
 Selection::toggle (const MidiNoteSelection& midi_note_list)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        for (MidiNoteSelection::const_iterator i = midi_note_list.begin(); i != midi_note_list.end(); ++i) {
                toggle ((*i));
@@ -291,6 +295,7 @@ void
 Selection::toggle (RegionView* r)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        
        RegionSelection::iterator i;
 
@@ -307,6 +312,7 @@ void
 Selection::toggle (MidiRegionView* mrv)
 {
        clear_time();   //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        MidiRegionSelection::iterator i;
 
@@ -323,6 +329,7 @@ void
 Selection::toggle (vector<RegionView*>& r)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        RegionSelection::iterator i;
 
@@ -346,19 +353,20 @@ Selection::toggle (framepos_t start, framepos_t end)
 
        /* XXX this implementation is incorrect */
 
-       time.push_back (AudioRange (start, end, next_time_id++));
+       time.push_back (AudioRange (start, end, ++next_time_id));
        time.consolidate ();
        time.sort (cmp);
 
        TimeChanged ();
 
-       return next_time_id - 1;
+       return next_time_id;
 }
 
 void
 Selection::add (boost::shared_ptr<Playlist> pl)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        
        if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) {
                pl->use ();
@@ -371,6 +379,7 @@ void
 Selection::add (const list<boost::shared_ptr<Playlist> >& pllist)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        
        bool changed = false;
 
@@ -393,6 +402,9 @@ Selection::add (const TrackViewList& track_list)
        TrackViewList added = tracks.add (track_list);
 
        if (!added.empty()) {
+               for (TrackViewList::iterator x = added.begin(); x != added.end(); ++x) {
+                       (*x)->set_selected (true);
+               }
                if (!_no_tracks_changed) {
                        TracksChanged ();
                }
@@ -403,6 +415,7 @@ void
 Selection::add (TimeAxisView* track)
 {
        TrackViewList tr;
+       track->set_selected (true);
        tr.push_back (track);
        add (tr);
 }
@@ -411,6 +424,7 @@ void
 Selection::add (const MidiNoteSelection& midi_list)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        const MidiNoteSelection::const_iterator b = midi_list.begin();
        const MidiNoteSelection::const_iterator e = midi_list.end();
@@ -436,6 +450,7 @@ void
 Selection::add (vector<RegionView*>& v)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        /* XXX This method or the add (const RegionSelection&) needs to go
         */
@@ -445,9 +460,6 @@ Selection::add (vector<RegionView*>& v)
        for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
                if (find (regions.begin(), regions.end(), (*i)) == regions.end()) {
                        changed = regions.add ((*i));
-                       if (Config->get_link_region_and_track_selection() && changed) {
-                               add (&(*i)->get_time_axis_view());
-                       }
                }
        }
 
@@ -460,6 +472,7 @@ void
 Selection::add (const RegionSelection& rs)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        /* XXX This method or the add (const vector<RegionView*>&) needs to go
         */
@@ -469,9 +482,6 @@ Selection::add (const RegionSelection& rs)
        for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
                if (find (regions.begin(), regions.end(), (*i)) == regions.end()) {
                        changed = regions.add ((*i));
-                       if (Config->get_link_region_and_track_selection() && changed) {
-                               add (&(*i)->get_time_axis_view());
-                       }
                }
        }
 
@@ -484,15 +494,13 @@ void
 Selection::add (RegionView* r)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        if (find (regions.begin(), regions.end(), r) == regions.end()) {
                bool changed = regions.add (r);
-                if (Config->get_link_region_and_track_selection() && changed) {
-                        add (&r->get_time_axis_view());
-                }
-                if (changed) {
-                        RegionsChanged ();
-                }
+        if (changed) {
+            RegionsChanged ();
+        }
        }
 }
 
@@ -500,15 +508,11 @@ void
 Selection::add (MidiRegionView* mrv)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        if (find (midi_regions.begin(), midi_regions.end(), mrv) == midi_regions.end()) {
                midi_regions.push_back (mrv);
                /* XXX should we do this? */
-#if 0
-               if (Config->get_link_region_and_track_selection()) {
-                       add (&mrv->get_time_axis_view());
-               }
-#endif
                MidiRegionsChanged ();
        }
 }
@@ -522,13 +526,28 @@ Selection::add (framepos_t start, framepos_t end)
 
        /* XXX this implementation is incorrect */
 
-       time.push_back (AudioRange (start, end, next_time_id++));
+       time.push_back (AudioRange (start, end, ++next_time_id));
        time.consolidate ();
        time.sort (cmp);
 
        TimeChanged ();
 
-       return next_time_id - 1;
+       return next_time_id;
+}
+
+void
+Selection::move_time (framecnt_t distance)
+{
+       if (distance == 0) {
+               return;
+       }
+
+       for (list<AudioRange>::iterator i = time.begin(); i != time.end(); ++i) {
+               (*i).start += distance;
+               (*i).end += distance;
+       }
+
+       TimeChanged ();
 }
 
 void
@@ -557,6 +576,7 @@ void
 Selection::add (boost::shared_ptr<Evoral::ControlList> cl)
 {
        clear_time();  //enforce object/range exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        boost::shared_ptr<ARDOUR::AutomationList> al
                = boost::dynamic_pointer_cast<ARDOUR::AutomationList>(cl);
@@ -575,6 +595,7 @@ Selection::remove (TimeAxisView* track)
 {
        list<TimeAxisView*>::iterator i;
        if ((i = find (tracks.begin(), tracks.end(), track)) != tracks.end()) {
+               track->set_selected (false);
                tracks.erase (i);
                if (!_no_tracks_changed) {
                        TracksChanged();
@@ -582,15 +603,6 @@ Selection::remove (TimeAxisView* track)
        }
 }
 
-void
-Selection::remove (ControlPoint* p)
-{
-       PointSelection::iterator i = find (points.begin(), points.end(), p);
-       if (i != points.end ()) {
-               points.erase (i);
-       }
-}
-
 void
 Selection::remove (const TrackViewList& track_list)
 {
@@ -600,6 +612,7 @@ Selection::remove (const TrackViewList& track_list)
 
                TrackViewList::iterator x = find (tracks.begin(), tracks.end(), *i);
                if (x != tracks.end()) {
+                       (*i)->set_selected (false);
                        tracks.erase (x);
                        changed = true;
                }
@@ -612,6 +625,15 @@ Selection::remove (const TrackViewList& track_list)
        }
 }
 
+void
+Selection::remove (ControlPoint* p)
+{
+       PointSelection::iterator i = find (points.begin(), points.end(), p);
+       if (i != points.end ()) {
+               points.erase (i);
+       }
+}
+
 void
 Selection::remove (const MidiNoteSelection& midi_list)
 {
@@ -681,10 +703,6 @@ Selection::remove (RegionView* r)
        if (regions.remove (r)) {
                RegionsChanged ();
        }
-
-       if (Config->get_link_region_and_track_selection() && !regions.involves (r->get_time_axis_view())) {
-               remove (&r->get_time_axis_view());
-       }
 }
 
 void
@@ -696,13 +714,6 @@ Selection::remove (MidiRegionView* mrv)
                midi_regions.erase (x);
                MidiRegionsChanged ();
        }
-
-#if 0
-       /* XXX fix this up ? */
-       if (Config->get_link_region_and_track_selection() && !regions.involves (r->get_time_axis_view())) {
-               remove (&r->get_time_axis_view());
-       }
-#endif
 }
 
 
@@ -741,6 +752,7 @@ Selection::remove (boost::shared_ptr<ARDOUR::AutomationList> ac)
 void
 Selection::set (TimeAxisView* track)
 {
+       clear_objects();  //enforce object/range exclusivity
        clear_tracks ();
        add (track);
 }
@@ -748,6 +760,7 @@ Selection::set (TimeAxisView* track)
 void
 Selection::set (const TrackViewList& track_list)
 {
+       clear_objects();  //enforce object/range exclusivity
        clear_tracks ();
        add (track_list);
 }
@@ -756,6 +769,7 @@ void
 Selection::set (const MidiNoteSelection& midi_list)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects ();
        add (midi_list);
 }
@@ -764,6 +778,7 @@ void
 Selection::set (boost::shared_ptr<Playlist> playlist)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects ();
        add (playlist);
 }
@@ -780,6 +795,7 @@ void
 Selection::set (const RegionSelection& rs)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects();
        regions = rs;
        RegionsChanged(); /* EMIT SIGNAL */
@@ -789,44 +805,27 @@ void
 Selection::set (MidiRegionView* mrv)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects ();
        add (mrv);
 }
 
 void
-Selection::set (RegionView* r, bool also_clear_tracks)
+Selection::set (RegionView* r, bool /*also_clear_tracks*/)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects ();
-       if (also_clear_tracks && !Config->get_link_region_and_track_selection()) {
-               /* clear_regions() will have done this if the link preference
-                * is enabled
-                */
-               clear_tracks ();
-       }
        add (r);
 }
 
 void
 Selection::set (vector<RegionView*>& v)
 {
-       bool had_regions = !regions.empty();
-
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects();
 
-       if (Config->get_link_region_and_track_selection()) {
-               if (had_regions) {
-                       /* there were regions before, so we're changing the
-                        * region selection (likely), thus link region/track
-                        * selection. relevant tracks will get selected
-                        * as we ::add() below.
-                        */
-                       clear_tracks ();
-                       // make sure to deselect any automation selections
-                       clear_points();
-               }
-       }
        add (v);
 }
 
@@ -844,7 +843,7 @@ Selection::set (framepos_t start, framepos_t end)
        }
 
        if (time.empty()) {
-               time.push_back (AudioRange (start, end, next_time_id++));
+               time.push_back (AudioRange (start, end, ++next_time_id));
        } else {
                /* reuse the first entry, and remove all the rest */
 
@@ -880,7 +879,7 @@ Selection::set_preserving_all_ranges (framepos_t start, framepos_t end)
        }
 
        if (time.empty ()) {
-               time.push_back (AudioRange (start, end, next_time_id++));
+               time.push_back (AudioRange (start, end, ++next_time_id));
        } else {
                time.sort (AudioRangeComparator ());
                time.front().start = start;
@@ -896,6 +895,7 @@ void
 Selection::set (boost::shared_ptr<Evoral::ControlList> ac)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects();
        
        add (ac);
@@ -910,7 +910,7 @@ Selection::selected (Marker* m)
 bool
 Selection::selected (TimeAxisView* tv)
 {
-       return find (tracks.begin(), tracks.end(), tv) != tracks.end();
+       return tv->get_selected ();
 }
 
 bool
@@ -954,6 +954,7 @@ void
 Selection::toggle (ControlPoint* cp)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        cp->set_selected (!cp->get_selected ());
        PointSelection::iterator i = find (points.begin(), points.end(), cp);
@@ -970,6 +971,7 @@ void
 Selection::toggle (vector<ControlPoint*> const & cps)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
                toggle (*i);
@@ -980,6 +982,7 @@ void
 Selection::toggle (list<Selectable*> const & selectables)
 {
        clear_time();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        
        RegionView* rv;
        ControlPoint* cp;
@@ -1012,12 +1015,9 @@ void
 Selection::set (list<Selectable*> const & selectables)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
        clear_objects ();
 
-       if (Config->get_link_region_and_track_selection ()) {
-               clear_tracks ();
-       }
-
        add (selectables);
 }
 
@@ -1025,6 +1025,7 @@ void
 Selection::add (PointSelection const & s)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        for (PointSelection::const_iterator i = s.begin(); i != s.end(); ++i) {
                points.push_back (*i);
@@ -1035,6 +1036,7 @@ void
 Selection::add (list<Selectable*> const & selectables)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        RegionView* rv;
        ControlPoint* cp;
@@ -1076,6 +1078,7 @@ void
 Selection::add (ControlPoint* cp)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        cp->set_selected (true);
        points.push_back (cp);
@@ -1086,6 +1089,7 @@ void
 Selection::add (vector<ControlPoint*> const & cps)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        for (vector<ControlPoint*>::const_iterator i = cps.begin(); i != cps.end(); ++i) {
                (*i)->set_selected (true);
@@ -1098,6 +1102,7 @@ void
 Selection::set (ControlPoint* cp)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        if (cp->get_selected()) {
                return;
@@ -1115,7 +1120,8 @@ void
 Selection::set (Marker* m)
 {
        clear_time ();  //enforce region/object exclusivity
-       clear_objects();
+       clear_tracks();  //enforce object/track exclusivity
+       markers.clear ();
 
        add (m);
 }
@@ -1123,8 +1129,6 @@ Selection::set (Marker* m)
 void
 Selection::toggle (Marker* m)
 {
-       clear_time ();  //enforce region/object exclusivity
-
        MarkerSelection::iterator i;
 
        if ((i = find (markers.begin(), markers.end(), m)) == markers.end()) {
@@ -1149,6 +1153,7 @@ void
 Selection::add (Marker* m)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        if (find (markers.begin(), markers.end(), m) == markers.end()) {
                markers.push_back (m);
@@ -1160,6 +1165,7 @@ void
 Selection::add (const list<Marker*>& m)
 {
        clear_time ();  //enforce region/object exclusivity
+       clear_tracks();  //enforce object/track exclusivity
 
        markers.insert (markers.end(), m.begin(), m.end());
        markers.sort ();