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_event (GdkEvent *event, ArdourCanvas::Item* item)
52 switch (event->type) {
53 case GDK_MOTION_NOTIFY:
54 /* keep those motion events coming */
55 track_canvas.get_pointer (x, y);
56 return track_canvas_motion (event);
58 case GDK_BUTTON_RELEASE:
59 switch (event->button.button) {
62 button_release_handler (item, event, NoItem);
75 Editor::track_canvas_motion (GdkEvent *ev)
77 if (verbose_cursor_visible) {
78 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
79 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
85 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
89 switch (event->type) {
90 case GDK_BUTTON_PRESS:
91 case GDK_2BUTTON_PRESS:
92 case GDK_3BUTTON_PRESS:
93 ret = button_press_handler (item, event, type);
95 case GDK_BUTTON_RELEASE:
96 ret = button_release_handler (item, event, type);
98 case GDK_MOTION_NOTIFY:
99 ret = motion_handler (item, event, type);
102 case GDK_ENTER_NOTIFY:
103 ret = enter_handler (item, event, type);
106 case GDK_LEAVE_NOTIFY:
107 ret = leave_handler (item, event, type);
118 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
122 switch (event->type) {
123 case GDK_BUTTON_PRESS:
124 case GDK_2BUTTON_PRESS:
125 case GDK_3BUTTON_PRESS:
126 clicked_regionview = rv;
127 clicked_control_point = 0;
128 clicked_trackview = &rv->get_time_axis_view();
129 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
130 ret = button_press_handler (item, event, RegionItem);
133 case GDK_BUTTON_RELEASE:
134 ret = button_release_handler (item, event, RegionItem);
137 case GDK_MOTION_NOTIFY:
138 ret = motion_handler (item, event, RegionItem);
141 case GDK_ENTER_NOTIFY:
142 set_entered_regionview (rv);
145 case GDK_LEAVE_NOTIFY:
146 set_entered_regionview (0);
157 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
161 switch (event->type) {
162 case GDK_BUTTON_PRESS:
163 case GDK_2BUTTON_PRESS:
164 case GDK_3BUTTON_PRESS:
165 clicked_regionview = 0;
166 clicked_control_point = 0;
167 clicked_trackview = tv;
168 clicked_audio_trackview = tv;
169 ret = button_press_handler (item, event, StreamItem);
172 case GDK_BUTTON_RELEASE:
173 ret = button_release_handler (item, event, StreamItem);
176 case GDK_MOTION_NOTIFY:
177 ret = motion_handler (item, event, StreamItem);
180 case GDK_ENTER_NOTIFY:
193 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
197 switch (event->type) {
198 case GDK_BUTTON_PRESS:
199 case GDK_2BUTTON_PRESS:
200 case GDK_3BUTTON_PRESS:
201 clicked_regionview = 0;
202 clicked_control_point = 0;
203 clicked_trackview = atv;
204 clicked_audio_trackview = 0;
205 ret = button_press_handler (item, event, AutomationTrackItem);
208 case GDK_BUTTON_RELEASE:
209 ret = button_release_handler (item, event, AutomationTrackItem);
212 case GDK_MOTION_NOTIFY:
213 ret = motion_handler (item, event, AutomationTrackItem);
216 case GDK_ENTER_NOTIFY:
217 ret = enter_handler (item, event, AutomationTrackItem);
220 case GDK_LEAVE_NOTIFY:
221 ret = leave_handler (item, event, AutomationTrackItem);
232 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
234 /* we handle only button 3 press/release events */
236 switch (event->type) {
237 case GDK_BUTTON_PRESS:
238 clicked_regionview = rv;
239 clicked_control_point = 0;
240 clicked_trackview = &rv->get_time_axis_view();
241 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
242 if (event->button.button == 3) {
243 return button_press_handler (item, event, FadeInItem);
247 case GDK_BUTTON_RELEASE:
248 if (event->button.button == 3) {
249 return button_release_handler (item, event, FadeInItem);
258 /* proxy for the regionview */
260 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
264 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
268 switch (event->type) {
269 case GDK_BUTTON_PRESS:
270 case GDK_2BUTTON_PRESS:
271 case GDK_3BUTTON_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 ret = button_press_handler (item, event, FadeInHandleItem);
279 case GDK_BUTTON_RELEASE:
280 ret = button_release_handler (item, event, FadeInHandleItem);
283 case GDK_MOTION_NOTIFY:
284 ret = motion_handler (item, event, FadeInHandleItem);
287 case GDK_ENTER_NOTIFY:
288 ret = enter_handler (item, event, FadeInHandleItem);
291 case GDK_LEAVE_NOTIFY:
292 ret = leave_handler (item, event, FadeInHandleItem);
303 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
305 /* we handle only button 3 press/release events */
307 switch (event->type) {
308 case GDK_BUTTON_PRESS:
309 clicked_regionview = rv;
310 clicked_control_point = 0;
311 clicked_trackview = &rv->get_time_axis_view();
312 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
313 if (event->button.button == 3) {
314 return button_press_handler (item, event, FadeOutItem);
318 case GDK_BUTTON_RELEASE:
319 if (event->button.button == 3) {
320 return button_release_handler (item, event, FadeOutItem);
329 /* proxy for the regionview */
331 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
335 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
339 switch (event->type) {
340 case GDK_BUTTON_PRESS:
341 case GDK_2BUTTON_PRESS:
342 case GDK_3BUTTON_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 ret = button_press_handler (item, event, FadeOutHandleItem);
350 case GDK_BUTTON_RELEASE:
351 ret = button_release_handler (item, event, FadeOutHandleItem);
354 case GDK_MOTION_NOTIFY:
355 ret = motion_handler (item, event, FadeOutHandleItem);
358 case GDK_ENTER_NOTIFY:
359 ret = enter_handler (item, event, FadeOutHandleItem);
362 case GDK_LEAVE_NOTIFY:
363 ret = leave_handler (item, event, FadeOutHandleItem);
373 struct DescendingRegionLayerSorter {
374 bool operator()(Region* a, Region* b) {
375 return a->layer() > b->layer();
380 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
382 /* we handle only button 3 press/release events */
384 switch (event->type) {
385 case GDK_BUTTON_PRESS:
386 clicked_crossfadeview = xfv;
387 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
388 if (event->button.button == 3) {
389 return button_press_handler (item, event, CrossfadeViewItem);
393 case GDK_BUTTON_RELEASE:
394 if (event->button.button == 3) {
395 bool ret = button_release_handler (item, event, CrossfadeViewItem);
406 /* proxy for the upper most regionview */
408 /* XXX really need to check if we are in the name highlight,
409 and proxy to that when required.
412 TimeAxisView& tv (xfv->get_time_axis_view());
413 AudioTimeAxisView* atv;
415 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
417 if (atv->is_audio_track()) {
419 AudioPlaylist* pl = atv->get_diskstream()->playlist();
420 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
423 DescendingRegionLayerSorter cmp;
426 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
432 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
441 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
445 switch (event->type) {
446 case GDK_BUTTON_PRESS:
447 case GDK_2BUTTON_PRESS:
448 case GDK_3BUTTON_PRESS:
449 clicked_control_point = cp;
450 clicked_trackview = &cp->line.trackview;
451 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
452 clicked_regionview = 0;
459 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
460 type = GainControlPointItem;
461 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
462 type = GainAutomationControlPointItem;
463 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
464 type = PanAutomationControlPointItem;
465 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
466 type = RedirectAutomationControlPointItem;
471 return typed_event (item, event, type);
475 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
479 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
481 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
482 type = GainAutomationLineItem;
483 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
484 type = PanAutomationLineItem;
485 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
486 type = RedirectAutomationLineItem;
491 return typed_event (item, event, type);
495 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
499 switch (event->type) {
500 case GDK_BUTTON_PRESS:
501 case GDK_2BUTTON_PRESS:
502 case GDK_3BUTTON_PRESS:
503 clicked_selection = rect->id;
504 ret = button_press_handler (item, event, SelectionItem);
506 case GDK_BUTTON_RELEASE:
507 ret = button_release_handler (item, event, SelectionItem);
509 case GDK_MOTION_NOTIFY:
510 ret = motion_handler (item, event, SelectionItem);
512 /* Don't need these at the moment. */
513 case GDK_ENTER_NOTIFY:
514 ret = enter_handler (item, event, SelectionItem);
517 case GDK_LEAVE_NOTIFY:
518 ret = leave_handler (item, event, SelectionItem);
529 Editor::canvas_selection_start_trim_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, StartSelectionTrimItem);
540 case GDK_BUTTON_RELEASE:
541 ret = button_release_handler (item, event, StartSelectionTrimItem);
543 case GDK_MOTION_NOTIFY:
544 ret = motion_handler (item, event, StartSelectionTrimItem);
546 case GDK_ENTER_NOTIFY:
547 ret = enter_handler (item, event, StartSelectionTrimItem);
550 case GDK_LEAVE_NOTIFY:
551 ret = leave_handler (item, event, StartSelectionTrimItem);
562 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
566 switch (event->type) {
567 case GDK_BUTTON_PRESS:
568 case GDK_2BUTTON_PRESS:
569 case GDK_3BUTTON_PRESS:
570 clicked_selection = rect->id;
571 ret = button_press_handler (item, event, EndSelectionTrimItem);
573 case GDK_BUTTON_RELEASE:
574 ret = button_release_handler (item, event, EndSelectionTrimItem);
576 case GDK_MOTION_NOTIFY:
577 ret = motion_handler (item, event, EndSelectionTrimItem);
579 case GDK_ENTER_NOTIFY:
580 ret = enter_handler (item, event, EndSelectionTrimItem);
583 case GDK_LEAVE_NOTIFY:
584 ret = leave_handler (item, event, EndSelectionTrimItem);
596 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
600 switch (event->type) {
601 case GDK_BUTTON_PRESS:
602 case GDK_2BUTTON_PRESS:
603 case GDK_3BUTTON_PRESS:
604 clicked_regionview = rv;
605 clicked_control_point = 0;
606 clicked_trackview = &clicked_regionview->get_time_axis_view();
607 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
608 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
610 case GDK_BUTTON_RELEASE:
611 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
613 case GDK_MOTION_NOTIFY:
614 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
616 case GDK_ENTER_NOTIFY:
617 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
620 case GDK_LEAVE_NOTIFY:
621 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
632 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
636 switch (event->type) {
637 case GDK_BUTTON_PRESS:
638 case GDK_2BUTTON_PRESS:
639 case GDK_3BUTTON_PRESS:
640 clicked_regionview = rv;
641 clicked_control_point = 0;
642 clicked_trackview = &clicked_regionview->get_time_axis_view();
643 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
644 ret = button_press_handler (item, event, AudioRegionViewName);
646 case GDK_BUTTON_RELEASE:
647 ret = button_release_handler (item, event, AudioRegionViewName);
649 case GDK_MOTION_NOTIFY:
650 ret = motion_handler (item, event, AudioRegionViewName);
652 case GDK_ENTER_NOTIFY:
653 ret = enter_handler (item, event, AudioRegionViewName);
656 case GDK_LEAVE_NOTIFY:
657 ret = leave_handler (item, event, AudioRegionViewName);
668 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
670 return typed_event (item, event, MarkerItem);
674 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
676 return typed_event (item, event, MarkerBarItem);
680 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
682 return typed_event (item, event, RangeMarkerBarItem);
686 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
688 return typed_event (item, event, TransportMarkerBarItem);
692 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
694 return typed_event (item, event, TempoMarkerItem);
698 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
700 return typed_event (item, event, MeterMarkerItem);
704 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
706 return typed_event (item, event, TempoBarItem);
710 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
712 return typed_event (item, event, MeterBarItem);
716 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
718 return typed_event (item, event, PlayheadCursorItem);
722 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
724 return typed_event (item, event, EditCursorItem);
728 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
730 return typed_event (item, event, NoItem);