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