clean up item event handling in MidiRegionViews by removing unnecessary InteractiveIt...
[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/audioplaylist.h"
28 #include "ardour/audioregion.h"
29 #include "ardour/region_factory.h"
30 #include "ardour/midi_region.h"
31
32 #include "editor.h"
33 #include "keyboard.h"
34 #include "public_editor.h"
35 #include "audio_region_view.h"
36 #include "audio_streamview.h"
37 #include "canvas-noevent-text.h"
38 #include "crossfade_view.h"
39 #include "audio_time_axis.h"
40 #include "region_gain_line.h"
41 #include "automation_line.h"
42 #include "automation_time_axis.h"
43 #include "automation_line.h"
44 #include "control_point.h"
45 #include "canvas_impl.h"
46 #include "simplerect.h"
47 #include "editor_drag.h"
48 #include "midi_time_axis.h"
49 #include "editor_regions.h"
50
51 #include "i18n.h"
52
53 using namespace std;
54 using namespace ARDOUR;
55 using namespace PBD;
56 using namespace Gtk;
57 using namespace ArdourCanvas;
58
59 using Gtkmm2ext::Keyboard;
60
61 bool
62 Editor::track_canvas_scroll (GdkEventScroll* ev)
63 {
64         nframes64_t xdelta;
65         int direction = ev->direction;
66
67   retry:
68         switch (direction) {
69         case GDK_SCROLL_UP:
70                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
71                         temporal_zoom_step (false);
72                         return true;
73                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
74                         direction = GDK_SCROLL_LEFT;
75                         goto retry;
76                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
77                         if (!current_stepping_trackview) {
78                                 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
79                                 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
80                                 current_stepping_trackview = p.first;
81                                 if (!current_stepping_trackview) {
82                                         return false;
83                                 }
84                         }
85                         last_track_height_step_timestamp = get_microseconds();
86                         current_stepping_trackview->step_height (true);
87                         return true;
88                 } else {
89                         scroll_tracks_up_line ();
90                         return true;
91                 }
92                 break;
93
94         case GDK_SCROLL_DOWN:
95                 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
96                         temporal_zoom_step (true);
97                         return true;
98                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
99                         direction = GDK_SCROLL_RIGHT;
100                         goto retry;
101                 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
102                         if (!current_stepping_trackview) {
103                                 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
104                                 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
105                                 current_stepping_trackview = p.first;
106                                 if (!current_stepping_trackview) {
107                                         return false;
108                                 }
109                         }
110                         last_track_height_step_timestamp = get_microseconds();
111                         current_stepping_trackview->step_height (false);
112                         return true;
113                 } else {
114                         scroll_tracks_down_line ();
115                         return true;
116                 }
117                 break;
118
119         case GDK_SCROLL_LEFT:
120                 xdelta = (current_page_frames() / 8);
121                 if (leftmost_frame > xdelta) {
122                         reset_x_origin (leftmost_frame - xdelta);
123                 } else {
124                         reset_x_origin (0);
125                 }
126                 break;
127
128         case GDK_SCROLL_RIGHT:
129                 xdelta = (current_page_frames() / 8);
130                 if (max_frames - xdelta > leftmost_frame) {
131                         reset_x_origin (leftmost_frame + xdelta);
132                 } else {
133                         reset_x_origin (max_frames - current_page_frames());
134                 }
135                 break;
136
137         default:
138                 /* what? */
139                 break;
140         }
141
142         return false;
143 }
144
145 bool
146 Editor::track_canvas_scroll_event (GdkEventScroll *event)
147 {
148         track_canvas->grab_focus();
149         return track_canvas_scroll (event);
150 }
151
152 bool
153 Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
154 {
155         selection->clear ();
156         track_canvas->grab_focus();
157         return false;
158 }
159
160 bool
161 Editor::track_canvas_button_release_event (GdkEventButton *event)
162 {
163         if (_drags->active ()) {
164                 _drags->end_grab ((GdkEvent*) event);
165         }
166         return false;
167 }
168
169 bool
170 Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/)
171 {
172         int x, y;
173         /* keep those motion events coming */
174         track_canvas->get_pointer (x, y);
175         return false;
176 }
177
178 bool
179 Editor::track_canvas_motion (GdkEvent *ev)
180 {
181         if (verbose_cursor_visible) {
182                 verbose_canvas_cursor->property_x() = clamp_verbose_cursor_x (ev->motion.x + 10);
183                 verbose_canvas_cursor->property_y() = clamp_verbose_cursor_y (ev->motion.y + 10);
184         }
185
186         return false;
187 }
188
189 bool
190 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
191 {
192         gint ret = FALSE;
193
194         switch (event->type) {
195         case GDK_BUTTON_PRESS:
196         case GDK_2BUTTON_PRESS:
197         case GDK_3BUTTON_PRESS:
198                 ret = button_press_handler (item, event, type);
199                 break;
200         case GDK_BUTTON_RELEASE:
201                 ret = button_release_handler (item, event, type);
202                 break;
203         case GDK_MOTION_NOTIFY:
204                 ret = motion_handler (item, event);
205                 break;
206
207         case GDK_ENTER_NOTIFY:
208                 ret = enter_handler (item, event, type);
209                 break;
210
211         case GDK_LEAVE_NOTIFY:
212                 ret = leave_handler (item, event, type);
213                 break;
214
215         default:
216                 break;
217         }
218         return ret;
219 }
220
221 bool
222 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
223 {
224         bool ret = false;
225
226         if (!rv->sensitive ()) {
227                 return false;
228         }
229
230         switch (event->type) {
231         case GDK_BUTTON_PRESS:
232         case GDK_2BUTTON_PRESS:
233         case GDK_3BUTTON_PRESS:
234                 clicked_regionview = rv;
235                 clicked_control_point = 0;
236                 clicked_axisview = &rv->get_time_axis_view();
237                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
238                 ret = button_press_handler (item, event, RegionItem);
239                 break;
240
241         case GDK_BUTTON_RELEASE:
242                 ret = button_release_handler (item, event, RegionItem);
243                 break;
244
245         case GDK_MOTION_NOTIFY:
246                 ret = motion_handler (item, event);
247                 break;
248
249         case GDK_ENTER_NOTIFY:
250                 set_entered_track (&rv->get_time_axis_view ());
251                 set_entered_regionview (rv);
252                 break;
253
254         case GDK_LEAVE_NOTIFY:
255                 set_entered_track (0);
256                 set_entered_regionview (0);
257                 break;
258
259         default:
260                 break;
261         }
262
263         return ret;
264 }
265
266 bool
267 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
268 {
269         bool ret = FALSE;
270
271         switch (event->type) {
272         case GDK_BUTTON_PRESS:
273         case GDK_2BUTTON_PRESS:
274         case GDK_3BUTTON_PRESS:
275                 clicked_regionview = 0;
276                 clicked_control_point = 0;
277                 clicked_axisview = tv;
278                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(tv);
279                 ret = button_press_handler (item, event, StreamItem);
280                 break;
281
282         case GDK_BUTTON_RELEASE:
283                 ret = button_release_handler (item, event, StreamItem);
284                 break;
285
286         case GDK_MOTION_NOTIFY:
287                 ret = motion_handler (item, event);
288                 break;
289
290         case GDK_ENTER_NOTIFY:
291                 set_entered_track (tv);
292                 break;
293
294         case GDK_LEAVE_NOTIFY:
295                 set_entered_track (0);
296                 break;
297
298         default:
299                 break;
300         }
301
302         return ret;
303 }
304
305 bool
306 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
307 {
308         bool ret = false;
309
310         switch (event->type) {
311         case GDK_BUTTON_PRESS:
312         case GDK_2BUTTON_PRESS:
313         case GDK_3BUTTON_PRESS:
314                 clicked_regionview = 0;
315                 clicked_control_point = 0;
316                 clicked_axisview = atv;
317                 clicked_routeview = 0;
318                 ret = button_press_handler (item, event, AutomationTrackItem);
319                 break;
320
321         case GDK_BUTTON_RELEASE:
322                 ret = button_release_handler (item, event, AutomationTrackItem);
323                 break;
324
325         case GDK_MOTION_NOTIFY:
326                 ret = motion_handler (item, event);
327                 break;
328
329         case GDK_ENTER_NOTIFY:
330                 ret = enter_handler (item, event, AutomationTrackItem);
331                 break;
332
333         case GDK_LEAVE_NOTIFY:
334                 ret = leave_handler (item, event, AutomationTrackItem);
335                 break;
336
337         default:
338                 break;
339         }
340
341         return ret;
342 }
343
344 bool
345 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
346 {
347         /* we handle only button 3 press/release events */
348
349         if (!rv->sensitive()) {
350                 return false;
351         }
352
353         switch (event->type) {
354         case GDK_BUTTON_PRESS:
355                 clicked_regionview = rv;
356                 clicked_control_point = 0;
357                 clicked_axisview = &rv->get_time_axis_view();
358                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
359                 if (event->button.button == 3) {
360                         return button_press_handler (item, event, FadeInItem);
361                 }
362                 break;
363
364         case GDK_BUTTON_RELEASE:
365                 if (event->button.button == 3) {
366                         return button_release_handler (item, event, FadeInItem);
367                 }
368                 break;
369
370         default:
371                 break;
372
373         }
374
375         /* proxy for the regionview */
376
377         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
378 }
379
380 bool
381 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
382 {
383         bool ret = false;
384
385         if (!rv->sensitive()) {
386                 return false;
387         }
388
389         switch (event->type) {
390         case GDK_BUTTON_PRESS:
391         case GDK_2BUTTON_PRESS:
392         case GDK_3BUTTON_PRESS:
393                 clicked_regionview = rv;
394                 clicked_control_point = 0;
395                 clicked_axisview = &rv->get_time_axis_view();
396                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
397                 ret = button_press_handler (item, event, FadeInHandleItem);
398                 break;
399
400         case GDK_BUTTON_RELEASE:
401                 ret = button_release_handler (item, event, FadeInHandleItem);
402                 break;
403
404         case GDK_MOTION_NOTIFY:
405                 ret = motion_handler (item, event);
406                 break;
407
408         case GDK_ENTER_NOTIFY:
409                 ret = enter_handler (item, event, FadeInHandleItem);
410                 break;
411
412         case GDK_LEAVE_NOTIFY:
413                 ret = leave_handler (item, event, FadeInHandleItem);
414                 break;
415
416         default:
417                 break;
418         }
419
420         return ret;
421 }
422
423 bool
424 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
425 {
426         /* we handle only button 3 press/release events */
427
428         if (!rv->sensitive()) {
429                 return false;
430         }
431
432         switch (event->type) {
433         case GDK_BUTTON_PRESS:
434                 clicked_regionview = rv;
435                 clicked_control_point = 0;
436                 clicked_axisview = &rv->get_time_axis_view();
437                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
438                 if (event->button.button == 3) {
439                         return button_press_handler (item, event, FadeOutItem);
440                 }
441                 break;
442
443         case GDK_BUTTON_RELEASE:
444                 if (event->button.button == 3) {
445                         return button_release_handler (item, event, FadeOutItem);
446                 }
447                 break;
448
449         default:
450                 break;
451
452         }
453
454         /* proxy for the regionview */
455
456         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
457 }
458
459 bool
460 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
461 {
462         bool ret = false;
463
464         if (!rv->sensitive()) {
465                 return false;
466         }
467
468         switch (event->type) {
469         case GDK_BUTTON_PRESS:
470         case GDK_2BUTTON_PRESS:
471         case GDK_3BUTTON_PRESS:
472                 clicked_regionview = rv;
473                 clicked_control_point = 0;
474                 clicked_axisview = &rv->get_time_axis_view();
475                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
476                 ret = button_press_handler (item, event, FadeOutHandleItem);
477                 break;
478
479         case GDK_BUTTON_RELEASE:
480                 ret = button_release_handler (item, event, FadeOutHandleItem);
481                 break;
482
483         case GDK_MOTION_NOTIFY:
484                 ret = motion_handler (item, event);
485                 break;
486
487         case GDK_ENTER_NOTIFY:
488                 ret = enter_handler (item, event, FadeOutHandleItem);
489                 break;
490
491         case GDK_LEAVE_NOTIFY:
492                 ret = leave_handler (item, event, FadeOutHandleItem);
493                 break;
494
495         default:
496                 break;
497         }
498
499         return ret;
500 }
501
502 struct DescendingRegionLayerSorter {
503     bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
504             return a->layer() > b->layer();
505     }
506 };
507
508 bool
509 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
510 {
511         /* we handle only button 3 press/release events */
512
513         switch (event->type) {
514         case GDK_BUTTON_PRESS:
515                 clicked_crossfadeview = xfv;
516                 clicked_axisview = &clicked_crossfadeview->get_time_axis_view();
517                 if (event->button.button == 3) {
518                         return button_press_handler (item, event, CrossfadeViewItem);
519                 }
520                 break;
521
522         case GDK_BUTTON_RELEASE:
523                 if (event->button.button == 3) {
524                         bool ret = button_release_handler (item, event, CrossfadeViewItem);
525                         return ret;
526                 }
527                 break;
528
529         default:
530                 break;
531
532         }
533
534         /* XXX do not forward double clicks */
535
536         if (event->type == GDK_2BUTTON_PRESS) {
537                 return false;
538         }
539
540         /* proxy for an underlying regionview */
541
542         /* XXX really need to check if we are in the name highlight,
543            and proxy to that when required.
544         */
545
546         TimeAxisView& tv (xfv->get_time_axis_view());
547         AudioTimeAxisView* atv;
548
549         if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
550
551                 if (atv->is_audio_track()) {
552
553                         boost::shared_ptr<AudioPlaylist> pl;
554                         if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->track()->playlist())) != 0) {
555
556                                 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
557                                 if (!rl->empty()) {
558
559                                         if (atv->layer_display() == Overlaid) {
560
561                                                 /* we're in overlaid mode; proxy to the uppermost region view */
562
563                                                 DescendingRegionLayerSorter cmp;
564                                                 rl->sort (cmp);
565
566                                                 RegionView* rv = atv->view()->find_view (rl->front());
567
568                                                 delete rl;
569
570                                                 /* proxy */
571                                                 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
572
573                                         } else {
574
575                                                 /* we're in stacked mode; proxy to the region view under the mouse */
576
577                                                 /* XXX: FIXME: this is an evil hack; it assumes that any event for which
578                                                    this proxy is being used has its GdkEvent laid out such that the y
579                                                    member is in the same place as that for a GdkEventButton */
580
581                                                 /* position of the event within the track */
582                                                 double cx = event->button.x;
583                                                 double cy = event->button.y;
584                                                 atv->view()->canvas_item()->w2i (cx, cy);
585
586                                                 /* hence layer that we're over */
587                                                 double const c = atv->view()->child_height ();
588                                                 layer_t const l = pl->top_layer () + 1 - (cy / c);
589
590                                                 /* hence region */
591                                                 Playlist::RegionList::iterator i = rl->begin();
592                                                 while (i != rl->end() && (*i)->layer() != l) {
593                                                         ++i;
594                                                 }
595
596                                                 if (i != rl->end()) {
597                                                         RegionView* rv = atv->view()->find_view (*i);
598                                                         delete rl;
599
600                                                         /* proxy */
601                                                         return canvas_region_view_event (event, rv->get_canvas_group(), rv);
602                                                 }
603                                         }
604                                 }
605
606                                 delete rl;
607                         }
608                 }
609         }
610
611         return TRUE;
612 }
613
614 bool
615 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
616 {
617         switch (event->type) {
618         case GDK_BUTTON_PRESS:
619         case GDK_2BUTTON_PRESS:
620         case GDK_3BUTTON_PRESS:
621                 clicked_control_point = cp;
622                 clicked_axisview = &cp->line().trackview;
623                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
624                 clicked_regionview = 0;
625                 break;
626
627         case GDK_SCROLL_UP:
628                 break;
629
630         case GDK_SCROLL_DOWN:
631                 break;
632
633         default:
634                 break;
635         }
636
637         return typed_event (item, event, ControlPointItem);
638 }
639
640 bool
641 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
642 {
643         ItemType type;
644
645         if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
646                 type = GainLineItem;
647         } else {
648                 type = AutomationLineItem;
649         }
650
651         return typed_event (item, event, type);
652 }
653
654 bool
655 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
656 {
657         bool ret = false;
658
659         switch (event->type) {
660         case GDK_BUTTON_PRESS:
661         case GDK_2BUTTON_PRESS:
662         case GDK_3BUTTON_PRESS:
663                 clicked_selection = rect->id;
664                 ret = button_press_handler (item, event, SelectionItem);
665                 break;
666         case GDK_BUTTON_RELEASE:
667                 ret = button_release_handler (item, event, SelectionItem);
668                 break;
669         case GDK_MOTION_NOTIFY:
670                 ret = motion_handler (item, event);
671                 break;
672                 /* Don't need these at the moment. */
673         case GDK_ENTER_NOTIFY:
674                 ret = enter_handler (item, event, SelectionItem);
675                 break;
676
677         case GDK_LEAVE_NOTIFY:
678                 ret = leave_handler (item, event, SelectionItem);
679                 break;
680
681         default:
682                 break;
683         }
684
685         return ret;
686 }
687
688 bool
689 Editor::canvas_selection_start_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, StartSelectionTrimItem);
699                 break;
700         case GDK_BUTTON_RELEASE:
701                 ret = button_release_handler (item, event, StartSelectionTrimItem);
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, StartSelectionTrimItem);
708                 break;
709
710         case GDK_LEAVE_NOTIFY:
711                 ret = leave_handler (item, event, StartSelectionTrimItem);
712                 break;
713
714         default:
715                 break;
716         }
717
718         return ret;
719 }
720
721 bool
722 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
723 {
724         bool ret = false;
725
726         switch (event->type) {
727         case GDK_BUTTON_PRESS:
728         case GDK_2BUTTON_PRESS:
729         case GDK_3BUTTON_PRESS:
730                 clicked_selection = rect->id;
731                 ret = button_press_handler (item, event, EndSelectionTrimItem);
732                 break;
733         case GDK_BUTTON_RELEASE:
734                 ret = button_release_handler (item, event, EndSelectionTrimItem);
735                 break;
736         case GDK_MOTION_NOTIFY:
737                 ret = motion_handler (item, event);
738                 break;
739         case GDK_ENTER_NOTIFY:
740                 ret = enter_handler (item, event, EndSelectionTrimItem);
741                 break;
742
743         case GDK_LEAVE_NOTIFY:
744                 ret = leave_handler (item, event, EndSelectionTrimItem);
745                 break;
746
747         default:
748                 break;
749         }
750
751         return ret;
752 }
753
754 bool
755 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
756 {
757         bool ret = false;
758
759         /* frame handles are not active when in internal edit mode, because actual notes
760            might be in the area occupied by the handle - we want them to be editable as normal.
761         */
762
763         if (internal_editing() || !rv->sensitive()) {
764                 return false;
765         }
766
767         /* NOTE: frame handles pretend to be the colored trim bar from an event handling
768            perspective. XXX change this ??
769         */
770
771         switch (event->type) {
772         case GDK_BUTTON_PRESS:
773         case GDK_2BUTTON_PRESS:
774         case GDK_3BUTTON_PRESS:
775                 clicked_regionview = rv;
776                 clicked_control_point = 0;
777                 clicked_axisview = &clicked_regionview->get_time_axis_view();
778                 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
779                 ret = button_press_handler (item, event, RegionViewNameHighlight);
780                 break;
781         case GDK_BUTTON_RELEASE:
782                 ret = button_release_handler (item, event, RegionViewNameHighlight);
783                 break;
784         case GDK_MOTION_NOTIFY:
785                 ret = motion_handler (item, event);
786                 break;
787         case GDK_ENTER_NOTIFY:
788                 ret = enter_handler (item, event, RegionViewNameHighlight);
789                 break;
790
791         case GDK_LEAVE_NOTIFY:
792                 ret = leave_handler (item, event, RegionViewNameHighlight);
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);
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);
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
949 bool
950 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
951 {
952         if (!internal_editing()) {
953                 return false;
954         }
955
956         cerr << "Forward note event item on to editor\n";
957         return typed_event (item, event, NoteItem);
958 }
959
960 bool
961 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/, int x, int y, guint /*time*/)
962 {
963         double wx;
964         double wy;
965         track_canvas->window_to_world (x, y, wx, wy);
966
967         GdkEvent event;
968         event.type = GDK_MOTION_NOTIFY;
969         event.button.x = wx;
970         event.button.y = wy;
971         /* assume we're dragging with button 1 */
972         event.motion.state = Gdk::BUTTON1_MASK;
973
974         if (!_drags->active ()) {
975
976                 double px;
977                 double py;
978                 nframes64_t const pos = event_frame (&event, &px, &py);
979
980                 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
981                 if (tv.first == 0) {
982                         return true;
983                 }
984
985                 RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
986                 if (rtav == 0 || !rtav->is_track ()) {
987                         return true;
988                 }
989
990                 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
991
992                 if (!region) {
993                         return true;
994                 }
995
996                 boost::shared_ptr<Region> region_copy = RegionFactory::create (region);
997
998                 if (boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
999                     dynamic_cast<AudioTimeAxisView*> (tv.first) == 0) {
1000
1001                         /* audio -> non-audio */
1002                         return true;
1003                 }
1004
1005                 if (boost::dynamic_pointer_cast<MidiRegion> (region_copy) == 0 &&
1006                     dynamic_cast<MidiTimeAxisView*> (tv.first) != 0) {
1007
1008                         /* MIDI -> non-MIDI */
1009                         return true;
1010                 }
1011
1012                 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1013         }
1014
1015         _drags->motion_handler (&event, false);
1016
1017         return true;
1018 }