X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas_events.cc;h=4b7d40cdce2087fd98925a7a7c65faf4220f4fa3;hb=f2009ea7771048a89463fea25f0bad9de1e17567;hp=fa83ac94e5f0ae90ab766559b535898492ad0648;hpb=14543eb1374dc51834385d2f3886f1e6068223c5;p=ardour.git diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index fa83ac94e5..4b7d40cdce 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,167 +15,171 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include #include +#include +#include -#include -#include +#include "pbd/stacktrace.h" + +#include "ardour/midi_region.h" +#include "ardour/region_factory.h" #include "editor.h" #include "keyboard.h" #include "public_editor.h" #include "audio_region_view.h" #include "audio_streamview.h" -#include "crossfade_view.h" +#include "canvas-noevent-text.h" #include "audio_time_axis.h" #include "region_gain_line.h" -#include "automation_gain_line.h" -#include "automation_pan_line.h" +#include "automation_line.h" #include "automation_time_axis.h" -#include "redirect_automation_line.h" +#include "automation_line.h" +#include "control_point.h" #include "canvas_impl.h" #include "simplerect.h" +#include "editor_drag.h" +#include "midi_time_axis.h" +#include "editor_regions.h" +#include "verbose_cursor.h" #include "i18n.h" -using namespace sigc; +using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Gtk; +using namespace ArdourCanvas; + +using Gtkmm2ext::Keyboard; bool Editor::track_canvas_scroll (GdkEventScroll* ev) { - int x, y; - double wx, wy; + framepos_t xdelta; + int direction = ev->direction; - switch (ev->direction) { + retry: + switch (direction) { case GDK_SCROLL_UP: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { - //if (ev->state == GDK_CONTROL_MASK) { - /* XXX - the ev->x will be out of step with the canvas - if we're in mid zoom, so we have to get the damn mouse - pointer again - */ - track_canvas.get_pointer (x, y); - track_canvas.window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); - - GdkEvent event; - event.type = GDK_BUTTON_RELEASE; - event.button.x = wx; - event.button.y = wy; - - nframes_t where = event_frame (&event, 0, 0); - temporal_zoom_to_frame (true, where); + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { + temporal_zoom_step (false); return true; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { + direction = GDK_SCROLL_LEFT; + goto retry; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { + step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500); + std::pair const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize); + current_stepping_trackview = p.first; + if (!current_stepping_trackview) { return false; } } - gettimeofday (&last_track_height_step_timestamp, 0); - current_stepping_trackview->step_height (true); + last_track_height_step_timestamp = get_microseconds(); + current_stepping_trackview->step_height (false); return true; } else { scroll_tracks_up_line (); return true; } break; + case GDK_SCROLL_DOWN: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) { - //if (ev->state == GDK_CONTROL_MASK) { - track_canvas.get_pointer (x, y); - track_canvas.window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); - wy += vertical_adjustment.get_value(); - - GdkEvent event; - event.type = GDK_BUTTON_RELEASE; - event.button.x = wx; - event.button.y = wy; - - nframes_t where = event_frame (&event, 0, 0); - temporal_zoom_to_frame (false, where); + if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { + temporal_zoom_step (true); return true; - } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { + direction = GDK_SCROLL_RIGHT; + goto retry; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - if (!(current_stepping_trackview = trackview_by_y_position (ev->y))) { + step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500); + std::pair const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize); + current_stepping_trackview = p.first; + if (!current_stepping_trackview) { return false; } } - gettimeofday (&last_track_height_step_timestamp, 0); - current_stepping_trackview->step_height (false); + last_track_height_step_timestamp = get_microseconds(); + current_stepping_trackview->step_height (true); return true; } else { scroll_tracks_down_line (); return true; } - break; + break; + + case GDK_SCROLL_LEFT: + xdelta = (current_page_frames() / 8); + if (leftmost_frame > xdelta) { + reset_x_origin (leftmost_frame - xdelta); + } else { + reset_x_origin (0); + } + break; + + case GDK_SCROLL_RIGHT: + xdelta = (current_page_frames() / 8); + if (max_framepos - xdelta > leftmost_frame) { + reset_x_origin (leftmost_frame + xdelta); + } else { + reset_x_origin (max_framepos - current_page_frames()); + } + break; default: - /* no left/right handling yet */ + /* what? */ break; } - + return false; } bool -Editor::track_canvas_event (GdkEvent *event, ArdourCanvas::Item* item) +Editor::track_canvas_scroll_event (GdkEventScroll *event) { - gint x, y; - - /* this is the handler for events that are not handled by - items. - */ - - switch (event->type) { - case GDK_MOTION_NOTIFY: - /* keep those motion events coming */ - track_canvas.get_pointer (x, y); - return track_canvas_motion (event); - - case GDK_BUTTON_PRESS: - track_canvas.grab_focus(); - break; - - case GDK_BUTTON_RELEASE: - switch (event->button.button) { - case 4: - case 5: - button_release_handler (item, event, NoItem); - break; - } - break; + track_canvas->grab_focus(); + return track_canvas_scroll (event); +} - case GDK_SCROLL: - track_canvas.grab_focus(); - track_canvas_scroll (&event->scroll); - break; +bool +Editor::track_canvas_button_press_event (GdkEventButton */*event*/) +{ + selection->clear (); + track_canvas->grab_focus(); + return false; +} - default: - break; +bool +Editor::track_canvas_button_release_event (GdkEventButton *event) +{ + if (_drags->active ()) { + _drags->end_grab ((GdkEvent*) event); } + return false; +} - return FALSE; +bool +Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/) +{ + int x, y; + /* keep those motion events coming */ + track_canvas->get_pointer (x, y); + return false; } bool Editor::track_canvas_motion (GdkEvent *ev) { - if (verbose_cursor_visible) { - verbose_canvas_cursor->property_x() = ev->motion.x + 20; - verbose_canvas_cursor->property_y() = ev->motion.y + 20; + if (_verbose_cursor->visible ()) { + _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10); } + return false; } @@ -183,7 +187,7 @@ bool Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) { gint ret = FALSE; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -194,7 +198,7 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) ret = button_release_handler (item, event, type); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, type); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: @@ -205,17 +209,28 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) ret = leave_handler (item, event, type); break; + case GDK_KEY_PRESS: + ret = key_press_handler (item, event, type); + break; + + case GDK_KEY_RELEASE: + ret = key_release_handler (item, event, type); + break; + default: break; } - return ret; } bool Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv) { - gint ret = FALSE; + bool ret = false; + + if (!rv->sensitive ()) { + return false; + } switch (event->type) { case GDK_BUTTON_PRESS: @@ -223,8 +238,8 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg case GDK_3BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &rv->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, RegionItem); break; @@ -233,14 +248,16 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, RegionItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_track (&rv->get_time_axis_view ()); set_entered_regionview (rv); break; case GDK_LEAVE_NOTIFY: + set_entered_track (0); set_entered_regionview (0); break; @@ -255,15 +272,15 @@ bool Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv) { bool ret = FALSE; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = 0; clicked_control_point = 0; - clicked_trackview = tv; - clicked_audio_trackview = dynamic_cast(tv); + clicked_axisview = tv; + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, StreamItem); break; @@ -272,10 +289,15 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, StreamItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_track (tv); + break; + + case GDK_LEAVE_NOTIFY: + set_entered_track (0); break; default: @@ -285,21 +307,19 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou return ret; } - - bool Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv) { bool ret = false; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = 0; clicked_control_point = 0; - clicked_trackview = atv; - clicked_audio_trackview = 0; + clicked_axisview = atv; + clicked_routeview = 0; ret = button_press_handler (item, event, AutomationTrackItem); break; @@ -308,7 +328,7 @@ Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, AutomationTrackItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: @@ -326,17 +346,85 @@ Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item return ret; } +bool +Editor::canvas_start_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) +{ + if (!rv->sensitive()) { + return false; + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + clicked_regionview = rv; + clicked_control_point = 0; + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); + if (event->button.button == 3) { + return button_press_handler (item, event, StartCrossFadeItem); + } + break; + + case GDK_BUTTON_RELEASE: + if (event->button.button == 3) { + return button_release_handler (item, event, StartCrossFadeItem); + } + break; + + default: + break; + + } + + return typed_event (item, event, StartCrossFadeItem); +} + +bool +Editor::canvas_end_xfade_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) +{ + if (!rv->sensitive()) { + return false; + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + clicked_regionview = rv; + clicked_control_point = 0; + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); + if (event->button.button == 3) { + return button_press_handler (item, event, EndCrossFadeItem); + } + break; + + case GDK_BUTTON_RELEASE: + if (event->button.button == 3) { + return button_release_handler (item, event, EndCrossFadeItem); + } + break; + + default: + break; + + } + + return typed_event (item, event, EndCrossFadeItem); +} + bool Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) { /* we handle only button 3 press/release events */ + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &rv->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); if (event->button.button == 3) { return button_press_handler (item, event, FadeInItem); } @@ -350,11 +438,11 @@ Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRe default: break; - + } /* proxy for the regionview */ - + return canvas_region_view_event (event, rv->get_canvas_group(), rv); } @@ -362,15 +450,19 @@ bool Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) { bool ret = false; - + + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &rv->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, FadeInHandleItem); break; @@ -379,14 +471,16 @@ Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, FadeInHandleItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, FadeInHandleItem); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, FadeInHandleItem); break; @@ -402,12 +496,16 @@ Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioR { /* we handle only button 3 press/release events */ + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &rv->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); if (event->button.button == 3) { return button_press_handler (item, event, FadeOutItem); } @@ -421,11 +519,11 @@ Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioR default: break; - + } /* proxy for the regionview */ - + return canvas_region_view_event (event, rv->get_canvas_group(), rv); } @@ -433,15 +531,19 @@ bool Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) { bool ret = false; - + + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &rv->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &rv->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, FadeOutHandleItem); break; @@ -450,14 +552,16 @@ Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, FadeOutHandleItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, FadeOutHandleItem); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, FadeOutHandleItem); break; @@ -474,82 +578,16 @@ struct DescendingRegionLayerSorter { } }; -bool -Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, CrossfadeView* xfv) -{ - /* we handle only button 3 press/release events */ - - switch (event->type) { - case GDK_BUTTON_PRESS: - clicked_crossfadeview = xfv; - clicked_trackview = &clicked_crossfadeview->get_time_axis_view(); - if (event->button.button == 3) { - return button_press_handler (item, event, CrossfadeViewItem); - } - break; - - case GDK_BUTTON_RELEASE: - if (event->button.button == 3) { - bool ret = button_release_handler (item, event, CrossfadeViewItem); - return ret; - } - break; - - default: - break; - - } - - - /* proxy for the upper most regionview */ - - /* XXX really need to check if we are in the name highlight, - and proxy to that when required. - */ - - TimeAxisView& tv (xfv->get_time_axis_view()); - AudioTimeAxisView* atv; - - if ((atv = dynamic_cast(&tv)) != 0) { - - if (atv->is_audio_track()) { - - boost::shared_ptr pl; - if ((pl = boost::dynamic_pointer_cast (atv->get_diskstream()->playlist())) != 0) { - - Playlist::RegionList* rl = pl->regions_at (event_frame (event)); - - if (!rl->empty()) { - DescendingRegionLayerSorter cmp; - rl->sort (cmp); - - RegionView* rv = atv->view()->find_view (rl->front()); - - /* proxy */ - - delete rl; - - return canvas_region_view_event (event, rv->get_canvas_group(), rv); - } - } - } - } - - return TRUE; -} - bool Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, ControlPoint* cp) { - ItemType type; - switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_control_point = cp; - clicked_trackview = &cp->line.trackview; - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &cp->line().trackview; + clicked_routeview = dynamic_cast(clicked_axisview); clicked_regionview = 0; break; @@ -563,19 +601,7 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C break; } - if (dynamic_cast (&cp->line) != 0) { - type = GainControlPointItem; - } else if (dynamic_cast (&cp->line) != 0) { - type = GainAutomationControlPointItem; - } else if (dynamic_cast (&cp->line) != 0) { - type = PanAutomationControlPointItem; - } else if (dynamic_cast (&cp->line) != 0) { - type = RedirectAutomationControlPointItem; - } else { - return false; - } - - return typed_event (item, event, type); + return typed_event (item, event, ControlPointItem); } bool @@ -585,14 +611,8 @@ Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, Automation if (dynamic_cast (al) != 0) { type = GainLineItem; - } else if (dynamic_cast (al) != 0) { - type = GainAutomationLineItem; - } else if (dynamic_cast (al) != 0) { - type = PanAutomationLineItem; - } else if (dynamic_cast (al) != 0) { - type = RedirectAutomationLineItem; } else { - return false; + type = AutomationLineItem; } return typed_event (item, event, type); @@ -602,7 +622,7 @@ bool Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect) { bool ret = false; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -614,7 +634,7 @@ Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, ret = button_release_handler (item, event, SelectionItem); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, SelectionItem); + ret = motion_handler (item, event); break; /* Don't need these at the moment. */ case GDK_ENTER_NOTIFY: @@ -628,7 +648,7 @@ Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, default: break; } - + return ret; } @@ -648,7 +668,7 @@ Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* ret = button_release_handler (item, event, StartSelectionTrimItem); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, StartSelectionTrimItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: ret = enter_handler (item, event, StartSelectionTrimItem); @@ -661,7 +681,7 @@ Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* default: break; } - + return ret; } @@ -681,7 +701,7 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it ret = button_release_handler (item, event, EndSelectionTrimItem); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, EndSelectionTrimItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: ret = enter_handler (item, event, EndSelectionTrimItem); @@ -694,7 +714,65 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it default: break; } - + + return ret; +} + +bool +Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv) +{ + bool ret = false; + + /* frame handles are not active when in internal edit mode, because actual notes + might be in the area occupied by the handle - we want them to be editable as normal. + */ + + if (internal_editing() || !rv->sensitive()) { + return false; + } + + /* NOTE: frame handles pretend to be the colored trim bar from an event handling + perspective. XXX change this ?? + */ + + ItemType type; + + if (item->get_data ("isleft")) { + type = LeftFrameHandle; + } else { + type = RightFrameHandle; + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + clicked_regionview = rv; + clicked_control_point = 0; + clicked_axisview = &clicked_regionview->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); + ret = button_press_handler (item, event, type); + break; + case GDK_BUTTON_RELEASE: + ret = button_release_handler (item, event, type); + break; + case GDK_MOTION_NOTIFY: + ret = motion_handler (item, event); + break; + case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); + ret = enter_handler (item, event, type); + break; + + case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); + ret = leave_handler (item, event, type); + break; + + default: + break; + } + return ret; } @@ -703,28 +781,35 @@ bool Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv) { bool ret = false; - + + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &clicked_regionview->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &clicked_regionview->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, RegionViewNameHighlight); break; case GDK_BUTTON_RELEASE: ret = button_release_handler (item, event, RegionViewNameHighlight); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, RegionViewNameHighlight); + motion_handler (item, event); + ret = true; // force this to avoid progagating the event into the regionview break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, RegionViewNameHighlight); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, RegionViewNameHighlight); break; @@ -740,27 +825,33 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item { bool ret = false; + if (!rv->sensitive()) { + return false; + } + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: clicked_regionview = rv; clicked_control_point = 0; - clicked_trackview = &clicked_regionview->get_time_axis_view(); - clicked_audio_trackview = dynamic_cast(clicked_trackview); + clicked_axisview = &clicked_regionview->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); ret = button_press_handler (item, event, RegionViewName); break; case GDK_BUTTON_RELEASE: ret = button_release_handler (item, event, RegionViewName); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, RegionViewName); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, RegionViewName); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, RegionViewName); break; @@ -772,7 +863,46 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item } bool -Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker) +Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView*) +{ + bool ret = false; + + switch (event->type) { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + clicked_regionview = 0; + clicked_control_point = 0; + clicked_axisview = 0; + clicked_routeview = 0; //dynamic_cast(clicked_axisview); + ret = button_press_handler (item, event, FeatureLineItem); + break; + + case GDK_BUTTON_RELEASE: + ret = button_release_handler (item, event, FeatureLineItem); + break; + + case GDK_MOTION_NOTIFY: + ret = motion_handler (item, event); + break; + + case GDK_ENTER_NOTIFY: + ret = enter_handler (item, event, FeatureLineItem); + break; + + case GDK_LEAVE_NOTIFY: + ret = leave_handler (item, event, FeatureLineItem); + break; + + default: + break; + } + + return ret; +} + +bool +Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/) { return typed_event (item, event, MarkerItem); } @@ -796,13 +926,19 @@ Editor::canvas_transport_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* } bool -Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker) +Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item) +{ + return typed_event (item, event, CdMarkerBarItem); +} + +bool +Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/) { return typed_event (item, event, TempoMarkerItem); } bool -Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker) +Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/) { return typed_event (item, event, MeterMarkerItem); } @@ -826,14 +962,119 @@ Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item) } bool -Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item) +Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item) { - return typed_event (item, event, EditCursorItem); + return typed_event (item, event, NoItem); } bool -Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item) +Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item) { - return typed_event (item, event, NoItem); + if (!internal_editing()) { + return false; + } + + return typed_event (item, event, NoteItem); +} + +bool +Editor::track_canvas_drag_motion (Glib::RefPtr const & /*c*/, int x, int y, guint /*time*/) +{ + double wx; + double wy; + track_canvas->window_to_world (x, y, wx, wy); + + GdkEvent event; + event.type = GDK_MOTION_NOTIFY; + event.button.x = wx; + event.button.y = wy; + /* assume we're dragging with button 1 */ + event.motion.state = Gdk::BUTTON1_MASK; + + if (!_drags->active ()) { + + double px; + double py; + framepos_t const pos = event_frame (&event, &px, &py); + + std::pair const tv = trackview_by_y_position (py); + if (tv.first == 0) { + return true; + } + + RouteTimeAxisView* rtav = dynamic_cast (tv.first); + if (rtav == 0 || !rtav->is_track ()) { + return true; + } + + boost::shared_ptr region = _regions->get_dragged_region (); + + if (!region) { + return true; + } + + boost::shared_ptr region_copy = RegionFactory::create (region, true); + + if (boost::dynamic_pointer_cast (region_copy) != 0 && + dynamic_cast (tv.first) == 0) { + + /* audio -> non-audio */ + return true; + } + + if (boost::dynamic_pointer_cast (region_copy) != 0 && + dynamic_cast (tv.first) == 0) { + + /* MIDI -> non-MIDI */ + return true; + } + + _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event); + } + + _drags->motion_handler (&event, false); + + return true; +} + +bool +Editor::key_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) +{ + return false; } +bool +Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType type) +{ + + bool handled = false; + + switch (type) { + case TempoMarkerItem: + switch (event->key.keyval) { + case GDK_Delete: + remove_tempo_marker (item); + handled = true; + break; + default: + break; + } + break; + + case MeterMarkerItem: + switch (event->key.keyval) { + case GDK_Delete: + remove_meter_marker (item); + handled = true; + break; + default: + break; + } + break; + + default: + break; + } + + return handled; +}