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>
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;
49 Editor::track_canvas_scroll (GdkEventScroll* ev)
54 switch (ev->direction) {
56 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
57 //if (ev->state == GDK_CONTROL_MASK) {
59 the ev->x will be out of step with the canvas
60 if we're in mid zoom, so we have to get the damn mouse
63 track_canvas.get_pointer (x, y);
64 track_canvas.window_to_world (x, y, wx, wy);
65 wx += horizontal_adjustment.get_value();
66 wy += vertical_adjustment.get_value();
69 event.type = GDK_BUTTON_RELEASE;
73 jack_nframes_t where = event_frame (&event, 0, 0);
74 temporal_zoom_to_frame (true, where);
76 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
77 if (!current_stepping_trackview) {
78 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
79 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
83 gettimeofday (&last_track_height_step_timestamp, 0);
84 current_stepping_trackview->step_height (true);
87 scroll_tracks_up_line ();
92 if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
93 //if (ev->state == GDK_CONTROL_MASK) {
94 track_canvas.get_pointer (x, y);
95 track_canvas.window_to_world (x, y, wx, wy);
96 wx += horizontal_adjustment.get_value();
97 wy += vertical_adjustment.get_value();
100 event.type = GDK_BUTTON_RELEASE;
104 jack_nframes_t where = event_frame (&event, 0, 0);
105 temporal_zoom_to_frame (false, where);
107 } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
108 if (!current_stepping_trackview) {
109 step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500);
110 if (!(current_stepping_trackview = dynamic_cast<AudioTimeAxisView*> (trackview_by_y_position (ev->y)))) {
114 gettimeofday (&last_track_height_step_timestamp, 0);
115 current_stepping_trackview->step_height (false);
118 scroll_tracks_down_line ();
124 /* no left/right handling yet */
132 Editor::track_canvas_event (GdkEvent *event, ArdourCanvas::Item* item)
136 /* this is the handler for events that are not handled by
140 switch (event->type) {
141 case GDK_MOTION_NOTIFY:
142 /* keep those motion events coming */
143 track_canvas.get_pointer (x, y);
144 return track_canvas_motion (event);
146 case GDK_BUTTON_PRESS:
147 track_canvas.grab_focus();
150 case GDK_BUTTON_RELEASE:
151 switch (event->button.button) {
154 button_release_handler (item, event, NoItem);
160 track_canvas.grab_focus();
161 track_canvas_scroll (&event->scroll);
172 Editor::track_canvas_motion (GdkEvent *ev)
174 if (verbose_cursor_visible) {
175 verbose_canvas_cursor->property_x() = ev->motion.x + 20;
176 verbose_canvas_cursor->property_y() = ev->motion.y + 20;
182 Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
186 switch (event->type) {
187 case GDK_BUTTON_PRESS:
188 case GDK_2BUTTON_PRESS:
189 case GDK_3BUTTON_PRESS:
190 ret = button_press_handler (item, event, type);
192 case GDK_BUTTON_RELEASE:
193 ret = button_release_handler (item, event, type);
195 case GDK_MOTION_NOTIFY:
196 ret = motion_handler (item, event, type);
199 case GDK_ENTER_NOTIFY:
200 ret = enter_handler (item, event, type);
203 case GDK_LEAVE_NOTIFY:
204 ret = leave_handler (item, event, type);
215 Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
219 switch (event->type) {
220 case GDK_BUTTON_PRESS:
221 case GDK_2BUTTON_PRESS:
222 case GDK_3BUTTON_PRESS:
223 clicked_regionview = rv;
224 clicked_control_point = 0;
225 clicked_trackview = &rv->get_time_axis_view();
226 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
227 ret = button_press_handler (item, event, RegionItem);
230 case GDK_BUTTON_RELEASE:
231 ret = button_release_handler (item, event, RegionItem);
234 case GDK_MOTION_NOTIFY:
235 ret = motion_handler (item, event, RegionItem);
238 case GDK_ENTER_NOTIFY:
239 set_entered_regionview (rv);
242 case GDK_LEAVE_NOTIFY:
243 set_entered_regionview (0);
254 Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
258 switch (event->type) {
259 case GDK_BUTTON_PRESS:
260 case GDK_2BUTTON_PRESS:
261 case GDK_3BUTTON_PRESS:
262 clicked_regionview = 0;
263 clicked_control_point = 0;
264 clicked_trackview = tv;
265 clicked_audio_trackview = tv;
266 ret = button_press_handler (item, event, StreamItem);
269 case GDK_BUTTON_RELEASE:
270 ret = button_release_handler (item, event, StreamItem);
273 case GDK_MOTION_NOTIFY:
274 ret = motion_handler (item, event, StreamItem);
277 case GDK_ENTER_NOTIFY:
290 Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
294 switch (event->type) {
295 case GDK_BUTTON_PRESS:
296 case GDK_2BUTTON_PRESS:
297 case GDK_3BUTTON_PRESS:
298 clicked_regionview = 0;
299 clicked_control_point = 0;
300 clicked_trackview = atv;
301 clicked_audio_trackview = 0;
302 ret = button_press_handler (item, event, AutomationTrackItem);
305 case GDK_BUTTON_RELEASE:
306 ret = button_release_handler (item, event, AutomationTrackItem);
309 case GDK_MOTION_NOTIFY:
310 ret = motion_handler (item, event, AutomationTrackItem);
313 case GDK_ENTER_NOTIFY:
314 ret = enter_handler (item, event, AutomationTrackItem);
317 case GDK_LEAVE_NOTIFY:
318 ret = leave_handler (item, event, AutomationTrackItem);
329 Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
331 /* we handle only button 3 press/release events */
333 switch (event->type) {
334 case GDK_BUTTON_PRESS:
335 clicked_regionview = rv;
336 clicked_control_point = 0;
337 clicked_trackview = &rv->get_time_axis_view();
338 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
339 if (event->button.button == 3) {
340 return button_press_handler (item, event, FadeInItem);
344 case GDK_BUTTON_RELEASE:
345 if (event->button.button == 3) {
346 return button_release_handler (item, event, FadeInItem);
355 /* proxy for the regionview */
357 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
361 Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
365 switch (event->type) {
366 case GDK_BUTTON_PRESS:
367 case GDK_2BUTTON_PRESS:
368 case GDK_3BUTTON_PRESS:
369 clicked_regionview = rv;
370 clicked_control_point = 0;
371 clicked_trackview = &rv->get_time_axis_view();
372 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
373 ret = button_press_handler (item, event, FadeInHandleItem);
376 case GDK_BUTTON_RELEASE:
377 ret = button_release_handler (item, event, FadeInHandleItem);
380 case GDK_MOTION_NOTIFY:
381 ret = motion_handler (item, event, FadeInHandleItem);
384 case GDK_ENTER_NOTIFY:
385 ret = enter_handler (item, event, FadeInHandleItem);
388 case GDK_LEAVE_NOTIFY:
389 ret = leave_handler (item, event, FadeInHandleItem);
400 Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
402 /* we handle only button 3 press/release events */
404 switch (event->type) {
405 case GDK_BUTTON_PRESS:
406 clicked_regionview = rv;
407 clicked_control_point = 0;
408 clicked_trackview = &rv->get_time_axis_view();
409 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
410 if (event->button.button == 3) {
411 return button_press_handler (item, event, FadeOutItem);
415 case GDK_BUTTON_RELEASE:
416 if (event->button.button == 3) {
417 return button_release_handler (item, event, FadeOutItem);
426 /* proxy for the regionview */
428 return canvas_region_view_event (event, rv->get_canvas_group(), rv);
432 Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
436 switch (event->type) {
437 case GDK_BUTTON_PRESS:
438 case GDK_2BUTTON_PRESS:
439 case GDK_3BUTTON_PRESS:
440 clicked_regionview = rv;
441 clicked_control_point = 0;
442 clicked_trackview = &rv->get_time_axis_view();
443 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
444 ret = button_press_handler (item, event, FadeOutHandleItem);
447 case GDK_BUTTON_RELEASE:
448 ret = button_release_handler (item, event, FadeOutHandleItem);
451 case GDK_MOTION_NOTIFY:
452 ret = motion_handler (item, event, FadeOutHandleItem);
455 case GDK_ENTER_NOTIFY:
456 ret = enter_handler (item, event, FadeOutHandleItem);
459 case GDK_LEAVE_NOTIFY:
460 ret = leave_handler (item, event, FadeOutHandleItem);
470 struct DescendingRegionLayerSorter {
471 bool operator()(Region* a, Region* b) {
472 return a->layer() > b->layer();
477 Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv)
479 /* we handle only button 3 press/release events */
481 switch (event->type) {
482 case GDK_BUTTON_PRESS:
483 clicked_crossfadeview = xfv;
484 clicked_trackview = &clicked_crossfadeview->get_time_axis_view();
485 if (event->button.button == 3) {
486 return button_press_handler (item, event, CrossfadeViewItem);
490 case GDK_BUTTON_RELEASE:
491 if (event->button.button == 3) {
492 bool ret = button_release_handler (item, event, CrossfadeViewItem);
503 /* proxy for the upper most regionview */
505 /* XXX really need to check if we are in the name highlight,
506 and proxy to that when required.
509 TimeAxisView& tv (xfv->get_time_axis_view());
510 AudioTimeAxisView* atv;
512 if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
514 if (atv->is_audio_track()) {
517 if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
519 Playlist::RegionList* rl = pl->regions_at (event_frame (event));
522 DescendingRegionLayerSorter cmp;
525 AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
531 return canvas_region_view_event (event, arv->get_canvas_group(), arv);
541 Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp)
545 switch (event->type) {
546 case GDK_BUTTON_PRESS:
547 case GDK_2BUTTON_PRESS:
548 case GDK_3BUTTON_PRESS:
549 clicked_control_point = cp;
550 clicked_trackview = &cp->line.trackview;
551 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
552 clicked_regionview = 0;
558 case GDK_SCROLL_DOWN:
565 if (dynamic_cast<AudioRegionGainLine*> (&cp->line) != 0) {
566 type = GainControlPointItem;
567 } else if (dynamic_cast<AutomationGainLine*> (&cp->line) != 0) {
568 type = GainAutomationControlPointItem;
569 } else if (dynamic_cast<AutomationPanLine*> (&cp->line) != 0) {
570 type = PanAutomationControlPointItem;
571 } else if (dynamic_cast<RedirectAutomationLine*> (&cp->line) != 0) {
572 type = RedirectAutomationControlPointItem;
577 return typed_event (item, event, type);
581 Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
585 if (dynamic_cast<AudioRegionGainLine*> (al) != 0) {
587 } else if (dynamic_cast<AutomationGainLine*> (al) != 0) {
588 type = GainAutomationLineItem;
589 } else if (dynamic_cast<AutomationPanLine*> (al) != 0) {
590 type = PanAutomationLineItem;
591 } else if (dynamic_cast<RedirectAutomationLine*> (al) != 0) {
592 type = RedirectAutomationLineItem;
597 return typed_event (item, event, type);
601 Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
605 switch (event->type) {
606 case GDK_BUTTON_PRESS:
607 case GDK_2BUTTON_PRESS:
608 case GDK_3BUTTON_PRESS:
609 clicked_selection = rect->id;
610 ret = button_press_handler (item, event, SelectionItem);
612 case GDK_BUTTON_RELEASE:
613 ret = button_release_handler (item, event, SelectionItem);
615 case GDK_MOTION_NOTIFY:
616 ret = motion_handler (item, event, SelectionItem);
618 /* Don't need these at the moment. */
619 case GDK_ENTER_NOTIFY:
620 ret = enter_handler (item, event, SelectionItem);
623 case GDK_LEAVE_NOTIFY:
624 ret = leave_handler (item, event, SelectionItem);
635 Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
639 switch (event->type) {
640 case GDK_BUTTON_PRESS:
641 case GDK_2BUTTON_PRESS:
642 case GDK_3BUTTON_PRESS:
643 clicked_selection = rect->id;
644 ret = button_press_handler (item, event, StartSelectionTrimItem);
646 case GDK_BUTTON_RELEASE:
647 ret = button_release_handler (item, event, StartSelectionTrimItem);
649 case GDK_MOTION_NOTIFY:
650 ret = motion_handler (item, event, StartSelectionTrimItem);
652 case GDK_ENTER_NOTIFY:
653 ret = enter_handler (item, event, StartSelectionTrimItem);
656 case GDK_LEAVE_NOTIFY:
657 ret = leave_handler (item, event, StartSelectionTrimItem);
668 Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect)
672 switch (event->type) {
673 case GDK_BUTTON_PRESS:
674 case GDK_2BUTTON_PRESS:
675 case GDK_3BUTTON_PRESS:
676 clicked_selection = rect->id;
677 ret = button_press_handler (item, event, EndSelectionTrimItem);
679 case GDK_BUTTON_RELEASE:
680 ret = button_release_handler (item, event, EndSelectionTrimItem);
682 case GDK_MOTION_NOTIFY:
683 ret = motion_handler (item, event, EndSelectionTrimItem);
685 case GDK_ENTER_NOTIFY:
686 ret = enter_handler (item, event, EndSelectionTrimItem);
689 case GDK_LEAVE_NOTIFY:
690 ret = leave_handler (item, event, EndSelectionTrimItem);
702 Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
706 switch (event->type) {
707 case GDK_BUTTON_PRESS:
708 case GDK_2BUTTON_PRESS:
709 case GDK_3BUTTON_PRESS:
710 clicked_regionview = rv;
711 clicked_control_point = 0;
712 clicked_trackview = &clicked_regionview->get_time_axis_view();
713 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
714 ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
716 case GDK_BUTTON_RELEASE:
717 ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
719 case GDK_MOTION_NOTIFY:
720 ret = motion_handler (item, event, AudioRegionViewNameHighlight);
722 case GDK_ENTER_NOTIFY:
723 ret = enter_handler (item, event, AudioRegionViewNameHighlight);
726 case GDK_LEAVE_NOTIFY:
727 ret = leave_handler (item, event, AudioRegionViewNameHighlight);
738 Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
742 switch (event->type) {
743 case GDK_BUTTON_PRESS:
744 case GDK_2BUTTON_PRESS:
745 case GDK_3BUTTON_PRESS:
746 clicked_regionview = rv;
747 clicked_control_point = 0;
748 clicked_trackview = &clicked_regionview->get_time_axis_view();
749 clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
750 ret = button_press_handler (item, event, AudioRegionViewName);
752 case GDK_BUTTON_RELEASE:
753 ret = button_release_handler (item, event, AudioRegionViewName);
755 case GDK_MOTION_NOTIFY:
756 ret = motion_handler (item, event, AudioRegionViewName);
758 case GDK_ENTER_NOTIFY:
759 ret = enter_handler (item, event, AudioRegionViewName);
762 case GDK_LEAVE_NOTIFY:
763 ret = leave_handler (item, event, AudioRegionViewName);
774 Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker)
776 return typed_event (item, event, MarkerItem);
780 Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
782 return typed_event (item, event, MarkerBarItem);
786 Editor::canvas_range_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
788 return typed_event (item, event, RangeMarkerBarItem);
792 Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
794 return typed_event (item, event, TransportMarkerBarItem);
798 Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker)
800 return typed_event (item, event, TempoMarkerItem);
804 Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker)
806 return typed_event (item, event, MeterMarkerItem);
810 Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
812 return typed_event (item, event, TempoBarItem);
816 Editor::canvas_meter_bar_event (GdkEvent *event, ArdourCanvas::Item* item)
818 return typed_event (item, event, MeterBarItem);
822 Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
824 return typed_event (item, event, PlayheadCursorItem);
828 Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
830 return typed_event (item, event, EditCursorItem);
834 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
836 return typed_event (item, event, NoItem);