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