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)
53 switch (ev->direction) {
55 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
56 //if (ev->state == GDK_CONTROL_MASK) {
58 the ev->x will be out of step with the canvas
59 if we're in mid zoom, so we have to get the damn mouse
62 track_canvas.get_pointer (x, y);
63 track_canvas.window_to_world (x, y, wx, wy);
64 wx += horizontal_adjustment.get_value();
65 wy += vertical_adjustment.get_value();
68 event.type = GDK_BUTTON_RELEASE;
72 jack_nframes_t where = event_frame (&event, 0, 0);
73 temporal_zoom_to_frame (true, where);
75 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
76 if (!current_stepping_trackview) {
77 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
78 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
82 gettimeofday (&last_track_height_step_timestamp, 0);
83 current_stepping_trackview->step_height (true);
86 scroll_tracks_up_line ();
91 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
92 //if (ev->state == GDK_CONTROL_MASK) {
93 track_canvas.get_pointer (x, y);
94 track_canvas.window_to_world (x, y, wx, wy);
95 wx += horizontal_adjustment.get_value();
96 wy += vertical_adjustment.get_value();
99 event.type = GDK_BUTTON_RELEASE;
103 jack_nframes_t where = event_frame (&event, 0, 0);
104 temporal_zoom_to_frame (false, where);
106 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
107 if (!current_stepping_trackview) {
108 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
109 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
113 gettimeofday (&last_track_height_step_timestamp, 0);
114 current_stepping_trackview->step_height (false);
117 scroll_tracks_down_line ();
123 /* no left/right handling yet */
131 Editor::track_canvas_event (GdkEvent *event, ArdourCanvas::Item* item)
135 /* this is the handler for events that are not handled by
139 switch (event->type) {
140 case GDK_MOTION_NOTIFY:
141 /* keep those motion events coming */
142 track_canvas.get_pointer (x, y);
143 return track_canvas_motion (event);
145 case GDK_BUTTON_PRESS:
146 track_canvas.grab_focus();
149 case GDK_BUTTON_RELEASE:
150 switch (event->button.button) {
153 button_release_handler (item, event, NoItem);
159 track_canvas.grab_focus();
160 track_canvas_scroll (&event->scroll);
171 Editor::track_canvas_motion (GdkEvent *ev)
173 if (verbose_cursor_visible) {
174 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
175 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
181 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
185 switch (event->type) {
186 case GDK_BUTTON_PRESS:
187 case GDK_2BUTTON_PRESS:
188 case GDK_3BUTTON_PRESS:
189 ret = button_press_handler (item, event, type);
191 case GDK_BUTTON_RELEASE:
192 ret = button_release_handler (item, event, type);
194 case GDK_MOTION_NOTIFY:
195 ret = motion_handler (item, event, type);
198 case GDK_ENTER_NOTIFY:
199 ret = enter_handler (item, event, type);
202 case GDK_LEAVE_NOTIFY:
203 ret = leave_handler (item, event, type);
214 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
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_trackview = &rv->get_time_axis_view();
225 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
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, AudioTimeAxisView *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_trackview = tv;
264 clicked_audio_trackview = 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)
293 switch (event->type) {
294 case GDK_BUTTON_PRESS:
295 case GDK_2BUTTON_PRESS:
296 case GDK_3BUTTON_PRESS:
297 clicked_regionview = 0;
298 clicked_control_point = 0;
299 clicked_trackview = atv;
300 clicked_audio_trackview = 0;
301 ret = button_press_handler (item, event, AutomationTrackItem);
304 case GDK_BUTTON_RELEASE:
305 ret = button_release_handler (item, event, AutomationTrackItem);
308 case GDK_MOTION_NOTIFY:
309 ret = motion_handler (item, event, AutomationTrackItem);
312 case GDK_ENTER_NOTIFY:
313 ret = enter_handler (item, event, AutomationTrackItem);
316 case GDK_LEAVE_NOTIFY:
317 ret = leave_handler (item, event, AutomationTrackItem);
328 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
330 /* we handle only button 3 press/release events */
332 switch (event->type) {
333 case GDK_BUTTON_PRESS:
334 clicked_regionview = rv;
335 clicked_control_point = 0;
336 clicked_trackview = &rv->get_time_axis_view();
337 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
338 if (event->button.button == 3) {
339 return button_press_handler (item, event, FadeInItem);
343 case GDK_BUTTON_RELEASE:
344 if (event->button.button == 3) {
345 return button_release_handler (item, event, FadeInItem);
354 /* proxy for the regionview */
356 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
360 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
364 switch (event->type) {
365 case GDK_BUTTON_PRESS:
366 case GDK_2BUTTON_PRESS:
367 case GDK_3BUTTON_PRESS:
368 clicked_regionview = rv;
369 clicked_control_point = 0;
370 clicked_trackview = &rv->get_time_axis_view();
371 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
372 ret = button_press_handler (item, event, FadeInHandleItem);
375 case GDK_BUTTON_RELEASE:
376 ret = button_release_handler (item, event, FadeInHandleItem);
379 case GDK_MOTION_NOTIFY:
380 ret = motion_handler (item, event, FadeInHandleItem);
383 case GDK_ENTER_NOTIFY:
384 ret = enter_handler (item, event, FadeInHandleItem);
387 case GDK_LEAVE_NOTIFY:
388 ret = leave_handler (item, event, FadeInHandleItem);
399 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
401 /* we handle only button 3 press/release events */
403 switch (event->type) {
404 case GDK_BUTTON_PRESS:
405 clicked_regionview = rv;
406 clicked_control_point = 0;
407 clicked_trackview = &rv->get_time_axis_view();
408 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
409 if (event->button.button == 3) {
410 return button_press_handler (item, event, FadeOutItem);
414 case GDK_BUTTON_RELEASE:
415 if (event->button.button == 3) {
416 return button_release_handler (item, event, FadeOutItem);
425 /* proxy for the regionview */
427 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
431 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
435 switch (event->type) {
436 case GDK_BUTTON_PRESS:
437 case GDK_2BUTTON_PRESS:
438 case GDK_3BUTTON_PRESS:
439 clicked_regionview = rv;
440 clicked_control_point = 0;
441 clicked_trackview = &rv->get_time_axis_view();
442 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
443 ret = button_press_handler (item, event, FadeOutHandleItem);
446 case GDK_BUTTON_RELEASE:
447 ret = button_release_handler (item, event, FadeOutHandleItem);
450 case GDK_MOTION_NOTIFY:
451 ret = motion_handler (item, event, FadeOutHandleItem);
454 case GDK_ENTER_NOTIFY:
455 ret = enter_handler (item, event, FadeOutHandleItem);
458 case GDK_LEAVE_NOTIFY:
459 ret = leave_handler (item, event, FadeOutHandleItem);
469 struct DescendingRegionLayerSorter {
470 bool operator()(Region* a, Region* b) {
471 return a->layer() > b->layer();
476 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
478 /* we handle only button 3 press/release events */
480 switch (event->type) {
481 case GDK_BUTTON_PRESS:
482 clicked_crossfadeview = xfv;
483 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
484 if (event->button.button == 3) {
485 return button_press_handler (item, event, CrossfadeViewItem);
489 case GDK_BUTTON_RELEASE:
490 if (event->button.button == 3) {
491 bool ret = button_release_handler (item, event, CrossfadeViewItem);
502 /* proxy for the upper most regionview */
504 /* XXX really need to check if we are in the name highlight,
505 and proxy to that when required.
508 TimeAxisView& tv (xfv->get_time_axis_view());
509 AudioTimeAxisView* atv;
511 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
513 if (atv->is_audio_track()) {
515 AudioPlaylist* pl = atv->get_diskstream()->playlist();
516 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
519 DescendingRegionLayerSorter cmp;
522 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
528 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
537 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
541 switch (event->type) {
542 case GDK_BUTTON_PRESS:
543 case GDK_2BUTTON_PRESS:
544 case GDK_3BUTTON_PRESS:
545 clicked_control_point = cp;
546 clicked_trackview = &cp->line.trackview;
547 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
548 clicked_regionview = 0;
554 case GDK_SCROLL_DOWN:
561 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
562 type = GainControlPointItem;
563 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
564 type = GainAutomationControlPointItem;
565 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
566 type = PanAutomationControlPointItem;
567 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
568 type = RedirectAutomationControlPointItem;
573 return typed_event (item, event, type);
577 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
581 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
583 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
584 type = GainAutomationLineItem;
585 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
586 type = PanAutomationLineItem;
587 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
588 type = RedirectAutomationLineItem;
593 return typed_event (item, event, type);
597 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
601 switch (event->type) {
602 case GDK_BUTTON_PRESS:
603 case GDK_2BUTTON_PRESS:
604 case GDK_3BUTTON_PRESS:
605 clicked_selection = rect->id;
606 ret = button_press_handler (item, event, SelectionItem);
608 case GDK_BUTTON_RELEASE:
609 ret = button_release_handler (item, event, SelectionItem);
611 case GDK_MOTION_NOTIFY:
612 ret = motion_handler (item, event, SelectionItem);
614 /* Don't need these at the moment. */
615 case GDK_ENTER_NOTIFY:
616 ret = enter_handler (item, event, SelectionItem);
619 case GDK_LEAVE_NOTIFY:
620 ret = leave_handler (item, event, SelectionItem);
631 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
635 switch (event->type) {
636 case GDK_BUTTON_PRESS:
637 case GDK_2BUTTON_PRESS:
638 case GDK_3BUTTON_PRESS:
639 clicked_selection = rect->id;
640 ret = button_press_handler (item, event, StartSelectionTrimItem);
642 case GDK_BUTTON_RELEASE:
643 ret = button_release_handler (item, event, StartSelectionTrimItem);
645 case GDK_MOTION_NOTIFY:
646 ret = motion_handler (item, event, StartSelectionTrimItem);
648 case GDK_ENTER_NOTIFY:
649 ret = enter_handler (item, event, StartSelectionTrimItem);
652 case GDK_LEAVE_NOTIFY:
653 ret = leave_handler (item, event, StartSelectionTrimItem);
664 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
668 switch (event->type) {
669 case GDK_BUTTON_PRESS:
670 case GDK_2BUTTON_PRESS:
671 case GDK_3BUTTON_PRESS:
672 clicked_selection = rect->id;
673 ret = button_press_handler (item, event, EndSelectionTrimItem);
675 case GDK_BUTTON_RELEASE:
676 ret = button_release_handler (item, event, EndSelectionTrimItem);
678 case GDK_MOTION_NOTIFY:
679 ret = motion_handler (item, event, EndSelectionTrimItem);
681 case GDK_ENTER_NOTIFY:
682 ret = enter_handler (item, event, EndSelectionTrimItem);
685 case GDK_LEAVE_NOTIFY:
686 ret = leave_handler (item, event, EndSelectionTrimItem);
698 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
702 switch (event->type) {
703 case GDK_BUTTON_PRESS:
704 case GDK_2BUTTON_PRESS:
705 case GDK_3BUTTON_PRESS:
706 clicked_regionview = rv;
707 clicked_control_point = 0;
708 clicked_trackview = &clicked_regionview->get_time_axis_view();
709 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
710 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
712 case GDK_BUTTON_RELEASE:
713 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
715 case GDK_MOTION_NOTIFY:
716 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
718 case GDK_ENTER_NOTIFY:
719 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
722 case GDK_LEAVE_NOTIFY:
723 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
734 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
738 switch (event->type) {
739 case GDK_BUTTON_PRESS:
740 case GDK_2BUTTON_PRESS:
741 case GDK_3BUTTON_PRESS:
742 clicked_regionview = rv;
743 clicked_control_point = 0;
744 clicked_trackview = &clicked_regionview->get_time_axis_view();
745 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
746 ret = button_press_handler (item, event, AudioRegionViewName);
748 case GDK_BUTTON_RELEASE:
749 ret = button_release_handler (item, event, AudioRegionViewName);
751 case GDK_MOTION_NOTIFY:
752 ret = motion_handler (item, event, AudioRegionViewName);
754 case GDK_ENTER_NOTIFY:
755 ret = enter_handler (item, event, AudioRegionViewName);
758 case GDK_LEAVE_NOTIFY:
759 ret = leave_handler (item, event, AudioRegionViewName);
770 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
772 return typed_event (item, event, MarkerItem);
776 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
778 return typed_event (item, event, MarkerBarItem);
782 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
784 return typed_event (item, event, RangeMarkerBarItem);
788 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
790 return typed_event (item, event, TransportMarkerBarItem);
794 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
796 return typed_event (item, event, TempoMarkerItem);
800 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
802 return typed_event (item, event, MeterMarkerItem);
806 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
808 return typed_event (item, event, TempoBarItem);
812 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
814 return typed_event (item, event, MeterBarItem);
818 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
820 return typed_event (item, event, PlayheadCursorItem);
824 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
826 return typed_event (item, event, EditCursorItem);
830 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
832 return typed_event (item, event, NoItem);