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