some small optimizations for track-selection process
[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 bool
133 Editor::track_canvas_scroll_event (GdkEventScroll *event)
134 {
135         track_canvas.grab_focus();
136         track_canvas_scroll (event);
137         return false;
138 }
139
140 bool
141 Editor::track_canvas_button_press_event (GdkEventButton *event)
142 {
143         track_canvas.grab_focus();
144         return false;
145 }
146
147 bool
148 Editor::track_canvas_button_release_event (GdkEventButton *event)
149 {
150         if (drag_info.item) {
151                 end_grab (drag_info.item, (GdkEvent*) event);
152         }
153         return false;
154 }
155
156 bool
157 Editor::track_canvas_motion_notify_event (GdkEventMotion *event)
158 {
159         int x, y;
160         /* keep those motion events coming */
161         track_canvas.get_pointer (x, y);
162         return false;
163 }
164
165 bool
166 Editor::track_canvas_motion (GdkEvent *ev)
167 {
168         if (verbose_cursor_visible) {
169                 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
170                 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
171         }
172         return false;
173 }
174
175 bool
176 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
177 {
178         gint ret = FALSE;
179         
180         switch (event->type) {
181         case GDK_BUTTON_PRESS:
182         case GDK_2BUTTON_PRESS:
183         case GDK_3BUTTON_PRESS:
184                 ret = button_press_handler (item, event, type);
185                 break;
186         case GDK_BUTTON_RELEASE:
187                 ret = button_release_handler (item, event, type);
188                 break;
189         case GDK_MOTION_NOTIFY:
190                 ret = motion_handler (item, event, type);
191                 break;
192
193         case GDK_ENTER_NOTIFY:
194                 ret = enter_handler (item, event, type);
195                 break;
196
197         case GDK_LEAVE_NOTIFY:
198                 ret = leave_handler (item, event, type);
199                 break;
200
201         default:
202                 break;
203         }
204         return ret;
205 }
206
207 bool
208 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
209 {
210         bool ret = false;
211
212         if (!rv->sensitive ()) {
213                 return false;
214         }
215
216
217         switch (event->type) {
218         case GDK_BUTTON_PRESS:
219         case GDK_2BUTTON_PRESS:
220         case GDK_3BUTTON_PRESS:
221                 clicked_regionview = rv;
222                 clicked_control_point = 0;
223                 clicked_trackview = &rv->get_time_axis_view();
224                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
225                 ret = button_press_handler (item, event, RegionItem);
226                 break;
227
228         case GDK_BUTTON_RELEASE:
229                 ret = button_release_handler (item, event, RegionItem);
230                 break;
231
232         case GDK_MOTION_NOTIFY:
233                 ret = motion_handler (item, event, RegionItem);
234                 break;
235
236         case GDK_ENTER_NOTIFY:
237                 set_entered_regionview (rv);
238                 break;
239
240         case GDK_LEAVE_NOTIFY:
241                 set_entered_regionview (0);
242                 break;
243
244         default:
245                 break;
246         }
247
248         return ret;
249 }
250
251 bool
252 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
253 {
254         bool ret = FALSE;
255         
256         switch (event->type) {
257         case GDK_BUTTON_PRESS:
258         case GDK_2BUTTON_PRESS:
259         case GDK_3BUTTON_PRESS:
260                 clicked_regionview = 0;
261                 clicked_control_point = 0;
262                 clicked_trackview = tv;
263                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(tv);
264                 ret = button_press_handler (item, event, StreamItem);
265                 break;
266
267         case GDK_BUTTON_RELEASE:
268                 ret = button_release_handler (item, event, StreamItem);
269                 break;
270
271         case GDK_MOTION_NOTIFY:
272                 ret = motion_handler (item, event, StreamItem);
273                 break;
274
275         case GDK_ENTER_NOTIFY:
276                 break;
277
278         default:
279                 break;
280         }
281
282         return ret;
283 }
284
285
286
287 bool
288 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
289 {
290         bool ret = false;
291
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         if (!rv->sensitive()) {
333                 return false;
334         }
335
336         switch (event->type) {
337         case GDK_BUTTON_PRESS:
338                 clicked_regionview = rv;
339                 clicked_control_point = 0;
340                 clicked_trackview = &rv->get_time_axis_view();
341                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
342                 if (event->button.button == 3) {
343                         return button_press_handler (item, event, FadeInItem);
344                 }
345                 break;
346
347         case GDK_BUTTON_RELEASE:
348                 if (event->button.button == 3) {
349                         return button_release_handler (item, event, FadeInItem);
350                 }
351                 break;
352
353         default:
354                 break;
355                 
356         }
357
358         /* proxy for the regionview */
359         
360         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
361 }
362
363 bool
364 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
365 {
366         bool ret = false;
367         
368         if (!rv->sensitive()) {
369                 return false;
370         }
371
372         switch (event->type) {
373         case GDK_BUTTON_PRESS:
374         case GDK_2BUTTON_PRESS:
375         case GDK_3BUTTON_PRESS:
376                 clicked_regionview = rv;
377                 clicked_control_point = 0;
378                 clicked_trackview = &rv->get_time_axis_view();
379                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
380                 ret = button_press_handler (item, event, FadeInHandleItem);
381                 break;
382
383         case GDK_BUTTON_RELEASE:
384                 ret = button_release_handler (item, event, FadeInHandleItem);
385                 break;
386
387         case GDK_MOTION_NOTIFY:
388                 ret = motion_handler (item, event, FadeInHandleItem);
389                 break;
390
391         case GDK_ENTER_NOTIFY:
392                 ret = enter_handler (item, event, FadeInHandleItem);
393                 break;
394
395         case GDK_LEAVE_NOTIFY:
396                 ret = leave_handler (item, event, FadeInHandleItem);
397                 break;
398
399         default:
400                 break;
401         }
402
403         return ret;
404 }
405
406 bool
407 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
408 {
409         /* we handle only button 3 press/release events */
410
411         if (!rv->sensitive()) {
412                 return false;
413         }
414
415         switch (event->type) {
416         case GDK_BUTTON_PRESS:
417                 clicked_regionview = rv;
418                 clicked_control_point = 0;
419                 clicked_trackview = &rv->get_time_axis_view();
420                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
421                 if (event->button.button == 3) {
422                         return button_press_handler (item, event, FadeOutItem);
423                 }
424                 break;
425
426         case GDK_BUTTON_RELEASE:
427                 if (event->button.button == 3) {
428                         return button_release_handler (item, event, FadeOutItem);
429                 }
430                 break;
431
432         default:
433                 break;
434                 
435         }
436
437         /* proxy for the regionview */
438         
439         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
440 }
441
442 bool
443 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
444 {
445         bool ret = false;
446         
447         if (!rv->sensitive()) {
448                 return false;
449         }
450
451         switch (event->type) {
452         case GDK_BUTTON_PRESS:
453         case GDK_2BUTTON_PRESS:
454         case GDK_3BUTTON_PRESS:
455                 clicked_regionview = rv;
456                 clicked_control_point = 0;
457                 clicked_trackview = &rv->get_time_axis_view();
458                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
459                 ret = button_press_handler (item, event, FadeOutHandleItem);
460                 break;
461
462         case GDK_BUTTON_RELEASE:
463                 ret = button_release_handler (item, event, FadeOutHandleItem);
464                 break;
465
466         case GDK_MOTION_NOTIFY:
467                 ret = motion_handler (item, event, FadeOutHandleItem);
468                 break;
469
470         case GDK_ENTER_NOTIFY:
471                 ret = enter_handler (item, event, FadeOutHandleItem);
472                 break;
473
474         case GDK_LEAVE_NOTIFY:
475                 ret = leave_handler (item, event, FadeOutHandleItem);
476                 break;
477
478         default:
479                 break;
480         }
481
482         return ret;
483 }
484
485 struct DescendingRegionLayerSorter {
486     bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
487             return a->layer() > b->layer();
488     }
489 };
490
491 bool
492 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
493 {
494         /* we handle only button 3 press/release events */
495
496         switch (event->type) {
497         case GDK_BUTTON_PRESS:
498                 clicked_crossfadeview = xfv;
499                 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
500                 if (event->button.button == 3) {
501                         return button_press_handler (item, event, CrossfadeViewItem);
502                 } 
503                 break;
504
505         case GDK_BUTTON_RELEASE:
506                 if (event->button.button == 3) {
507                         bool ret = button_release_handler (item, event, CrossfadeViewItem);
508                         return ret;
509                 }
510                 break;
511
512         default:
513                 break;
514                 
515         }
516
517         /* XXX do not forward double clicks */
518
519         if (event->type == GDK_2BUTTON_PRESS) {
520                 return false;
521         }
522         
523         /* proxy for the upper most regionview */
524
525         /* XXX really need to check if we are in the name highlight,
526            and proxy to that when required.
527         */
528         
529         TimeAxisView& tv (xfv->get_time_axis_view());
530         AudioTimeAxisView* atv;
531
532         if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
533
534                 if (atv->is_audio_track()) {
535
536                         boost::shared_ptr<AudioPlaylist> pl;
537                         if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
538
539                                 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
540
541                                 if (!rl->empty()) {
542                                         DescendingRegionLayerSorter cmp;
543                                         rl->sort (cmp);
544
545                                         RegionView* rv = atv->view()->find_view (rl->front());
546
547                                         delete rl;
548
549                                         /* proxy */
550                                         
551                                         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
552                                 } 
553                         }
554                 }
555         }
556
557         return TRUE;
558 }
559
560 bool
561 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
562 {
563         ItemType type;
564
565         switch (event->type) {
566         case GDK_BUTTON_PRESS:
567         case GDK_2BUTTON_PRESS:
568         case GDK_3BUTTON_PRESS:
569                 clicked_control_point = cp;
570                 clicked_trackview = &cp->line.trackview;
571                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
572                 clicked_regionview = 0;
573                 break;
574
575         case GDK_SCROLL_UP:
576                 break;
577
578         case GDK_SCROLL_DOWN:
579                 break;
580
581         default:
582                 break;
583         }
584
585         if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
586                 type = GainControlPointItem;
587         } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
588                 type = GainAutomationControlPointItem;
589         } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
590                 type = PanAutomationControlPointItem;
591         } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
592                 type = RedirectAutomationControlPointItem;
593         } else {
594                 return false;
595         }
596
597         return typed_event (item, event, type);
598 }
599
600 bool
601 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
602 {
603         ItemType type;
604
605         if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
606                 type = GainLineItem;
607         } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
608                 type = GainAutomationLineItem;
609         } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
610                 type = PanAutomationLineItem;
611         } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
612                 type = RedirectAutomationLineItem;
613         } else {
614                 return false;
615         }
616
617         return typed_event (item, event, type);
618 }
619
620 bool
621 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
622 {
623         bool ret = false;
624         
625         switch (event->type) {
626         case GDK_BUTTON_PRESS:
627         case GDK_2BUTTON_PRESS:
628         case GDK_3BUTTON_PRESS:
629                 clicked_selection = rect->id;
630                 ret = button_press_handler (item, event, SelectionItem);
631                 break;
632         case GDK_BUTTON_RELEASE:
633                 ret = button_release_handler (item, event, SelectionItem);
634                 break;
635         case GDK_MOTION_NOTIFY:
636                 ret = motion_handler (item, event, SelectionItem);
637                 break;
638                 /* Don't need these at the moment. */
639         case GDK_ENTER_NOTIFY:
640                 ret = enter_handler (item, event, SelectionItem);
641                 break;
642
643         case GDK_LEAVE_NOTIFY:
644                 ret = leave_handler (item, event, SelectionItem);
645                 break;
646
647         default:
648                 break;
649         }
650                         
651         return ret;
652 }
653
654 bool
655 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
656 {
657         bool ret = false;
658
659         switch (event->type) {
660         case GDK_BUTTON_PRESS:
661         case GDK_2BUTTON_PRESS:
662         case GDK_3BUTTON_PRESS:
663                 clicked_selection = rect->id;
664                 ret = button_press_handler (item, event, StartSelectionTrimItem);
665                 break;
666         case GDK_BUTTON_RELEASE:
667                 ret = button_release_handler (item, event, StartSelectionTrimItem);
668                 break;
669         case GDK_MOTION_NOTIFY:
670                 ret = motion_handler (item, event, StartSelectionTrimItem);
671                 break;
672         case GDK_ENTER_NOTIFY:
673                 ret = enter_handler (item, event, StartSelectionTrimItem);
674                 break;
675
676         case GDK_LEAVE_NOTIFY:
677                 ret = leave_handler (item, event, StartSelectionTrimItem);
678                 break;
679
680         default:
681                 break;
682         }
683                         
684         return ret;
685 }
686
687 bool
688 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
689 {
690         bool ret = false;
691
692         switch (event->type) {
693         case GDK_BUTTON_PRESS:
694         case GDK_2BUTTON_PRESS:
695         case GDK_3BUTTON_PRESS:
696                 clicked_selection = rect->id;
697                 ret = button_press_handler (item, event, EndSelectionTrimItem);
698                 break;
699         case GDK_BUTTON_RELEASE:
700                 ret = button_release_handler (item, event, EndSelectionTrimItem);
701                 break;
702         case GDK_MOTION_NOTIFY:
703                 ret = motion_handler (item, event, EndSelectionTrimItem);
704                 break;
705         case GDK_ENTER_NOTIFY:
706                 ret = enter_handler (item, event, EndSelectionTrimItem);
707                 break;
708
709         case GDK_LEAVE_NOTIFY:
710                 ret = leave_handler (item, event, EndSelectionTrimItem);
711                 break;
712
713         default:
714                 break;
715         }
716                         
717         return ret;
718 }
719
720
721 bool
722 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
723 {
724         bool ret = false;
725         
726         if (!rv->sensitive()) {
727                 return false;
728         }
729
730         switch (event->type) {
731         case GDK_BUTTON_PRESS:
732         case GDK_2BUTTON_PRESS:
733         case GDK_3BUTTON_PRESS:
734                 clicked_regionview = rv;
735                 clicked_control_point = 0;
736                 clicked_trackview = &clicked_regionview->get_time_axis_view();
737                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
738                 ret = button_press_handler (item, event, RegionViewNameHighlight);
739                 break;
740         case GDK_BUTTON_RELEASE:
741                 ret = button_release_handler (item, event, RegionViewNameHighlight);
742                 break;
743         case GDK_MOTION_NOTIFY:
744                 ret = motion_handler (item, event, RegionViewNameHighlight);
745                 break;
746         case GDK_ENTER_NOTIFY:
747                 ret = enter_handler (item, event, RegionViewNameHighlight);
748                 break;
749
750         case GDK_LEAVE_NOTIFY:
751                 ret = leave_handler (item, event, RegionViewNameHighlight);
752                 break;
753
754         default:
755                 break;
756         }
757
758         return ret;
759 }
760
761 bool
762 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
763 {
764         bool ret = false;
765
766         if (!rv->sensitive()) {
767                 return false;
768         }
769
770         switch (event->type) {
771         case GDK_BUTTON_PRESS:
772         case GDK_2BUTTON_PRESS:
773         case GDK_3BUTTON_PRESS:
774                 clicked_regionview = rv;
775                 clicked_control_point = 0;
776                 clicked_trackview = &clicked_regionview->get_time_axis_view();
777                 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
778                 ret = button_press_handler (item, event, RegionViewName);
779                 break;
780         case GDK_BUTTON_RELEASE:
781                 ret = button_release_handler (item, event, RegionViewName);
782                 break;
783         case GDK_MOTION_NOTIFY:
784                 ret = motion_handler (item, event, RegionViewName);
785                 break;
786         case GDK_ENTER_NOTIFY:
787                 ret = enter_handler (item, event, RegionViewName);
788                 break;
789
790         case GDK_LEAVE_NOTIFY:
791                 ret = leave_handler (item, event, RegionViewName);
792                 break;
793
794         default:
795                 break;
796         }
797
798         return ret;
799 }
800
801 bool
802 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
803 {
804         return typed_event (item, event, MarkerItem);
805 }
806
807 bool
808 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
809 {
810         return typed_event (item, event, MarkerBarItem);
811 }
812
813 bool
814 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
815 {
816         return typed_event (item, event, RangeMarkerBarItem);
817 }
818
819 bool
820 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
821 {
822         return typed_event (item, event, TransportMarkerBarItem);
823 }
824
825 bool
826 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
827 {
828         return typed_event (item, event, TempoMarkerItem);
829 }
830
831 bool
832 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
833 {
834         return typed_event (item, event, MeterMarkerItem);
835 }
836
837 bool
838 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
839 {
840         return typed_event (item, event, TempoBarItem);
841 }
842
843 bool
844 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
845 {
846         return typed_event (item, event, MeterBarItem);
847 }
848
849 bool
850 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
851 {
852         return typed_event (item, event, PlayheadCursorItem);
853 }
854
855 bool
856 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
857 {
858         return typed_event (item, event, EditCursorItem);
859 }
860
861 bool
862 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
863 {
864         return typed_event (item, event, NoItem);
865 }
866