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/diskstream.h>
25 #include <ardour/audioplaylist.h>
28 #include "public_editor.h"
29 #include "regionview.h"
30 #include "streamview.h"
31 #include "crossfade_view.h"
32 #include "audio_time_axis.h"
33 #include "region_gain_line.h"
34 #include "automation_gain_line.h"
35 #include "automation_pan_line.h"
36 #include "automation_time_axis.h"
37 #include "redirect_automation_line.h"
38 #include "canvas_impl.h"
39 #include "simplerect.h"
44 using namespace ARDOUR;
48 Editor::track_canvas_scroll (GdkEventScroll* ev)
50 switch (ev->direction) {
52 scroll_tracks_up_line ();
57 scroll_tracks_down_line ();
61 /* no left/right handling yet */
69 Editor::track_canvas_event (GdkEvent *event, ArdourCanvas::Item* item)
73 /* this is the handler for events that are not handled by
77 switch (event->type) {
78 case GDK_MOTION_NOTIFY:
79 /* keep those motion events coming */
80 track_canvas.get_pointer (x, y);
81 return track_canvas_motion (event);
83 case GDK_BUTTON_RELEASE:
84 switch (event->button.button) {
87 button_release_handler (item, event, NoItem);
93 track_canvas_scroll (&event->scroll);
104 Editor::track_canvas_motion (GdkEvent *ev)
106 if (verbose_cursor_visible) {
107 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
108 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
114 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
118 switch (event->type) {
119 case GDK_BUTTON_PRESS:
120 case GDK_2BUTTON_PRESS:
121 case GDK_3BUTTON_PRESS:
122 ret = button_press_handler (item, event, type);
124 case GDK_BUTTON_RELEASE:
125 ret = button_release_handler (item, event, type);
127 case GDK_MOTION_NOTIFY:
128 ret = motion_handler (item, event, type);
131 case GDK_ENTER_NOTIFY:
132 ret = enter_handler (item, event, type);
135 case GDK_LEAVE_NOTIFY:
136 ret = leave_handler (item, event, type);
147 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
151 switch (event->type) {
152 case GDK_BUTTON_PRESS:
153 case GDK_2BUTTON_PRESS:
154 case GDK_3BUTTON_PRESS:
155 clicked_regionview = rv;
156 clicked_control_point = 0;
157 clicked_trackview = &rv->get_time_axis_view();
158 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
159 ret = button_press_handler (item, event, RegionItem);
162 case GDK_BUTTON_RELEASE:
163 ret = button_release_handler (item, event, RegionItem);
166 case GDK_MOTION_NOTIFY:
167 ret = motion_handler (item, event, RegionItem);
170 case GDK_ENTER_NOTIFY:
171 set_entered_regionview (rv);
174 case GDK_LEAVE_NOTIFY:
175 set_entered_regionview (0);
186 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
190 switch (event->type) {
191 case GDK_BUTTON_PRESS:
192 case GDK_2BUTTON_PRESS:
193 case GDK_3BUTTON_PRESS:
194 clicked_regionview = 0;
195 clicked_control_point = 0;
196 clicked_trackview = tv;
197 clicked_audio_trackview = tv;
198 ret = button_press_handler (item, event, StreamItem);
201 case GDK_BUTTON_RELEASE:
202 ret = button_release_handler (item, event, StreamItem);
205 case GDK_MOTION_NOTIFY:
206 ret = motion_handler (item, event, StreamItem);
209 case GDK_ENTER_NOTIFY:
222 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
226 switch (event->type) {
227 case GDK_BUTTON_PRESS:
228 case GDK_2BUTTON_PRESS:
229 case GDK_3BUTTON_PRESS:
230 clicked_regionview = 0;
231 clicked_control_point = 0;
232 clicked_trackview = atv;
233 clicked_audio_trackview = 0;
234 ret = button_press_handler (item, event, AutomationTrackItem);
237 case GDK_BUTTON_RELEASE:
238 ret = button_release_handler (item, event, AutomationTrackItem);
241 case GDK_MOTION_NOTIFY:
242 ret = motion_handler (item, event, AutomationTrackItem);
245 case GDK_ENTER_NOTIFY:
246 ret = enter_handler (item, event, AutomationTrackItem);
249 case GDK_LEAVE_NOTIFY:
250 ret = leave_handler (item, event, AutomationTrackItem);
261 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
263 /* we handle only button 3 press/release events */
265 switch (event->type) {
266 case GDK_BUTTON_PRESS:
267 clicked_regionview = rv;
268 clicked_control_point = 0;
269 clicked_trackview = &rv->get_time_axis_view();
270 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
271 if (event->button.button == 3) {
272 return button_press_handler (item, event, FadeInItem);
276 case GDK_BUTTON_RELEASE:
277 if (event->button.button == 3) {
278 return button_release_handler (item, event, FadeInItem);
287 /* proxy for the regionview */
289 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
293 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
297 switch (event->type) {
298 case GDK_BUTTON_PRESS:
299 case GDK_2BUTTON_PRESS:
300 case GDK_3BUTTON_PRESS:
301 clicked_regionview = rv;
302 clicked_control_point = 0;
303 clicked_trackview = &rv->get_time_axis_view();
304 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
305 ret = button_press_handler (item, event, FadeInHandleItem);
308 case GDK_BUTTON_RELEASE:
309 ret = button_release_handler (item, event, FadeInHandleItem);
312 case GDK_MOTION_NOTIFY:
313 ret = motion_handler (item, event, FadeInHandleItem);
316 case GDK_ENTER_NOTIFY:
317 ret = enter_handler (item, event, FadeInHandleItem);
320 case GDK_LEAVE_NOTIFY:
321 ret = leave_handler (item, event, FadeInHandleItem);
332 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
334 /* we handle only button 3 press/release events */
336 switch (event->type) {
337 case GDK_BUTTON_PRESS:
338 clicked_regionview = rv;
339 clicked_control_point = 0;
340 clicked_trackview = &rv->get_time_axis_view();
341 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
342 if (event->button.button == 3) {
343 return button_press_handler (item, event, FadeOutItem);
347 case GDK_BUTTON_RELEASE:
348 if (event->button.button == 3) {
349 return button_release_handler (item, event, FadeOutItem);
358 /* proxy for the regionview */
360 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
364 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
368 switch (event->type) {
369 case GDK_BUTTON_PRESS:
370 case GDK_2BUTTON_PRESS:
371 case GDK_3BUTTON_PRESS:
372 clicked_regionview = rv;
373 clicked_control_point = 0;
374 clicked_trackview = &rv->get_time_axis_view();
375 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
376 ret = button_press_handler (item, event, FadeOutHandleItem);
379 case GDK_BUTTON_RELEASE:
380 ret = button_release_handler (item, event, FadeOutHandleItem);
383 case GDK_MOTION_NOTIFY:
384 ret = motion_handler (item, event, FadeOutHandleItem);
387 case GDK_ENTER_NOTIFY:
388 ret = enter_handler (item, event, FadeOutHandleItem);
391 case GDK_LEAVE_NOTIFY:
392 ret = leave_handler (item, event, FadeOutHandleItem);
402 struct DescendingRegionLayerSorter {
403 bool operator()(Region* a, Region* b) {
404 return a->layer() > b->layer();
409 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
411 /* we handle only button 3 press/release events */
413 switch (event->type) {
414 case GDK_BUTTON_PRESS:
415 clicked_crossfadeview = xfv;
416 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
417 if (event->button.button == 3) {
418 return button_press_handler (item, event, CrossfadeViewItem);
422 case GDK_BUTTON_RELEASE:
423 if (event->button.button == 3) {
424 bool ret = button_release_handler (item, event, CrossfadeViewItem);
435 /* proxy for the upper most regionview */
437 /* XXX really need to check if we are in the name highlight,
438 and proxy to that when required.
441 TimeAxisView& tv (xfv->get_time_axis_view());
442 AudioTimeAxisView* atv;
444 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
446 if (atv->is_audio_track()) {
448 AudioPlaylist* pl = atv->get_diskstream()->playlist();
449 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
452 DescendingRegionLayerSorter cmp;
455 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
461 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
470 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
474 switch (event->type) {
475 case GDK_BUTTON_PRESS:
476 case GDK_2BUTTON_PRESS:
477 case GDK_3BUTTON_PRESS:
478 clicked_control_point = cp;
479 clicked_trackview = &cp->line.trackview;
480 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
481 clicked_regionview = 0;
488 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
489 type = GainControlPointItem;
490 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
491 type = GainAutomationControlPointItem;
492 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
493 type = PanAutomationControlPointItem;
494 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
495 type = RedirectAutomationControlPointItem;
500 return typed_event (item, event, type);
504 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
508 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
510 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
511 type = GainAutomationLineItem;
512 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
513 type = PanAutomationLineItem;
514 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
515 type = RedirectAutomationLineItem;
520 return typed_event (item, event, type);
524 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
528 switch (event->type) {
529 case GDK_BUTTON_PRESS:
530 case GDK_2BUTTON_PRESS:
531 case GDK_3BUTTON_PRESS:
532 clicked_selection = rect->id;
533 ret = button_press_handler (item, event, SelectionItem);
535 case GDK_BUTTON_RELEASE:
536 ret = button_release_handler (item, event, SelectionItem);
538 case GDK_MOTION_NOTIFY:
539 ret = motion_handler (item, event, SelectionItem);
541 /* Don't need these at the moment. */
542 case GDK_ENTER_NOTIFY:
543 ret = enter_handler (item, event, SelectionItem);
546 case GDK_LEAVE_NOTIFY:
547 ret = leave_handler (item, event, SelectionItem);
558 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
562 switch (event->type) {
563 case GDK_BUTTON_PRESS:
564 case GDK_2BUTTON_PRESS:
565 case GDK_3BUTTON_PRESS:
566 clicked_selection = rect->id;
567 ret = button_press_handler (item, event, StartSelectionTrimItem);
569 case GDK_BUTTON_RELEASE:
570 ret = button_release_handler (item, event, StartSelectionTrimItem);
572 case GDK_MOTION_NOTIFY:
573 ret = motion_handler (item, event, StartSelectionTrimItem);
575 case GDK_ENTER_NOTIFY:
576 ret = enter_handler (item, event, StartSelectionTrimItem);
579 case GDK_LEAVE_NOTIFY:
580 ret = leave_handler (item, event, StartSelectionTrimItem);
591 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
595 switch (event->type) {
596 case GDK_BUTTON_PRESS:
597 case GDK_2BUTTON_PRESS:
598 case GDK_3BUTTON_PRESS:
599 clicked_selection = rect->id;
600 ret = button_press_handler (item, event, EndSelectionTrimItem);
602 case GDK_BUTTON_RELEASE:
603 ret = button_release_handler (item, event, EndSelectionTrimItem);
605 case GDK_MOTION_NOTIFY:
606 ret = motion_handler (item, event, EndSelectionTrimItem);
608 case GDK_ENTER_NOTIFY:
609 ret = enter_handler (item, event, EndSelectionTrimItem);
612 case GDK_LEAVE_NOTIFY:
613 ret = leave_handler (item, event, EndSelectionTrimItem);
625 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
629 switch (event->type) {
630 case GDK_BUTTON_PRESS:
631 case GDK_2BUTTON_PRESS:
632 case GDK_3BUTTON_PRESS:
633 clicked_regionview = rv;
634 clicked_control_point = 0;
635 clicked_trackview = &clicked_regionview->get_time_axis_view();
636 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
637 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
639 case GDK_BUTTON_RELEASE:
640 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
642 case GDK_MOTION_NOTIFY:
643 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
645 case GDK_ENTER_NOTIFY:
646 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
649 case GDK_LEAVE_NOTIFY:
650 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
661 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
665 switch (event->type) {
666 case GDK_BUTTON_PRESS:
667 case GDK_2BUTTON_PRESS:
668 case GDK_3BUTTON_PRESS:
669 clicked_regionview = rv;
670 clicked_control_point = 0;
671 clicked_trackview = &clicked_regionview->get_time_axis_view();
672 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
673 ret = button_press_handler (item, event, AudioRegionViewName);
675 case GDK_BUTTON_RELEASE:
676 ret = button_release_handler (item, event, AudioRegionViewName);
678 case GDK_MOTION_NOTIFY:
679 ret = motion_handler (item, event, AudioRegionViewName);
681 case GDK_ENTER_NOTIFY:
682 ret = enter_handler (item, event, AudioRegionViewName);
685 case GDK_LEAVE_NOTIFY:
686 ret = leave_handler (item, event, AudioRegionViewName);
697 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
699 return typed_event (item, event, MarkerItem);
703 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
705 return typed_event (item, event, MarkerBarItem);
709 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
711 return typed_event (item, event, RangeMarkerBarItem);
715 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
717 return typed_event (item, event, TransportMarkerBarItem);
721 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
723 return typed_event (item, event, TempoMarkerItem);
727 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
729 return typed_event (item, event, MeterMarkerItem);
733 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
735 return typed_event (item, event, TempoBarItem);
739 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
741 return typed_event (item, event, MeterBarItem);
745 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
747 return typed_event (item, event, PlayheadCursorItem);
751 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
753 return typed_event (item, event, EditCursorItem);
757 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
759 return typed_event (item, event, NoItem);