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)
64 int direction = ev->direction;
66 /* this event arrives without transformation by the canvas, so we have
67 * to transform the coordinates to be able to look things up.
70 Duple event_coords = _track_canvas->window_to_canvas (Duple (ev->x, ev->y));
75 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
76 //for mouse-wheel zoom, force zoom-focus to mouse
77 Editing::ZoomFocus temp_focus = zoom_focus;
78 zoom_focus = Editing::ZoomFocusMouse;
79 temporal_zoom_step (false);
80 zoom_focus = temp_focus;
82 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
83 direction = GDK_SCROLL_LEFT;
85 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
86 if (!current_stepping_trackview) {
87 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
88 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (event_coords.y);
89 current_stepping_trackview = p.first;
90 if (!current_stepping_trackview) {
94 last_track_height_step_timestamp = get_microseconds();
95 current_stepping_trackview->step_height (false);
98 scroll_tracks_up_line ();
103 case GDK_SCROLL_DOWN:
104 if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) {
105 //for mouse-wheel zoom, force zoom-focus to mouse
106 Editing::ZoomFocus temp_focus = zoom_focus;
107 zoom_focus = Editing::ZoomFocusMouse;
108 temporal_zoom_step (true);
109 zoom_focus = temp_focus;
111 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) {
112 direction = GDK_SCROLL_RIGHT;
114 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) {
115 if (!current_stepping_trackview) {
116 step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500);
117 std::pair<TimeAxisView*, int> const p = trackview_by_y_position (event_coords.y);
118 current_stepping_trackview = p.first;
119 if (!current_stepping_trackview) {
123 last_track_height_step_timestamp = get_microseconds();
124 current_stepping_trackview->step_height (true);
127 scroll_tracks_down_line ();
132 case GDK_SCROLL_LEFT:
133 xdelta = (current_page_samples() / 8);
134 if (leftmost_frame > xdelta) {
135 reset_x_origin (leftmost_frame - xdelta);
141 case GDK_SCROLL_RIGHT:
142 xdelta = (current_page_samples() / 8);
143 if (max_framepos - xdelta > leftmost_frame) {
144 reset_x_origin (leftmost_frame + xdelta);
146 reset_x_origin (max_framepos - current_page_samples());
159 Editor::track_canvas_scroll_event (GdkEventScroll *event)
161 _track_canvas->grab_focus();
162 return track_canvas_scroll (event);
166 Editor::track_canvas_button_press_event (GdkEventButton */*event*/)
169 _track_canvas->grab_focus();
174 Editor::track_canvas_button_release_event (GdkEventButton *event)
176 if (_drags->active ()) {
177 _drags->end_grab ((GdkEvent*) event);
183 Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/)
186 /* keep those motion events coming */
187 _track_canvas->get_pointer (x, y);
192 Editor::track_canvas_motion (GdkEvent *ev)
194 if (_verbose_cursor->visible ()) {
195 _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10);
202 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
206 switch (event->type) {
207 case GDK_BUTTON_PRESS:
208 case GDK_2BUTTON_PRESS:
209 case GDK_3BUTTON_PRESS:
210 ret = button_press_handler (item, event, type);
212 case GDK_BUTTON_RELEASE:
213 ret = button_release_handler (item, event, type);
215 case GDK_MOTION_NOTIFY:
216 ret = motion_handler (item, event);
219 case GDK_ENTER_NOTIFY:
220 ret = enter_handler (item, event, type);
223 case GDK_LEAVE_NOTIFY:
224 ret = leave_handler (item, event, type);
228 ret = key_press_handler (item, event, type);
231 case GDK_KEY_RELEASE:
232 ret = key_release_handler (item, event, type);
242 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
246 if (!rv->sensitive ()) {
250 switch (event->type) {
251 case GDK_BUTTON_PRESS:
252 case GDK_2BUTTON_PRESS:
253 case GDK_3BUTTON_PRESS:
254 clicked_regionview = rv;
255 clicked_control_point = 0;
256 clicked_axisview = &rv->get_time_axis_view();
257 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
258 ret = button_press_handler (item, event, RegionItem);
261 case GDK_BUTTON_RELEASE:
262 ret = button_release_handler (item, event, RegionItem);
265 case GDK_MOTION_NOTIFY:
266 ret = motion_handler (item, event);
269 case GDK_ENTER_NOTIFY:
270 set_entered_regionview (rv);
274 case GDK_LEAVE_NOTIFY:
275 set_entered_regionview (0);
286 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
290 switch (event->type) {
291 case GDK_BUTTON_PRESS:
292 case GDK_2BUTTON_PRESS:
293 case GDK_3BUTTON_PRESS:
294 clicked_regionview = 0;
295 clicked_control_point = 0;
296 clicked_axisview = tv;
297 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
298 ret = button_press_handler (item, event, StreamItem);
301 case GDK_BUTTON_RELEASE:
302 ret = button_release_handler (item, event, StreamItem);
305 case GDK_MOTION_NOTIFY:
306 ret = motion_handler (item, event);
309 case GDK_ENTER_NOTIFY:
310 set_entered_track (tv);
314 case GDK_LEAVE_NOTIFY:
315 set_entered_track (0);
326 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
330 switch (event->type) {
331 case GDK_BUTTON_PRESS:
332 case GDK_2BUTTON_PRESS:
333 case GDK_3BUTTON_PRESS:
334 clicked_regionview = 0;
335 clicked_control_point = 0;
336 clicked_axisview = atv;
337 clicked_routeview = 0;
338 ret = button_press_handler (item, event, AutomationTrackItem);
341 case GDK_BUTTON_RELEASE:
342 ret = button_release_handler (item, event, AutomationTrackItem);
345 case GDK_MOTION_NOTIFY:
346 ret = motion_handler (item, event);
349 case GDK_ENTER_NOTIFY:
350 ret = enter_handler (item, event, AutomationTrackItem);
353 case GDK_LEAVE_NOTIFY:
354 ret = leave_handler (item, event, AutomationTrackItem);
365 Editor::canvas_start_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
367 if (!rv->sensitive()) {
371 switch (event->type) {
372 case GDK_BUTTON_PRESS:
373 clicked_regionview = rv;
374 clicked_control_point = 0;
375 clicked_axisview = &rv->get_time_axis_view();
376 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
377 if (event->button.button == 3) {
378 return button_press_handler (item, event, StartCrossFadeItem);
382 case GDK_BUTTON_RELEASE:
383 if (event->button.button == 3) {
384 return button_release_handler (item, event, StartCrossFadeItem);
393 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
394 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
395 /* if we return RegionItem here then we avoid the issue until it is resolved later */
396 return typed_event (item, event, RegionItem); // StartCrossFadeItem);
400 Editor::canvas_end_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
402 if (!rv->sensitive()) {
406 switch (event->type) {
407 case GDK_BUTTON_PRESS:
408 clicked_regionview = rv;
409 clicked_control_point = 0;
410 clicked_axisview = &rv->get_time_axis_view();
411 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
412 if (event->button.button == 3) {
413 return button_press_handler (item, event, EndCrossFadeItem);
417 case GDK_BUTTON_RELEASE:
418 if (event->button.button == 3) {
419 return button_release_handler (item, event, EndCrossFadeItem);
428 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
429 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
430 /* if we return RegionItem here then we avoid the issue until it is resolved later */
431 return typed_event (item, event, RegionItem); // EndCrossFadeItem);
435 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
437 /* we handle only button 3 press/release events */
439 if (!rv->sensitive()) {
443 switch (event->type) {
444 case GDK_BUTTON_PRESS:
445 clicked_regionview = rv;
446 clicked_control_point = 0;
447 clicked_axisview = &rv->get_time_axis_view();
448 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
449 if (event->button.button == 3) {
450 return button_press_handler (item, event, FadeInItem);
454 case GDK_BUTTON_RELEASE:
455 if (event->button.button == 3) {
456 return button_release_handler (item, event, FadeInItem);
465 /* proxy for the regionview, except enter/leave events */
467 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
470 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
475 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
479 if (!rv->sensitive()) {
483 switch (event->type) {
484 case GDK_BUTTON_PRESS:
485 case GDK_2BUTTON_PRESS:
486 case GDK_3BUTTON_PRESS:
487 clicked_regionview = rv;
488 clicked_control_point = 0;
489 clicked_axisview = &rv->get_time_axis_view();
490 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
491 ret = button_press_handler (item, event, FadeInHandleItem);
494 case GDK_BUTTON_RELEASE:
495 ret = button_release_handler (item, event, FadeInHandleItem);
496 maybe_locate_with_edit_preroll ( rv->region()->position() );
499 case GDK_MOTION_NOTIFY:
500 ret = motion_handler (item, event);
503 case GDK_ENTER_NOTIFY:
504 ret = enter_handler (item, event, FadeInHandleItem);
507 case GDK_LEAVE_NOTIFY:
508 ret = leave_handler (item, event, FadeInHandleItem);
519 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
521 /* we handle only button 3 press/release events */
523 if (!rv->sensitive()) {
527 switch (event->type) {
528 case GDK_BUTTON_PRESS:
529 clicked_regionview = rv;
530 clicked_control_point = 0;
531 clicked_axisview = &rv->get_time_axis_view();
532 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
533 if (event->button.button == 3) {
534 return button_press_handler (item, event, FadeOutItem);
538 case GDK_BUTTON_RELEASE:
539 if (event->button.button == 3) {
540 return button_release_handler (item, event, FadeOutItem);
549 /* proxy for the regionview, except enter/leave events */
551 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
554 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
559 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
563 if (!rv->sensitive()) {
567 switch (event->type) {
568 case GDK_BUTTON_PRESS:
569 case GDK_2BUTTON_PRESS:
570 case GDK_3BUTTON_PRESS:
571 clicked_regionview = rv;
572 clicked_control_point = 0;
573 clicked_axisview = &rv->get_time_axis_view();
574 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
575 ret = button_press_handler (item, event, FadeOutHandleItem);
578 case GDK_BUTTON_RELEASE:
579 ret = button_release_handler (item, event, FadeOutHandleItem);
580 maybe_locate_with_edit_preroll ( rv->region()->last_frame() - rv->get_fade_out_shape_width() );
583 case GDK_MOTION_NOTIFY:
584 ret = motion_handler (item, event);
587 case GDK_ENTER_NOTIFY:
588 ret = enter_handler (item, event, FadeOutHandleItem);
591 case GDK_LEAVE_NOTIFY:
592 ret = leave_handler (item, event, FadeOutHandleItem);
602 struct DescendingRegionLayerSorter {
603 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
604 return a->layer() > b->layer();
609 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
611 switch (event->type) {
612 case GDK_BUTTON_PRESS:
613 case GDK_2BUTTON_PRESS:
614 case GDK_3BUTTON_PRESS:
615 clicked_control_point = cp;
616 clicked_axisview = &cp->line().trackview;
617 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
618 clicked_regionview = 0;
624 case GDK_SCROLL_DOWN:
631 return typed_event (item, event, ControlPointItem);
635 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
639 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
642 type = AutomationLineItem;
645 return typed_event (item, event, type);
649 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
653 switch (event->type) {
654 case GDK_BUTTON_PRESS:
655 case GDK_2BUTTON_PRESS:
656 case GDK_3BUTTON_PRESS:
657 clicked_selection = rect->id;
658 ret = button_press_handler (item, event, SelectionItem);
660 case GDK_BUTTON_RELEASE:
661 ret = button_release_handler (item, event, SelectionItem);
663 case GDK_MOTION_NOTIFY:
664 ret = motion_handler (item, event);
666 /* Don't need these at the moment. */
667 case GDK_ENTER_NOTIFY:
668 ret = enter_handler (item, event, SelectionItem);
671 case GDK_LEAVE_NOTIFY:
672 ret = leave_handler (item, event, SelectionItem);
683 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
687 switch (event->type) {
688 case GDK_BUTTON_PRESS:
689 case GDK_2BUTTON_PRESS:
690 case GDK_3BUTTON_PRESS:
691 clicked_selection = rect->id;
692 ret = button_press_handler (item, event, StartSelectionTrimItem);
694 case GDK_BUTTON_RELEASE:
695 ret = button_release_handler (item, event, StartSelectionTrimItem);
697 case GDK_MOTION_NOTIFY:
698 ret = motion_handler (item, event);
700 case GDK_ENTER_NOTIFY:
701 ret = enter_handler (item, event, StartSelectionTrimItem);
704 case GDK_LEAVE_NOTIFY:
705 ret = leave_handler (item, event, StartSelectionTrimItem);
716 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
720 switch (event->type) {
721 case GDK_BUTTON_PRESS:
722 case GDK_2BUTTON_PRESS:
723 case GDK_3BUTTON_PRESS:
724 clicked_selection = rect->id;
725 ret = button_press_handler (item, event, EndSelectionTrimItem);
727 case GDK_BUTTON_RELEASE:
728 ret = button_release_handler (item, event, EndSelectionTrimItem);
730 case GDK_MOTION_NOTIFY:
731 ret = motion_handler (item, event);
733 case GDK_ENTER_NOTIFY:
734 ret = enter_handler (item, event, EndSelectionTrimItem);
737 case GDK_LEAVE_NOTIFY:
738 ret = leave_handler (item, event, EndSelectionTrimItem);
749 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
753 /* frame handles are not active when in internal edit mode, because actual notes
754 might be in the area occupied by the handle - we want them to be editable as normal.
757 if (internal_editing() || !rv->sensitive()) {
761 /* NOTE: frame handles pretend to be the colored trim bar from an event handling
762 perspective. XXX change this ??
767 if (item->get_data ("isleft")) {
768 type = LeftFrameHandle;
770 type = RightFrameHandle;
773 switch (event->type) {
774 case GDK_BUTTON_PRESS:
775 case GDK_2BUTTON_PRESS:
776 case GDK_3BUTTON_PRESS:
777 clicked_regionview = rv;
778 clicked_control_point = 0;
779 clicked_axisview = &clicked_regionview->get_time_axis_view();
780 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
781 ret = button_press_handler (item, event, type);
783 case GDK_BUTTON_RELEASE:
784 ret = button_release_handler (item, event, type);
786 case GDK_MOTION_NOTIFY:
787 ret = motion_handler (item, event);
789 case GDK_ENTER_NOTIFY:
790 ret = enter_handler (item, event, type);
793 case GDK_LEAVE_NOTIFY:
794 ret = leave_handler (item, event, type);
806 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
810 if (!rv->sensitive()) {
814 switch (event->type) {
815 case GDK_BUTTON_PRESS:
816 case GDK_2BUTTON_PRESS:
817 case GDK_3BUTTON_PRESS:
818 clicked_regionview = rv;
819 clicked_control_point = 0;
820 clicked_axisview = &clicked_regionview->get_time_axis_view();
821 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
822 ret = button_press_handler (item, event, RegionViewNameHighlight);
824 case GDK_BUTTON_RELEASE:
825 ret = button_release_handler (item, event, RegionViewNameHighlight);
827 case GDK_MOTION_NOTIFY:
828 motion_handler (item, event);
829 ret = true; // force this to avoid progagating the event into the regionview
831 case GDK_ENTER_NOTIFY:
832 ret = enter_handler (item, event, RegionViewNameHighlight);
835 case GDK_LEAVE_NOTIFY:
836 ret = leave_handler (item, event, RegionViewNameHighlight);
847 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
851 if (!rv->sensitive()) {
855 switch (event->type) {
856 case GDK_BUTTON_PRESS:
857 case GDK_2BUTTON_PRESS:
858 case GDK_3BUTTON_PRESS:
859 clicked_regionview = rv;
860 clicked_control_point = 0;
861 clicked_axisview = &clicked_regionview->get_time_axis_view();
862 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
863 ret = button_press_handler (item, event, RegionViewName);
865 case GDK_BUTTON_RELEASE:
866 ret = button_release_handler (item, event, RegionViewName);
868 case GDK_MOTION_NOTIFY:
869 ret = motion_handler (item, event);
871 case GDK_ENTER_NOTIFY:
872 ret = enter_handler (item, event, RegionViewName);
875 case GDK_LEAVE_NOTIFY:
876 ret = leave_handler (item, event, RegionViewName);
887 Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*)
891 switch (event->type) {
892 case GDK_BUTTON_PRESS:
893 case GDK_2BUTTON_PRESS:
894 case GDK_3BUTTON_PRESS:
895 clicked_regionview = 0;
896 clicked_control_point = 0;
897 clicked_axisview = 0;
898 clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
899 ret = button_press_handler (item, event, FeatureLineItem);
902 case GDK_BUTTON_RELEASE:
903 ret = button_release_handler (item, event, FeatureLineItem);
906 case GDK_MOTION_NOTIFY:
907 ret = motion_handler (item, event);
910 case GDK_ENTER_NOTIFY:
911 ret = enter_handler (item, event, FeatureLineItem);
914 case GDK_LEAVE_NOTIFY:
915 ret = leave_handler (item, event, FeatureLineItem);
926 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
928 return typed_event (item, event, MarkerItem);
932 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
934 return typed_event (item, event, MarkerBarItem);
938 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
940 return typed_event (item, event, RangeMarkerBarItem);
944 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
946 return typed_event (item, event, TransportMarkerBarItem);
950 Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
952 return typed_event (item, event, CdMarkerBarItem);
956 Editor::canvas_videotl_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
958 return typed_event (item, event, VideoBarItem);
962 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/)
964 return typed_event (item, event, TempoMarkerItem);
968 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/)
970 return typed_event (item, event, MeterMarkerItem);
974 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
976 return typed_event (item, event, TempoBarItem);
980 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
982 return typed_event (item, event, MeterBarItem);
986 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
988 return typed_event (item, event, PlayheadCursorItem);
992 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
994 return typed_event (item, event, NoItem);
998 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
1000 if (!internal_editing()) {
1004 return typed_event (item, event, NoteItem);
1008 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, int x, int y, guint time)
1010 boost::shared_ptr<Region> region;
1011 boost::shared_ptr<Region> region_copy;
1012 RouteTimeAxisView* rtav;
1017 string target = _track_canvas->drag_dest_find_target (context, _track_canvas->drag_dest_get_target_list());
1019 if (target.empty()) {
1023 event.type = GDK_MOTION_NOTIFY;
1026 /* assume we're dragging with button 1 */
1027 event.motion.state = Gdk::BUTTON1_MASK;
1029 (void) window_event_frame (&event, &px, &py);
1031 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1032 bool can_drop = false;
1034 if (tv.first != 0) {
1036 /* over a time axis view of some kind */
1038 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1040 if (rtav != 0 && rtav->is_track ()) {
1041 /* over a track, not a bus */
1047 /* not over a time axis view, so drop is possible */
1052 region = _regions->get_dragged_region ();
1056 if ((boost::dynamic_pointer_cast<AudioRegion> (region) != 0 &&
1057 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1058 (boost::dynamic_pointer_cast<MidiRegion> (region) != 0 &&
1059 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1066 context->drag_status (context->get_suggested_action(), time);
1070 /* DND originating from outside ardour
1072 * TODO: check if file is audio/midi, allow drops on same track-type only,
1073 * currently: if audio is dropped on a midi-track, it is only added to the region-list
1075 if (Profile->get_sae() || Config->get_only_copy_imported_files()) {
1076 context->drag_status(Gdk::ACTION_COPY, time);
1078 if ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY) {
1079 context->drag_status(Gdk::ACTION_COPY, time);
1081 context->drag_status(Gdk::ACTION_LINK, time);
1089 context->drag_status (Gdk::DragAction (0), time);
1094 Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
1096 const SelectionData& /*data*/,
1097 guint /*info*/, guint /*time*/)
1099 boost::shared_ptr<Region> region;
1100 boost::shared_ptr<Region> region_copy;
1101 RouteTimeAxisView* rtav;
1106 event.type = GDK_MOTION_NOTIFY;
1109 /* assume we're dragging with button 1 */
1110 event.motion.state = Gdk::BUTTON1_MASK;
1112 framepos_t const pos = window_event_frame (&event, &px, &py);
1114 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1116 if (tv.first != 0) {
1118 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1120 if (rtav != 0 && rtav->is_track ()) {
1122 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
1126 region_copy = RegionFactory::create (region, true);
1129 if ((boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
1130 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1131 (boost::dynamic_pointer_cast<MidiRegion> (region_copy) != 0 &&
1132 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1140 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1141 _drags->end_grab (0);
1149 Editor::key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType)
1155 Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType type)
1158 bool handled = false;
1161 case TempoMarkerItem:
1162 switch (event->key.keyval) {
1164 remove_tempo_marker (item);
1172 case MeterMarkerItem:
1173 switch (event->key.keyval) {
1175 remove_meter_marker (item);