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.
25 #include "pbd/stacktrace.h"
27 #include "ardour/midi_region.h"
28 #include "ardour/region_factory.h"
29 #include "ardour/profile.h"
31 #include "canvas/canvas.h"
32 #include "canvas/text.h"
36 #include "public_editor.h"
37 #include "audio_region_view.h"
38 #include "audio_streamview.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 "editor_drag.h"
46 #include "midi_time_axis.h"
47 #include "editor_regions.h"
48 #include "verbose_cursor.h"
53 using namespace ARDOUR;
56 using namespace ArdourCanvas;
58 using Gtkmm2ext::Keyboard;
61 Editor::track_canvas_scroll (GdkEventScroll* ev)
63 if (Keyboard::some_magic_widget_has_focus()) {
68 int direction = ev->direction;
70 /* this event arrives without transformation by the canvas, so we have
71 * to transform the coordinates to be able to look things up.
74 Duple event_coords = _track_canvas->window_to_canvas (Duple (ev->x, ev->y));
79 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
80 //for mouse-wheel zoom, force zoom-focus to mouse
81 Editing::ZoomFocus temp_focus = zoom_focus;
82 zoom_focus = Editing::ZoomFocusMouse;
83 temporal_zoom_step (false);
84 zoom_focus = temp_focus;
86 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
87 direction = GDK_SCROLL_LEFT;
89 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
90 if (!current_stepping_trackview) {
91 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
92 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (event_coords.y);
93 current_stepping_trackview = p.first;
94 if (!current_stepping_trackview) {
98 last_track_height_step_timestamp = get_microseconds();
99 current_stepping_trackview->step_height (false);
102 scroll_tracks_up_line ();
107 case GDK_SCROLL_DOWN:
108 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
109 //for mouse-wheel zoom, force zoom-focus to mouse
110 Editing::ZoomFocus temp_focus = zoom_focus;
111 zoom_focus = Editing::ZoomFocusMouse;
112 temporal_zoom_step (true);
113 zoom_focus = temp_focus;
115 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
116 direction = GDK_SCROLL_RIGHT;
118 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
119 if (!current_stepping_trackview) {
120 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
121 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (event_coords.y);
122 current_stepping_trackview = p.first;
123 if (!current_stepping_trackview) {
127 last_track_height_step_timestamp = get_microseconds();
128 current_stepping_trackview->step_height (true);
131 scroll_tracks_down_line ();
136 case GDK_SCROLL_LEFT:
137 xdelta = (current_page_samples() / 8);
138 if (leftmost_frame > xdelta) {
139 reset_x_origin (leftmost_frame - xdelta);
145 case GDK_SCROLL_RIGHT:
146 xdelta = (current_page_samples() / 8);
147 if (max_framepos - xdelta > leftmost_frame) {
148 reset_x_origin (leftmost_frame + xdelta);
150 reset_x_origin (max_framepos - current_page_samples());
163 Editor::canvas_scroll_event (GdkEventScroll *event)
165 _track_canvas->grab_focus();
166 return track_canvas_scroll (event);
170 Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
173 _track_canvas->grab_focus();
178 Editor::track_canvas_button_release_event (GdkEventButton *event)
180 if (_drags->active ()) {
181 _drags->end_grab ((GdkEvent*) event);
187 Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/)
190 /* keep those motion events coming */
191 _track_canvas->get_pointer (x, y);
196 Editor::track_canvas_motion (GdkEvent *ev)
198 if (_verbose_cursor->visible ()) {
199 _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10);
206 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
210 switch (event->type) {
211 case GDK_BUTTON_PRESS:
212 case GDK_2BUTTON_PRESS:
213 case GDK_3BUTTON_PRESS:
214 ret = button_press_handler (item, event, type);
216 case GDK_BUTTON_RELEASE:
217 ret = button_release_handler (item, event, type);
219 case GDK_MOTION_NOTIFY:
220 ret = motion_handler (item, event);
223 case GDK_ENTER_NOTIFY:
224 ret = enter_handler (item, event, type);
227 case GDK_LEAVE_NOTIFY:
228 ret = leave_handler (item, event, type);
232 ret = key_press_handler (item, event, type);
235 case GDK_KEY_RELEASE:
236 ret = key_release_handler (item, event, type);
246 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
250 if (!rv->sensitive ()) {
254 switch (event->type) {
255 case GDK_BUTTON_PRESS:
256 case GDK_2BUTTON_PRESS:
257 case GDK_3BUTTON_PRESS:
258 clicked_regionview = rv;
259 clicked_control_point = 0;
260 clicked_axisview = &rv->get_time_axis_view();
261 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
262 ret = button_press_handler (item, event, RegionItem);
265 case GDK_BUTTON_RELEASE:
266 ret = button_release_handler (item, event, RegionItem);
269 case GDK_MOTION_NOTIFY:
270 ret = motion_handler (item, event);
273 case GDK_ENTER_NOTIFY:
274 if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
275 set_entered_regionview (rv);
280 case GDK_LEAVE_NOTIFY:
281 if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
282 set_entered_regionview (0);
295 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
299 switch (event->type) {
300 case GDK_BUTTON_PRESS:
301 case GDK_2BUTTON_PRESS:
302 case GDK_3BUTTON_PRESS:
303 clicked_regionview = 0;
304 clicked_control_point = 0;
305 clicked_axisview = tv;
306 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
307 ret = button_press_handler (item, event, StreamItem);
310 case GDK_BUTTON_RELEASE:
311 ret = button_release_handler (item, event, StreamItem);
314 case GDK_MOTION_NOTIFY:
315 ret = motion_handler (item, event);
318 case GDK_ENTER_NOTIFY:
319 set_entered_track (tv);
323 case GDK_LEAVE_NOTIFY:
324 set_entered_track (0);
335 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
339 switch (event->type) {
340 case GDK_BUTTON_PRESS:
341 case GDK_2BUTTON_PRESS:
342 case GDK_3BUTTON_PRESS:
343 clicked_regionview = 0;
344 clicked_control_point = 0;
345 clicked_axisview = atv;
346 clicked_routeview = 0;
347 ret = button_press_handler (item, event, AutomationTrackItem);
350 case GDK_BUTTON_RELEASE:
351 ret = button_release_handler (item, event, AutomationTrackItem);
354 case GDK_MOTION_NOTIFY:
355 ret = motion_handler (item, event);
358 case GDK_ENTER_NOTIFY:
359 ret = enter_handler (item, event, AutomationTrackItem);
362 case GDK_LEAVE_NOTIFY:
363 ret = leave_handler (item, event, AutomationTrackItem);
374 Editor::canvas_start_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
376 if (!rv->sensitive()) {
380 switch (event->type) {
381 case GDK_BUTTON_PRESS:
382 clicked_regionview = rv;
383 clicked_control_point = 0;
384 clicked_axisview = &rv->get_time_axis_view();
385 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
386 if (event->button.button == 3) {
387 return button_press_handler (item, event, StartCrossFadeItem);
391 case GDK_BUTTON_RELEASE:
392 if (event->button.button == 3) {
393 return button_release_handler (item, event, StartCrossFadeItem);
402 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
403 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
404 /* if we return RegionItem here then we avoid the issue until it is resolved later */
405 return typed_event (item, event, RegionItem); // StartCrossFadeItem);
409 Editor::canvas_end_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
411 if (!rv->sensitive()) {
415 switch (event->type) {
416 case GDK_BUTTON_PRESS:
417 clicked_regionview = rv;
418 clicked_control_point = 0;
419 clicked_axisview = &rv->get_time_axis_view();
420 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
421 if (event->button.button == 3) {
422 return button_press_handler (item, event, EndCrossFadeItem);
426 case GDK_BUTTON_RELEASE:
427 if (event->button.button == 3) {
428 return button_release_handler (item, event, EndCrossFadeItem);
437 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
438 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
439 /* if we return RegionItem here then we avoid the issue until it is resolved later */
440 return typed_event (item, event, RegionItem); // EndCrossFadeItem);
444 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
446 /* we handle only button 3 press/release events */
448 if (!rv->sensitive()) {
452 switch (event->type) {
453 case GDK_BUTTON_PRESS:
454 clicked_regionview = rv;
455 clicked_control_point = 0;
456 clicked_axisview = &rv->get_time_axis_view();
457 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
458 if (event->button.button == 3) {
459 return button_press_handler (item, event, FadeInItem);
463 case GDK_BUTTON_RELEASE:
464 if (event->button.button == 3) {
465 return button_release_handler (item, event, FadeInItem);
474 /* proxy for the regionview, except enter/leave events */
476 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
479 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
484 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv, bool trim)
488 if (!rv->sensitive()) {
492 switch (event->type) {
493 case GDK_BUTTON_PRESS:
494 case GDK_2BUTTON_PRESS:
495 case GDK_3BUTTON_PRESS:
496 clicked_regionview = rv;
497 clicked_control_point = 0;
498 clicked_axisview = &rv->get_time_axis_view();
499 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
500 ret = button_press_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem);
503 case GDK_BUTTON_RELEASE:
504 ret = button_release_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem);
505 maybe_locate_with_edit_preroll ( rv->region()->position() );
508 case GDK_MOTION_NOTIFY:
509 ret = motion_handler (item, event);
512 case GDK_ENTER_NOTIFY:
513 ret = enter_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem);
516 case GDK_LEAVE_NOTIFY:
517 ret = leave_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem);
528 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
530 /* we handle only button 3 press/release events */
532 if (!rv->sensitive()) {
536 switch (event->type) {
537 case GDK_BUTTON_PRESS:
538 clicked_regionview = rv;
539 clicked_control_point = 0;
540 clicked_axisview = &rv->get_time_axis_view();
541 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
542 if (event->button.button == 3) {
543 return button_press_handler (item, event, FadeOutItem);
547 case GDK_BUTTON_RELEASE:
548 if (event->button.button == 3) {
549 return button_release_handler (item, event, FadeOutItem);
558 /* proxy for the regionview, except enter/leave events */
560 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
563 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
568 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv, bool trim)
572 if (!rv->sensitive()) {
576 switch (event->type) {
577 case GDK_BUTTON_PRESS:
578 case GDK_2BUTTON_PRESS:
579 case GDK_3BUTTON_PRESS:
580 clicked_regionview = rv;
581 clicked_control_point = 0;
582 clicked_axisview = &rv->get_time_axis_view();
583 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
584 ret = button_press_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem);
587 case GDK_BUTTON_RELEASE:
588 ret = button_release_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem);
589 maybe_locate_with_edit_preroll ( rv->region()->last_frame() - rv->get_fade_out_shape_width() );
592 case GDK_MOTION_NOTIFY:
593 ret = motion_handler (item, event);
596 case GDK_ENTER_NOTIFY:
597 ret = enter_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem);
600 case GDK_LEAVE_NOTIFY:
601 ret = leave_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem);
611 struct DescendingRegionLayerSorter {
612 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
613 return a->layer() > b->layer();
618 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
620 switch (event->type) {
621 case GDK_BUTTON_PRESS:
622 case GDK_2BUTTON_PRESS:
623 case GDK_3BUTTON_PRESS:
624 clicked_control_point = cp;
625 clicked_axisview = &cp->line().trackview;
626 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
627 clicked_regionview = 0;
633 case GDK_SCROLL_DOWN:
640 return typed_event (item, event, ControlPointItem);
644 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
648 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
651 type = AutomationLineItem;
654 return typed_event (item, event, type);
658 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
662 switch (event->type) {
663 case GDK_BUTTON_PRESS:
664 case GDK_2BUTTON_PRESS:
665 case GDK_3BUTTON_PRESS:
666 clicked_selection = rect->id;
667 ret = button_press_handler (item, event, SelectionItem);
669 case GDK_BUTTON_RELEASE:
670 ret = button_release_handler (item, event, SelectionItem);
672 case GDK_MOTION_NOTIFY:
673 ret = motion_handler (item, event);
675 /* Don't need these at the moment. */
676 case GDK_ENTER_NOTIFY:
677 ret = enter_handler (item, event, SelectionItem);
680 case GDK_LEAVE_NOTIFY:
681 ret = leave_handler (item, event, SelectionItem);
692 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
696 switch (event->type) {
697 case GDK_BUTTON_PRESS:
698 case GDK_2BUTTON_PRESS:
699 case GDK_3BUTTON_PRESS:
700 clicked_selection = rect->id;
701 ret = button_press_handler (item, event, StartSelectionTrimItem);
703 case GDK_BUTTON_RELEASE:
704 ret = button_release_handler (item, event, StartSelectionTrimItem);
706 case GDK_MOTION_NOTIFY:
707 ret = motion_handler (item, event);
709 case GDK_ENTER_NOTIFY:
710 ret = enter_handler (item, event, StartSelectionTrimItem);
713 case GDK_LEAVE_NOTIFY:
714 ret = leave_handler (item, event, StartSelectionTrimItem);
725 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
729 switch (event->type) {
730 case GDK_BUTTON_PRESS:
731 case GDK_2BUTTON_PRESS:
732 case GDK_3BUTTON_PRESS:
733 clicked_selection = rect->id;
734 ret = button_press_handler (item, event, EndSelectionTrimItem);
736 case GDK_BUTTON_RELEASE:
737 ret = button_release_handler (item, event, EndSelectionTrimItem);
739 case GDK_MOTION_NOTIFY:
740 ret = motion_handler (item, event);
742 case GDK_ENTER_NOTIFY:
743 ret = enter_handler (item, event, EndSelectionTrimItem);
746 case GDK_LEAVE_NOTIFY:
747 ret = leave_handler (item, event, EndSelectionTrimItem);
758 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
762 /* frame handles are not active when in internal edit mode, because actual notes
763 might be in the area occupied by the handle - we want them to be editable as normal.
766 if (internal_editing() || !rv->sensitive()) {
770 /* NOTE: frame handles pretend to be the colored trim bar from an event handling
771 perspective. XXX change this ??
776 if (item->get_data ("isleft")) {
777 type = LeftFrameHandle;
779 type = RightFrameHandle;
782 switch (event->type) {
783 case GDK_BUTTON_PRESS:
784 case GDK_2BUTTON_PRESS:
785 case GDK_3BUTTON_PRESS:
786 clicked_regionview = rv;
787 clicked_control_point = 0;
788 clicked_axisview = &clicked_regionview->get_time_axis_view();
789 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
790 ret = button_press_handler (item, event, type);
792 case GDK_BUTTON_RELEASE:
793 ret = button_release_handler (item, event, type);
795 case GDK_MOTION_NOTIFY:
796 ret = motion_handler (item, event);
798 case GDK_ENTER_NOTIFY:
799 ret = enter_handler (item, event, type);
802 case GDK_LEAVE_NOTIFY:
803 ret = leave_handler (item, event, type);
815 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
819 if (!rv->sensitive()) {
823 switch (event->type) {
824 case GDK_BUTTON_PRESS:
825 case GDK_2BUTTON_PRESS:
826 case GDK_3BUTTON_PRESS:
827 clicked_regionview = rv;
828 clicked_control_point = 0;
829 clicked_axisview = &clicked_regionview->get_time_axis_view();
830 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
831 ret = button_press_handler (item, event, RegionViewNameHighlight);
833 case GDK_BUTTON_RELEASE:
834 ret = button_release_handler (item, event, RegionViewNameHighlight);
836 case GDK_MOTION_NOTIFY:
837 motion_handler (item, event);
838 ret = true; // force this to avoid progagating the event into the regionview
840 case GDK_ENTER_NOTIFY:
841 ret = enter_handler (item, event, RegionViewNameHighlight);
844 case GDK_LEAVE_NOTIFY:
845 ret = leave_handler (item, event, RegionViewNameHighlight);
856 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
860 if (!rv->sensitive()) {
864 switch (event->type) {
865 case GDK_BUTTON_PRESS:
866 case GDK_2BUTTON_PRESS:
867 case GDK_3BUTTON_PRESS:
868 clicked_regionview = rv;
869 clicked_control_point = 0;
870 clicked_axisview = &clicked_regionview->get_time_axis_view();
871 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
872 ret = button_press_handler (item, event, RegionViewName);
874 case GDK_BUTTON_RELEASE:
875 ret = button_release_handler (item, event, RegionViewName);
877 case GDK_MOTION_NOTIFY:
878 ret = motion_handler (item, event);
880 case GDK_ENTER_NOTIFY:
881 ret = enter_handler (item, event, RegionViewName);
884 case GDK_LEAVE_NOTIFY:
885 ret = leave_handler (item, event, RegionViewName);
896 Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*)
900 switch (event->type) {
901 case GDK_BUTTON_PRESS:
902 case GDK_2BUTTON_PRESS:
903 case GDK_3BUTTON_PRESS:
904 clicked_regionview = 0;
905 clicked_control_point = 0;
906 clicked_axisview = 0;
907 clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
908 ret = button_press_handler (item, event, FeatureLineItem);
911 case GDK_BUTTON_RELEASE:
912 ret = button_release_handler (item, event, FeatureLineItem);
915 case GDK_MOTION_NOTIFY:
916 ret = motion_handler (item, event);
919 case GDK_ENTER_NOTIFY:
920 ret = enter_handler (item, event, FeatureLineItem);
923 case GDK_LEAVE_NOTIFY:
924 ret = leave_handler (item, event, FeatureLineItem);
935 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
937 return typed_event (item, event, MarkerItem);
941 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
943 return typed_event (item, event, MarkerBarItem);
947 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
949 return typed_event (item, event, RangeMarkerBarItem);
953 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
955 return typed_event (item, event, TransportMarkerBarItem);
959 Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
961 return typed_event (item, event, CdMarkerBarItem);
965 Editor::canvas_videotl_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
967 return typed_event (item, event, VideoBarItem);
971 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/)
973 return typed_event (item, event, TempoMarkerItem);
977 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/)
979 return typed_event (item, event, MeterMarkerItem);
983 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
985 return typed_event (item, event, TempoBarItem);
989 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
991 return typed_event (item, event, MeterBarItem);
995 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
997 return typed_event (item, event, PlayheadCursorItem);
1001 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
1003 return typed_event (item, event, NoItem);
1007 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
1009 if (!internal_editing()) {
1013 return typed_event (item, event, NoteItem);
1017 Editor::canvas_drop_zone_event (GdkEvent* /*event*/)
1023 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, int x, int y, guint time)
1025 boost::shared_ptr<Region> region;
1026 boost::shared_ptr<Region> region_copy;
1027 RouteTimeAxisView* rtav;
1032 string target = _track_canvas->drag_dest_find_target (context, _track_canvas->drag_dest_get_target_list());
1034 if (target.empty()) {
1038 event.type = GDK_MOTION_NOTIFY;
1041 /* assume we're dragging with button 1 */
1042 event.motion.state = Gdk::BUTTON1_MASK;
1044 (void) window_event_sample (&event, &px, &py);
1046 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1047 bool can_drop = false;
1049 if (tv.first != 0) {
1051 /* over a time axis view of some kind */
1053 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1055 if (rtav != 0 && rtav->is_track ()) {
1056 /* over a track, not a bus */
1062 /* not over a time axis view, so drop is possible */
1067 region = _regions->get_dragged_region ();
1071 if ((boost::dynamic_pointer_cast<AudioRegion> (region) != 0 &&
1072 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1073 (boost::dynamic_pointer_cast<MidiRegion> (region) != 0 &&
1074 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1081 context->drag_status (context->get_suggested_action(), time);
1085 /* DND originating from outside ardour
1087 * TODO: check if file is audio/midi, allow drops on same track-type only,
1088 * currently: if audio is dropped on a midi-track, it is only added to the region-list
1090 if (Profile->get_sae() || Config->get_only_copy_imported_files()) {
1091 context->drag_status(Gdk::ACTION_COPY, time);
1093 if ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY) {
1094 context->drag_status(Gdk::ACTION_COPY, time);
1096 context->drag_status(Gdk::ACTION_LINK, time);
1104 context->drag_status (Gdk::DragAction (0), time);
1109 Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
1111 const SelectionData& /*data*/,
1112 guint /*info*/, guint /*time*/)
1114 boost::shared_ptr<Region> region;
1115 boost::shared_ptr<Region> region_copy;
1116 RouteTimeAxisView* rtav;
1121 event.type = GDK_MOTION_NOTIFY;
1124 /* assume we're dragging with button 1 */
1125 event.motion.state = Gdk::BUTTON1_MASK;
1127 framepos_t const pos = window_event_sample (&event, &px, &py);
1129 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1131 if (tv.first != 0) {
1133 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1135 if (rtav != 0 && rtav->is_track ()) {
1137 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
1141 region_copy = RegionFactory::create (region, true);
1144 if ((boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
1145 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1146 (boost::dynamic_pointer_cast<MidiRegion> (region_copy) != 0 &&
1147 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1155 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1156 _drags->end_grab (0);
1164 Editor::key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType)
1170 Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType type)
1173 bool handled = false;
1176 case TempoMarkerItem:
1177 switch (event->key.keyval) {
1179 remove_tempo_marker (item);
1187 case MeterMarkerItem:
1188 switch (event->key.keyval) {
1190 remove_meter_marker (item);