advance compiling to the m*.cc point
[ardour.git] / gtk2_ardour / marker.cc
1 /*
2     Copyright (C) 2001 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <sigc++/bind.h>
22 #include <ardour/tempo.h>
23
24 #include "marker.h"
25 #include "public_editor.h"
26 #include "utils.h"
27 #include "canvas_impl.h"
28
29 #include "i18n.h"
30
31 Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, const string& annotation, 
32                 Type type, jack_nframes_t frame, bool handle_events)
33
34         : editor (ed), _type(type)
35 {
36         double label_offset = 0;
37
38         /* Shapes we use:
39
40           Mark:
41
42            (0,0) -> (6,0)
43              ^        |
44              |        V
45            (0,5)    (6,5)
46                \    / 
47                (3,10)
48
49
50            TempoMark:
51            MeterMark:
52
53                (3,0)
54               /      \
55            (0,5) -> (6,5)
56              ^        |
57              |        V
58            (0,10)<-(6,10)
59
60
61            Start:
62
63            0,0  -> 5,0 
64             |          \
65             |          10,5
66             |          /
67            0,10 -> 5,10
68
69            End:
70
71              5,0 -> 10,0
72              /       |
73            0,5       |
74              \       |
75              5,10 <-10,10
76
77              
78            TransportStart:
79
80              0,0->3,0
81               |    |
82               |    |
83               |    |
84               |   3,8 -> 7,8
85               |           |
86              0,11 ------ 7,11
87
88            TransportEnd:
89
90                       4,0->7,0
91                        |    |
92                        |    |
93                        |    |
94              0,8 ---- 4,8   |
95               |             |
96              0,11 -------- 7,11
97              
98
99              PunchIn:
100
101              0,0 ------> 8,0
102               |       /
103               |      /
104               |    4,5
105               |     |
106               |     |
107               |     |
108              0,11->4,11
109
110              PunchOut
111
112            0,0 -->-8,0
113             \       | 
114              \      |
115              4,5    |
116               |     |
117               |     |
118               |     |
119              4,11->8,11
120              
121            
122         */
123
124         switch (type) {
125         case Mark:
126                 points = new ArdourCanvas::Points ();
127
128                 points->push_back (Gnome::Art::Point (0.0, 0.0));
129                 points->push_back (Gnome::Art::Point (6.0, 0.0));
130                 points->push_back (Gnome::Art::Point (6.0, 5.0));
131                 points->push_back (Gnome::Art::Point (3.0, 10.0));              
132                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
133                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
134                 
135                 shift = 3;
136                 label_offset = 8.0;
137                 break;
138
139         case Tempo:
140         case Meter:
141
142                 points = new ArdourCanvas::Points ();
143                 points->push_back (Gnome::Art::Point (3.0, 0.0));
144                 points->push_back (Gnome::Art::Point (6.0, 5.0));               
145                 points->push_back (Gnome::Art::Point (6.0, 10.0));              
146                 points->push_back (Gnome::Art::Point (0.0, 10.0));              
147                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
148                 points->push_back (Gnome::Art::Point (3.0, 0.0));               
149
150                 shift = 3;
151                 label_offset = 8.0;
152                 break;
153
154         case Start:
155                 points = new ArdourCanvas::Points ();
156                 points->push_back (Gnome::Art::Point (0.0, 0.0)); 
157                 points->push_back (Gnome::Art::Point (5.0, 0.0));               
158                 points->push_back (Gnome::Art::Point (10.0, 5.0));              
159                 points->push_back (Gnome::Art::Point (5.0, 10.0));              
160                 points->push_back (Gnome::Art::Point (0.0, 10.0));              
161                 points->push_back (Gnome::Art::Point (0.0, 0.0));       
162
163                 shift = 10;
164                 label_offset = 12.0;
165                 break;
166
167         case End:
168                 points = new ArdourCanvas::Points ();
169                 points->push_back (Gnome::Art::Point (5.0, 0.0));
170                 points->push_back (Gnome::Art::Point (10.0, 0.0));              
171                 points->push_back (Gnome::Art::Point (10.0, 10.0));             
172                 points->push_back (Gnome::Art::Point (5.0, 10.0));              
173                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
174                 points->push_back (Gnome::Art::Point (5.0, 0.0));               
175                 
176                 shift = 0;
177                 label_offset = 12.0;
178                 break;
179
180         case LoopStart:
181                 points = new ArdourCanvas::Points ();
182                 points->push_back (Gnome::Art::Point (0.0, 0.0));
183                 points->push_back (Gnome::Art::Point (4.0, 0.0));               
184                 points->push_back (Gnome::Art::Point (4.0, 8.0));               
185                 points->push_back (Gnome::Art::Point (8.0, 8.0));               
186                 points->push_back (Gnome::Art::Point (8.0, 11.0));              
187                 points->push_back (Gnome::Art::Point (0.0, 11.0));              
188                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
189                 
190                 shift = 0;
191                 label_offset = 11.0;
192                 break;
193
194         case LoopEnd:
195                 points = new ArdourCanvas::Points ();
196                 points->push_back (Gnome::Art::Point (8.0,  0.0));
197                 points->push_back (Gnome::Art::Point (8.0, 11.0));      
198                 points->push_back (Gnome::Art::Point (0.0, 11.0));              
199                 points->push_back (Gnome::Art::Point (0.0, 8.0));
200                 points->push_back (Gnome::Art::Point (4.0, 8.0));
201                 points->push_back (Gnome::Art::Point (4.0, 0.0));       
202                 points->push_back (Gnome::Art::Point (8.0, 0.0));
203                 
204                 shift = 8;
205                 label_offset = 11.0;
206                 break;
207
208         case  PunchIn:
209                 points = new ArdourCanvas::Points ();
210                 points->push_back (Gnome::Art::Point (0.0, 0.0));
211                 points->push_back (Gnome::Art::Point (8.0, 0.0));               
212                 points->push_back (Gnome::Art::Point (4.0, 4.0));       
213                 points->push_back (Gnome::Art::Point (4.0, 11.0));      
214                 points->push_back (Gnome::Art::Point (0.0, 11.0));      
215                 points->push_back (Gnome::Art::Point (0.0, 0.0));       
216
217                 shift = 0;
218                 label_offset = 10.0;
219                 break;
220                 
221         case  PunchOut:
222                 points = new ArdourCanvas::Points ();
223                 points->push_back (Gnome::Art::Point (0.0, 0.0));
224                 points->push_back (Gnome::Art::Point (8.0, 0.0));               
225                 points->push_back (Gnome::Art::Point (8.0, 11.0));              
226                 points->push_back (Gnome::Art::Point (4.0, 11.0));              
227                 points->push_back (Gnome::Art::Point (4.0, 4.0));               
228                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
229
230                 shift = 8;
231                 label_offset = 11.0;
232                 break;
233                 
234         }
235
236         frame_position = frame;
237         unit_position = editor.frame_to_unit (frame);
238
239         /* adjust to properly locate the tip */
240
241         unit_position -= shift;
242
243         group = &parent;
244         group->set_property ("x", unit_position);
245         group->set_property ("y", 1.0);
246         // cerr << "set mark al points, nc = " << points->num_points << endl;
247         mark = new Polygon (*group);
248         mark->set_property ("points", points);
249         mark->set_property ("fill_color_rgba", rgba);
250         mark->set_property ("outline_color", Gdk::Color ("black"));
251
252         Pango::FontDescription font = get_font_for_style (N_("MarkerText"));
253
254         text = new Text (*group);
255         text->set_property ("text", annotation.c_str());
256         text->set_property ("x", label_offset);
257         text->set_property ("y", 0.0);
258         text->set_property ("fontdesc", font);
259         text->set_property ("anchor", Gtk::ANCHOR_NW);
260         text->set_property ("fill_color", Gdk::Color ("black"));
261
262         editor.ZoomChanged.connect (mem_fun (*this, &Marker::reposition));
263
264         mark->set_data ("marker", this);
265
266         if (handle_events) {
267                 group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
268         }
269
270 }
271
272 Marker::~Marker ()
273 {
274         /* destroying the parent group destroys its contents, namely any polygons etc. that we added */
275         delete text;
276         delete mark;
277         delete points;
278 }
279
280 ArdourCanvas::Item&
281 Marker::the_item() const
282 {
283         return *mark;
284 }
285
286 void
287 Marker::set_name (const string& name)
288 {
289         text->set_property ("text", name.c_str());
290 }
291
292 void
293 Marker::set_position (jack_nframes_t frame)
294 {
295         double new_unit_position = editor.frame_to_unit (frame);
296         new_unit_position -= shift;
297         group->move (new_unit_position - unit_position, 0.0);
298         frame_position = frame;
299         unit_position = new_unit_position;
300 }
301
302 void
303 Marker::reposition ()
304 {
305         set_position (frame_position);
306 }       
307
308 void
309 Marker::show ()
310 {
311         group->show();
312 }
313
314 void
315 Marker::hide ()
316 {
317         group->hide();
318 }
319
320 void
321 Marker::set_color_rgba (uint32_t color)
322 {
323         mark->set_property ("fill_color_rgba", color);
324 }
325
326 /***********************************************************************/
327
328 TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text, 
329                           ARDOUR::TempoSection& temp)
330         : Marker (editor, parent, rgba, text, Tempo, 0, false),
331           _tempo (temp)
332 {
333         set_position (_tempo.frame());
334         group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_tempo_marker_event), mark, this));
335 }
336
337 TempoMarker::~TempoMarker ()
338 {
339 }
340
341 /***********************************************************************/
342
343 MeterMarker::MeterMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text, 
344                           ARDOUR::MeterSection& m) 
345         : Marker (editor, parent, rgba, text, Meter, 0, false),
346           _meter (m)
347 {
348         set_position (_meter.frame());
349         group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_meter_marker_event), mark, this));
350 }
351
352 MeterMarker::~MeterMarker ()
353 {
354 }
355