allow for mandatory control protocols, plus some ongoing work on automation control...
[ardour.git] / gtk2_ardour / editor_canvas_events.cc
1 /*
2     Copyright (C) 2000 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 <cstdlib>
22 #include <cmath>
23
24 #include <ardour/diskstream.h>
25 #include <ardour/audioplaylist.h>
26
27 #include "editor.h"
28 #include "public_editor.h"
29 #include "regionview.h"
30 #include "streamview.h"
31 #include "crossfade_view.h"
32 #include "audio_time_axis.h"
33 #include "region_gain_line.h"
34 #include "automation_gain_line.h"
35 #include "automation_pan_line.h"
36 #include "automation_time_axis.h"
37 #include "redirect_automation_line.h"
38 #include "canvas_impl.h"
39 #include "simplerect.h"
40
41 #include "i18n.h"
42
43 using namespace sigc;
44 using namespace ARDOUR;
45 using namespace Gtk;
46
47 bool
48 Editor::track_canvas_scroll (GdkEventScroll* ev)
49 {
50         int x, y;
51         double wx, wy;
52
53         switch (ev->direction) {
54         case GDK_SCROLL_UP:
55                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
56                         //if (ev->state == GDK_CONTROL_MASK) {
57                         /* XXX 
58                            the ev->x will be out of step with the canvas
59                            if we're in mid zoom, so we have to get the damn mouse 
60                            pointer again
61                         */
62                         track_canvas.get_pointer (x, y);
63                         track_canvas.window_to_world (x, y, wx, wy);
64                         wx += horizontal_adjustment.get_value();
65                         wy += vertical_adjustment.get_value();
66                         
67                         GdkEvent event;
68                         event.type = GDK_BUTTON_RELEASE;
69                         event.button.x = wx;
70                         event.button.y = wy;
71                         
72                         jack_nframes_t where = event_frame (&event, 0, 0);
73                         temporal_zoom_to_frame (true, where);
74                         return true;
75                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
76                         if (!current_stepping_trackview) {
77                                 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
78                                 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
79                                         return false;
80                                 }
81                         }
82                         gettimeofday (&last_track_height_step_timestamp, 0);
83                         current_stepping_trackview->step_height (true);
84                         return true;
85                 } else {
86                         scroll_tracks_up_line ();
87                         return true;
88                 }
89                 break;
90         case GDK_SCROLL_DOWN:
91                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
92                         //if (ev->state == GDK_CONTROL_MASK) {
93                         track_canvas.get_pointer (x, y);
94                         track_canvas.window_to_world (x, y, wx, wy);
95                         wx += horizontal_adjustment.get_value();
96                         wy += vertical_adjustment.get_value();
97                         
98                         GdkEvent event;
99                         event.type = GDK_BUTTON_RELEASE;
100                         event.button.x = wx;
101                         event.button.y = wy;
102                         
103                         jack_nframes_t where = event_frame (&event, 0, 0);
104                         temporal_zoom_to_frame (false, where);
105                         return true;
106                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
107                         if (!current_stepping_trackview) {
108                                 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
109                                 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
110                                         return false;
111                                 }
112                         }
113                         gettimeofday (&last_track_height_step_timestamp, 0);
114                         current_stepping_trackview->step_height (false);
115                         return true;
116                 } else {
117                         scroll_tracks_down_line ();
118                         return true;
119                 }
120                 break;  
121
122         default:
123                 /* no left/right handling yet */
124                 break;
125         }
126         
127         return false;
128 }
129
130 bool
131 Editor::track_canvas_event (GdkEvent *event, ArdourCanvas::Item* item)
132 {
133         gint x, y;
134
135         /* this is the handler for events that are not handled by
136            items.
137         */
138
139         switch (event->type) {
140         case GDK_MOTION_NOTIFY:
141                 /* keep those motion events coming */
142                 track_canvas.get_pointer (x, y);
143                 return track_canvas_motion (event);
144
145         case GDK_BUTTON_PRESS:
146                 track_canvas.grab_focus();
147                 break;
148
149         case GDK_BUTTON_RELEASE:
150                 switch (event->button.button) {
151                 case 4:
152                 case 5:
153                         button_release_handler (item, event, NoItem);
154                         break;
155                 }
156                 break;
157
158         case GDK_SCROLL:
159                 track_canvas.grab_focus();
160                 track_canvas_scroll (&event->scroll);
161                 break;
162
163         default:
164                 break;
165         }
166
167         return FALSE;
168 }
169
170 bool
171 Editor::track_canvas_motion (GdkEvent *ev)
172 {
173         if (verbose_cursor_visible) {
174                 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
175                 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
176         }
177         return false;
178 }
179
180 bool
181 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
182 {
183         gint ret = FALSE;
184         
185         switch (event->type) {
186         case GDK_BUTTON_PRESS:
187         case GDK_2BUTTON_PRESS:
188         case GDK_3BUTTON_PRESS:
189                 ret = button_press_handler (item, event, type);
190                 break;
191         case GDK_BUTTON_RELEASE:
192                 ret = button_release_handler (item, event, type);
193                 break;
194         case GDK_MOTION_NOTIFY:
195                 ret = motion_handler (item, event, type);
196                 break;
197
198         case GDK_ENTER_NOTIFY:
199                 ret = enter_handler (item, event, type);
200                 break;
201
202         case GDK_LEAVE_NOTIFY:
203                 ret = leave_handler (item, event, type);
204                 break;
205
206         default:
207                 break;
208         }
209                         
210         return ret;
211 }
212
213 bool
214 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
215 {
216         gint ret = FALSE;
217
218         switch (event->type) {
219         case GDK_BUTTON_PRESS:
220         case GDK_2BUTTON_PRESS:
221         case GDK_3BUTTON_PRESS:
222                 clicked_regionview = rv;
223                 clicked_control_point = 0;
224                 clicked_trackview = &rv->get_time_axis_view();
225                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
226                 ret = button_press_handler (item, event, RegionItem);
227                 break;
228
229         case GDK_BUTTON_RELEASE:
230                 ret = button_release_handler (item, event, RegionItem);
231                 break;
232
233         case GDK_MOTION_NOTIFY:
234                 ret = motion_handler (item, event, RegionItem);
235                 break;
236
237         case GDK_ENTER_NOTIFY:
238                 set_entered_regionview (rv);
239                 break;
240
241         case GDK_LEAVE_NOTIFY:
242                 set_entered_regionview (0);
243                 break;
244
245         default:
246                 break;
247         }
248
249         return ret;
250 }
251
252 bool
253 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
254 {
255         bool ret = FALSE;
256         
257         switch (event->type) {
258         case GDK_BUTTON_PRESS:
259         case GDK_2BUTTON_PRESS:
260         case GDK_3BUTTON_PRESS:
261                 clicked_regionview = 0;
262                 clicked_control_point = 0;
263                 clicked_trackview = tv;
264                 clicked_audio_trackview = tv;
265                 ret = button_press_handler (item, event, StreamItem);
266                 break;
267
268         case GDK_BUTTON_RELEASE:
269                 ret = button_release_handler (item, event, StreamItem);
270                 break;
271
272         case GDK_MOTION_NOTIFY:
273                 ret = motion_handler (item, event, StreamItem);
274                 break;
275
276         case GDK_ENTER_NOTIFY:
277                 break;
278
279         default:
280                 break;
281         }
282
283         return ret;
284 }
285
286
287
288 bool
289 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
290 {
291         bool ret = false;
292         
293         switch (event->type) {
294         case GDK_BUTTON_PRESS:
295         case GDK_2BUTTON_PRESS:
296         case GDK_3BUTTON_PRESS:
297                 clicked_regionview = 0;
298                 clicked_control_point = 0;
299                 clicked_trackview = atv;
300                 clicked_audio_trackview = 0;
301                 ret = button_press_handler (item, event, AutomationTrackItem);
302                 break;
303
304         case GDK_BUTTON_RELEASE:
305                 ret = button_release_handler (item, event, AutomationTrackItem);
306                 break;
307
308         case GDK_MOTION_NOTIFY:
309                 ret = motion_handler (item, event, AutomationTrackItem);
310                 break;
311
312         case GDK_ENTER_NOTIFY:
313                 ret = enter_handler (item, event, AutomationTrackItem);
314                 break;
315
316         case GDK_LEAVE_NOTIFY:
317                 ret = leave_handler (item, event, AutomationTrackItem);
318                 break;
319
320         default:
321                 break;
322         }
323
324         return ret;
325 }
326
327 bool
328 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
329 {
330         /* we handle only button 3 press/release events */
331
332         switch (event->type) {
333         case GDK_BUTTON_PRESS:
334                 clicked_regionview = rv;
335                 clicked_control_point = 0;
336                 clicked_trackview = &rv->get_time_axis_view();
337                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
338                 if (event->button.button == 3) {
339                         return button_press_handler (item, event, FadeInItem);
340                 }
341                 break;
342
343         case GDK_BUTTON_RELEASE:
344                 if (event->button.button == 3) {
345                         return button_release_handler (item, event, FadeInItem);
346                 }
347                 break;
348
349         default:
350                 break;
351                 
352         }
353
354         /* proxy for the regionview */
355         
356         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
357 }
358
359 bool
360 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
361 {
362         bool ret = false;
363         
364         switch (event->type) {
365         case GDK_BUTTON_PRESS:
366         case GDK_2BUTTON_PRESS:
367         case GDK_3BUTTON_PRESS:
368                 clicked_regionview = rv;
369                 clicked_control_point = 0;
370                 clicked_trackview = &rv->get_time_axis_view();
371                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
372                 ret = button_press_handler (item, event, FadeInHandleItem);
373                 break;
374
375         case GDK_BUTTON_RELEASE:
376                 ret = button_release_handler (item, event, FadeInHandleItem);
377                 break;
378
379         case GDK_MOTION_NOTIFY:
380                 ret = motion_handler (item, event, FadeInHandleItem);
381                 break;
382
383         case GDK_ENTER_NOTIFY:
384                 ret = enter_handler (item, event, FadeInHandleItem);
385                 break;
386
387         case GDK_LEAVE_NOTIFY:
388                 ret = leave_handler (item, event, FadeInHandleItem);
389                 break;
390
391         default:
392                 break;
393         }
394
395         return ret;
396 }
397
398 bool
399 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
400 {
401         /* we handle only button 3 press/release events */
402
403         switch (event->type) {
404         case GDK_BUTTON_PRESS:
405                 clicked_regionview = rv;
406                 clicked_control_point = 0;
407                 clicked_trackview = &rv->get_time_axis_view();
408                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
409                 if (event->button.button == 3) {
410                         return button_press_handler (item, event, FadeOutItem);
411                 }
412                 break;
413
414         case GDK_BUTTON_RELEASE:
415                 if (event->button.button == 3) {
416                         return button_release_handler (item, event, FadeOutItem);
417                 }
418                 break;
419
420         default:
421                 break;
422                 
423         }
424
425         /* proxy for the regionview */
426         
427         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
428 }
429
430 bool
431 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
432 {
433         bool ret = false;
434         
435         switch (event->type) {
436         case GDK_BUTTON_PRESS:
437         case GDK_2BUTTON_PRESS:
438         case GDK_3BUTTON_PRESS:
439                 clicked_regionview = rv;
440                 clicked_control_point = 0;
441                 clicked_trackview = &rv->get_time_axis_view();
442                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
443                 ret = button_press_handler (item, event, FadeOutHandleItem);
444                 break;
445
446         case GDK_BUTTON_RELEASE:
447                 ret = button_release_handler (item, event, FadeOutHandleItem);
448                 break;
449
450         case GDK_MOTION_NOTIFY:
451                 ret = motion_handler (item, event, FadeOutHandleItem);
452                 break;
453
454         case GDK_ENTER_NOTIFY:
455                 ret = enter_handler (item, event, FadeOutHandleItem);
456                 break;
457
458         case GDK_LEAVE_NOTIFY:
459                 ret = leave_handler (item, event, FadeOutHandleItem);
460                 break;
461
462         default:
463                 break;
464         }
465
466         return ret;
467 }
468
469 struct DescendingRegionLayerSorter {
470     bool operator()(Region* a, Region* b) {
471             return a->layer() > b->layer();
472     }
473 };
474
475 bool
476 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
477 {
478         /* we handle only button 3 press/release events */
479
480         switch (event->type) {
481         case GDK_BUTTON_PRESS:
482                 clicked_crossfadeview = xfv;
483                 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
484                 if (event->button.button == 3) {
485                         return button_press_handler (item, event, CrossfadeViewItem);
486                 } 
487                 break;
488
489         case GDK_BUTTON_RELEASE:
490                 if (event->button.button == 3) {
491                         bool ret = button_release_handler (item, event, CrossfadeViewItem);
492                         return ret;
493                 }
494                 break;
495
496         default:
497                 break;
498                 
499         }
500
501         
502         /* proxy for the upper most regionview */
503
504         /* XXX really need to check if we are in the name highlight,
505            and proxy to that when required.
506         */
507         
508         TimeAxisView& tv (xfv->get_time_axis_view());
509         AudioTimeAxisView* atv;
510
511         if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
512
513                 if (atv->is_audio_track()) {
514                         
515                         AudioPlaylist* pl = atv->get_diskstream()->playlist();
516                         Playlist::RegionList* rl = pl->regions_at (event_frame (event));
517
518                         if (!rl->empty()) {
519                                 DescendingRegionLayerSorter cmp;
520                                 rl->sort (cmp);
521
522                                 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
523
524                                 /* proxy */
525                                 
526                                 delete rl;
527
528                                 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
529                         } 
530                 }
531         }
532
533         return TRUE;
534 }
535
536 bool
537 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
538 {
539         ItemType type;
540
541         switch (event->type) {
542         case GDK_BUTTON_PRESS:
543         case GDK_2BUTTON_PRESS:
544         case GDK_3BUTTON_PRESS:
545                 clicked_control_point = cp;
546                 clicked_trackview = &cp->line.trackview;
547                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
548                 clicked_regionview = 0;
549                 break;
550
551         case GDK_SCROLL_UP:
552                 break;
553
554         case GDK_SCROLL_DOWN:
555                 break;
556
557         default:
558                 break;
559         }
560
561         if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
562                 type = GainControlPointItem;
563         } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
564                 type = GainAutomationControlPointItem;
565         } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
566                 type = PanAutomationControlPointItem;
567         } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
568                 type = RedirectAutomationControlPointItem;
569         } else {
570                 return false;
571         }
572
573         return typed_event (item, event, type);
574 }
575
576 bool
577 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
578 {
579         ItemType type;
580
581         if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
582                 type = GainLineItem;
583         } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
584                 type = GainAutomationLineItem;
585         } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
586                 type = PanAutomationLineItem;
587         } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
588                 type = RedirectAutomationLineItem;
589         } else {
590                 return false;
591         }
592
593         return typed_event (item, event, type);
594 }
595
596 bool
597 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
598 {
599         bool ret = false;
600         
601         switch (event->type) {
602         case GDK_BUTTON_PRESS:
603         case GDK_2BUTTON_PRESS:
604         case GDK_3BUTTON_PRESS:
605                 clicked_selection = rect->id;
606                 ret = button_press_handler (item, event, SelectionItem);
607                 break;
608         case GDK_BUTTON_RELEASE:
609                 ret = button_release_handler (item, event, SelectionItem);
610                 break;
611         case GDK_MOTION_NOTIFY:
612                 ret = motion_handler (item, event, SelectionItem);
613                 break;
614                 /* Don't need these at the moment. */
615         case GDK_ENTER_NOTIFY:
616                 ret = enter_handler (item, event, SelectionItem);
617                 break;
618
619         case GDK_LEAVE_NOTIFY:
620                 ret = leave_handler (item, event, SelectionItem);
621                 break;
622
623         default:
624                 break;
625         }
626                         
627         return ret;
628 }
629
630 bool
631 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
632 {
633         bool ret = false;
634
635         switch (event->type) {
636         case GDK_BUTTON_PRESS:
637         case GDK_2BUTTON_PRESS:
638         case GDK_3BUTTON_PRESS:
639                 clicked_selection = rect->id;
640                 ret = button_press_handler (item, event, StartSelectionTrimItem);
641                 break;
642         case GDK_BUTTON_RELEASE:
643                 ret = button_release_handler (item, event, StartSelectionTrimItem);
644                 break;
645         case GDK_MOTION_NOTIFY:
646                 ret = motion_handler (item, event, StartSelectionTrimItem);
647                 break;
648         case GDK_ENTER_NOTIFY:
649                 ret = enter_handler (item, event, StartSelectionTrimItem);
650                 break;
651
652         case GDK_LEAVE_NOTIFY:
653                 ret = leave_handler (item, event, StartSelectionTrimItem);
654                 break;
655
656         default:
657                 break;
658         }
659                         
660         return ret;
661 }
662
663 bool
664 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
665 {
666         bool ret = false;
667
668         switch (event->type) {
669         case GDK_BUTTON_PRESS:
670         case GDK_2BUTTON_PRESS:
671         case GDK_3BUTTON_PRESS:
672                 clicked_selection = rect->id;
673                 ret = button_press_handler (item, event, EndSelectionTrimItem);
674                 break;
675         case GDK_BUTTON_RELEASE:
676                 ret = button_release_handler (item, event, EndSelectionTrimItem);
677                 break;
678         case GDK_MOTION_NOTIFY:
679                 ret = motion_handler (item, event, EndSelectionTrimItem);
680                 break;
681         case GDK_ENTER_NOTIFY:
682                 ret = enter_handler (item, event, EndSelectionTrimItem);
683                 break;
684
685         case GDK_LEAVE_NOTIFY:
686                 ret = leave_handler (item, event, EndSelectionTrimItem);
687                 break;
688
689         default:
690                 break;
691         }
692                         
693         return ret;
694 }
695
696
697 bool
698 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
699 {
700         bool ret = false;
701         
702         switch (event->type) {
703         case GDK_BUTTON_PRESS:
704         case GDK_2BUTTON_PRESS:
705         case GDK_3BUTTON_PRESS:
706                 clicked_regionview = rv;
707                 clicked_control_point = 0;
708                 clicked_trackview = &clicked_regionview->get_time_axis_view();
709                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
710                 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
711                 break;
712         case GDK_BUTTON_RELEASE:
713                 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
714                 break;
715         case GDK_MOTION_NOTIFY:
716                 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
717                 break;
718         case GDK_ENTER_NOTIFY:
719                 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
720                 break;
721
722         case GDK_LEAVE_NOTIFY:
723                 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
724                 break;
725
726         default:
727                 break;
728         }
729
730         return ret;
731 }
732
733 bool
734 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
735 {
736         bool ret = false;
737
738         switch (event->type) {
739         case GDK_BUTTON_PRESS:
740         case GDK_2BUTTON_PRESS:
741         case GDK_3BUTTON_PRESS:
742                 clicked_regionview = rv;
743                 clicked_control_point = 0;
744                 clicked_trackview = &clicked_regionview->get_time_axis_view();
745                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
746                 ret = button_press_handler (item, event, AudioRegionViewName);
747                 break;
748         case GDK_BUTTON_RELEASE:
749                 ret = button_release_handler (item, event, AudioRegionViewName);
750                 break;
751         case GDK_MOTION_NOTIFY:
752                 ret = motion_handler (item, event, AudioRegionViewName);
753                 break;
754         case GDK_ENTER_NOTIFY:
755                 ret = enter_handler (item, event, AudioRegionViewName);
756                 break;
757
758         case GDK_LEAVE_NOTIFY:
759                 ret = leave_handler (item, event, AudioRegionViewName);
760                 break;
761
762         default:
763                 break;
764         }
765
766         return ret;
767 }
768
769 bool
770 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
771 {
772         return typed_event (item, event, MarkerItem);
773 }
774
775 bool
776 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
777 {
778         return typed_event (item, event, MarkerBarItem);
779 }
780
781 bool
782 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
783 {
784         return typed_event (item, event, RangeMarkerBarItem);
785 }
786
787 bool
788 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
789 {
790         return typed_event (item, event, TransportMarkerBarItem);
791 }
792
793 bool
794 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
795 {
796         return typed_event (item, event, TempoMarkerItem);
797 }
798
799 bool
800 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
801 {
802         return typed_event (item, event, MeterMarkerItem);
803 }
804
805 bool
806 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
807 {
808         return typed_event (item, event, TempoBarItem);
809 }
810
811 bool
812 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
813 {
814         return typed_event (item, event, MeterBarItem);
815 }
816
817 bool
818 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
819 {
820         return typed_event (item, event, PlayheadCursorItem);
821 }
822
823 bool
824 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
825 {
826         return typed_event (item, event, EditCursorItem);
827 }
828
829 bool
830 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
831 {
832         return typed_event (item, event, NoItem);
833 }
834