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_PRESS:
84 track_canvas.grab_focus();
87 case GDK_BUTTON_RELEASE:
88 switch (event->button.button) {
91 button_release_handler (item, event, NoItem);
97 track_canvas.grab_focus();
98 track_canvas_scroll (&event->scroll);
109 Editor::track_canvas_motion (GdkEvent *ev)
111 if (verbose_cursor_visible) {
112 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
113 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
119 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
123 switch (event->type) {
124 case GDK_BUTTON_PRESS:
125 case GDK_2BUTTON_PRESS:
126 case GDK_3BUTTON_PRESS:
127 ret = button_press_handler (item, event, type);
129 case GDK_BUTTON_RELEASE:
130 ret = button_release_handler (item, event, type);
132 case GDK_MOTION_NOTIFY:
133 ret = motion_handler (item, event, type);
136 case GDK_ENTER_NOTIFY:
137 ret = enter_handler (item, event, type);
140 case GDK_LEAVE_NOTIFY:
141 ret = leave_handler (item, event, type);
152 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
156 switch (event->type) {
157 case GDK_BUTTON_PRESS:
158 case GDK_2BUTTON_PRESS:
159 case GDK_3BUTTON_PRESS:
160 clicked_regionview = rv;
161 clicked_control_point = 0;
162 clicked_trackview = &rv->get_time_axis_view();
163 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
164 ret = button_press_handler (item, event, RegionItem);
167 case GDK_BUTTON_RELEASE:
168 ret = button_release_handler (item, event, RegionItem);
171 case GDK_MOTION_NOTIFY:
172 ret = motion_handler (item, event, RegionItem);
175 case GDK_ENTER_NOTIFY:
176 set_entered_regionview (rv);
179 case GDK_LEAVE_NOTIFY:
180 set_entered_regionview (0);
191 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
195 switch (event->type) {
196 case GDK_BUTTON_PRESS:
197 case GDK_2BUTTON_PRESS:
198 case GDK_3BUTTON_PRESS:
199 clicked_regionview = 0;
200 clicked_control_point = 0;
201 clicked_trackview = tv;
202 clicked_audio_trackview = tv;
203 ret = button_press_handler (item, event, StreamItem);
206 case GDK_BUTTON_RELEASE:
207 ret = button_release_handler (item, event, StreamItem);
210 case GDK_MOTION_NOTIFY:
211 ret = motion_handler (item, event, StreamItem);
214 case GDK_ENTER_NOTIFY:
227 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
231 switch (event->type) {
232 case GDK_BUTTON_PRESS:
233 case GDK_2BUTTON_PRESS:
234 case GDK_3BUTTON_PRESS:
235 clicked_regionview = 0;
236 clicked_control_point = 0;
237 clicked_trackview = atv;
238 clicked_audio_trackview = 0;
239 ret = button_press_handler (item, event, AutomationTrackItem);
242 case GDK_BUTTON_RELEASE:
243 ret = button_release_handler (item, event, AutomationTrackItem);
246 case GDK_MOTION_NOTIFY:
247 ret = motion_handler (item, event, AutomationTrackItem);
250 case GDK_ENTER_NOTIFY:
251 ret = enter_handler (item, event, AutomationTrackItem);
254 case GDK_LEAVE_NOTIFY:
255 ret = leave_handler (item, event, AutomationTrackItem);
266 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
268 /* we handle only button 3 press/release events */
270 switch (event->type) {
271 case GDK_BUTTON_PRESS:
272 clicked_regionview = rv;
273 clicked_control_point = 0;
274 clicked_trackview = &rv->get_time_axis_view();
275 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
276 if (event->button.button == 3) {
277 return button_press_handler (item, event, FadeInItem);
281 case GDK_BUTTON_RELEASE:
282 if (event->button.button == 3) {
283 return button_release_handler (item, event, FadeInItem);
292 /* proxy for the regionview */
294 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
298 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
302 switch (event->type) {
303 case GDK_BUTTON_PRESS:
304 case GDK_2BUTTON_PRESS:
305 case GDK_3BUTTON_PRESS:
306 clicked_regionview = rv;
307 clicked_control_point = 0;
308 clicked_trackview = &rv->get_time_axis_view();
309 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
310 ret = button_press_handler (item, event, FadeInHandleItem);
313 case GDK_BUTTON_RELEASE:
314 ret = button_release_handler (item, event, FadeInHandleItem);
317 case GDK_MOTION_NOTIFY:
318 ret = motion_handler (item, event, FadeInHandleItem);
321 case GDK_ENTER_NOTIFY:
322 ret = enter_handler (item, event, FadeInHandleItem);
325 case GDK_LEAVE_NOTIFY:
326 ret = leave_handler (item, event, FadeInHandleItem);
337 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
339 /* we handle only button 3 press/release events */
341 switch (event->type) {
342 case GDK_BUTTON_PRESS:
343 clicked_regionview = rv;
344 clicked_control_point = 0;
345 clicked_trackview = &rv->get_time_axis_view();
346 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
347 if (event->button.button == 3) {
348 return button_press_handler (item, event, FadeOutItem);
352 case GDK_BUTTON_RELEASE:
353 if (event->button.button == 3) {
354 return button_release_handler (item, event, FadeOutItem);
363 /* proxy for the regionview */
365 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
369 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
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_trackview = &rv->get_time_axis_view();
380 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
381 ret = button_press_handler (item, event, FadeOutHandleItem);
384 case GDK_BUTTON_RELEASE:
385 ret = button_release_handler (item, event, FadeOutHandleItem);
388 case GDK_MOTION_NOTIFY:
389 ret = motion_handler (item, event, FadeOutHandleItem);
392 case GDK_ENTER_NOTIFY:
393 ret = enter_handler (item, event, FadeOutHandleItem);
396 case GDK_LEAVE_NOTIFY:
397 ret = leave_handler (item, event, FadeOutHandleItem);
407 struct DescendingRegionLayerSorter {
408 bool operator()(Region* a, Region* b) {
409 return a->layer() > b->layer();
414 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
416 /* we handle only button 3 press/release events */
418 switch (event->type) {
419 case GDK_BUTTON_PRESS:
420 clicked_crossfadeview = xfv;
421 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
422 if (event->button.button == 3) {
423 return button_press_handler (item, event, CrossfadeViewItem);
427 case GDK_BUTTON_RELEASE:
428 if (event->button.button == 3) {
429 bool ret = button_release_handler (item, event, CrossfadeViewItem);
440 /* proxy for the upper most regionview */
442 /* XXX really need to check if we are in the name highlight,
443 and proxy to that when required.
446 TimeAxisView& tv (xfv->get_time_axis_view());
447 AudioTimeAxisView* atv;
449 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
451 if (atv->is_audio_track()) {
453 AudioPlaylist* pl = atv->get_diskstream()->playlist();
454 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
457 DescendingRegionLayerSorter cmp;
460 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
466 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
475 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
479 switch (event->type) {
480 case GDK_BUTTON_PRESS:
481 case GDK_2BUTTON_PRESS:
482 case GDK_3BUTTON_PRESS:
483 clicked_control_point = cp;
484 clicked_trackview = &cp->line.trackview;
485 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
486 clicked_regionview = 0;
493 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
494 type = GainControlPointItem;
495 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
496 type = GainAutomationControlPointItem;
497 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
498 type = PanAutomationControlPointItem;
499 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
500 type = RedirectAutomationControlPointItem;
505 return typed_event (item, event, type);
509 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
513 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
515 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
516 type = GainAutomationLineItem;
517 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
518 type = PanAutomationLineItem;
519 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
520 type = RedirectAutomationLineItem;
525 return typed_event (item, event, type);
529 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
533 switch (event->type) {
534 case GDK_BUTTON_PRESS:
535 case GDK_2BUTTON_PRESS:
536 case GDK_3BUTTON_PRESS:
537 clicked_selection = rect->id;
538 ret = button_press_handler (item, event, SelectionItem);
540 case GDK_BUTTON_RELEASE:
541 ret = button_release_handler (item, event, SelectionItem);
543 case GDK_MOTION_NOTIFY:
544 ret = motion_handler (item, event, SelectionItem);
546 /* Don't need these at the moment. */
547 case GDK_ENTER_NOTIFY:
548 ret = enter_handler (item, event, SelectionItem);
551 case GDK_LEAVE_NOTIFY:
552 ret = leave_handler (item, event, SelectionItem);
563 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
567 switch (event->type) {
568 case GDK_BUTTON_PRESS:
569 case GDK_2BUTTON_PRESS:
570 case GDK_3BUTTON_PRESS:
571 clicked_selection = rect->id;
572 ret = button_press_handler (item, event, StartSelectionTrimItem);
574 case GDK_BUTTON_RELEASE:
575 ret = button_release_handler (item, event, StartSelectionTrimItem);
577 case GDK_MOTION_NOTIFY:
578 ret = motion_handler (item, event, StartSelectionTrimItem);
580 case GDK_ENTER_NOTIFY:
581 ret = enter_handler (item, event, StartSelectionTrimItem);
584 case GDK_LEAVE_NOTIFY:
585 ret = leave_handler (item, event, StartSelectionTrimItem);
596 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
600 switch (event->type) {
601 case GDK_BUTTON_PRESS:
602 case GDK_2BUTTON_PRESS:
603 case GDK_3BUTTON_PRESS:
604 clicked_selection = rect->id;
605 ret = button_press_handler (item, event, EndSelectionTrimItem);
607 case GDK_BUTTON_RELEASE:
608 ret = button_release_handler (item, event, EndSelectionTrimItem);
610 case GDK_MOTION_NOTIFY:
611 ret = motion_handler (item, event, EndSelectionTrimItem);
613 case GDK_ENTER_NOTIFY:
614 ret = enter_handler (item, event, EndSelectionTrimItem);
617 case GDK_LEAVE_NOTIFY:
618 ret = leave_handler (item, event, EndSelectionTrimItem);
630 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
634 switch (event->type) {
635 case GDK_BUTTON_PRESS:
636 case GDK_2BUTTON_PRESS:
637 case GDK_3BUTTON_PRESS:
638 clicked_regionview = rv;
639 clicked_control_point = 0;
640 clicked_trackview = &clicked_regionview->get_time_axis_view();
641 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
642 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
644 case GDK_BUTTON_RELEASE:
645 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
647 case GDK_MOTION_NOTIFY:
648 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
650 case GDK_ENTER_NOTIFY:
651 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
654 case GDK_LEAVE_NOTIFY:
655 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
666 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
670 switch (event->type) {
671 case GDK_BUTTON_PRESS:
672 case GDK_2BUTTON_PRESS:
673 case GDK_3BUTTON_PRESS:
674 clicked_regionview = rv;
675 clicked_control_point = 0;
676 clicked_trackview = &clicked_regionview->get_time_axis_view();
677 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
678 ret = button_press_handler (item, event, AudioRegionViewName);
680 case GDK_BUTTON_RELEASE:
681 ret = button_release_handler (item, event, AudioRegionViewName);
683 case GDK_MOTION_NOTIFY:
684 ret = motion_handler (item, event, AudioRegionViewName);
686 case GDK_ENTER_NOTIFY:
687 ret = enter_handler (item, event, AudioRegionViewName);
690 case GDK_LEAVE_NOTIFY:
691 ret = leave_handler (item, event, AudioRegionViewName);
702 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
704 return typed_event (item, event, MarkerItem);
708 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
710 return typed_event (item, event, MarkerBarItem);
714 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
716 return typed_event (item, event, RangeMarkerBarItem);
720 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
722 return typed_event (item, event, TransportMarkerBarItem);
726 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
728 return typed_event (item, event, TempoMarkerItem);
732 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
734 return typed_event (item, event, MeterMarkerItem);
738 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
740 return typed_event (item, event, TempoBarItem);
744 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
746 return typed_event (item, event, MeterBarItem);
750 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
752 return typed_event (item, event, PlayheadCursorItem);
756 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
758 return typed_event (item, event, EditCursorItem);
762 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
764 return typed_event (item, event, NoItem);