Fly my pretties!
[ardour.git] / gtk2_ardour / region_selection.cc
1 #include <algorithm>
2
3 #include <ardour/audioregion.h>
4
5 #include "regionview.h"
6 #include "region_selection.h"
7
8 using namespace ARDOUR;
9 using namespace sigc;
10
11
12 bool 
13 AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionView* b) const
14 {
15         if (a == b) {
16                 return false;
17         } else {
18                 return a < b;
19         }
20 }
21
22 AudioRegionSelection::AudioRegionSelection ()
23 {
24         _current_start = 0;
25         _current_end = 0;
26 }
27
28 AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other)
29 {
30
31         for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
32                 add (*i, false);
33         }
34         _current_start = other._current_start;
35         _current_end = other._current_end;
36 }
37
38
39
40 AudioRegionSelection&
41 AudioRegionSelection::operator= (const AudioRegionSelection& other)
42 {
43         if (this != &other) {
44
45                 clear_all();
46                 
47                 for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
48                         add (*i, false);
49                 }
50
51                 _current_start = other._current_start;
52                 _current_end = other._current_end;
53         }
54
55         return *this;
56 }
57
58 void
59 AudioRegionSelection::clear_all()
60 {
61         clear();
62         _bylayer.clear();
63 }
64
65 bool AudioRegionSelection::contains (AudioRegionView* rv)
66 {
67         if (this->find (rv) != end()) {
68                 return true;
69         }
70         else {
71                 return false;
72         }
73         
74 }
75
76 void
77 AudioRegionSelection::add (AudioRegionView* rv, bool dosort)
78 {
79         if (this->find (rv) != end()) {
80                 /* we already have it */
81                 return;
82         }
83
84         rv->AudioRegionViewGoingAway.connect (slot (*this, &AudioRegionSelection::remove_it));
85
86         if (rv->region.first_frame() < _current_start || empty()) {
87                 _current_start = rv->region.first_frame();
88         }
89         
90         if (rv->region.last_frame() > _current_end || empty()) {
91                 _current_end = rv->region.last_frame();
92         }
93         
94         insert (rv);
95
96         // add to layer sorted list
97         add_to_layer (rv);
98         
99 }
100
101 void
102 AudioRegionSelection::remove_it (AudioRegionView *rv)
103 {
104         remove (rv);
105 }
106
107 bool
108 AudioRegionSelection::remove (AudioRegionView* rv)
109 {
110         AudioRegionSelection::iterator i;
111
112         if ((i = this->find (rv)) != end()) {
113
114                 erase (i);
115
116                 // remove from layer sorted list
117                 _bylayer.remove (rv);
118                 
119                 if (empty()) {
120
121                         _current_start = 0;
122                         _current_end = 0;
123
124                 } else {
125                         
126                         AudioRegion& region ((*i)->region);
127
128                         if (region.first_frame() == _current_start) {
129                                 
130                                 /* reset current start */
131                                 
132                                 jack_nframes_t ref = max_frames;
133                                 
134                                 for (i = begin (); i != end(); ++i) {
135                                         if (region.first_frame() < ref) {
136                                                 ref = region.first_frame();
137                                         }
138                                 }
139                                 
140                                 _current_start = ref;
141                                 
142                         }
143                         
144                         if (region.last_frame() == _current_end) {
145
146                                 /* reset current end */
147                                 
148                                 jack_nframes_t ref = 0;
149                                 
150                                 for (i = begin (); i != end(); ++i) {
151                                         if (region.first_frame() > ref) {
152                                                 ref = region.first_frame();
153                                         }
154                                 }
155                                 
156                                 _current_end = ref;
157                         }
158                 }
159
160                 return true;
161         }
162
163         return false;
164 }
165
166 void
167 AudioRegionSelection::add_to_layer (AudioRegionView * rv)
168 {
169         // insert it into layer sorted position
170
171         list<AudioRegionView*>::iterator i;
172
173         for (i = _bylayer.begin(); i != _bylayer.end(); ++i)
174         {
175                 if (rv->region.layer() < (*i)->region.layer()) {
176                         _bylayer.insert(i, rv);
177                         return;
178                 }
179         }
180
181         // insert at end if we get here
182         _bylayer.insert(i, rv);
183 }
184
185 struct RegionSortByTime {
186     bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
187             return a->region.position() < b->region.position();
188     }
189 };
190
191
192 void
193 AudioRegionSelection::by_position (list<AudioRegionView*>& foo) const
194 {
195         list<AudioRegionView*>::const_iterator i;
196         RegionSortByTime sorter;
197
198         for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
199                 foo.push_back (*i);
200         }
201
202         foo.sort (sorter);
203         return;
204 }