Initial import of gtk2_ardour.
[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, GtkCanvasGroup *parent, guint32 rgba, const string& annotation, 
31                 Type type, gint (*callback)(GtkCanvasItem *, 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 = gtk_canvas_points_new (6);
126
127                 points->coords[0] = 0.0;
128                 points->coords[1] = 0.0;
129                 
130                 points->coords[2] = 6.0;
131                 points->coords[3] = 0.0;
132                 
133                 points->coords[4] = 6.0;
134                 points->coords[5] = 5.0;
135                 
136                 points->coords[6] = 3.0;
137                 points->coords[7] = 10.0;
138                 
139                 points->coords[8] = 0.0;
140                 points->coords[9] = 5.0;
141                 
142                 points->coords[10] = 0.0;
143                 points->coords[11] = 0.0;
144                 
145                 shift = 3;
146                 label_offset = 8.0;
147                 break;
148
149         case Tempo:
150         case Meter:
151                 points = gtk_canvas_points_new (6);
152
153                 points->coords[0] = 3.0;
154                 points->coords[1] = 0.0;
155                 
156                 points->coords[2] = 6.0;
157                 points->coords[3] = 5.0;
158                 
159                 points->coords[4] = 6.0;
160                 points->coords[5] = 10.0;
161                 
162                 points->coords[6] = 0.0;
163                 points->coords[7] = 10.0;
164                 
165                 points->coords[8] = 0.0;
166                 points->coords[9] = 5.0;
167                 
168                 points->coords[10] = 3.0;
169                 points->coords[11] = 0.0;
170                 
171                 shift = 3;
172                 label_offset = 8.0;
173                 break;
174
175         case Start:
176                 points = gtk_canvas_points_new (6);
177
178                 points->coords[0] = 0.0;
179                 points->coords[1] = 0.0;
180                 
181                 points->coords[2] = 5.0;
182                 points->coords[3] = 0.0;
183                 
184                 points->coords[4] = 10.0;
185                 points->coords[5] = 5.0;
186                 
187                 points->coords[6] = 5.0;
188                 points->coords[7] = 10.0;
189                 
190                 points->coords[8] = 0.0;
191                 points->coords[9] = 10.0;
192                 
193                 points->coords[10] = 0.0;
194                 points->coords[11] = 0.0;
195                 
196                 shift = 10;
197                 label_offset = 12.0;
198                 break;
199
200         case End:
201                 points = gtk_canvas_points_new (6);
202
203                 points->coords[0] = 5.0;
204                 points->coords[1] = 0.0;
205                 
206                 points->coords[2] = 10.0;
207                 points->coords[3] = 0.0;
208                 
209                 points->coords[4] = 10.0;
210                 points->coords[5] = 10.0;
211                 
212                 points->coords[6] = 5.0;
213                 points->coords[7] = 10.0;
214                 
215                 points->coords[8] = 0.0;
216                 points->coords[9] = 5.0;
217                 
218                 points->coords[10] = 5.0;
219                 points->coords[11] = 0.0;
220                 
221                 shift = 0;
222                 label_offset = 12.0;
223                 break;
224
225         case LoopStart:
226                 points = gtk_canvas_points_new (7);
227
228                 points->coords[0] = 0.0;
229                 points->coords[1] = 0.0;
230                 
231                 points->coords[2] = 4.0;
232                 points->coords[3] = 0.0;
233                 
234                 points->coords[4] = 4.0;
235                 points->coords[5] = 8.0;
236                 
237                 points->coords[6] = 8.0;
238                 points->coords[7] = 8.0;
239                 
240                 points->coords[8] = 8.0;
241                 points->coords[9] = 11.0;
242                 
243                 points->coords[10] = 0.0;
244                 points->coords[11] = 11.0;
245                 
246                 points->coords[12] = 0.0;
247                 points->coords[13] = 0.0;
248                 
249                 shift = 0;
250                 label_offset = 11.0;
251                 break;
252
253         case LoopEnd:
254                 points = gtk_canvas_points_new (7);
255
256                 points->coords[0] = 8.0;
257                 points->coords[1] = 0.0;
258                 
259                 points->coords[2] = 8.0;
260                 points->coords[3] = 11.0;
261                 
262                 points->coords[4] = 0.0;
263                 points->coords[5] = 11.0;
264                 
265                 points->coords[6] = 0.0;
266                 points->coords[7] = 8.0;
267                 
268                 points->coords[8] = 4.0;
269                 points->coords[9] = 8.0;
270                 
271                 points->coords[10] = 4.0;
272                 points->coords[11] = 0.0;
273                 
274                 points->coords[12] = 8.0;
275                 points->coords[13] = 0.0;
276                 
277                 shift = 8;
278                 label_offset = 11.0;
279                 break;
280
281         case  PunchIn:
282                 points = gtk_canvas_points_new (6);
283
284                 points->coords[0] = 0.0;
285                 points->coords[1] = 0.0;
286                 
287                 points->coords[2] = 8.0;
288                 points->coords[3] = 0.0;
289                 
290                 points->coords[4] = 4.0;
291                 points->coords[5] = 4.0;
292                 
293                 points->coords[6] = 4.0;
294                 points->coords[7] = 11.0;
295                 
296                 points->coords[8] = 0.0;
297                 points->coords[9] = 11.0;
298                 
299                 points->coords[10] = 0.0;
300                 points->coords[11] = 0.0;
301                 
302                 shift = 0;
303                 label_offset = 10.0;
304                 break;
305                 
306         case  PunchOut:
307                 points = gtk_canvas_points_new (6);
308
309                 points->coords[0] = 0.0;
310                 points->coords[1] = 0.0;
311                 
312                 points->coords[2] = 8.0;
313                 points->coords[3] = 0.0;
314                 
315                 points->coords[4] = 8.0;
316                 points->coords[5] = 11.0;
317                 
318                 points->coords[6] = 4.0;
319                 points->coords[7] = 11.0;
320                 
321                 points->coords[8] = 4.0;
322                 points->coords[9] = 4.0;
323                 
324                 points->coords[10] = 0.0;
325                 points->coords[11] = 0.0;
326                 
327                 shift = 8;
328                 label_offset = 11.0;
329                 break;
330                 
331         }
332
333         frame_position = frame;
334         unit_position = editor.frame_to_unit (frame);
335
336         /* adjust to properly locate the tip */
337
338         unit_position -= shift;
339
340         group = gtk_canvas_item_new (parent,
341                                      gtk_canvas_group_get_type(),
342                                      "x", unit_position,
343                                      "y", 1.0,
344                                      NULL);
345
346         // cerr << "set mark al points, nc = " << points->num_points << endl;
347         mark = gtk_canvas_item_new (GTK_CANVAS_GROUP(group),
348                                     gtk_canvas_polygon_get_type(),
349                                     "points", points,
350                                     "fill_color_rgba", rgba,
351                                     "outline_color", "black",
352                                     NULL);
353
354         string fontname = get_font_for_style (N_("MarkerText"));
355
356         text = gtk_canvas_item_new (GTK_CANVAS_GROUP(group),
357                                     gtk_canvas_text_get_type (),
358                                     "text", annotation.c_str(),
359                                     "x", label_offset,
360                                     "y", 0.0,
361                                     "font", fontname.c_str(),
362                                     "anchor", GTK_ANCHOR_NW,
363                                     "fill_color", "black",
364                                     NULL);
365
366         gtk_object_set_data (GTK_OBJECT(group), "marker", this);
367         gtk_signal_connect (GTK_OBJECT(group), "event", (GtkSignalFunc) callback, &editor);
368
369         editor.ZoomChanged.connect (slot (*this, &Marker::reposition));
370 }
371
372 Marker::~Marker ()
373 {
374         /* destroying the group destroys its contents */
375         gtk_object_destroy (GTK_OBJECT(group));
376         gtk_canvas_points_unref (points);
377 }
378
379 void
380 Marker::set_name (const string& name)
381 {
382         gtk_canvas_item_set (text, "text", name.c_str(), NULL);
383 }
384
385 void
386 Marker::set_position (jack_nframes_t frame)
387 {
388         double new_unit_position = editor.frame_to_unit (frame);
389         new_unit_position -= shift;
390         gtk_canvas_item_move (group, new_unit_position - unit_position, 0.0);
391         frame_position = frame;
392         unit_position = new_unit_position;
393 }
394
395 void
396 Marker::reposition ()
397 {
398         set_position (frame_position);
399 }       
400
401 void
402 Marker::show ()
403 {
404         gtk_canvas_item_show (group);
405 }
406
407 void
408 Marker::hide ()
409 {
410         gtk_canvas_item_hide (group);
411 }
412
413 void
414 Marker::set_color_rgba (uint32_t color)
415 {
416         gtk_canvas_item_set (mark, "fill_color_rgba", color, NULL);
417 }
418
419 /***********************************************************************/
420
421 TempoMarker::TempoMarker (PublicEditor& editor, GtkCanvasGroup *parent, guint32 rgba, const string& text, 
422                           ARDOUR::TempoSection& temp, 
423                           gint (*callback)(GtkCanvasItem *, GdkEvent *, gpointer))
424         : Marker (editor, parent, rgba, text, Tempo, callback, 0),
425           _tempo (temp)
426 {
427         set_position (_tempo.frame());
428         gtk_object_set_data (GTK_OBJECT(group), "tempo_marker", this);
429 }
430
431 TempoMarker::~TempoMarker ()
432 {
433 }
434
435 /***********************************************************************/
436
437 MeterMarker::MeterMarker (PublicEditor& editor, GtkCanvasGroup *parent, guint32 rgba, const string& text, 
438                           ARDOUR::MeterSection& m, 
439                           gint (*callback)(GtkCanvasItem *, GdkEvent *, gpointer))
440         : Marker (editor, parent, rgba, text, Meter, callback, 0),
441           _meter (m)
442 {
443         set_position (_meter.frame());
444         gtk_object_set_data (GTK_OBJECT(group), "meter_marker", this);
445 }
446
447 MeterMarker::~MeterMarker ()
448 {
449 }