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