79ae58a98d02cccd9daedd4939b20c40ca9e237b
[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 <ardour/tempo.h>
22
23 #include "marker.h"
24 #include "public_editor.h"
25 #include "canvas-simpleline.h"
26 #include "utils.h"
27
28 #include "i18n.h"
29
30 Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, const string& annotation, 
31                 Type type, gint (*callback)(ArdourCanvas::Item *, GdkEvent *, gpointer), jack_nframes_t frame)
32
33         : editor (ed), _type(type)
34 {
35         double label_offset = 0;
36
37         /* Shapes we use:
38
39           Mark:
40
41            (0,0) -> (6,0)
42              ^        |
43              |        V
44            (0,5)    (6,5)
45                \    / 
46                (3,10)
47
48
49            TempoMark:
50            MeterMark:
51
52                (3,0)
53               /      \
54            (0,5) -> (6,5)
55              ^        |
56              |        V
57            (0,10)<-(6,10)
58
59
60            Start:
61
62            0,0  -> 5,0 
63             |          \
64             |          10,5
65             |          /
66            0,10 -> 5,10
67
68            End:
69
70              5,0 -> 10,0
71              /       |
72            0,5       |
73              \       |
74              5,10 <-10,10
75
76              
77            TransportStart:
78
79              0,0->3,0
80               |    |
81               |    |
82               |    |
83               |   3,8 -> 7,8
84               |           |
85              0,11 ------ 7,11
86
87            TransportEnd:
88
89                       4,0->7,0
90                        |    |
91                        |    |
92                        |    |
93              0,8 ---- 4,8   |
94               |             |
95              0,11 -------- 7,11
96              
97
98              PunchIn:
99
100              0,0 ------> 8,0
101               |       /
102               |      /
103               |    4,5
104               |     |
105               |     |
106               |     |
107              0,11->4,11
108
109              PunchOut
110
111            0,0 -->-8,0
112             \       | 
113              \      |
114              4,5    |
115               |     |
116               |     |
117               |     |
118              4,11->8,11
119              
120            
121         */
122
123         switch (type) {
124         case Mark:
125                 points = new ArdourCanvas::Points ();
126
127                 points->push_back (Gnome::Art::Point (0.0, 0.0));
128                 points->push_back (Gnome::Art::Point (6.0, 0.0));
129                 points->push_back (Gnome::Art::Point (6.0, 5.0));
130                 points->push_back (Gnome::Art::Point (3.0, 10.0));              
131                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
132                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
133                 
134                 shift = 3;
135                 label_offset = 8.0;
136                 break;
137
138         case Tempo:
139         case Meter:
140
141                 points = new ArdourCanvas::Points ();
142                 points->push_back (Gnome::Art::Point (3.0, 0.0));
143                 points->push_back (Gnome::Art::Point (6.0, 5.0));               
144                 points->push_back (Gnome::Art::Point (6.0, 10.0));              
145                 points->push_back (Gnome::Art::Point (0.0, 10.0));              
146                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
147                 points->push_back (Gnome::Art::Point (3.0, 0.0));               
148
149                 shift = 3;
150                 label_offset = 8.0;
151                 break;
152
153         case Start:
154                 points = new ArdourCanvas::Points ();
155                 points->push_back (Gnome::Art::Point (0.0, 0.0)); 
156                 points->push_back (Gnome::Art::Point (5.0, 0.0));               
157                 points->push_back (Gnome::Art::Point (10.0, 5.0));              
158                 points->push_back (Gnome::Art::Point (5.0, 10.0));              
159                 points->push_back (Gnome::Art::Point (0.0, 10.0));              
160                 points->push_back (Gnome::Art::Point (0.0, 0.0));       
161
162                 shift = 10;
163                 label_offset = 12.0;
164                 break;
165
166         case End:
167                 points = new ArdourCanvas::Points ();
168                 points->push_back (Gnome::Art::Point (5.0, 0.0));
169                 points->push_back (Gnome::Art::Point (10.0, 0.0));              
170                 points->push_back (Gnome::Art::Point (10.0, 10.0));             
171                 points->push_back (Gnome::Art::Point (5.0, 10.0));              
172                 points->push_back (Gnome::Art::Point (0.0, 5.0));               
173                 points->push_back (Gnome::Art::Point (5.0, 0.0));               
174                 
175                 shift = 0;
176                 label_offset = 12.0;
177                 break;
178
179         case LoopStart:
180                 points = new ArdourCanvas::Points ();
181                 points->push_back (Gnome::Art::Point (0.0, 0.0));
182                 points->push_back (Gnome::Art::Point (4.0, 0.0));               
183                 points->push_back (Gnome::Art::Point (4.0, 8.0));               
184                 points->push_back (Gnome::Art::Point (8.0, 8.0));               
185                 points->push_back (Gnome::Art::Point (8.0, 11.0));              
186                 points->push_back (Gnome::Art::Point (0.0, 11.0));              
187                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
188                 
189                 shift = 0;
190                 label_offset = 11.0;
191                 break;
192
193         case LoopEnd:
194                 points = new ArdourCanvas::Points ();
195                 points->push_back (Gnome::Art::Point (8.0,  0.0));
196                 points->push_back (Gnome::Art::Point (8.0, 11.0));      
197                 points->push_back (Gnome::Art::Point (0.0, 11.0));              
198                 points->push_back (Gnome::Art::Point (0.0, 8.0));
199                 points->push_back (Gnome::Art::Point (4.0, 8.0));
200                 points->push_back (Gnome::Art::Point (4.0, 0.0));       
201                 points->push_back (Gnome::Art::Point (8.0, 0.0));
202                 
203                 shift = 8;
204                 label_offset = 11.0;
205                 break;
206
207         case  PunchIn:
208                 points = new ArdourCanvas::Points ();
209                 points->push_back (Gnome::Art::Point (0.0, 0.0));
210                 points->push_back (Gnome::Art::Point (8.0, 0.0));               
211                 points->push_back (Gnome::Art::Point (4.0, 4.0));       
212                 points->push_back (Gnome::Art::Point (4.0, 11.0));      
213                 points->push_back (Gnome::Art::Point (0.0, 11.0));      
214                 points->push_back (Gnome::Art::Point (0.0, 0.0));       
215
216                 shift = 0;
217                 label_offset = 10.0;
218                 break;
219                 
220         case  PunchOut:
221                 points = new ArdourCanvas::Points ();
222                 points->push_back (Gnome::Art::Point (0.0, 0.0));
223                 points->push_back (Gnome::Art::Point (8.0, 0.0));               
224                 points->push_back (Gnome::Art::Point (8.0, 11.0));              
225                 points->push_back (Gnome::Art::Point (4.0, 11.0));              
226                 points->push_back (Gnome::Art::Point (4.0, 4.0));               
227                 points->push_back (Gnome::Art::Point (0.0, 0.0));               
228
229                 shift = 8;
230                 label_offset = 11.0;
231                 break;
232                 
233         }
234
235         frame_position = frame;
236         unit_position = editor.frame_to_unit (frame);
237
238         /* adjust to properly locate the tip */
239
240         unit_position -= shift;
241
242         group = &parent;
243         group->set_property ("x", unit_position);
244         group->set_property ("y", 1.0);
245         // cerr << "set mark al points, nc = " << points->num_points << endl;
246         mark = new ArdourCanvas::Polygon (*group);
247         mark->set_property ("points", points);
248         mark->set_property ("fill_color_rgba", rgba);
249         mark->set_property ("outline_color", Gdk::Color ("black"));
250
251         Pango::FontDescription font = get_font_for_style (N_("MarkerText"));
252
253         text = new ArdourCanvas::Text (*group);
254         text->set_property ("text", annotation.c_str());
255         text->set_property ("x", label_offset);
256         text->set_property ("y", 0.0);
257         text->set_property ("fontdesc", font);
258         text->set_property ("anchor", Gtk::ANCHOR_NW);
259         text->set_property ("fill_color", Gdk::Color ("black"));
260
261         group->signal_event().connect() (bind (mem_fun (editor, &PublicEditor::reposition), group, this));
262 }
263
264 Marker::~Marker ()
265 {
266         /* destroying the group destroys its contents */
267         delete text;
268         delete mark;
269         delete points;
270 }
271
272 void
273 Marker::set_name (const string& name)
274 {
275         text->set_property ("text", name.c_str());
276 }
277
278 void
279 Marker::set_position (jack_nframes_t frame)
280 {
281         double new_unit_position = editor.frame_to_unit (frame);
282         new_unit_position -= shift;
283         group->move (new_unit_position - unit_position, 0.0);
284         frame_position = frame;
285         unit_position = new_unit_position;
286 }
287
288 void
289 Marker::reposition ()
290 {
291         set_position (frame_position);
292 }       
293
294 void
295 Marker::show ()
296 {
297         group->show();
298 }
299
300 void
301 Marker::hide ()
302 {
303         group->hide();
304 }
305
306 void
307 Marker::set_color_rgba (uint32_t color)
308 {
309         mark->set_property ("fill_color_rgba", color);
310 }
311
312 /***********************************************************************/
313
314 TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text, 
315                           ARDOUR::TempoSection& temp, 
316                           gint (*callback)(ArdourCanvas::Item *, GdkEvent *, gpointer))
317         : Marker (editor, parent, rgba, text, Tempo, callback, 0),
318           _tempo (temp)
319 {
320         set_position (_tempo.frame());
321         group->set_data ("tempo_marker", this);
322 }
323
324 TempoMarker::~TempoMarker ()
325 {
326 }
327
328 /***********************************************************************/
329
330 MeterMarker::MeterMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text, 
331                           ARDOUR::MeterSection& m, 
332                           gint (*callback)(ArdourCanvas::Item *, GdkEvent *, gpointer))
333         : Marker (editor, parent, rgba, text, Meter, callback, 0),
334           _meter (m)
335 {
336         set_position (_meter.frame());
337         gtk_object_set_data (GTK_OBJECT(group), "meter_marker", this);
338 }
339
340 MeterMarker::~MeterMarker ()
341 {
342 }