X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas_events.cc;h=c26e4b96dc091e321e4371130a438e24e7daec3f;hb=205fbb99ad65b899a5047165422f442d9930103a;hp=9bceb1c26c561c9aa548dfcf02bc7737f4fb115d;hpb=30968b854257cb5f9159ca59589f783c85615601;p=ardour.git diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 9bceb1c26c..c26e4b96dc 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -24,12 +24,15 @@ #include "pbd/stacktrace.h" +#include "ardour/audio_track.h" +#include "ardour/midi_track.h" #include "ardour/midi_region.h" #include "ardour/region_factory.h" #include "ardour/profile.h" #include "canvas/canvas.h" #include "canvas/text.h" +#include "canvas/scroll_group.h" #include "editor.h" #include "keyboard.h" @@ -45,6 +48,7 @@ #include "editor_drag.h" #include "midi_time_axis.h" #include "editor_regions.h" +#include "ui_config.h" #include "verbose_cursor.h" #include "i18n.h" @@ -60,26 +64,30 @@ using Gtkmm2ext::Keyboard; bool Editor::track_canvas_scroll (GdkEventScroll* ev) { - framepos_t xdelta; int direction = ev->direction; - retry: + /* this event arrives without transformation by the canvas, so we have + * to transform the coordinates to be able to look things up. + */ + + Duple event_coords = _track_canvas->window_to_canvas (Duple (ev->x, ev->y)); + switch (direction) { case GDK_SCROLL_UP: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - //for mouse-wheel zoom, force zoom-focus to mouse - Editing::ZoomFocus temp_focus = zoom_focus; - zoom_focus = Editing::ZoomFocusMouse; - temporal_zoom_step (false); - zoom_focus = temp_focus; + if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) { + if (UIConfiguration::instance().get_use_mouse_position_as_zoom_focus_on_scroll()) { + temporal_zoom_step_mouse_focus (false); + } else { + temporal_zoom_step (false); + } + return true; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) { + scroll_left_step (); return true; - } 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)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) { if (!current_stepping_trackview) { 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()); + std::pair const p = trackview_by_y_position (event_coords.y, false); current_stepping_trackview = p.first; if (!current_stepping_trackview) { return false; @@ -89,26 +97,26 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) current_stepping_trackview->step_height (false); return true; } else { - scroll_tracks_up_line (); + scroll_up_one_track (); return true; } break; case GDK_SCROLL_DOWN: - if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - //for mouse-wheel zoom, force zoom-focus to mouse - Editing::ZoomFocus temp_focus = zoom_focus; - zoom_focus = Editing::ZoomFocusMouse; - temporal_zoom_step (true); - zoom_focus = temp_focus; + if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomHorizontalModifier)) { + if (UIConfiguration::instance().get_use_mouse_position_as_zoom_focus_on_scroll()) { + temporal_zoom_step_mouse_focus (true); + } else { + temporal_zoom_step (true); + } + return true; + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollHorizontalModifier)) { + scroll_right_step (); return true; - } 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)) { + } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ScrollZoomVerticalModifier)) { if (!current_stepping_trackview) { 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()); + std::pair const p = trackview_by_y_position (event_coords.y, false); current_stepping_trackview = p.first; if (!current_stepping_trackview) { return false; @@ -118,27 +126,19 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) current_stepping_trackview->step_height (true); return true; } else { - scroll_tracks_down_line (); + scroll_down_one_track (); return true; } 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); - } + scroll_left_step (); + return true; 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()); - } + scroll_right_step (); + return true; break; default: @@ -150,26 +150,39 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) } bool -Editor::track_canvas_scroll_event (GdkEventScroll *event) +Editor::canvas_scroll_event (GdkEventScroll *event, bool from_canvas) { + if (from_canvas) { + boost::optional rulers = _time_markers_group->bounding_box(); + if (rulers && rulers->contains (Duple (event->x, event->y))) { + return canvas_ruler_event ((GdkEvent*) event, timecode_ruler, TimecodeRulerItem); + } + } + _track_canvas->grab_focus(); return track_canvas_scroll (event); } bool -Editor::track_canvas_button_press_event (GdkEventButton */*event*/) +Editor::track_canvas_button_press_event (GdkEventButton *event) { - selection->clear (); _track_canvas->grab_focus(); + if (!Keyboard::is_context_menu_event (event)) { + begin_reversible_selection_op (X_("Clear Selection Click (track canvas)")); + selection->clear (); + commit_reversible_selection_op(); + } return false; } bool Editor::track_canvas_button_release_event (GdkEventButton *event) { - if (_drags->active ()) { - _drags->end_grab ((GdkEvent*) event); - } + if (!Keyboard::is_context_menu_event (event)) { + if (_drags->active ()) { + _drags->end_grab ((GdkEvent*) event); + } + } return false; } @@ -182,16 +195,6 @@ Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/) return false; } -bool -Editor::track_canvas_motion (GdkEvent *ev) -{ - if (_verbose_cursor->visible ()) { - _verbose_cursor->set_position (ev->motion.x + 10, ev->motion.y + 10); - } - - return false; -} - bool Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) { @@ -261,13 +264,15 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg break; case GDK_ENTER_NOTIFY: - set_entered_track (&rv->get_time_axis_view ()); set_entered_regionview (rv); + ret = enter_handler (item, event, RegionItem); break; case GDK_LEAVE_NOTIFY: - set_entered_track (0); - set_entered_regionview (0); + if (event->crossing.detail != GDK_NOTIFY_INFERIOR) { + set_entered_regionview (0); + ret = leave_handler (item, event, RegionItem); + } break; default: @@ -277,6 +282,42 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg return ret; } +bool +Editor::canvas_wave_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv) +{ + /* we only care about enter events here, required for mouse/cursor + * tracking. there is a non-linear (non-child/non-parent) relationship + * between various components of a regionview and so when we leave one + * of them (e.g. a trim handle) and enter another (e.g. the waveview) + * no other items get notified. enter/leave handling does not propagate + * in the same way as other events, so we need to catch this because + * entering (and leaving) the waveview is equivalent to + * entering/leaving the regionview (which is why it is passed in as a + * third argument). + * + * And in fact, we really only care about enter events. + */ + + bool ret = false; + + if (!rv->sensitive ()) { + return false; + } + + switch (event->type) { + case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); + ret = enter_handler (item, event, WaveItem); + break; + + default: + break; + } + + return ret; +} + + bool Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv) { @@ -303,10 +344,14 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou case GDK_ENTER_NOTIFY: set_entered_track (tv); + ret = enter_handler (item, event, StreamItem); break; case GDK_LEAVE_NOTIFY: - set_entered_track (0); + if (event->crossing.detail != GDK_NOTIFY_INFERIOR) { + set_entered_track (0); + } + ret = leave_handler (item, event, StreamItem); break; default: @@ -456,13 +501,17 @@ Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRe } - /* proxy for the regionview */ + /* proxy for the regionview, except enter/leave events */ - return canvas_region_view_event (event, rv->get_canvas_group(), rv); + if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) { + return true; + } else { + return canvas_region_view_event (event, rv->get_canvas_group(), rv); + } } bool -Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) +Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv, bool trim) { bool ret = false; @@ -478,11 +527,11 @@ Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, clicked_control_point = 0; clicked_axisview = &rv->get_time_axis_view(); clicked_routeview = dynamic_cast(clicked_axisview); - ret = button_press_handler (item, event, FadeInHandleItem); + ret = button_press_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem); break; case GDK_BUTTON_RELEASE: - ret = button_release_handler (item, event, FadeInHandleItem); + ret = button_release_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem); maybe_locate_with_edit_preroll ( rv->region()->position() ); break; @@ -491,13 +540,11 @@ Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_ENTER_NOTIFY: - set_entered_regionview (rv); - ret = enter_handler (item, event, FadeInHandleItem); + ret = enter_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem); break; case GDK_LEAVE_NOTIFY: - set_entered_regionview (0); - ret = leave_handler (item, event, FadeInHandleItem); + ret = leave_handler (item, event, trim ? FadeInTrimHandleItem : FadeInHandleItem); break; default: @@ -538,13 +585,17 @@ Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioR } - /* proxy for the regionview */ + /* proxy for the regionview, except enter/leave events */ - return canvas_region_view_event (event, rv->get_canvas_group(), rv); + if (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) { + return true; + } else { + return canvas_region_view_event (event, rv->get_canvas_group(), rv); + } } bool -Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) +Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv, bool trim) { bool ret = false; @@ -560,11 +611,11 @@ Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, clicked_control_point = 0; clicked_axisview = &rv->get_time_axis_view(); clicked_routeview = dynamic_cast(clicked_axisview); - ret = button_press_handler (item, event, FadeOutHandleItem); + ret = button_press_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem); break; case GDK_BUTTON_RELEASE: - ret = button_release_handler (item, event, FadeOutHandleItem); + ret = button_release_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem); maybe_locate_with_edit_preroll ( rv->region()->last_frame() - rv->get_fade_out_shape_width() ); break; @@ -573,13 +624,11 @@ Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_ENTER_NOTIFY: - set_entered_regionview (rv); - ret = enter_handler (item, event, FadeOutHandleItem); + ret = enter_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem); break; case GDK_LEAVE_NOTIFY: - set_entered_regionview (0); - ret = leave_handler (item, event, FadeOutHandleItem); + ret = leave_handler (item, event, trim ? FadeOutTrimHandleItem : FadeOutHandleItem); break; default: @@ -625,13 +674,23 @@ bool Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al) { ItemType type; - - if (dynamic_cast (al) != 0) { + AudioRegionGainLine* gl; + if ((gl = dynamic_cast (al)) != 0) { type = GainLineItem; + if (event->type == GDK_BUTTON_PRESS) { + clicked_regionview = &gl->region_view (); + } } else { type = AutomationLineItem; + if (event->type == GDK_BUTTON_PRESS) { + clicked_regionview = 0; + } } + clicked_control_point = 0; + clicked_axisview = &al->trackview; + clicked_routeview = dynamic_cast(clicked_axisview); + return typed_event (item, event, type); } @@ -777,12 +836,10 @@ Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, Re 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; @@ -821,12 +878,10 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas:: 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; @@ -863,12 +918,10 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item 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; @@ -919,7 +972,7 @@ Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, Re } bool -Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/) +Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, ArdourMarker* /*marker*/) { return typed_event (item, event, MarkerItem); } @@ -948,13 +1001,11 @@ Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item) return typed_event (item, event, CdMarkerBarItem); } -#ifdef WITH_VIDEOTIMELINE bool Editor::canvas_videotl_bar_event (GdkEvent *event, ArdourCanvas::Item* item) { return typed_event (item, event, VideoBarItem); } -#endif bool Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/) @@ -962,12 +1013,74 @@ Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Te return typed_event (item, event, TempoMarkerItem); } +bool +Editor::canvas_tempo_curve_event (GdkEvent *event, ArdourCanvas::Item* item, TempoCurve* /*marker*/) +{ + return typed_event (item, event, TempoCurveItem); +} + bool Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/) { return typed_event (item, event, MeterMarkerItem); } +bool +Editor::canvas_ruler_event (GdkEvent *event, ArdourCanvas::Item* item, ItemType type) +{ + bool handled = false; + + if (event->type == GDK_SCROLL) { + + /* scroll events in the rulers are handled a little differently from + scrolling elsewhere in the canvas. + */ + + switch (event->scroll.direction) { + case GDK_SCROLL_UP: + if (Keyboard::modifier_state_equals(event->scroll.state, + Keyboard::ScrollHorizontalModifier)) { + scroll_left_step (); + } else if (UIConfiguration::instance().get_use_mouse_position_as_zoom_focus_on_scroll()) { + temporal_zoom_step_mouse_focus (false); + } else { + temporal_zoom_step (false); + } + handled = true; + break; + + case GDK_SCROLL_DOWN: + if (Keyboard::modifier_state_equals(event->scroll.state, + Keyboard::ScrollHorizontalModifier)) { + scroll_right_step (); + } else if (UIConfiguration::instance().get_use_mouse_position_as_zoom_focus_on_scroll()) { + temporal_zoom_step_mouse_focus (true); + } else { + temporal_zoom_step (true); + } + handled = true; + break; + + case GDK_SCROLL_LEFT: + scroll_left_half_page (); + handled = true; + break; + + case GDK_SCROLL_RIGHT: + scroll_right_half_page (); + handled = true; + break; + + default: + /* what? */ + break; + } + return handled; + } + + return typed_event (item, event, type); +} + bool Editor::canvas_tempo_bar_event (GdkEvent *event, ArdourCanvas::Item* item) { @@ -986,12 +1099,6 @@ Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item) return typed_event (item, event, PlayheadCursorItem); } -bool -Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item) -{ - return typed_event (item, event, NoItem); -} - bool Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item) { @@ -1002,11 +1109,49 @@ Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item) return typed_event (item, event, NoteItem); } +bool +Editor::canvas_drop_zone_event (GdkEvent* event) +{ + GdkEventScroll scroll; + ArdourCanvas::Duple winpos; + + switch (event->type) { + case GDK_BUTTON_RELEASE: + if (event->button.button == 1) { + begin_reversible_selection_op (X_("Nowhere Click")); + selection->clear_objects (); + selection->clear_tracks (); + commit_reversible_selection_op (); + } + break; + + case GDK_SCROLL: + /* convert coordinates back into window space so that + we can just call canvas_scroll_event(). + */ + winpos = _track_canvas->canvas_to_window (Duple (event->scroll.x, event->scroll.y)); + scroll = event->scroll; + scroll.x = winpos.x; + scroll.y = winpos.y; + return canvas_scroll_event (&scroll, true); + break; + + case GDK_ENTER_NOTIFY: + return typed_event (_canvas_drop_zone, event, DropZoneItem); + + case GDK_LEAVE_NOTIFY: + return typed_event (_canvas_drop_zone, event, DropZoneItem); + + default: + break; + } + + return true; +} + bool Editor::track_canvas_drag_motion (Glib::RefPtr const& context, int x, int y, guint time) { - ArdourCanvas::Coord wx; - ArdourCanvas::Coord wy; boost::shared_ptr region; boost::shared_ptr region_copy; RouteTimeAxisView* rtav; @@ -1020,30 +1165,28 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const& context, return false; } - _track_canvas_viewport->window_to_canvas (x, y, wx, wy); - event.type = GDK_MOTION_NOTIFY; - event.button.x = wx; - event.button.y = wy; + event.button.x = x; + event.button.y = y; /* assume we're dragging with button 1 */ event.motion.state = Gdk::BUTTON1_MASK; - (void) event_frame (&event, &px, &py); + (void) window_event_sample (&event, &px, &py); - std::pair const tv = trackview_by_y_position (py); + std::pair const tv = trackview_by_y_position (py, false); bool can_drop = false; - + if (tv.first != 0) { /* over a time axis view of some kind */ rtav = dynamic_cast (tv.first); - + if (rtav != 0 && rtav->is_track ()) { /* over a track, not a bus */ can_drop = true; } - + } else { /* not over a time axis view, so drop is possible */ @@ -1052,19 +1195,31 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const& context, if (can_drop) { region = _regions->get_dragged_region (); - + if (region) { - + + if (tv.first == 0 + && ( + boost::dynamic_pointer_cast (region) != 0 || + boost::dynamic_pointer_cast (region) != 0 + ) + ) + { + /* drop to drop-zone */ + context->drag_status (context->get_suggested_action(), time); + return true; + } + if ((boost::dynamic_pointer_cast (region) != 0 && dynamic_cast (tv.first) != 0) || (boost::dynamic_pointer_cast (region) != 0 && dynamic_cast (tv.first) != 0)) { - - /* audio to audio - OR + + /* audio to audio + OR midi to midi */ - + context->drag_status (context->get_suggested_action(), time); return true; } @@ -1074,7 +1229,7 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const& context, * TODO: check if file is audio/midi, allow drops on same track-type only, * currently: if audio is dropped on a midi-track, it is only added to the region-list */ - if (Profile->get_sae() || Config->get_only_copy_imported_files()) { + if (UIConfiguration::instance().get_only_copy_imported_files()) { context->drag_status(Gdk::ACTION_COPY, time); } else { if ((context->get_actions() & (Gdk::ACTION_COPY | Gdk::ACTION_LINK | Gdk::ACTION_MOVE)) == Gdk::ACTION_COPY) { @@ -1098,55 +1253,58 @@ Editor::drop_regions (const Glib::RefPtr& /*context*/, const SelectionData& /*data*/, guint /*info*/, guint /*time*/) { - double wx; - double wy; - boost::shared_ptr region; - boost::shared_ptr region_copy; - RouteTimeAxisView* rtav; GdkEvent event; double px; double py; - _track_canvas_viewport->window_to_canvas (x, y, wx, wy); - event.type = GDK_MOTION_NOTIFY; - event.button.x = wx; - event.button.y = wy; + event.button.x = x; + event.button.y = y; /* assume we're dragging with button 1 */ event.motion.state = Gdk::BUTTON1_MASK; + framepos_t const pos = window_event_sample (&event, &px, &py); - framepos_t const pos = event_frame (&event, &px, &py); + boost::shared_ptr region = _regions->get_dragged_region (); + if (!region) { return; } - std::pair const tv = trackview_by_y_position (py); + RouteTimeAxisView* rtav = 0; + std::pair const tv = trackview_by_y_position (py, false); if (tv.first != 0) { - rtav = dynamic_cast (tv.first); - - if (rtav != 0 && rtav->is_track ()) { - - boost::shared_ptr region = _regions->get_dragged_region (); - - if (region) { - - region_copy = RegionFactory::create (region, true); - - - if ((boost::dynamic_pointer_cast (region_copy) != 0 && - dynamic_cast (tv.first) != 0) || - (boost::dynamic_pointer_cast (region_copy) != 0 && - dynamic_cast (tv.first) != 0)) { - - /* audio to audio - OR - midi to midi - */ - - - _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event); - _drags->end_grab (0); + } else { + try { + if (boost::dynamic_pointer_cast (region)) { + uint32_t output_chan = region->n_channels(); + if ((Config->get_output_auto_connect() & AutoConnectMaster) && session()->master_out()) { + output_chan = session()->master_out()->n_inputs().n_audio(); } + list > audio_tracks; + audio_tracks = session()->new_audio_track (region->n_channels(), output_chan, 0, 1, region->name(), PresentationInfo::max_order); + rtav = dynamic_cast (axis_view_from_stripable (audio_tracks.front())); + } else if (boost::dynamic_pointer_cast (region)) { + ChanCount one_midi_port (DataType::MIDI, 1); + list > midi_tracks; + midi_tracks = session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr(), + (ARDOUR::Plugin::PresetRecord*) 0, + (ARDOUR::RouteGroup*) 0, 1, region->name(), PresentationInfo::max_order); + rtav = dynamic_cast (axis_view_from_stripable (midi_tracks.front())); + } else { + return; } + } catch (...) { + error << _("Could not create new track after region placed in the drop zone") << endmsg; + return; + } + } + + if (rtav != 0 && rtav->is_track ()) { + boost::shared_ptr region_copy = RegionFactory::create (region, true); + + if ((boost::dynamic_pointer_cast (region_copy) != 0 && dynamic_cast (rtav) != 0) || + (boost::dynamic_pointer_cast (region_copy) != 0 && dynamic_cast (rtav) != 0)) { + _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event); + _drags->end_grab (0); } } } @@ -1192,3 +1350,4 @@ Editor::key_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType return handled; } +