Remove over 500 unnecessary includes (including 54 of session.h).
[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/midi_region.h"
28 #include "ardour/region_factory.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 "canvas-noevent-text.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 "editor_drag.h"
45 #include "midi_time_axis.h"
46 #include "editor_regions.h"
47 #include "verbose_cursor.h"
48
49 #include "i18n.h"
50
51 using namespace std;
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace Gtk;
55 using namespace ArdourCanvas;
56
57 using Gtkmm2ext::Keyboard;
58
59 bool
60 Editor::track_canvas_scroll (GdkEventScroll* ev)
61 {
62         framepos_t xdelta;
63         int direction = ev->direction;
64
65   retry:
66         switch (direction) {
67         case GDK_SCROLL_UP:
68                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
69                         temporal_zoom_step (false);
70                         return true;
71                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
72                         direction = GDK_SCROLL_LEFT;
73                         goto retry;
74                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
75                         if (!current_stepping_trackview) {
76                                 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
77                                 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
78                                 current_stepping_trackview = p.first;
79                                 if (!current_stepping_trackview) {
80                                         return false;
81                                 }
82                         }
83                         last_track_height_step_timestamp = get_microseconds();
84                         current_stepping_trackview->step_height (false);
85                         return true;
86                 } else {
87                         scroll_tracks_up_line ();
88                         return true;
89                 }
90                 break;
91
92         case GDK_SCROLL_DOWN:
93                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
94                         temporal_zoom_step (true);
95                         return true;
96                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
97                         direction = GDK_SCROLL_RIGHT;
98                         goto retry;
99                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
100                         if (!current_stepping_trackview) {
101                                 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
102                                 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
103                                 current_stepping_trackview = p.first;
104                                 if (!current_stepping_trackview) {
105                                         return false;
106                                 }
107                         }
108                         last_track_height_step_timestamp = get_microseconds();
109                         current_stepping_trackview->step_height (true);
110                         return true;
111                 } else {
112                         scroll_tracks_down_line ();
113                         return true;
114                 }
115                 break;
116
117         case GDK_SCROLL_LEFT:
118                 xdelta = (current_page_frames() / 8);
119                 if (leftmost_frame > xdelta) {
120                         reset_x_origin (leftmost_frame - xdelta);
121                 } else {
122                         reset_x_origin (0);
123                 }
124                 break;
125
126         case GDK_SCROLL_RIGHT:
127                 xdelta = (current_page_frames() / 8);
128                 if (max_framepos - xdelta > leftmost_frame) {
129                         reset_x_origin (leftmost_frame + xdelta);
130                 } else {
131                         reset_x_origin (max_framepos - current_page_frames());
132                 }
133                 break;
134
135         default:
136                 /* what? */
137                 break;
138         }
139
140         return false;
141 }
142
143 bool
144 Editor::track_canvas_scroll_event (GdkEventScroll *event)
145 {
146         track_canvas->grab_focus();
147         return track_canvas_scroll (event);
148 }
149
150 bool
151 Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
152 {
153         selection->clear ();
154         track_canvas->grab_focus();
155         return false;
156 }
157
158 bool
159 Editor::track_canvas_button_release_event (GdkEventButton *event)
160 {
161         if (_drags->active ()) {
162                 _drags->end_grab ((GdkEvent*) event);
163         }
164         return false;
165 }
166
167 bool
168 Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/)
169 {
170         int x, y;
171         /* keep those motion events coming */
172         track_canvas->get_pointer (x, y);
173         return false;
174 }
175
176 bool
177 Editor::track_canvas_motion (GdkEvent *ev)
178 {
179         if (_verbose_cursor->visible ()) {
180                 _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10);
181         }
182
183         return false;
184 }
185
186 bool
187 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
188 {
189         gint ret = FALSE;
190
191         switch (event->type) {
192         case GDK_BUTTON_PRESS:
193         case GDK_2BUTTON_PRESS:
194         case GDK_3BUTTON_PRESS:
195                 ret = button_press_handler (item, event, type);
196                 break;
197         case GDK_BUTTON_RELEASE:
198                 ret = button_release_handler (item, event, type);
199                 break;
200         case GDK_MOTION_NOTIFY:
201                 ret = motion_handler (item, event);
202                 break;
203
204         case GDK_ENTER_NOTIFY:
205                 ret = enter_handler (item, event, type);
206                 break;
207
208         case GDK_LEAVE_NOTIFY:
209                 ret = leave_handler (item, event, type);
210                 break;
211
212         case GDK_KEY_PRESS:
213                 ret = key_press_handler (item, event, type);
214                 break;
215
216         case GDK_KEY_RELEASE:
217                 ret = key_release_handler (item, event, type);
218                 break;
219
220         default:
221                 break;
222         }
223         return ret;
224 }
225
226 bool
227 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
228 {
229         bool ret = false;
230
231         if (!rv->sensitive ()) {
232                 return false;
233         }
234
235         switch (event->type) {
236         case GDK_BUTTON_PRESS:
237         case GDK_2BUTTON_PRESS:
238         case GDK_3BUTTON_PRESS:
239                 clicked_regionview = rv;
240                 clicked_control_point = 0;
241                 clicked_axisview = &rv->get_time_axis_view();
242                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
243                 ret = button_press_handler (item, event, RegionItem);
244                 break;
245
246         case GDK_BUTTON_RELEASE:
247                 ret = button_release_handler (item, event, RegionItem);
248                 break;
249
250         case GDK_MOTION_NOTIFY:
251                 ret = motion_handler (item, event);
252                 break;
253
254         case GDK_ENTER_NOTIFY:
255                 set_entered_track (&rv->get_time_axis_view ());
256                 set_entered_regionview (rv);
257                 break;
258
259         case GDK_LEAVE_NOTIFY:
260                 set_entered_track (0);
261                 set_entered_regionview (0);
262                 break;
263
264         default:
265                 break;
266         }
267
268         return ret;
269 }
270
271 bool
272 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
273 {
274         bool ret = FALSE;
275
276         switch (event->type) {
277         case GDK_BUTTON_PRESS:
278         case GDK_2BUTTON_PRESS:
279         case GDK_3BUTTON_PRESS:
280                 clicked_regionview = 0;
281                 clicked_control_point = 0;
282                 clicked_axisview = tv;
283                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
284                 ret = button_press_handler (item, event, StreamItem);
285                 break;
286
287         case GDK_BUTTON_RELEASE:
288                 ret = button_release_handler (item, event, StreamItem);
289                 break;
290
291         case GDK_MOTION_NOTIFY:
292                 ret = motion_handler (item, event);
293                 break;
294
295         case GDK_ENTER_NOTIFY:
296                 set_entered_track (tv);
297                 break;
298
299         case GDK_LEAVE_NOTIFY:
300                 set_entered_track (0);
301                 break;
302
303         default:
304                 break;
305         }
306
307         return ret;
308 }
309
310 bool
311 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
312 {
313         bool ret = false;
314
315         switch (event->type) {
316         case GDK_BUTTON_PRESS:
317         case GDK_2BUTTON_PRESS:
318         case GDK_3BUTTON_PRESS:
319                 clicked_regionview = 0;
320                 clicked_control_point = 0;
321                 clicked_axisview = atv;
322                 clicked_routeview = 0;
323                 ret = button_press_handler (item, event, AutomationTrackItem);
324                 break;
325
326         case GDK_BUTTON_RELEASE:
327                 ret = button_release_handler (item, event, AutomationTrackItem);
328                 break;
329
330         case GDK_MOTION_NOTIFY:
331                 ret = motion_handler (item, event);
332                 break;
333
334         case GDK_ENTER_NOTIFY:
335                 ret = enter_handler (item, event, AutomationTrackItem);
336                 break;
337
338         case GDK_LEAVE_NOTIFY:
339                 ret = leave_handler (item, event, AutomationTrackItem);
340                 break;
341
342         default:
343                 break;
344         }
345
346         return ret;
347 }
348
349 bool
350 Editor::canvas_start_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
351 {
352         if (!rv->sensitive()) {
353                 return false;
354         }
355
356         switch (event->type) {
357         case GDK_BUTTON_PRESS:
358                 clicked_regionview = rv;
359                 clicked_control_point = 0;
360                 clicked_axisview = &rv->get_time_axis_view();
361                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
362                 if (event->button.button == 3) {
363                         return button_press_handler (item, event, StartCrossFadeItem);
364                 }
365                 break;
366
367         case GDK_BUTTON_RELEASE:
368                 if (event->button.button == 3) {
369                         return button_release_handler (item, event, StartCrossFadeItem);
370                 }
371                 break;
372
373         default:
374                 break;
375
376         }
377
378         return typed_event (item, event, StartCrossFadeItem);
379 }
380
381 bool
382 Editor::canvas_end_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
383 {
384         if (!rv->sensitive()) {
385                 return false;
386         }
387
388         switch (event->type) {
389         case GDK_BUTTON_PRESS:
390                 clicked_regionview = rv;
391                 clicked_control_point = 0;
392                 clicked_axisview = &rv->get_time_axis_view();
393                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
394                 if (event->button.button == 3) {
395                         return button_press_handler (item, event, EndCrossFadeItem);
396                 }
397                 break;
398
399         case GDK_BUTTON_RELEASE:
400                 if (event->button.button == 3) {
401                         return button_release_handler (item, event, EndCrossFadeItem);
402                 }
403                 break;
404
405         default:
406                 break;
407
408         }
409
410         return typed_event (item, event, EndCrossFadeItem);
411 }
412
413 bool
414 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
415 {
416         /* we handle only button 3 press/release events */
417
418         if (!rv->sensitive()) {
419                 return false;
420         }
421
422         switch (event->type) {
423         case GDK_BUTTON_PRESS:
424                 clicked_regionview = rv;
425                 clicked_control_point = 0;
426                 clicked_axisview = &rv->get_time_axis_view();
427                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
428                 if (event->button.button == 3) {
429                         return button_press_handler (item, event, FadeInItem);
430                 }
431                 break;
432
433         case GDK_BUTTON_RELEASE:
434                 if (event->button.button == 3) {
435                         return button_release_handler (item, event, FadeInItem);
436                 }
437                 break;
438
439         default:
440                 break;
441
442         }
443
444         /* proxy for the regionview */
445
446         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
447 }
448
449 bool
450 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
451 {
452         bool ret = false;
453
454         if (!rv->sensitive()) {
455                 return false;
456         }
457
458         switch (event->type) {
459         case GDK_BUTTON_PRESS:
460         case GDK_2BUTTON_PRESS:
461         case GDK_3BUTTON_PRESS:
462                 clicked_regionview = rv;
463                 clicked_control_point = 0;
464                 clicked_axisview = &rv->get_time_axis_view();
465                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
466                 ret = button_press_handler (item, event, FadeInHandleItem);
467                 break;
468
469         case GDK_BUTTON_RELEASE:
470                 ret = button_release_handler (item, event, FadeInHandleItem);
471                 break;
472
473         case GDK_MOTION_NOTIFY:
474                 ret = motion_handler (item, event);
475                 break;
476
477         case GDK_ENTER_NOTIFY:
478                 set_entered_regionview (rv);
479                 ret = enter_handler (item, event, FadeInHandleItem);
480                 break;
481
482         case GDK_LEAVE_NOTIFY:
483                 set_entered_regionview (0);
484                 ret = leave_handler (item, event, FadeInHandleItem);
485                 break;
486
487         default:
488                 break;
489         }
490
491         return ret;
492 }
493
494 bool
495 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
496 {
497         /* we handle only button 3 press/release events */
498
499         if (!rv->sensitive()) {
500                 return false;
501         }
502
503         switch (event->type) {
504         case GDK_BUTTON_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                 if (event->button.button == 3) {
510                         return button_press_handler (item, event, FadeOutItem);
511                 }
512                 break;
513
514         case GDK_BUTTON_RELEASE:
515                 if (event->button.button == 3) {
516                         return button_release_handler (item, event, FadeOutItem);
517                 }
518                 break;
519
520         default:
521                 break;
522
523         }
524
525         /* proxy for the regionview */
526
527         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
528 }
529
530 bool
531 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
532 {
533         bool ret = false;
534
535         if (!rv->sensitive()) {
536                 return false;
537         }
538
539         switch (event->type) {
540         case GDK_BUTTON_PRESS:
541         case GDK_2BUTTON_PRESS:
542         case GDK_3BUTTON_PRESS:
543                 clicked_regionview = rv;
544                 clicked_control_point = 0;
545                 clicked_axisview = &rv->get_time_axis_view();
546                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
547                 ret = button_press_handler (item, event, FadeOutHandleItem);
548                 break;
549
550         case GDK_BUTTON_RELEASE:
551                 ret = button_release_handler (item, event, FadeOutHandleItem);
552                 break;
553
554         case GDK_MOTION_NOTIFY:
555                 ret = motion_handler (item, event);
556                 break;
557
558         case GDK_ENTER_NOTIFY:
559                 set_entered_regionview (rv);
560                 ret = enter_handler (item, event, FadeOutHandleItem);
561                 break;
562
563         case GDK_LEAVE_NOTIFY:
564                 set_entered_regionview (0);
565                 ret = leave_handler (item, event, FadeOutHandleItem);
566                 break;
567
568         default:
569                 break;
570         }
571
572         return ret;
573 }
574
575 struct DescendingRegionLayerSorter {
576     bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
577             return a->layer() > b->layer();
578     }
579 };
580
581 bool
582 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
583 {
584         switch (event->type) {
585         case GDK_BUTTON_PRESS:
586         case GDK_2BUTTON_PRESS:
587         case GDK_3BUTTON_PRESS:
588                 clicked_control_point = cp;
589                 clicked_axisview = &cp->line().trackview;
590                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
591                 clicked_regionview = 0;
592                 break;
593
594         case GDK_SCROLL_UP:
595                 break;
596
597         case GDK_SCROLL_DOWN:
598                 break;
599
600         default:
601                 break;
602         }
603
604         return typed_event (item, event, ControlPointItem);
605 }
606
607 bool
608 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
609 {
610         ItemType type;
611
612         if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
613                 type = GainLineItem;
614         } else {
615                 type = AutomationLineItem;
616         }
617
618         return typed_event (item, event, type);
619 }
620
621 bool
622 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
623 {
624         bool ret = false;
625
626         switch (event->type) {
627         case GDK_BUTTON_PRESS:
628         case GDK_2BUTTON_PRESS:
629         case GDK_3BUTTON_PRESS:
630                 clicked_selection = rect->id;
631                 ret = button_press_handler (item, event, SelectionItem);
632                 break;
633         case GDK_BUTTON_RELEASE:
634                 ret = button_release_handler (item, event, SelectionItem);
635                 break;
636         case GDK_MOTION_NOTIFY:
637                 ret = motion_handler (item, event);
638                 break;
639                 /* Don't need these at the moment. */
640         case GDK_ENTER_NOTIFY:
641                 ret = enter_handler (item, event, SelectionItem);
642                 break;
643
644         case GDK_LEAVE_NOTIFY:
645                 ret = leave_handler (item, event, SelectionItem);
646                 break;
647
648         default:
649                 break;
650         }
651
652         return ret;
653 }
654
655 bool
656 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
657 {
658         bool ret = false;
659
660         switch (event->type) {
661         case GDK_BUTTON_PRESS:
662         case GDK_2BUTTON_PRESS:
663         case GDK_3BUTTON_PRESS:
664                 clicked_selection = rect->id;
665                 ret = button_press_handler (item, event, StartSelectionTrimItem);
666                 break;
667         case GDK_BUTTON_RELEASE:
668                 ret = button_release_handler (item, event, StartSelectionTrimItem);
669                 break;
670         case GDK_MOTION_NOTIFY:
671                 ret = motion_handler (item, event);
672                 break;
673         case GDK_ENTER_NOTIFY:
674                 ret = enter_handler (item, event, StartSelectionTrimItem);
675                 break;
676
677         case GDK_LEAVE_NOTIFY:
678                 ret = leave_handler (item, event, StartSelectionTrimItem);
679                 break;
680
681         default:
682                 break;
683         }
684
685         return ret;
686 }
687
688 bool
689 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
690 {
691         bool ret = false;
692
693         switch (event->type) {
694         case GDK_BUTTON_PRESS:
695         case GDK_2BUTTON_PRESS:
696         case GDK_3BUTTON_PRESS:
697                 clicked_selection = rect->id;
698                 ret = button_press_handler (item, event, EndSelectionTrimItem);
699                 break;
700         case GDK_BUTTON_RELEASE:
701                 ret = button_release_handler (item, event, EndSelectionTrimItem);
702                 break;
703         case GDK_MOTION_NOTIFY:
704                 ret = motion_handler (item, event);
705                 break;
706         case GDK_ENTER_NOTIFY:
707                 ret = enter_handler (item, event, EndSelectionTrimItem);
708                 break;
709
710         case GDK_LEAVE_NOTIFY:
711                 ret = leave_handler (item, event, EndSelectionTrimItem);
712                 break;
713
714         default:
715                 break;
716         }
717
718         return ret;
719 }
720
721 bool
722 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
723 {
724         bool ret = false;
725
726         /* frame handles are not active when in internal edit mode, because actual notes
727            might be in the area occupied by the handle - we want them to be editable as normal.
728         */
729
730         if (internal_editing() || !rv->sensitive()) {
731                 return false;
732         }
733
734         /* NOTE: frame handles pretend to be the colored trim bar from an event handling
735            perspective. XXX change this ??
736         */
737
738         ItemType type;
739
740         if (item->get_data ("isleft")) {
741                 type = LeftFrameHandle;
742         } else {
743                 type = RightFrameHandle;
744         }
745
746         switch (event->type) {
747         case GDK_BUTTON_PRESS:
748         case GDK_2BUTTON_PRESS:
749         case GDK_3BUTTON_PRESS:
750                 clicked_regionview = rv;
751                 clicked_control_point = 0;
752                 clicked_axisview = &clicked_regionview->get_time_axis_view();
753                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
754                 ret = button_press_handler (item, event, type);
755                 break;
756         case GDK_BUTTON_RELEASE:
757                 ret = button_release_handler (item, event, type);
758                 break;
759         case GDK_MOTION_NOTIFY:
760                 ret = motion_handler (item, event);
761                 break;
762         case GDK_ENTER_NOTIFY:
763                 set_entered_regionview (rv);
764                 ret = enter_handler (item, event, type);
765                 break;
766
767         case GDK_LEAVE_NOTIFY:
768                 set_entered_regionview (0);
769                 ret = leave_handler (item, event, type);
770                 break;
771
772         default:
773                 break;
774         }
775
776         return ret;
777 }
778
779
780 bool
781 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
782 {
783         bool ret = false;
784
785         if (!rv->sensitive()) {
786                 return false;
787         }
788
789         switch (event->type) {
790         case GDK_BUTTON_PRESS:
791         case GDK_2BUTTON_PRESS:
792         case GDK_3BUTTON_PRESS:
793                 clicked_regionview = rv;
794                 clicked_control_point = 0;
795                 clicked_axisview = &clicked_regionview->get_time_axis_view();
796                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
797                 ret = button_press_handler (item, event, RegionViewNameHighlight);
798                 break;
799         case GDK_BUTTON_RELEASE:
800                 ret = button_release_handler (item, event, RegionViewNameHighlight);
801                 break;
802         case GDK_MOTION_NOTIFY:
803                 motion_handler (item, event);
804                 ret = true; // force this to avoid progagating the event into the regionview
805                 break;
806         case GDK_ENTER_NOTIFY:
807                 set_entered_regionview (rv);
808                 ret = enter_handler (item, event, RegionViewNameHighlight);
809                 break;
810
811         case GDK_LEAVE_NOTIFY:
812                 set_entered_regionview (0);
813                 ret = leave_handler (item, event, RegionViewNameHighlight);
814                 break;
815
816         default:
817                 break;
818         }
819
820         return ret;
821 }
822
823 bool
824 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
825 {
826         bool ret = false;
827
828         if (!rv->sensitive()) {
829                 return false;
830         }
831
832         switch (event->type) {
833         case GDK_BUTTON_PRESS:
834         case GDK_2BUTTON_PRESS:
835         case GDK_3BUTTON_PRESS:
836                 clicked_regionview = rv;
837                 clicked_control_point = 0;
838                 clicked_axisview = &clicked_regionview->get_time_axis_view();
839                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
840                 ret = button_press_handler (item, event, RegionViewName);
841                 break;
842         case GDK_BUTTON_RELEASE:
843                 ret = button_release_handler (item, event, RegionViewName);
844                 break;
845         case GDK_MOTION_NOTIFY:
846                 ret = motion_handler (item, event);
847                 break;
848         case GDK_ENTER_NOTIFY:
849                 set_entered_regionview (rv);
850                 ret = enter_handler (item, event, RegionViewName);
851                 break;
852
853         case GDK_LEAVE_NOTIFY:
854                 set_entered_regionview (0);
855                 ret = leave_handler (item, event, RegionViewName);
856                 break;
857
858         default:
859                 break;
860         }
861
862         return ret;
863 }
864
865 bool
866 Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*)
867 {
868         bool ret = false;
869
870         switch (event->type) {
871         case GDK_BUTTON_PRESS:
872         case GDK_2BUTTON_PRESS:
873         case GDK_3BUTTON_PRESS:
874                 clicked_regionview = 0;
875                 clicked_control_point = 0;
876                 clicked_axisview = 0;
877                 clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
878                 ret = button_press_handler (item, event, FeatureLineItem);
879                 break;
880
881         case GDK_BUTTON_RELEASE:
882                 ret = button_release_handler (item, event, FeatureLineItem);
883                 break;
884
885         case GDK_MOTION_NOTIFY:
886                 ret = motion_handler (item, event);
887                 break;
888
889         case GDK_ENTER_NOTIFY:
890                 ret = enter_handler (item, event, FeatureLineItem);
891                 break;
892
893         case GDK_LEAVE_NOTIFY:
894                 ret = leave_handler (item, event, FeatureLineItem);
895                 break;
896
897         default:
898                 break;
899         }
900
901         return ret;
902 }
903
904 bool
905 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
906 {
907         return typed_event (item, event, MarkerItem);
908 }
909
910 bool
911 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
912 {
913         return typed_event (item, event, MarkerBarItem);
914 }
915
916 bool
917 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
918 {
919         return typed_event (item, event, RangeMarkerBarItem);
920 }
921
922 bool
923 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
924 {
925         return typed_event (item, event, TransportMarkerBarItem);
926 }
927
928 bool
929 Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
930 {
931         return typed_event (item, event, CdMarkerBarItem);
932 }
933
934 bool
935 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/)
936 {
937         return typed_event (item, event, TempoMarkerItem);
938 }
939
940 bool
941 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/)
942 {
943         return typed_event (item, event, MeterMarkerItem);
944 }
945
946 bool
947 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
948 {
949         return typed_event (item, event, TempoBarItem);
950 }
951
952 bool
953 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
954 {
955         return typed_event (item, event, MeterBarItem);
956 }
957
958 bool
959 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
960 {
961         return typed_event (item, event, PlayheadCursorItem);
962 }
963
964 bool
965 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
966 {
967         return typed_event (item, event, NoItem);
968 }
969
970 bool
971 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
972 {
973         if (!internal_editing()) {
974                 return false;
975         }
976
977         return typed_event (item, event, NoteItem);
978 }
979
980 bool
981 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/, int x, int y, guint /*time*/)
982 {
983         double wx;
984         double wy;
985         track_canvas->window_to_world (x, y, wx, wy);
986
987         GdkEvent event;
988         event.type = GDK_MOTION_NOTIFY;
989         event.button.x = wx;
990         event.button.y = wy;
991         /* assume we're dragging with button 1 */
992         event.motion.state = Gdk::BUTTON1_MASK;
993
994         if (!_drags->active ()) {
995
996                 double px;
997                 double py;
998                 framepos_t const pos = event_frame (&event, &px, &py);
999
1000                 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1001                 if (tv.first == 0) {
1002                         return true;
1003                 }
1004
1005                 RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1006                 if (rtav == 0 || !rtav->is_track ()) {
1007                         return true;
1008                 }
1009
1010                 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
1011
1012                 if (!region) {
1013                         return true;
1014                 }
1015
1016                 boost::shared_ptr<Region> region_copy = RegionFactory::create (region);
1017
1018                 if (boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
1019                     dynamic_cast<AudioTimeAxisView*> (tv.first) == 0) {
1020
1021                         /* audio -> non-audio */
1022                         return true;
1023                 }
1024
1025                 if (boost::dynamic_pointer_cast<MidiRegion> (region_copy) != 0 &&
1026                     dynamic_cast<MidiTimeAxisView*> (tv.first) == 0) {
1027
1028                         /* MIDI -> non-MIDI */
1029                         return true;
1030                 }
1031
1032                 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1033         }
1034
1035         _drags->motion_handler (&event, false);
1036
1037         return true;
1038 }
1039
1040 bool
1041 Editor::key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType)
1042 {
1043         return false;
1044 }
1045
1046 bool
1047 Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType type)
1048 {
1049
1050         bool handled = false;
1051
1052         switch (type) {
1053         case TempoMarkerItem:
1054                 switch (event->key.keyval) {
1055                 case GDK_Delete:
1056                         remove_tempo_marker (item);
1057                         handled = true;
1058                         break;
1059                 default:
1060                         break;
1061                 }
1062                 break;
1063
1064         case MeterMarkerItem:
1065                 switch (event->key.keyval) {
1066                 case GDK_Delete:
1067                         remove_meter_marker (item);
1068                         handled = true;
1069                         break;
1070                 default:
1071                         break;
1072                 }
1073                 break;
1074
1075         default:
1076                 break;
1077         }
1078
1079         return handled;
1080 }