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 if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
271 set_entered_regionview (rv);
276 case GDK_LEAVE_NOTIFY:
277 if (event->crossing.detail != GDK_NOTIFY_INFERIOR) {
278 set_entered_regionview (0);
291 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
295 switch (event->type) {
296 case GDK_BUTTON_PRESS:
297 case GDK_2BUTTON_PRESS:
298 case GDK_3BUTTON_PRESS:
299 clicked_regionview = 0;
300 clicked_control_point = 0;
301 clicked_axisview = tv;
302 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
303 ret = button_press_handler (item, event, StreamItem);
306 case GDK_BUTTON_RELEASE:
307 ret = button_release_handler (item, event, StreamItem);
310 case GDK_MOTION_NOTIFY:
311 ret = motion_handler (item, event);
314 case GDK_ENTER_NOTIFY:
315 set_entered_track (tv);
319 case GDK_LEAVE_NOTIFY:
320 set_entered_track (0);
331 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
335 switch (event->type) {
336 case GDK_BUTTON_PRESS:
337 case GDK_2BUTTON_PRESS:
338 case GDK_3BUTTON_PRESS:
339 clicked_regionview = 0;
340 clicked_control_point = 0;
341 clicked_axisview = atv;
342 clicked_routeview = 0;
343 ret = button_press_handler (item, event, AutomationTrackItem);
346 case GDK_BUTTON_RELEASE:
347 ret = button_release_handler (item, event, AutomationTrackItem);
350 case GDK_MOTION_NOTIFY:
351 ret = motion_handler (item, event);
354 case GDK_ENTER_NOTIFY:
355 ret = enter_handler (item, event, AutomationTrackItem);
358 case GDK_LEAVE_NOTIFY:
359 ret = leave_handler (item, event, AutomationTrackItem);
370 Editor::canvas_start_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
372 if (!rv->sensitive()) {
376 switch (event->type) {
377 case GDK_BUTTON_PRESS:
378 clicked_regionview = rv;
379 clicked_control_point = 0;
380 clicked_axisview = &rv->get_time_axis_view();
381 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
382 if (event->button.button == 3) {
383 return button_press_handler (item, event, StartCrossFadeItem);
387 case GDK_BUTTON_RELEASE:
388 if (event->button.button == 3) {
389 return button_release_handler (item, event, StartCrossFadeItem);
398 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
399 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
400 /* if we return RegionItem here then we avoid the issue until it is resolved later */
401 return typed_event (item, event, RegionItem); // StartCrossFadeItem);
405 Editor::canvas_end_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
407 if (!rv->sensitive()) {
411 switch (event->type) {
412 case GDK_BUTTON_PRESS:
413 clicked_regionview = rv;
414 clicked_control_point = 0;
415 clicked_axisview = &rv->get_time_axis_view();
416 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
417 if (event->button.button == 3) {
418 return button_press_handler (item, event, EndCrossFadeItem);
422 case GDK_BUTTON_RELEASE:
423 if (event->button.button == 3) {
424 return button_release_handler (item, event, EndCrossFadeItem);
433 /* In Mixbus, the crossfade area is used to trim the region while leaving the fade anchor intact (see preserve_fade_anchor)*/
434 /* however in A3 this feature is unfinished, and it might be better to do it with a modifier-trim instead, anyway */
435 /* if we return RegionItem here then we avoid the issue until it is resolved later */
436 return typed_event (item, event, RegionItem); // EndCrossFadeItem);
440 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
442 /* we handle only button 3 press/release events */
444 if (!rv->sensitive()) {
448 switch (event->type) {
449 case GDK_BUTTON_PRESS:
450 clicked_regionview = rv;
451 clicked_control_point = 0;
452 clicked_axisview = &rv->get_time_axis_view();
453 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
454 if (event->button.button == 3) {
455 return button_press_handler (item, event, FadeInItem);
459 case GDK_BUTTON_RELEASE:
460 if (event->button.button == 3) {
461 return button_release_handler (item, event, FadeInItem);
470 /* proxy for the regionview, except enter/leave events */
472 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
475 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
480 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
484 if (!rv->sensitive()) {
488 switch (event->type) {
489 case GDK_BUTTON_PRESS:
490 case GDK_2BUTTON_PRESS:
491 case GDK_3BUTTON_PRESS:
492 clicked_regionview = rv;
493 clicked_control_point = 0;
494 clicked_axisview = &rv->get_time_axis_view();
495 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
496 ret = button_press_handler (item, event, FadeInHandleItem);
499 case GDK_BUTTON_RELEASE:
500 ret = button_release_handler (item, event, FadeInHandleItem);
501 maybe_locate_with_edit_preroll ( rv->region()->position() );
504 case GDK_MOTION_NOTIFY:
505 ret = motion_handler (item, event);
508 case GDK_ENTER_NOTIFY:
509 ret = enter_handler (item, event, FadeInHandleItem);
512 case GDK_LEAVE_NOTIFY:
513 ret = leave_handler (item, event, FadeInHandleItem);
524 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
526 /* we handle only button 3 press/release events */
528 if (!rv->sensitive()) {
532 switch (event->type) {
533 case GDK_BUTTON_PRESS:
534 clicked_regionview = rv;
535 clicked_control_point = 0;
536 clicked_axisview = &rv->get_time_axis_view();
537 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
538 if (event->button.button == 3) {
539 return button_press_handler (item, event, FadeOutItem);
543 case GDK_BUTTON_RELEASE:
544 if (event->button.button == 3) {
545 return button_release_handler (item, event, FadeOutItem);
554 /* proxy for the regionview, except enter/leave events */
556 if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) {
559 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
564 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
568 if (!rv->sensitive()) {
572 switch (event->type) {
573 case GDK_BUTTON_PRESS:
574 case GDK_2BUTTON_PRESS:
575 case GDK_3BUTTON_PRESS:
576 clicked_regionview = rv;
577 clicked_control_point = 0;
578 clicked_axisview = &rv->get_time_axis_view();
579 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
580 ret = button_press_handler (item, event, FadeOutHandleItem);
583 case GDK_BUTTON_RELEASE:
584 ret = button_release_handler (item, event, FadeOutHandleItem);
585 maybe_locate_with_edit_preroll ( rv->region()->last_frame() - rv->get_fade_out_shape_width() );
588 case GDK_MOTION_NOTIFY:
589 ret = motion_handler (item, event);
592 case GDK_ENTER_NOTIFY:
593 ret = enter_handler (item, event, FadeOutHandleItem);
596 case GDK_LEAVE_NOTIFY:
597 ret = leave_handler (item, event, FadeOutHandleItem);
607 struct DescendingRegionLayerSorter {
608 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
609 return a->layer() > b->layer();
614 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
616 switch (event->type) {
617 case GDK_BUTTON_PRESS:
618 case GDK_2BUTTON_PRESS:
619 case GDK_3BUTTON_PRESS:
620 clicked_control_point = cp;
621 clicked_axisview = &cp->line().trackview;
622 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
623 clicked_regionview = 0;
629 case GDK_SCROLL_DOWN:
636 return typed_event (item, event, ControlPointItem);
640 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
644 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
647 type = AutomationLineItem;
650 return typed_event (item, event, type);
654 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
658 switch (event->type) {
659 case GDK_BUTTON_PRESS:
660 case GDK_2BUTTON_PRESS:
661 case GDK_3BUTTON_PRESS:
662 clicked_selection = rect->id;
663 ret = button_press_handler (item, event, SelectionItem);
665 case GDK_BUTTON_RELEASE:
666 ret = button_release_handler (item, event, SelectionItem);
668 case GDK_MOTION_NOTIFY:
669 ret = motion_handler (item, event);
671 /* Don't need these at the moment. */
672 case GDK_ENTER_NOTIFY:
673 ret = enter_handler (item, event, SelectionItem);
676 case GDK_LEAVE_NOTIFY:
677 ret = leave_handler (item, event, SelectionItem);
688 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
692 switch (event->type) {
693 case GDK_BUTTON_PRESS:
694 case GDK_2BUTTON_PRESS:
695 case GDK_3BUTTON_PRESS:
696 clicked_selection = rect->id;
697 ret = button_press_handler (item, event, StartSelectionTrimItem);
699 case GDK_BUTTON_RELEASE:
700 ret = button_release_handler (item, event, StartSelectionTrimItem);
702 case GDK_MOTION_NOTIFY:
703 ret = motion_handler (item, event);
705 case GDK_ENTER_NOTIFY:
706 ret = enter_handler (item, event, StartSelectionTrimItem);
709 case GDK_LEAVE_NOTIFY:
710 ret = leave_handler (item, event, StartSelectionTrimItem);
721 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
725 switch (event->type) {
726 case GDK_BUTTON_PRESS:
727 case GDK_2BUTTON_PRESS:
728 case GDK_3BUTTON_PRESS:
729 clicked_selection = rect->id;
730 ret = button_press_handler (item, event, EndSelectionTrimItem);
732 case GDK_BUTTON_RELEASE:
733 ret = button_release_handler (item, event, EndSelectionTrimItem);
735 case GDK_MOTION_NOTIFY:
736 ret = motion_handler (item, event);
738 case GDK_ENTER_NOTIFY:
739 ret = enter_handler (item, event, EndSelectionTrimItem);
742 case GDK_LEAVE_NOTIFY:
743 ret = leave_handler (item, event, EndSelectionTrimItem);
754 Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
758 /* frame handles are not active when in internal edit mode, because actual notes
759 might be in the area occupied by the handle - we want them to be editable as normal.
762 if (internal_editing() || !rv->sensitive()) {
766 /* NOTE: frame handles pretend to be the colored trim bar from an event handling
767 perspective. XXX change this ??
772 if (item->get_data ("isleft")) {
773 type = LeftFrameHandle;
775 type = RightFrameHandle;
778 switch (event->type) {
779 case GDK_BUTTON_PRESS:
780 case GDK_2BUTTON_PRESS:
781 case GDK_3BUTTON_PRESS:
782 clicked_regionview = rv;
783 clicked_control_point = 0;
784 clicked_axisview = &clicked_regionview->get_time_axis_view();
785 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
786 ret = button_press_handler (item, event, type);
788 case GDK_BUTTON_RELEASE:
789 ret = button_release_handler (item, event, type);
791 case GDK_MOTION_NOTIFY:
792 ret = motion_handler (item, event);
794 case GDK_ENTER_NOTIFY:
795 ret = enter_handler (item, event, type);
798 case GDK_LEAVE_NOTIFY:
799 ret = leave_handler (item, event, type);
811 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
815 if (!rv->sensitive()) {
819 switch (event->type) {
820 case GDK_BUTTON_PRESS:
821 case GDK_2BUTTON_PRESS:
822 case GDK_3BUTTON_PRESS:
823 clicked_regionview = rv;
824 clicked_control_point = 0;
825 clicked_axisview = &clicked_regionview->get_time_axis_view();
826 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
827 ret = button_press_handler (item, event, RegionViewNameHighlight);
829 case GDK_BUTTON_RELEASE:
830 ret = button_release_handler (item, event, RegionViewNameHighlight);
832 case GDK_MOTION_NOTIFY:
833 motion_handler (item, event);
834 ret = true; // force this to avoid progagating the event into the regionview
836 case GDK_ENTER_NOTIFY:
837 ret = enter_handler (item, event, RegionViewNameHighlight);
840 case GDK_LEAVE_NOTIFY:
841 ret = leave_handler (item, event, RegionViewNameHighlight);
852 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
856 if (!rv->sensitive()) {
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);
870 case GDK_BUTTON_RELEASE:
871 ret = button_release_handler (item, event, RegionViewName);
873 case GDK_MOTION_NOTIFY:
874 ret = motion_handler (item, event);
876 case GDK_ENTER_NOTIFY:
877 ret = enter_handler (item, event, RegionViewName);
880 case GDK_LEAVE_NOTIFY:
881 ret = leave_handler (item, event, RegionViewName);
892 Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*)
896 switch (event->type) {
897 case GDK_BUTTON_PRESS:
898 case GDK_2BUTTON_PRESS:
899 case GDK_3BUTTON_PRESS:
900 clicked_regionview = 0;
901 clicked_control_point = 0;
902 clicked_axisview = 0;
903 clicked_routeview = 0; //dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
904 ret = button_press_handler (item, event, FeatureLineItem);
907 case GDK_BUTTON_RELEASE:
908 ret = button_release_handler (item, event, FeatureLineItem);
911 case GDK_MOTION_NOTIFY:
912 ret = motion_handler (item, event);
915 case GDK_ENTER_NOTIFY:
916 ret = enter_handler (item, event, FeatureLineItem);
919 case GDK_LEAVE_NOTIFY:
920 ret = leave_handler (item, event, FeatureLineItem);
931 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/)
933 return typed_event (item, event, MarkerItem);
937 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
939 return typed_event (item, event, MarkerBarItem);
943 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
945 return typed_event (item, event, RangeMarkerBarItem);
949 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
951 return typed_event (item, event, TransportMarkerBarItem);
955 Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
957 return typed_event (item, event, CdMarkerBarItem);
961 Editor::canvas_videotl_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
963 return typed_event (item, event, VideoBarItem);
967 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/)
969 return typed_event (item, event, TempoMarkerItem);
973 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/)
975 return typed_event (item, event, MeterMarkerItem);
979 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
981 return typed_event (item, event, TempoBarItem);
985 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
987 return typed_event (item, event, MeterBarItem);
991 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
993 return typed_event (item, event, PlayheadCursorItem);
997 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
999 return typed_event (item, event, NoItem);
1003 Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item)
1005 if (!internal_editing()) {
1009 return typed_event (item, event, NoteItem);
1013 Editor::canvas_bottom_rect_event (GdkEvent* event)
1015 cerr << "CBR event, type " << event << endl;
1020 Editor::track_canvas_drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, int x, int y, guint time)
1022 boost::shared_ptr<Region> region;
1023 boost::shared_ptr<Region> region_copy;
1024 RouteTimeAxisView* rtav;
1029 string target = _track_canvas->drag_dest_find_target (context, _track_canvas->drag_dest_get_target_list());
1031 if (target.empty()) {
1035 event.type = GDK_MOTION_NOTIFY;
1038 /* assume we're dragging with button 1 */
1039 event.motion.state = Gdk::BUTTON1_MASK;
1041 (void) window_event_sample (&event, &px, &py);
1043 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1044 bool can_drop = false;
1046 if (tv.first != 0) {
1048 /* over a time axis view of some kind */
1050 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1052 if (rtav != 0 && rtav->is_track ()) {
1053 /* over a track, not a bus */
1059 /* not over a time axis view, so drop is possible */
1064 region = _regions->get_dragged_region ();
1068 if ((boost::dynamic_pointer_cast<AudioRegion> (region) != 0 &&
1069 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1070 (boost::dynamic_pointer_cast<MidiRegion> (region) != 0 &&
1071 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1078 context->drag_status (context->get_suggested_action(), time);
1082 /* DND originating from outside ardour
1084 * TODO: check if file is audio/midi, allow drops on same track-type only,
1085 * currently: if audio is dropped on a midi-track, it is only added to the region-list
1087 if (Profile->get_sae() || Config->get_only_copy_imported_files()) {
1088 context->drag_status(Gdk::ACTION_COPY, time);
1090 if ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY) {
1091 context->drag_status(Gdk::ACTION_COPY, time);
1093 context->drag_status(Gdk::ACTION_LINK, time);
1101 context->drag_status (Gdk::DragAction (0), time);
1106 Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
1108 const SelectionData& /*data*/,
1109 guint /*info*/, guint /*time*/)
1111 boost::shared_ptr<Region> region;
1112 boost::shared_ptr<Region> region_copy;
1113 RouteTimeAxisView* rtav;
1118 event.type = GDK_MOTION_NOTIFY;
1121 /* assume we're dragging with button 1 */
1122 event.motion.state = Gdk::BUTTON1_MASK;
1124 framepos_t const pos = window_event_sample (&event, &px, &py);
1126 std::pair<TimeAxisView*, int> const tv = trackview_by_y_position (py);
1128 if (tv.first != 0) {
1130 rtav = dynamic_cast<RouteTimeAxisView*> (tv.first);
1132 if (rtav != 0 && rtav->is_track ()) {
1134 boost::shared_ptr<Region> region = _regions->get_dragged_region ();
1138 region_copy = RegionFactory::create (region, true);
1141 if ((boost::dynamic_pointer_cast<AudioRegion> (region_copy) != 0 &&
1142 dynamic_cast<AudioTimeAxisView*> (tv.first) != 0) ||
1143 (boost::dynamic_pointer_cast<MidiRegion> (region_copy) != 0 &&
1144 dynamic_cast<MidiTimeAxisView*> (tv.first) != 0)) {
1152 _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event);
1153 _drags->end_grab (0);
1161 Editor::key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType)
1167 Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType type)
1170 bool handled = false;
1173 case TempoMarkerItem:
1174 switch (event->key.keyval) {
1176 remove_tempo_marker (item);
1184 case MeterMarkerItem:
1185 switch (event->key.keyval) {
1187 remove_meter_marker (item);