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.
24 #include <ardour/audio_diskstream.h>
25 #include <ardour/audioplaylist.h>
29 #include "public_editor.h"
30 #include "audio_region_view.h"
31 #include "audio_streamview.h"
32 #include "crossfade_view.h"
33 #include "audio_time_axis.h"
34 #include "region_gain_line.h"
35 #include "automation_gain_line.h"
36 #include "automation_pan_line.h"
37 #include "automation_time_axis.h"
38 #include "redirect_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 (true, 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 (false, 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_event (GdkEvent *event, ArdourCanvas::Item* item)
137 /* this is the handler for events that are not handled by
141 switch (event->type) {
142 case GDK_MOTION_NOTIFY:
143 /* keep those motion events coming */
144 track_canvas.get_pointer (x, y);
145 return track_canvas_motion (event);
147 case GDK_BUTTON_PRESS:
148 track_canvas.grab_focus();
151 case GDK_BUTTON_RELEASE:
152 switch (event->button.button) {
155 button_release_handler (item, event, NoItem);
161 track_canvas.grab_focus();
162 track_canvas_scroll (&event->scroll);
173 Editor::track_canvas_motion (GdkEvent *ev)
175 if (verbose_cursor_visible) {
176 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
177 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
183 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
187 switch (event->type) {
188 case GDK_BUTTON_PRESS:
189 case GDK_2BUTTON_PRESS:
190 case GDK_3BUTTON_PRESS:
191 ret = button_press_handler (item, event, type);
193 case GDK_BUTTON_RELEASE:
194 ret = button_release_handler (item, event, type);
196 case GDK_MOTION_NOTIFY:
197 ret = motion_handler (item, event, type);
200 case GDK_ENTER_NOTIFY:
201 ret = enter_handler (item, event, type);
204 case GDK_LEAVE_NOTIFY:
205 ret = leave_handler (item, event, type);
216 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
220 switch (event->type) {
221 case GDK_BUTTON_PRESS:
222 case GDK_2BUTTON_PRESS:
223 case GDK_3BUTTON_PRESS:
224 clicked_regionview = rv;
225 clicked_control_point = 0;
226 clicked_trackview = &rv->get_time_axis_view();
227 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
228 ret = button_press_handler (item, event, RegionItem);
231 case GDK_BUTTON_RELEASE:
232 ret = button_release_handler (item, event, RegionItem);
235 case GDK_MOTION_NOTIFY:
236 ret = motion_handler (item, event, RegionItem);
239 case GDK_ENTER_NOTIFY:
240 set_entered_regionview (rv);
243 case GDK_LEAVE_NOTIFY:
244 set_entered_regionview (0);
255 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
259 switch (event->type) {
260 case GDK_BUTTON_PRESS:
261 case GDK_2BUTTON_PRESS:
262 case GDK_3BUTTON_PRESS:
263 clicked_regionview = 0;
264 clicked_control_point = 0;
265 clicked_trackview = tv;
266 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(tv);
267 ret = button_press_handler (item, event, StreamItem);
270 case GDK_BUTTON_RELEASE:
271 ret = button_release_handler (item, event, StreamItem);
274 case GDK_MOTION_NOTIFY:
275 ret = motion_handler (item, event, StreamItem);
278 case GDK_ENTER_NOTIFY:
291 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
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_trackview = atv;
302 clicked_audio_trackview = 0;
303 ret = button_press_handler (item, event, AutomationTrackItem);
306 case GDK_BUTTON_RELEASE:
307 ret = button_release_handler (item, event, AutomationTrackItem);
310 case GDK_MOTION_NOTIFY:
311 ret = motion_handler (item, event, AutomationTrackItem);
314 case GDK_ENTER_NOTIFY:
315 ret = enter_handler (item, event, AutomationTrackItem);
318 case GDK_LEAVE_NOTIFY:
319 ret = leave_handler (item, event, AutomationTrackItem);
330 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
332 /* we handle only button 3 press/release events */
334 switch (event->type) {
335 case GDK_BUTTON_PRESS:
336 clicked_regionview = rv;
337 clicked_control_point = 0;
338 clicked_trackview = &rv->get_time_axis_view();
339 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
340 if (event->button.button == 3) {
341 return button_press_handler (item, event, FadeInItem);
345 case GDK_BUTTON_RELEASE:
346 if (event->button.button == 3) {
347 return button_release_handler (item, event, FadeInItem);
356 /* proxy for the regionview */
358 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
362 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
366 switch (event->type) {
367 case GDK_BUTTON_PRESS:
368 case GDK_2BUTTON_PRESS:
369 case GDK_3BUTTON_PRESS:
370 clicked_regionview = rv;
371 clicked_control_point = 0;
372 clicked_trackview = &rv->get_time_axis_view();
373 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
374 ret = button_press_handler (item, event, FadeInHandleItem);
377 case GDK_BUTTON_RELEASE:
378 ret = button_release_handler (item, event, FadeInHandleItem);
381 case GDK_MOTION_NOTIFY:
382 ret = motion_handler (item, event, FadeInHandleItem);
385 case GDK_ENTER_NOTIFY:
386 ret = enter_handler (item, event, FadeInHandleItem);
389 case GDK_LEAVE_NOTIFY:
390 ret = leave_handler (item, event, FadeInHandleItem);
401 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
403 /* we handle only button 3 press/release events */
405 switch (event->type) {
406 case GDK_BUTTON_PRESS:
407 clicked_regionview = rv;
408 clicked_control_point = 0;
409 clicked_trackview = &rv->get_time_axis_view();
410 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
411 if (event->button.button == 3) {
412 return button_press_handler (item, event, FadeOutItem);
416 case GDK_BUTTON_RELEASE:
417 if (event->button.button == 3) {
418 return button_release_handler (item, event, FadeOutItem);
427 /* proxy for the regionview */
429 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
433 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
437 switch (event->type) {
438 case GDK_BUTTON_PRESS:
439 case GDK_2BUTTON_PRESS:
440 case GDK_3BUTTON_PRESS:
441 clicked_regionview = rv;
442 clicked_control_point = 0;
443 clicked_trackview = &rv->get_time_axis_view();
444 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
445 ret = button_press_handler (item, event, FadeOutHandleItem);
448 case GDK_BUTTON_RELEASE:
449 ret = button_release_handler (item, event, FadeOutHandleItem);
452 case GDK_MOTION_NOTIFY:
453 ret = motion_handler (item, event, FadeOutHandleItem);
456 case GDK_ENTER_NOTIFY:
457 ret = enter_handler (item, event, FadeOutHandleItem);
460 case GDK_LEAVE_NOTIFY:
461 ret = leave_handler (item, event, FadeOutHandleItem);
471 struct DescendingRegionLayerSorter {
472 bool operator()(boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
473 return a->layer() > b->layer();
478 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
480 /* we handle only button 3 press/release events */
482 switch (event->type) {
483 case GDK_BUTTON_PRESS:
484 clicked_crossfadeview = xfv;
485 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
486 if (event->button.button == 3) {
487 return button_press_handler (item, event, CrossfadeViewItem);
491 case GDK_BUTTON_RELEASE:
492 if (event->button.button == 3) {
493 bool ret = button_release_handler (item, event, CrossfadeViewItem);
504 /* proxy for the upper most regionview */
506 /* XXX really need to check if we are in the name highlight,
507 and proxy to that when required.
510 TimeAxisView& tv (xfv->get_time_axis_view());
511 AudioTimeAxisView* atv;
513 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
515 if (atv->is_audio_track()) {
517 boost::shared_ptr<AudioPlaylist> pl;
518 if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
520 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
523 DescendingRegionLayerSorter cmp;
526 RegionView* rv = atv->view()->find_view (rl->front());
532 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
542 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
546 switch (event->type) {
547 case GDK_BUTTON_PRESS:
548 case GDK_2BUTTON_PRESS:
549 case GDK_3BUTTON_PRESS:
550 clicked_control_point = cp;
551 clicked_trackview = &cp->line.trackview;
552 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
553 clicked_regionview = 0;
559 case GDK_SCROLL_DOWN:
566 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
567 type = GainControlPointItem;
568 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
569 type = GainAutomationControlPointItem;
570 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
571 type = PanAutomationControlPointItem;
572 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
573 type = RedirectAutomationControlPointItem;
578 return typed_event (item, event, type);
582 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
586 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
588 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
589 type = GainAutomationLineItem;
590 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
591 type = PanAutomationLineItem;
592 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
593 type = RedirectAutomationLineItem;
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 switch (event->type) {
708 case GDK_BUTTON_PRESS:
709 case GDK_2BUTTON_PRESS:
710 case GDK_3BUTTON_PRESS:
711 clicked_regionview = rv;
712 clicked_control_point = 0;
713 clicked_trackview = &clicked_regionview->get_time_axis_view();
714 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
715 ret = button_press_handler (item, event, RegionViewNameHighlight);
717 case GDK_BUTTON_RELEASE:
718 ret = button_release_handler (item, event, RegionViewNameHighlight);
720 case GDK_MOTION_NOTIFY:
721 ret = motion_handler (item, event, RegionViewNameHighlight);
723 case GDK_ENTER_NOTIFY:
724 ret = enter_handler (item, event, RegionViewNameHighlight);
727 case GDK_LEAVE_NOTIFY:
728 ret = leave_handler (item, event, RegionViewNameHighlight);
739 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
743 switch (event->type) {
744 case GDK_BUTTON_PRESS:
745 case GDK_2BUTTON_PRESS:
746 case GDK_3BUTTON_PRESS:
747 clicked_regionview = rv;
748 clicked_control_point = 0;
749 clicked_trackview = &clicked_regionview->get_time_axis_view();
750 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
751 ret = button_press_handler (item, event, RegionViewName);
753 case GDK_BUTTON_RELEASE:
754 ret = button_release_handler (item, event, RegionViewName);
756 case GDK_MOTION_NOTIFY:
757 ret = motion_handler (item, event, RegionViewName);
759 case GDK_ENTER_NOTIFY:
760 ret = enter_handler (item, event, RegionViewName);
763 case GDK_LEAVE_NOTIFY:
764 ret = leave_handler (item, event, RegionViewName);
775 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
777 return typed_event (item, event, MarkerItem);
781 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
783 return typed_event (item, event, MarkerBarItem);
787 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
789 return typed_event (item, event, RangeMarkerBarItem);
793 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
795 return typed_event (item, event, TransportMarkerBarItem);
799 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
801 return typed_event (item, event, TempoMarkerItem);
805 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
807 return typed_event (item, event, MeterMarkerItem);
811 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
813 return typed_event (item, event, TempoBarItem);
817 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
819 return typed_event (item, event, MeterBarItem);
823 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
825 return typed_event (item, event, PlayheadCursorItem);
829 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
831 return typed_event (item, event, EditCursorItem);
835 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
837 return typed_event (item, event, NoItem);