debug output
[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 */
19
20 #include <sigc++/bind.h>
21 #include "ardour/tempo.h"
22
23 #include "ardour_ui.h"
24 /*
25  * ardour_ui.h include was moved to the top of the list
26  * due to a conflicting definition of 'Rect' between
27  * Apple's MacTypes.h and GTK.
28  */
29
30 #include "marker.h"
31 #include "public_editor.h"
32 #include "utils.h"
33 #include "canvas_impl.h"
34 #include "simpleline.h"
35
36 #include <gtkmm2ext/utils.h>
37
38 #include "i18n.h"
39
40 using namespace std;
41 using namespace ARDOUR;
42
43 Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, const string& annotation,
44                 Type type, nframes_t frame, bool handle_events)
45
46         : editor (ed), _parent(&parent), _type(type)
47 {
48         double label_offset = 0;
49
50         /* Shapes we use:
51
52           Mark:
53
54            (0,0) -> (6,0)
55              ^        |
56              |        V
57            (0,5)    (6,5)
58                \    /
59                (3,10)
60
61
62            TempoMark:
63            MeterMark:
64
65                (3,0)
66               /      \
67            (0,5) -> (6,5)
68              ^        |
69              |        V
70            (0,10)<-(6,10)
71
72
73            Start:
74
75            0,0\
76             |  \
77             |   \ 6,6
78             |   /
79             |  /
80            0,12
81
82            End:
83
84                /12,0
85               /     |
86              /      |
87            6,6      |
88              \      |
89               \     |
90                \    |
91                12,12
92
93
94            TransportStart:
95
96              0,0
97               | \
98               |  \
99               |   \
100               |    \
101               |     \
102              0,13 --- 13,13
103
104            TransportEnd:
105
106                     /13,0
107                    /   |
108                   /    |
109                  /     |
110                 /      |
111                /       |
112              0,13 ------ 13,13
113
114
115              PunchIn:
116
117              0,0 ------> 13,0
118               |       /
119               |      /
120               |     /
121               |    /
122               |   /
123               |  /
124              0,13
125
126              PunchOut
127
128            0,0 -->-13,0
129             \       |
130              \      |
131               \     |
132                \    |
133                 \   |
134                  \  |
135                  13,13
136
137
138         */
139
140         switch (type) {
141         case Mark:
142                 points = new ArdourCanvas::Points ();
143
144                 points->push_back (Gnome::Art::Point (0.0, 0.0));
145                 points->push_back (Gnome::Art::Point (6.0, 0.0));
146                 points->push_back (Gnome::Art::Point (6.0, 5.0));
147                 points->push_back (Gnome::Art::Point (3.0, 10.0));
148                 points->push_back (Gnome::Art::Point (0.0, 5.0));
149                 points->push_back (Gnome::Art::Point (0.0, 0.0));
150
151                 shift = 3;
152                 label_offset = 8.0;
153                 break;
154
155         case Tempo:
156         case Meter:
157
158                 points = new ArdourCanvas::Points ();
159                 points->push_back (Gnome::Art::Point (3.0, 0.0));
160                 points->push_back (Gnome::Art::Point (6.0, 5.0));
161                 points->push_back (Gnome::Art::Point (6.0, 10.0));
162                 points->push_back (Gnome::Art::Point (0.0, 10.0));
163                 points->push_back (Gnome::Art::Point (0.0, 5.0));
164                 points->push_back (Gnome::Art::Point (3.0, 0.0));
165
166                 shift = 3;
167                 label_offset = 8.0;
168                 break;
169
170         case Start:
171                 points = new ArdourCanvas::Points ();
172                 points->push_back (Gnome::Art::Point (0.0, 0.0));
173                 points->push_back (Gnome::Art::Point (6.5, 6.5));
174                 points->push_back (Gnome::Art::Point (0.0, 13.0));
175                 points->push_back (Gnome::Art::Point (0.0, 0.0));
176
177                 shift = 0;
178                 label_offset = 13.0;
179                 break;
180
181         case End:
182                 points = new ArdourCanvas::Points ();
183                 points->push_back (Gnome::Art::Point (6.5, 6.5));
184                 points->push_back (Gnome::Art::Point (13.0, 0.0));
185                 points->push_back (Gnome::Art::Point (13.0, 13.0));
186                 points->push_back (Gnome::Art::Point (6.5, 6.5));
187
188                 shift = 13;
189                 label_offset = 6.0;
190                 break;
191
192         case LoopStart:
193                 points = new ArdourCanvas::Points ();
194                 points->push_back (Gnome::Art::Point (0.0, 0.0));
195                 points->push_back (Gnome::Art::Point (13.0, 13.0));
196                 points->push_back (Gnome::Art::Point (0.0, 13.0));
197                 points->push_back (Gnome::Art::Point (0.0, 0.0));
198
199                 shift = 0;
200                 label_offset = 12.0;
201                 break;
202
203         case LoopEnd:
204                 points = new ArdourCanvas::Points ();
205                 points->push_back (Gnome::Art::Point (13.0,  0.0));
206                 points->push_back (Gnome::Art::Point (13.0, 13.0));
207                 points->push_back (Gnome::Art::Point (0.0, 13.0));
208                 points->push_back (Gnome::Art::Point (13.0, 0.0));
209
210                 shift = 13;
211                 label_offset = 0.0;
212                 break;
213
214         case  PunchIn:
215                 points = new ArdourCanvas::Points ();
216                 points->push_back (Gnome::Art::Point (0.0, 0.0));
217                 points->push_back (Gnome::Art::Point (13.0, 0.0));
218                 points->push_back (Gnome::Art::Point (0.0, 13.0));
219                 points->push_back (Gnome::Art::Point (0.0, 0.0));
220
221                 shift = 0;
222                 label_offset = 13.0;
223                 break;
224
225         case  PunchOut:
226                 points = new ArdourCanvas::Points ();
227                 points->push_back (Gnome::Art::Point (0.0, 0.0));
228                 points->push_back (Gnome::Art::Point (12.0, 0.0));
229                 points->push_back (Gnome::Art::Point (12.0, 12.0));
230                 points->push_back (Gnome::Art::Point (0.0, 0.0));
231
232                 shift = 13;
233                 label_offset = 0.0;
234                 break;
235
236         }
237
238         frame_position = frame;
239         unit_position = editor.frame_to_unit (frame);
240
241         /* adjust to properly locate the tip */
242
243         unit_position -= shift;
244
245         group = new Group (parent, unit_position, 1.0);
246
247         mark = new Polygon (*group);
248         mark->property_points() = *points;
249         mark->property_fill_color_rgba() = rgba;
250         mark->property_outline_color_rgba() = rgba;
251         mark->property_width_pixels() = 1;
252
253         /* setup name pixbuf sizes */
254         name_font = get_font_for_style (N_("MarkerText"));
255
256         Gtk::Window win;
257         Gtk::Label foo;
258         win.add (foo);
259
260         Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
261         int width;
262         int height;
263
264         layout->set_font_description (*name_font);
265         Gtkmm2ext::get_ink_pixel_size (layout, width, height);
266         name_height = height + 6;
267
268         name_pixbuf = new ArdourCanvas::Pixbuf(*group);
269         name_pixbuf->property_x() = label_offset;
270
271         set_name (annotation.c_str());
272
273         editor.ZoomChanged.connect (mem_fun (*this, &Marker::reposition));
274
275         mark->set_data ("marker", this);
276
277         if (handle_events) {
278                 group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
279         }
280
281         line = 0;
282
283 }
284
285
286 Marker::~Marker ()
287 {
288         drop_references ();
289
290         /* destroying the parent group destroys its contents, namely any polygons etc. that we added */
291         delete name_pixbuf;
292         delete mark;
293         delete points;
294
295         delete line;
296         line = 0;
297 }
298
299 void Marker::reparent(ArdourCanvas::Group & parent)
300 {
301         group->reparent(parent);
302         _parent = &parent;
303 }
304
305
306 void
307 Marker::set_line_vpos (double pos, double height)
308 {
309         if (line) {
310                 line->property_y1() = pos;
311                 line->property_y2() = pos + height;
312         }
313 }
314
315 void
316 Marker::add_line (ArdourCanvas::Group* group, double y_origin, double initial_height)
317 {
318         if (!line) {
319
320                 line = new ArdourCanvas::SimpleLine (*group);
321                 line->property_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get();
322                 line->property_x1() = unit_position + shift;
323                 line->property_y1() = y_origin;
324                 line->property_x2() = unit_position + shift;
325                 line->property_y2() = y_origin + initial_height;
326
327                 line->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
328         }
329
330         show_line ();
331 }
332
333 void
334 Marker::show_line ()
335 {
336         if (line) {
337                 line->raise_to_top();
338                 line->show ();
339         }
340 }
341
342 void
343 Marker::hide_line ()
344 {
345         if (line) {
346                 line->hide ();
347         }
348 }
349
350 ArdourCanvas::Item&
351 Marker::the_item() const
352 {
353         return *mark;
354 }
355
356 void
357 Marker::set_name (const string& new_name)
358 {
359         int name_width = pixel_width (new_name, *name_font) + 2;
360
361         name_pixbuf->property_pixbuf() = pixbuf_from_ustring(new_name, name_font, name_width, name_height);
362
363         if (_type == End || _type == LoopEnd || _type == PunchOut) {
364                 name_pixbuf->property_x() = - (name_width);
365         }
366 }
367
368 void
369 Marker::set_position (nframes64_t frame)
370 {
371         double new_unit_position = editor.frame_to_unit (frame);
372         new_unit_position -= shift;
373         group->move (new_unit_position - unit_position, 0.0);
374         frame_position = frame;
375         unit_position = new_unit_position;
376
377         if (line) {
378                 line->property_x1() = unit_position + shift;
379                 line->property_x2() = unit_position + shift;
380         }
381 }
382
383 void
384 Marker::reposition ()
385 {
386         set_position (frame_position);
387 }
388
389 void
390 Marker::show ()
391 {
392         group->show();
393 }
394
395 void
396 Marker::hide ()
397 {
398         group->hide();
399 }
400
401 void
402 Marker::set_color_rgba (uint32_t color)
403 {
404         mark->property_fill_color_rgba() = color;
405         mark->property_outline_color_rgba() = color;
406 }
407
408 /***********************************************************************/
409
410 TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text,
411                           ARDOUR::TempoSection& temp)
412         : Marker (editor, parent, rgba, text, Tempo, 0, false),
413           _tempo (temp)
414 {
415         set_position (_tempo.frame());
416         group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_tempo_marker_event), mark, this));
417 }
418
419 TempoMarker::~TempoMarker ()
420 {
421 }
422
423 /***********************************************************************/
424
425 MeterMarker::MeterMarker (PublicEditor& editor, ArdourCanvas::Group& parent, guint32 rgba, const string& text,
426                           ARDOUR::MeterSection& m)
427         : Marker (editor, parent, rgba, text, Meter, 0, false),
428           _meter (m)
429 {
430         set_position (_meter.frame());
431         group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_meter_marker_event), mark, this));
432 }
433
434 MeterMarker::~MeterMarker ()
435 {
436 }
437