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