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.
23 #include <pbd/stacktrace.h>
25 #include <ardour/audio_diskstream.h>
26 #include <ardour/audioplaylist.h>
30 #include "public_editor.h"
31 #include "audio_region_view.h"
32 #include "audio_streamview.h"
33 #include "crossfade_view.h"
34 #include "audio_time_axis.h"
35 #include "region_gain_line.h"
36 #include "automation_line.h"
37 #include "automation_time_axis.h"
38 #include "automation_line.h"
39 #include "canvas_impl.h"
40 #include "simplerect.h"
45 using namespace ARDOUR;
50 Editor::track_canvas_scroll (GdkEventScroll* ev)
55 switch (ev->direction) {
57 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
58 //if (ev->state == GDK_CONTROL_MASK) {
60 the ev->x will be out of step with the canvas
61 if we're in mid zoom, so we have to get the damn mouse
64 track_canvas.get_pointer (x, y);
65 track_canvas.window_to_world (x, y, wx, wy);
66 wx += horizontal_adjustment.get_value();
67 wy += vertical_adjustment.get_value();
70 event.type = GDK_BUTTON_RELEASE;
74 nframes_t where = event_frame (&event, 0, 0);
75 temporal_zoom_to_frame (false, where);
77 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
78 if (!current_stepping_trackview) {
79 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
80 if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
84 gettimeofday (&last_track_height_step_timestamp, 0);
85 current_stepping_trackview->step_height (true);
88 scroll_tracks_up_line ();
93 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
94 //if (ev->state == GDK_CONTROL_MASK) {
95 track_canvas.get_pointer (x, y);
96 track_canvas.window_to_world (x, y, wx, wy);
97 wx += horizontal_adjustment.get_value();
98 wy += vertical_adjustment.get_value();
101 event.type = GDK_BUTTON_RELEASE;
105 nframes_t where = event_frame (&event, 0, 0);
106 temporal_zoom_to_frame (true, where);
108 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
109 if (!current_stepping_trackview) {
110 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
111 if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) {
115 gettimeofday (&last_track_height_step_timestamp, 0);
116 current_stepping_trackview->step_height (false);
119 scroll_tracks_down_line ();
125 /* no left/right handling yet */
133 Editor::track_canvas_scroll_event (GdkEventScroll *event)
135 track_canvas.grab_focus();
136 track_canvas_scroll (event);
141 Editor::track_canvas_button_press_event (GdkEventButton *event)
143 track_canvas.grab_focus();
148 Editor::track_canvas_button_release_event (GdkEventButton *event)
150 if (drag_info.item) {
151 end_grab (drag_info.item, (GdkEvent*) event);
157 Editor::track_canvas_motion_notify_event (GdkEventMotion *event)
160 /* keep those motion events coming */
161 track_canvas.get_pointer (x, y);
166 Editor::track_canvas_motion (GdkEvent *ev)
168 if (verbose_cursor_visible) {
169 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
170 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
176 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
180 switch (event->type) {
181 case GDK_BUTTON_PRESS:
182 case GDK_2BUTTON_PRESS:
183 case GDK_3BUTTON_PRESS:
184 ret = button_press_handler (item, event, type);
186 case GDK_BUTTON_RELEASE:
187 ret = button_release_handler (item, event, type);
189 case GDK_MOTION_NOTIFY:
190 ret = motion_handler (item, event, type);
193 case GDK_ENTER_NOTIFY:
194 ret = enter_handler (item, event, type);
197 case GDK_LEAVE_NOTIFY:
198 ret = leave_handler (item, event, type);
209 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
213 if (!rv->sensitive ()) {
218 switch (event->type) {
219 case GDK_BUTTON_PRESS:
220 case GDK_2BUTTON_PRESS:
221 case GDK_3BUTTON_PRESS:
222 clicked_regionview = rv;
223 clicked_control_point = 0;
224 clicked_axisview = &rv->get_time_axis_view();
225 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
226 ret = button_press_handler (item, event, RegionItem);
229 case GDK_BUTTON_RELEASE:
230 ret = button_release_handler (item, event, RegionItem);
233 case GDK_MOTION_NOTIFY:
234 ret = motion_handler (item, event, RegionItem);
237 case GDK_ENTER_NOTIFY:
238 set_entered_regionview (rv);
241 case GDK_LEAVE_NOTIFY:
242 set_entered_regionview (0);
253 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
257 switch (event->type) {
258 case GDK_BUTTON_PRESS:
259 case GDK_2BUTTON_PRESS:
260 case GDK_3BUTTON_PRESS:
261 clicked_regionview = 0;
262 clicked_control_point = 0;
263 clicked_axisview = tv;
264 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(tv);
265 ret = button_press_handler (item, event, StreamItem);
268 case GDK_BUTTON_RELEASE:
269 ret = button_release_handler (item, event, StreamItem);
272 case GDK_MOTION_NOTIFY:
273 ret = motion_handler (item, event, StreamItem);
276 case GDK_ENTER_NOTIFY:
289 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
294 switch (event->type) {
295 case GDK_BUTTON_PRESS:
296 case GDK_2BUTTON_PRESS:
297 case GDK_3BUTTON_PRESS:
298 clicked_regionview = 0;
299 clicked_control_point = 0;
300 clicked_axisview = atv;
301 clicked_routeview = 0;
302 ret = button_press_handler (item, event, AutomationTrackItem);
305 case GDK_BUTTON_RELEASE:
306 ret = button_release_handler (item, event, AutomationTrackItem);
309 case GDK_MOTION_NOTIFY:
310 ret = motion_handler (item, event, AutomationTrackItem);
313 case GDK_ENTER_NOTIFY:
314 ret = enter_handler (item, event, AutomationTrackItem);
317 case GDK_LEAVE_NOTIFY:
318 ret = leave_handler (item, event, AutomationTrackItem);
329 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
331 /* we handle only button 3 press/release events */
333 if (!rv->sensitive()) {
337 switch (event->type) {
338 case GDK_BUTTON_PRESS:
339 clicked_regionview = rv;
340 clicked_control_point = 0;
341 clicked_axisview = &rv->get_time_axis_view();
342 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
343 if (event->button.button == 3) {
344 return button_press_handler (item, event, FadeInItem);
348 case GDK_BUTTON_RELEASE:
349 if (event->button.button == 3) {
350 return button_release_handler (item, event, FadeInItem);
359 /* proxy for the regionview */
361 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
365 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
369 if (!rv->sensitive()) {
373 switch (event->type) {
374 case GDK_BUTTON_PRESS:
375 case GDK_2BUTTON_PRESS:
376 case GDK_3BUTTON_PRESS:
377 clicked_regionview = rv;
378 clicked_control_point = 0;
379 clicked_axisview = &rv->get_time_axis_view();
380 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
381 ret = button_press_handler (item, event, FadeInHandleItem);
384 case GDK_BUTTON_RELEASE:
385 ret = button_release_handler (item, event, FadeInHandleItem);
388 case GDK_MOTION_NOTIFY:
389 ret = motion_handler (item, event, FadeInHandleItem);
392 case GDK_ENTER_NOTIFY:
393 ret = enter_handler (item, event, FadeInHandleItem);
396 case GDK_LEAVE_NOTIFY:
397 ret = leave_handler (item, event, FadeInHandleItem);
408 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
410 /* we handle only button 3 press/release events */
412 if (!rv->sensitive()) {
416 switch (event->type) {
417 case GDK_BUTTON_PRESS:
418 clicked_regionview = rv;
419 clicked_control_point = 0;
420 clicked_axisview = &rv->get_time_axis_view();
421 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
422 if (event->button.button == 3) {
423 return button_press_handler (item, event, FadeOutItem);
427 case GDK_BUTTON_RELEASE:
428 if (event->button.button == 3) {
429 return button_release_handler (item, event, FadeOutItem);
438 /* proxy for the regionview */
440 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
444 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
448 if (!rv->sensitive()) {
452 switch (event->type) {
453 case GDK_BUTTON_PRESS:
454 case GDK_2BUTTON_PRESS:
455 case GDK_3BUTTON_PRESS:
456 clicked_regionview = rv;
457 clicked_control_point = 0;
458 clicked_axisview = &rv->get_time_axis_view();
459 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
460 ret = button_press_handler (item, event, FadeOutHandleItem);
463 case GDK_BUTTON_RELEASE:
464 ret = button_release_handler (item, event, FadeOutHandleItem);
467 case GDK_MOTION_NOTIFY:
468 ret = motion_handler (item, event, FadeOutHandleItem);
471 case GDK_ENTER_NOTIFY:
472 ret = enter_handler (item, event, FadeOutHandleItem);
475 case GDK_LEAVE_NOTIFY:
476 ret = leave_handler (item, event, FadeOutHandleItem);
486 struct DescendingRegionLayerSorter {
487 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
488 return a->layer() > b->layer();
493 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
495 /* we handle only button 3 press/release events */
497 switch (event->type) {
498 case GDK_BUTTON_PRESS:
499 clicked_crossfadeview = xfv;
500 clicked_axisview = &clicked_crossfadeview->get_time_axis_view();
501 if (event->button.button == 3) {
502 return button_press_handler (item, event, CrossfadeViewItem);
506 case GDK_BUTTON_RELEASE:
507 if (event->button.button == 3) {
508 bool ret = button_release_handler (item, event, CrossfadeViewItem);
518 /* XXX do not forward double clicks */
520 if (event->type == GDK_2BUTTON_PRESS) {
524 /* proxy for the upper most regionview */
526 /* XXX really need to check if we are in the name highlight,
527 and proxy to that when required.
530 TimeAxisView& tv (xfv->get_time_axis_view());
531 AudioTimeAxisView* atv;
533 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
535 if (atv->is_audio_track()) {
537 boost::shared_ptr<AudioPlaylist> pl;
538 if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
540 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
543 DescendingRegionLayerSorter cmp;
546 RegionView* rv = atv->view()->find_view (rl->front());
552 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
562 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
564 switch (event->type) {
565 case GDK_BUTTON_PRESS:
566 case GDK_2BUTTON_PRESS:
567 case GDK_3BUTTON_PRESS:
568 clicked_control_point = cp;
569 clicked_axisview = &cp->line.trackview;
570 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
571 clicked_regionview = 0;
577 case GDK_SCROLL_DOWN:
584 return typed_event (item, event, ControlPointItem);
588 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
592 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
595 type = AutomationLineItem;
598 return typed_event (item, event, type);
602 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
606 switch (event->type) {
607 case GDK_BUTTON_PRESS:
608 case GDK_2BUTTON_PRESS:
609 case GDK_3BUTTON_PRESS:
610 clicked_selection = rect->id;
611 ret = button_press_handler (item, event, SelectionItem);
613 case GDK_BUTTON_RELEASE:
614 ret = button_release_handler (item, event, SelectionItem);
616 case GDK_MOTION_NOTIFY:
617 ret = motion_handler (item, event, SelectionItem);
619 /* Don't need these at the moment. */
620 case GDK_ENTER_NOTIFY:
621 ret = enter_handler (item, event, SelectionItem);
624 case GDK_LEAVE_NOTIFY:
625 ret = leave_handler (item, event, SelectionItem);
636 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
640 switch (event->type) {
641 case GDK_BUTTON_PRESS:
642 case GDK_2BUTTON_PRESS:
643 case GDK_3BUTTON_PRESS:
644 clicked_selection = rect->id;
645 ret = button_press_handler (item, event, StartSelectionTrimItem);
647 case GDK_BUTTON_RELEASE:
648 ret = button_release_handler (item, event, StartSelectionTrimItem);
650 case GDK_MOTION_NOTIFY:
651 ret = motion_handler (item, event, StartSelectionTrimItem);
653 case GDK_ENTER_NOTIFY:
654 ret = enter_handler (item, event, StartSelectionTrimItem);
657 case GDK_LEAVE_NOTIFY:
658 ret = leave_handler (item, event, StartSelectionTrimItem);
669 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
673 switch (event->type) {
674 case GDK_BUTTON_PRESS:
675 case GDK_2BUTTON_PRESS:
676 case GDK_3BUTTON_PRESS:
677 clicked_selection = rect->id;
678 ret = button_press_handler (item, event, EndSelectionTrimItem);
680 case GDK_BUTTON_RELEASE:
681 ret = button_release_handler (item, event, EndSelectionTrimItem);
683 case GDK_MOTION_NOTIFY:
684 ret = motion_handler (item, event, EndSelectionTrimItem);
686 case GDK_ENTER_NOTIFY:
687 ret = enter_handler (item, event, EndSelectionTrimItem);
690 case GDK_LEAVE_NOTIFY:
691 ret = leave_handler (item, event, EndSelectionTrimItem);
703 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
707 if (!rv->sensitive()) {
711 switch (event->type) {
712 case GDK_BUTTON_PRESS:
713 case GDK_2BUTTON_PRESS:
714 case GDK_3BUTTON_PRESS:
715 clicked_regionview = rv;
716 clicked_control_point = 0;
717 clicked_axisview = &clicked_regionview->get_time_axis_view();
718 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
719 ret = button_press_handler (item, event, RegionViewNameHighlight);
721 case GDK_BUTTON_RELEASE:
722 ret = button_release_handler (item, event, RegionViewNameHighlight);
724 case GDK_MOTION_NOTIFY:
725 ret = motion_handler (item, event, RegionViewNameHighlight);
727 case GDK_ENTER_NOTIFY:
728 ret = enter_handler (item, event, RegionViewNameHighlight);
731 case GDK_LEAVE_NOTIFY:
732 ret = leave_handler (item, event, RegionViewNameHighlight);
743 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
747 if (!rv->sensitive()) {
751 switch (event->type) {
752 case GDK_BUTTON_PRESS:
753 case GDK_2BUTTON_PRESS:
754 case GDK_3BUTTON_PRESS:
755 clicked_regionview = rv;
756 clicked_control_point = 0;
757 clicked_axisview = &clicked_regionview->get_time_axis_view();
758 clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
759 ret = button_press_handler (item, event, RegionViewName);
761 case GDK_BUTTON_RELEASE:
762 ret = button_release_handler (item, event, RegionViewName);
764 case GDK_MOTION_NOTIFY:
765 ret = motion_handler (item, event, RegionViewName);
767 case GDK_ENTER_NOTIFY:
768 ret = enter_handler (item, event, RegionViewName);
771 case GDK_LEAVE_NOTIFY:
772 ret = leave_handler (item, event, RegionViewName);
783 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
785 return typed_event (item, event, MarkerItem);
789 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
791 return typed_event (item, event, MarkerBarItem);
795 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
797 return typed_event (item, event, RangeMarkerBarItem);
801 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
803 return typed_event (item, event, TransportMarkerBarItem);
807 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
809 return typed_event (item, event, TempoMarkerItem);
813 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
815 return typed_event (item, event, MeterMarkerItem);
819 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
821 return typed_event (item, event, TempoBarItem);
825 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
827 return typed_event (item, event, MeterBarItem);
831 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
833 return typed_event (item, event, PlayheadCursorItem);
837 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
839 return typed_event (item, event, EditCursorItem);
843 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
845 return typed_event (item, event, NoItem);