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