Remove erroneous assert which I added earlier.
[ardour2.git] / gtk2_ardour / editor_canvas_events.cc
blob5dbc94a89748bfb81868f7835e70f4c4312c3b98
1 /*
2 Copyright (C) 2000 Paul Davis
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.
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.
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.
20 #include <cstdlib>
21 #include <cmath>
22 #include <algorithm>
23 #include <typeinfo>
25 #include "pbd/stacktrace.h"
27 #include "ardour/audioplaylist.h"
28 #include "ardour/audioregion.h"
29 #include "ardour/region_factory.h"
30 #include "ardour/midi_region.h"
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 #include "verbose_cursor.h"
52 #include "i18n.h"
54 using namespace std;
55 using namespace ARDOUR;
56 using namespace PBD;
57 using namespace Gtk;
58 using namespace ArdourCanvas;
60 using Gtkmm2ext::Keyboard;
62 bool
63 Editor::track_canvas_scroll (GdkEventScroll* ev)
65 framepos_t xdelta;
66 int direction = ev->direction;
68 retry:
69 switch (direction) {
70 case GDK_SCROLL_UP:
71 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
72 temporal_zoom_step (false);
73 return true;
74 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
75 direction = GDK_SCROLL_LEFT;
76 goto retry;
77 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
78 if (!current_stepping_trackview) {
79 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
80 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
81 current_stepping_trackview = p.first;
82 if (!current_stepping_trackview) {
83 return false;
86 last_track_height_step_timestamp = get_microseconds();
87 current_stepping_trackview->step_height (false);
88 return true;
89 } else {
90 scroll_tracks_up_line ();
91 return true;
93 break;
95 case GDK_SCROLL_DOWN:
96 if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
97 temporal_zoom_step (true);
98 return true;
99 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
100 direction = GDK_SCROLL_RIGHT;
101 goto retry;
102 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) {
103 if (!current_stepping_trackview) {
104 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
105 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize);
106 current_stepping_trackview = p.first;
107 if (!current_stepping_trackview) {
108 return false;
111 last_track_height_step_timestamp = get_microseconds();
112 current_stepping_trackview->step_height (true);
113 return true;
114 } else {
115 scroll_tracks_down_line ();
116 return true;
118 break;
120 case GDK_SCROLL_LEFT:
121 xdelta = (current_page_frames() / 8);
122 if (leftmost_frame > xdelta) {
123 reset_x_origin (leftmost_frame - xdelta);
124 } else {
125 reset_x_origin (0);
127 break;
129 case GDK_SCROLL_RIGHT:
130 xdelta = (current_page_frames() / 8);
131 if (max_framepos - xdelta > leftmost_frame) {
132 reset_x_origin (leftmost_frame + xdelta);
133 } else {
134 reset_x_origin (max_framepos - current_page_frames());
136 break;
138 default:
139 /* what? */
140 break;
143 return false;
146 bool
147 Editor::track_canvas_scroll_event (GdkEventScroll *event)
149 track_canvas->grab_focus();
150 return track_canvas_scroll (event);
153 bool
154 Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
156 selection->clear ();
157 track_canvas->grab_focus();
158 return false;
161 bool
162 Editor::track_canvas_button_release_event (GdkEventButton *event)
164 if (_drags->active ()) {
165 _drags->end_grab ((GdkEvent*) event);
167 return false;
170 bool
171 Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/)
173 int x, y;
174 /* keep those motion events coming */
175 track_canvas->get_pointer (x, y);
176 return false;
179 bool
180 Editor::track_canvas_motion (GdkEvent *ev)
182 if (_verbose_cursor->visible ()) {
183 _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10);
186 return false;
189 bool
190 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
192 gint ret = FALSE;
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;
207 case GDK_ENTER_NOTIFY:
208 ret = enter_handler (item, event, type);
209 break;
211 case GDK_LEAVE_NOTIFY:
212 ret = leave_handler (item, event, type);
213 break;
215 default:
216 break;
218 return ret;
221 bool
222 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
224 bool ret = false;
226 if (!rv->sensitive ()) {
227 return false;
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;
241 case GDK_BUTTON_RELEASE:
242 ret = button_release_handler (item, event, RegionItem);
243 break;
245 case GDK_MOTION_NOTIFY:
246 ret = motion_handler (item, event);
247 break;
249 case GDK_ENTER_NOTIFY:
250 set_entered_track (&rv->get_time_axis_view ());
251 set_entered_regionview (rv);
252 break;
254 case GDK_LEAVE_NOTIFY:
255 set_entered_track (0);
256 set_entered_regionview (0);
257 break;
259 default:
260 break;
263 return ret;
266 bool
267 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
269 bool ret = FALSE;
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*>(clicked_axisview);
279 ret = button_press_handler (item, event, StreamItem);
280 break;
282 case GDK_BUTTON_RELEASE:
283 ret = button_release_handler (item, event, StreamItem);
284 break;
286 case GDK_MOTION_NOTIFY:
287 ret = motion_handler (item, event);
288 break;
290 case GDK_ENTER_NOTIFY:
291 set_entered_track (tv);
292 break;
294 case GDK_LEAVE_NOTIFY:
295 set_entered_track (0);
296 break;
298 default:
299 break;
302 return ret;
305 bool
306 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
308 bool ret = false;
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;
321 case GDK_BUTTON_RELEASE:
322 ret = button_release_handler (item, event, AutomationTrackItem);
323 break;
325 case GDK_MOTION_NOTIFY:
326 ret = motion_handler (item, event);
327 break;
329 case GDK_ENTER_NOTIFY:
330 ret = enter_handler (item, event, AutomationTrackItem);
331 break;
333 case GDK_LEAVE_NOTIFY:
334 ret = leave_handler (item, event, AutomationTrackItem);
335 break;
337 default:
338 break;
341 return ret;
344 bool
345 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
347 /* we handle only button 3 press/release events */
349 if (!rv->sensitive()) {
350 return false;
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);
362 break;
364 case GDK_BUTTON_RELEASE:
365 if (event->button.button == 3) {
366 return button_release_handler (item, event, FadeInItem);
368 break;
370 default:
371 break;
375 /* proxy for the regionview */
377 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
380 bool
381 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
383 bool ret = false;
385 if (!rv->sensitive()) {
386 return false;
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;
400 case GDK_BUTTON_RELEASE:
401 ret = button_release_handler (item, event, FadeInHandleItem);
402 break;
404 case GDK_MOTION_NOTIFY:
405 ret = motion_handler (item, event);
406 break;
408 case GDK_ENTER_NOTIFY:
409 set_entered_regionview (rv);
410 ret = enter_handler (item, event, FadeInHandleItem);
411 break;
413 case GDK_LEAVE_NOTIFY:
414 set_entered_regionview (0);
415 ret = leave_handler (item, event, FadeInHandleItem);
416 break;
418 default:
419 break;
422 return ret;
425 bool
426 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
428 /* we handle only button 3 press/release events */
430 if (!rv->sensitive()) {
431 return false;
434 switch (event->type) {
435 case GDK_BUTTON_PRESS:
436 clicked_regionview = rv;
437 clicked_control_point = 0;
438 clicked_axisview = &rv->get_time_axis_view();
439 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
440 if (event->button.button == 3) {
441 return button_press_handler (item, event, FadeOutItem);
443 break;
445 case GDK_BUTTON_RELEASE:
446 if (event->button.button == 3) {
447 return button_release_handler (item, event, FadeOutItem);
449 break;
451 default:
452 break;
456 /* proxy for the regionview */
458 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
461 bool
462 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
464 bool ret = false;
466 if (!rv->sensitive()) {
467 return false;
470 switch (event->type) {
471 case GDK_BUTTON_PRESS:
472 case GDK_2BUTTON_PRESS:
473 case GDK_3BUTTON_PRESS:
474 clicked_regionview = rv;
475 clicked_control_point = 0;
476 clicked_axisview = &rv->get_time_axis_view();
477 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
478 ret = button_press_handler (item, event, FadeOutHandleItem);
479 break;
481 case GDK_BUTTON_RELEASE:
482 ret = button_release_handler (item, event, FadeOutHandleItem);
483 break;
485 case GDK_MOTION_NOTIFY:
486 ret = motion_handler (item, event);
487 break;
489 case GDK_ENTER_NOTIFY:
490 set_entered_regionview (rv);
491 ret = enter_handler (item, event, FadeOutHandleItem);
492 break;
494 case GDK_LEAVE_NOTIFY:
495 set_entered_regionview (0);
496 ret = leave_handler (item, event, FadeOutHandleItem);
497 break;
499 default:
500 break;
503 return ret;
506 struct DescendingRegionLayerSorter {
507 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
508 return a->layer() > b->layer();
512 bool
513 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
515 /* we handle only button 3 press/release events */
517 switch (event->type) {
518 case GDK_BUTTON_PRESS:
519 clicked_crossfadeview = xfv;
520 clicked_axisview = &clicked_crossfadeview->get_time_axis_view();
521 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
522 if (event->button.button == 3) {
523 return button_press_handler (item, event, CrossfadeViewItem);
525 break;
527 case GDK_BUTTON_RELEASE:
528 if (event->button.button == 3) {
529 bool ret = button_release_handler (item, event, CrossfadeViewItem);
530 return ret;
532 break;
534 default:
535 break;
539 /* XXX do not forward double clicks */
541 if (event->type == GDK_2BUTTON_PRESS) {
542 return false;
545 /* proxy for an underlying regionview */
547 /* XXX really need to check if we are in the name highlight,
548 and proxy to that when required.
551 TimeAxisView& tv (xfv->get_time_axis_view());
552 AudioTimeAxisView* atv;
554 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
556 if (atv->is_audio_track()) {
558 boost::shared_ptr<AudioPlaylist> pl;
559 if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->track()->playlist())) != 0) {
561 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
562 if (!rl->empty()) {
564 if (atv->layer_display() == Overlaid) {
566 /* we're in overlaid mode; proxy to the uppermost region view */
568 DescendingRegionLayerSorter cmp;
569 rl->sort (cmp);
571 RegionView* rv = atv->view()->find_view (rl->front());
573 delete rl;
575 /* proxy */
576 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
578 } else {
580 /* we're in stacked mode; proxy to the region view under the mouse */
582 /* XXX: FIXME: this is an evil hack; it assumes that any event for which
583 this proxy is being used has its GdkEvent laid out such that the y
584 member is in the same place as that for a GdkEventButton */
586 /* position of the event within the track */
587 double cx = event->button.x;
588 double cy = event->button.y;
589 atv->view()->canvas_item()->w2i (cx, cy);
591 /* hence layer that we're over */
592 double const c = atv->view()->child_height ();
593 layer_t const l = pl->top_layer () + 1 - (cy / c);
595 /* hence region */
596 Playlist::RegionList::iterator i = rl->begin();
597 while (i != rl->end() && (*i)->layer() != l) {
598 ++i;
601 if (i != rl->end()) {
602 RegionView* rv = atv->view()->find_view (*i);
603 delete rl;
605 /* proxy */
606 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
611 delete rl;
616 return TRUE;
619 bool
620 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
622 switch (event->type) {
623 case GDK_BUTTON_PRESS:
624 case GDK_2BUTTON_PRESS:
625 case GDK_3BUTTON_PRESS:
626 clicked_control_point = cp;
627 clicked_axisview = &cp->line().trackview;
628 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
629 clicked_regionview = 0;
630 break;
632 case GDK_SCROLL_UP:
633 break;
635 case GDK_SCROLL_DOWN:
636 break;
638 default:
639 break;
642 return typed_event (item, event, ControlPointItem);
645 bool
646 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
648 ItemType type;
650 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
651 type = GainLineItem;
652 } else {
653 type = AutomationLineItem;
656 return typed_event (item, event, type);
659 bool
660 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
662 bool ret = false;
664 switch (event->type) {
665 case GDK_BUTTON_PRESS:
666 case GDK_2BUTTON_PRESS:
667 case GDK_3BUTTON_PRESS:
668 clicked_selection = rect->id;
669 ret = button_press_handler (item, event, SelectionItem);
670 break;
671 case GDK_BUTTON_RELEASE:
672 ret = button_release_handler (item, event, SelectionItem);
673 break;
674 case GDK_MOTION_NOTIFY:
675 ret = motion_handler (item, event);
676 break;
677 /* Don't need these at the moment. */
678 case GDK_ENTER_NOTIFY:
679 ret = enter_handler (item, event, SelectionItem);
680 break;
682 case GDK_LEAVE_NOTIFY:
683 ret = leave_handler (item, event, SelectionItem);
684 break;
686 default:
687 break;
690 return ret;
693 bool
694 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
696 bool ret = false;
698 switch (event->type) {
699 case GDK_BUTTON_PRESS:
700 case GDK_2BUTTON_PRESS:
701 case GDK_3BUTTON_PRESS:
702 clicked_selection = rect->id;
703 ret = button_press_handler (item, event, StartSelectionTrimItem);
704 break;
705 case GDK_BUTTON_RELEASE:
706 ret = button_release_handler (item, event, StartSelectionTrimItem);
707 break;
708 case GDK_MOTION_NOTIFY:
709 ret = motion_handler (item, event);
710 break;
711 case GDK_ENTER_NOTIFY:
712 ret = enter_handler (item, event, StartSelectionTrimItem);
713 break;
715 case GDK_LEAVE_NOTIFY:
716 ret = leave_handler (item, event, StartSelectionTrimItem);
717 break;
719 default:
720 break;
723 return ret;
726 bool
727 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
729 bool ret = false;
731 switch (event->type) {
732 case GDK_BUTTON_PRESS:
733 case GDK_2BUTTON_PRESS:
734 case GDK_3BUTTON_PRESS:
735 clicked_selection = rect->id;
736 ret = button_press_handler (item, event, EndSelectionTrimItem);
737 break;
738 case GDK_BUTTON_RELEASE:
739 ret = button_release_handler (item, event, EndSelectionTrimItem);
740 break;
741 case GDK_MOTION_NOTIFY:
742 ret = motion_handler (item, event);
743 break;
744 case GDK_ENTER_NOTIFY:
745 ret = enter_handler (item, event, EndSelectionTrimItem);
746 break;
748 case GDK_LEAVE_NOTIFY:
749 ret = leave_handler (item, event, EndSelectionTrimItem);
750 break;
752 default:
753 break;
756 return ret;
759 bool
760 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
762 bool ret = false;
764 /* frame handles are not active when in internal edit mode, because actual notes
765 might be in the area occupied by the handle - we want them to be editable as normal.
768 if (internal_editing() || !rv->sensitive()) {
769 return false;
772 /* NOTE: frame handles pretend to be the colored trim bar from an event handling
773 perspective. XXX change this ??
776 ItemType type;
778 if (item->get_data ("isleft")) {
779 type = LeftFrameHandle;
780 } else {
781 type = RightFrameHandle;
784 switch (event->type) {
785 case GDK_BUTTON_PRESS:
786 case GDK_2BUTTON_PRESS:
787 case GDK_3BUTTON_PRESS:
788 clicked_regionview = rv;
789 clicked_control_point = 0;
790 clicked_axisview = &clicked_regionview->get_time_axis_view();
791 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
792 ret = button_press_handler (item, event, type);
793 break;
794 case GDK_BUTTON_RELEASE:
795 ret = button_release_handler (item, event, type);
796 break;
797 case GDK_MOTION_NOTIFY:
798 ret = motion_handler (item, event);
799 break;
800 case GDK_ENTER_NOTIFY:
801 set_entered_regionview (rv);
802 ret = enter_handler (item, event, type);
803 break;
805 case GDK_LEAVE_NOTIFY:
806 set_entered_regionview (0);
807 ret = leave_handler (item, event, type);
808 break;
810 default:
811 break;
814 return ret;
818 bool
819 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
821 bool ret = false;
823 if (!rv->sensitive()) {
824 return false;
827 switch (event->type) {
828 case GDK_BUTTON_PRESS:
829 case GDK_2BUTTON_PRESS:
830 case GDK_3BUTTON_PRESS:
831 clicked_regionview = rv;
832 clicked_control_point = 0;
833 clicked_axisview = &clicked_regionview->get_time_axis_view();
834 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
835 ret = button_press_handler (item, event, RegionViewNameHighlight);
836 break;
837 case GDK_BUTTON_RELEASE:
838 ret = button_release_handler (item, event, RegionViewNameHighlight);
839 break;
840 case GDK_MOTION_NOTIFY:
841 motion_handler (item, event);
842 ret = true; // force this to avoid progagating the event into the regionview
843 break;
844 case GDK_ENTER_NOTIFY:
845 set_entered_regionview (rv);
846 ret = enter_handler (item, event, RegionViewNameHighlight);
847 break;
849 case GDK_LEAVE_NOTIFY:
850 set_entered_regionview (0);
851 ret = leave_handler (item, event, RegionViewNameHighlight);
852 break;
854 default:
855 break;
858 return ret;
861 bool
862 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
864 bool ret = false;
866 if (!rv->sensitive()) {
867 return false;
870 switch (event->type) {
871 case GDK_BUTTON_PRESS:
872 case GDK_2BUTTON_PRESS:
873 case GDK_3BUTTON_PRESS:
874 clicked_regionview = rv;
875 clicked_control_point = 0;
876 clicked_axisview = &clicked_regionview->get_time_axis_view();
877 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
878 ret = button_press_handler (item, event, RegionViewName);
879 break;
880 case GDK_BUTTON_RELEASE:
881 ret = button_release_handler (item, event, RegionViewName);
882 break;
883 case GDK_MOTION_NOTIFY:
884 ret = motion_handler (item, event);
885 break;
886 case GDK_ENTER_NOTIFY:
887 set_entered_regionview (rv);
888 ret = enter_handler (item, event, RegionViewName);
889 break;
891 case GDK_LEAVE_NOTIFY:
892 set_entered_regionview (0);
893 ret = leave_handler (item, event, RegionViewName);
894 break;
896 default:
897 break;
900 return ret;
903 bool
904 Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*)
906 bool ret = false;
908 switch (event->type) {
909 case GDK_BUTTON_PRESS:
910 case GDK_2BUTTON_PRESS:
911 case GDK_3BUTTON_PRESS:
912 clicked_regionview = 0;
913 clicked_control_point = 0;
914 clicked_axisview = 0;
915 clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
916 ret = button_press_handler (item, event, FeatureLineItem);
917 break;
919 case GDK_BUTTON_RELEASE:
920 ret = button_release_handler (item, event, FeatureLineItem);
921 break;
923 case GDK_MOTION_NOTIFY:
924 ret = motion_handler (item, event);
925 break;
927 case GDK_ENTER_NOTIFY:
928 ret = enter_handler (item, event, FeatureLineItem);
929 break;
931 case GDK_LEAVE_NOTIFY:
932 ret = leave_handler (item, event, FeatureLineItem);
933 break;
935 default:
936 break;
939 return ret;
942 bool
943 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
945 return typed_event (item, event, MarkerItem);
948 bool
949 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
951 return typed_event (item, event, MarkerBarItem);
954 bool
955 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
957 return typed_event (item, event, RangeMarkerBarItem);
960 bool
961 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
963 return typed_event (item, event, TransportMarkerBarItem);
966 bool
967 Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
969 return typed_event (item, event, CdMarkerBarItem);
972 bool
973 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/)
975 return typed_event (item, event, TempoMarkerItem);
978 bool
979 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/)
981 return typed_event (item, event, MeterMarkerItem);
984 bool
985 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
987 return typed_event (item, event, TempoBarItem);
990 bool
991 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
993 return typed_event (item, event, MeterBarItem);
996 bool
997 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
999 return typed_event (item, event, PlayheadCursorItem);
1002 bool
1003 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
1005 return typed_event (item, event, NoItem);
1008 bool
1009 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
1011 if (!internal_editing()) {
1012 return false;
1015 return typed_event (item, event, NoteItem);
1018 bool
1019 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const & /*c*/, int x, int y, guint /*time*/)
1021 double wx;
1022 double wy;
1023 track_canvas->window_to_world (x, y, wx, wy);
1025 GdkEvent event;
1026 event.type = GDK_MOTION_NOTIFY;
1027 event.button.x = wx;
1028 event.button.y = wy;
1029 /* assume we're dragging with button 1 */
1030 event.motion.state = Gdk::BUTTON1_MASK;
1032 if (!_drags->active ()) {
1034 double px;
1035 double py;
1036 framepos_t const pos = event_frame (&event, &px, &py);
1038 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1039 if (tv.first == 0) {
1040 return true;
1043 RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1044 if (rtav == 0 || !rtav->is_track ()) {
1045 return true;
1048 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
1050 if (!region) {
1051 return true;
1054 boost::shared_ptr<Region> region_copy = RegionFactory::create (region);
1056 if (boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
1057 dynamic_cast<AudioTimeAxisView*> (tv.first) == 0) {
1059 /* audio -> non-audio */
1060 return true;
1063 if (boost::dynamic_pointer_cast<MidiRegion> (region_copy) == 0 &&
1064 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0) {
1066 /* MIDI -> non-MIDI */
1067 return true;
1070 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1073 _drags->motion_handler (&event, false);
1075 return true;