X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_mouse.cc;h=e8a50686b324d3f447241d7dfb19f7c5cadb7f9d;hb=b0685f4336f0496d58c16c516dfd0eabfb7f0456;hp=10d791a60601e0995b16a54d7efb5ec290f0d3e8;hpb=60454cc8dc1ca5e1819b853b55916d52497d495c;p=ardour.git diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 10d791a606..e8a50686b3 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include @@ -28,12 +27,14 @@ #include #include +#include #include "ardour_ui.h" #include "editor.h" #include "time_axis_view.h" #include "audio_time_axis.h" -#include "audio_regionview.h" +#include "audio_region_view.h" +#include "midi_region_view.h" #include "marker.h" #include "streamview.h" #include "region_gain_line.h" @@ -46,6 +47,7 @@ #include "rgb_macros.h" #include +#include #include #include #include @@ -68,7 +70,7 @@ using namespace sigc; using namespace Gtk; using namespace Editing; -jack_nframes_t +nframes_t Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) { double cx, cy; @@ -290,8 +292,6 @@ void Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { bool commit = false; - bool c1; - bool c2; /* in object/audition/timefx mode, any button press sets the selection if the object can be selected. this is a @@ -303,81 +303,84 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it if (((mouse_mode != MouseObject) && (mouse_mode != MouseAudition || item_type != RegionItem) && - (mouse_mode != MouseTimeFX || item_type != RegionItem)) || + (mouse_mode != MouseTimeFX || item_type != RegionItem) && + (mouse_mode != MouseRange)) || + (event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE || event->button.button > 3)) { return; } + + if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) { + + if ((event->button.state & Keyboard::RelevantModifierKeyMask) && event->button.button != 1) { + + /* almost no selection action on modified button-2 or button-3 events */ + + if (item_type != RegionItem && event->button.button != 2) { + return; + } + } + } Selection::Operation op = Keyboard::selection_type (event->button.state); bool press = (event->type == GDK_BUTTON_PRESS); - begin_reversible_command (_("select on click")); - + // begin_reversible_command (_("select on click")); + switch (item_type) { case RegionItem: - c1 = set_selected_track_from_click (press, op, true, true); - c2 = set_selected_regionview_from_click (press, op, true); - commit = (c1 || c2); - break; - case RegionViewNameHighlight: case RegionViewName: - c1 = set_selected_track_from_click (press, op, true, true); - c2 = set_selected_regionview_from_click (press, op, true); - commit = (c1 || c2); + case FadeInHandleItem: + case FadeInItem: + case FadeOutHandleItem: + case FadeOutItem: + if (mouse_mode != MouseRange) { + commit = set_selected_regionview_from_click (press, op, true); + } else if (event->type == GDK_BUTTON_PRESS) { + commit = set_selected_track_from_click (press, op, false); + } break; - + + case CrossfadeViewItem: + commit = set_selected_track_from_click (press, op, false); + break; + case GainAutomationControlPointItem: case PanAutomationControlPointItem: case RedirectAutomationControlPointItem: - c1 = set_selected_track_from_click (press, op, true, true); - c2 = set_selected_control_point_from_click (press, op, false); - commit = (c1 || c2); + commit = set_selected_track_from_click (press, op, true); + if (mouse_mode != MouseRange) { + commit |= set_selected_control_point_from_click (op, false); + } break; case StreamItem: - commit = set_selected_track_from_click (press, op, true, true); + /* for context click or range selection, select track */ + if (event->button.button == 3) { + commit = set_selected_track_from_click (press, op, true); + } else if (event->type == GDK_BUTTON_PRESS && mouse_mode == MouseRange) { + commit = set_selected_track_from_click (press, op, false); + } break; case AutomationTrackItem: - commit = set_selected_track_from_click (press, op, true, true); + commit = set_selected_track_from_click (press, op, true); break; default: break; } -#define SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE -#ifdef SELECT_TRACK_FROM_CANVAS_IN_RANGE_MODE - /* in range mode, button 1/2/3 press potentially selects a track */ - - if (mouse_mode == MouseRange && - event->type == GDK_BUTTON_PRESS && - event->button.button <= 3) { - - switch (item_type) { - case StreamItem: - case RegionItem: - case AutomationTrackItem: - commit = set_selected_track_from_click (press, op, true, true); - break; - - default: - break; - } - } -#endif - if (commit) { - commit_reversible_command (); - } +// if (commit) { +// commit_reversible_command (); +// } } bool Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { - jack_nframes_t where = event_frame (event, 0, 0); - track_canvas.grab_focus(); if (session && session->actively_recording()) { @@ -496,10 +499,9 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp break; case MouseObject: - if (Keyboard::modifier_state_contains (event->button.state, - Keyboard::ModifierMask(Keyboard::Control|Keyboard::Alt)) - && event->type == GDK_BUTTON_PRESS) { - + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::Control|Keyboard::Alt)) && + event->type == GDK_BUTTON_PRESS) { + start_rubberband_select (item, event); } else if (event->type == GDK_BUTTON_PRESS) { @@ -553,7 +555,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp start_rubberband_select (item, event); break; - /* */ +#ifdef WITH_CMT case ImageFrameHandleStartItem: imageframe_start_handle_op(item, event) ; return(true) ; @@ -570,16 +572,13 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp markerview_item_end_handle_op(item, event) ; return(true) ; break ; - /* */ - - /* */ case MarkerViewItem: start_markerview_grab(item, event) ; break ; case ImageFrameItem: start_imageframe_grab(item, event) ; break ; - /* */ +#endif case MarkerBarItem: @@ -736,79 +735,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case 3: break; - case 4: - switch (mouse_mode) { - case MouseZoom: - //temporal_zoom_to_frame (true, where); - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { - temporal_zoom_to_frame (true, where); - } - else { - temporal_zoom_step (true); - } - break; - default: - - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::Alt))) { - scroll_backward (0.6f); - return true; - } - else if (Keyboard::no_modifier_keys_pressed (&event->button)) { - scroll_tracks_up_line (); - } else { - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { - if (clicked_trackview) { - if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - current_stepping_trackview = clicked_trackview; - } - gettimeofday (&last_track_height_step_timestamp, 0); - current_stepping_trackview->step_height (true); - } - } - else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { - temporal_zoom_to_frame (true, where); - } - } - } - break; - - case 5: - switch (mouse_mode) { - case MouseZoom: - // temporal_zoom_to_frame (false, where); - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { - temporal_zoom_to_frame (false, where); - } - else { - temporal_zoom_step (false); - } - break; - default: - - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::Alt))) { - scroll_forward (0.6f); - return true; - } - else if (Keyboard::no_modifier_keys_pressed (&event->button)) { - scroll_tracks_down_line (); - } else { - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { - if (clicked_trackview) { - if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); - current_stepping_trackview = clicked_trackview; - } - gettimeofday (&last_track_height_step_timestamp, 0); - current_stepping_trackview->step_height (false); - } - } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { - temporal_zoom_to_frame (false, where); - } - } - } - break; - default: break; @@ -820,7 +746,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp bool Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { - jack_nframes_t where = event_frame (event, 0, 0); + nframes_t where = event_frame (event, 0, 0); /* no action if we're recording */ @@ -886,21 +812,13 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case StreamItem: - popup_track_context_menu (1, event->button.time, item_type, false, where); - break; - case RegionItem: case RegionViewNameHighlight: case RegionViewName: - popup_track_context_menu (1, event->button.time, item_type, false, where); - break; - case SelectionItem: - popup_track_context_menu (1, event->button.time, item_type, true, where); - break; - case AutomationTrackItem: - popup_track_context_menu (1, event->button.time, item_type, false, where); + case CrossfadeViewItem: + popup_track_context_menu (1, event->button.time, where); break; case MarkerBarItem: @@ -923,11 +841,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT tm_marker_context_menu (&event->button, item); break; - case CrossfadeViewItem: - popup_track_context_menu (1, event->button.time, item_type, false, where); - break; - - /* */ +#ifdef WITH_CMT case ImageFrameItem: popup_imageframe_edit_menu(1, event->button.time, item, true) ; break ; @@ -940,8 +854,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MarkerTimeAxisItem: popup_marker_time_axis_edit_menu(1, event->button.time, item, false) ; break ; - /* */ - +#endif default: break; @@ -1035,7 +948,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MouseObject: switch (item_type) { case AutomationTrackItem: - dynamic_cast(clicked_trackview)->add_automation_event + dynamic_cast(clicked_axisview)->add_automation_event (item, event, where, @@ -1049,8 +962,12 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case MouseGain: - // FIXME - assert(dynamic_cast(clicked_regionview)); + // Gain only makes sense for audio regions + + if (!dynamic_cast(clicked_regionview)) { + break; + } + switch (item_type) { case RegionItem: dynamic_cast(clicked_regionview)->add_gain_point_event (item, event); @@ -1058,7 +975,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case AutomationTrackItem: - dynamic_cast(clicked_trackview)-> + dynamic_cast(clicked_axisview)-> add_automation_event (item, event, where, event->button.y); return true; break; @@ -1089,25 +1006,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case 2: switch (mouse_mode) { - case MouseObject: - switch (item_type) { - case RegionItem: - if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Shift)) { - raise_region (); - } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::ModifierMask (Keyboard::Shift|Keyboard::Alt))) { - lower_region (); - } else { - // Button2 click is unused - } - return true; - - break; - - default: - break; - } - break; - case MouseRange: // x_style_paste (where, 1.0); @@ -1149,7 +1047,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ at_x += 20.0; at_y += 20.0; - fraction = 1.0 - (cp->get_y() / cp->line.height()); + fraction = 1.0 - ((cp->get_y() - cp->line.y_position()) / cp->line.height()); set_verbose_canvas_cursor (cp->line.get_verbose_cursor_string (fraction), at_x, at_y); show_verbose_canvas_cursor (); @@ -1163,23 +1061,25 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case GainAutomationControlPointItem: case PanAutomationControlPointItem: case RedirectAutomationControlPointItem: - cp = static_cast(item->get_data ("control_point")); - cp->set_visible (true); - - double at_x, at_y; - at_x = cp->get_x(); - at_y = cp->get_y (); - cp->item->i2w (at_x, at_y); - at_x += 20.0; - at_y += 20.0; - - fraction = 1.0 - (cp->get_y() / cp->line.height()); - - set_verbose_canvas_cursor (cp->line.get_verbose_cursor_string (fraction), at_x, at_y); - show_verbose_canvas_cursor (); - - if (is_drawable()) { - track_canvas.get_window()->set_cursor (*fader_cursor); + if (mouse_mode == MouseGain || mouse_mode == MouseObject) { + cp = static_cast(item->get_data ("control_point")); + cp->set_visible (true); + + double at_x, at_y; + at_x = cp->get_x(); + at_y = cp->get_y (); + cp->item->i2w (at_x, at_y); + at_x += 20.0; + at_y += 20.0; + + fraction = 1.0 - (cp->get_y() / cp->line.height()); + + set_verbose_canvas_cursor (cp->line.get_verbose_cursor_string (fraction), at_x, at_y); + show_verbose_canvas_cursor (); + + if (is_drawable()) { + track_canvas.get_window()->set_cursor (*fader_cursor); + } } break; @@ -1197,13 +1097,15 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case GainAutomationLineItem: case RedirectAutomationLineItem: case PanAutomationLineItem: - { - ArdourCanvas::Line *line = dynamic_cast (item); - if (line) - line->property_fill_color_rgba() = color_map[cEnteredAutomationLine]; - } - if (is_drawable()) { - track_canvas.get_window()->set_cursor (*fader_cursor); + if (mouse_mode == MouseGain || mouse_mode == MouseObject) { + { + ArdourCanvas::Line *line = dynamic_cast (item); + if (line) + line->property_fill_color_rgba() = color_map[cEnteredAutomationLine]; + } + if (is_drawable()) { + track_canvas.get_window()->set_cursor (*fader_cursor); + } } break; @@ -1215,12 +1117,13 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case StartSelectionTrimItem: case EndSelectionTrimItem: - /* */ + +#ifdef WITH_CMT case ImageFrameHandleStartItem: case ImageFrameHandleEndItem: case MarkerViewHandleStartItem: case MarkerViewHandleEndItem: - /* */ +#endif if (is_drawable()) { track_canvas.get_window()->set_cursor (*trimmer_cursor); @@ -1370,12 +1273,14 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ case EndSelectionTrimItem: case EditCursorItem: case PlayheadCursorItem: - /* */ + +#ifdef WITH_CMT case ImageFrameHandleStartItem: case ImageFrameHandleEndItem: case MarkerViewHandleStartItem: case MarkerViewHandleEndItem: - /* */ +#endif + if (is_drawable()) { track_canvas.get_window()->set_cursor (*current_canvas_cursor); } @@ -1504,7 +1409,10 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item */ if (!drag_info.move_threshold_passed) { - drag_info.move_threshold_passed = (abs ((int) (drag_info.current_pointer_x - drag_info.grab_x)) > 4); + bool x_threshold_passed = (abs ((nframes64_t) (drag_info.current_pointer_x - drag_info.grab_x)) > 4LL); + bool y_threshold_passed = (abs ((nframes64_t) (drag_info.current_pointer_y - drag_info.grab_y)) > 4LL); + + drag_info.move_threshold_passed = (x_threshold_passed || y_threshold_passed); // and change the initial grab loc/frame if this drag info wants us to @@ -1538,12 +1446,14 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item case PanAutomationLineItem: case FadeInHandleItem: case FadeOutHandleItem: - /* */ + +#ifdef WITH_CMT case ImageFrameHandleStartItem: case ImageFrameHandleEndItem: case MarkerViewHandleStartItem: case MarkerViewHandleEndItem: - /* */ +#endif + if (drag_info.item && (event->motion.state & Gdk::BUTTON1_MASK || (event->motion.state & Gdk::BUTTON2_MASK))) { if (!from_autoscroll) { @@ -1615,7 +1525,7 @@ Editor::start_grab (GdkEvent* event, Gdk::Cursor *cursor) drag_info.y_constrained = false; } - drag_info.grab_frame = event_frame(event, &drag_info.grab_x, &drag_info.grab_y); + drag_info.grab_frame = event_frame (event, &drag_info.grab_x, &drag_info.grab_y); drag_info.last_pointer_frame = drag_info.grab_frame; drag_info.current_pointer_frame = drag_info.grab_frame; drag_info.current_pointer_x = drag_info.grab_x; @@ -1707,7 +1617,7 @@ Editor::end_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::set_edit_cursor (GdkEvent* event) { - jack_nframes_t pointer_frame = event_frame (event); + nframes_t pointer_frame = event_frame (event); if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { if (snap_type != SnapToEditCursor) { @@ -1722,7 +1632,7 @@ Editor::set_edit_cursor (GdkEvent* event) void Editor::set_playhead_cursor (GdkEvent* event) { - jack_nframes_t pointer_frame = event_frame (event); + nframes_t pointer_frame = event_frame (event); if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (pointer_frame); @@ -1749,17 +1659,17 @@ Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event) AudioRegionView* arv = static_cast(drag_info.data); - drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->audio_region().fade_in().back()->when + arv->region().position()); + drag_info.pointer_frame_offset = drag_info.grab_frame - ((nframes_t) arv->audio_region()->fade_in().back()->when + arv->region()->position()); } void Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { AudioRegionView* arv = static_cast(drag_info.data); - jack_nframes_t pos; - jack_nframes_t fade_length; + nframes_t pos; + nframes_t fade_length; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; } else { @@ -1769,18 +1679,28 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (pos); } - - if (pos < (arv->region().position() + 64)) { + + if (pos < (arv->region()->position() + 64)) { fade_length = 64; // this should be a minimum defined somewhere - } else if (pos > arv->region().last_frame()) { - fade_length = arv->region().length(); + } else if (pos > arv->region()->last_frame()) { + fade_length = arv->region()->length(); } else { - fade_length = pos - arv->region().position(); - } + fade_length = pos - arv->region()->position(); + } + /* mapover the region selection */ + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + AudioRegionView* tmp = dynamic_cast (*i); + + if (!tmp) { + continue; + } - arv->reset_fade_in_shape_width (fade_length); + tmp->reset_fade_in_shape_width (fade_length); + } - show_verbose_duration_cursor (arv->region().position(), arv->region().position() + fade_length, 10); + show_verbose_duration_cursor (arv->region()->position(), arv->region()->position() + fade_length, 10); drag_info.first_move = false; } @@ -1788,39 +1708,46 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) void Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) { - if (drag_info.first_move) return; - AudioRegionView* arv = static_cast(drag_info.data); - jack_nframes_t pos; - jack_nframes_t fade_length; + nframes_t pos; + nframes_t fade_length; + + if (drag_info.first_move) return; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - } - else { + } else { pos = 0; } - if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { - snap_to (pos); - } - - if (pos < (arv->region().position() + 64)) { + if (pos < (arv->region()->position() + 64)) { fade_length = 64; // this should be a minimum defined somewhere + } else if (pos > arv->region()->last_frame()) { + fade_length = arv->region()->length(); + } else { + fade_length = pos - arv->region()->position(); } - else if (pos > arv->region().last_frame()) { - fade_length = arv->region().length(); - } - else { - fade_length = pos - arv->region().position(); + + begin_reversible_command (_("change fade in length")); + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + AudioRegionView* tmp = dynamic_cast (*i); + + if (!tmp) { + continue; + } + + AutomationList& alist = tmp->audio_region()->fade_in(); + XMLNode &before = alist.get_state(); + + tmp->audio_region()->set_fade_in_length (fade_length); + + XMLNode &after = alist.get_state(); + session->add_command(new MementoCommand(alist, &before, &after)); } - begin_reversible_command (_("change fade in length")); - session->add_undo (arv->region().get_memento()); - arv->audio_region().set_fade_in_length (fade_length); - session->add_redo_no_execute (arv->region().get_memento()); commit_reversible_command (); - fade_in_drag_motion_callback (item, event); } void @@ -1839,40 +1766,50 @@ Editor::start_fade_out_grab (ArdourCanvas::Item* item, GdkEvent* event) AudioRegionView* arv = static_cast(drag_info.data); - drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region().length() - (jack_nframes_t) arv->audio_region().fade_out().back()->when + arv->region().position()); + drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region()->length() - (nframes_t) arv->audio_region()->fade_out().back()->when + arv->region()->position()); } void Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { AudioRegionView* arv = static_cast(drag_info.data); - jack_nframes_t pos; - jack_nframes_t fade_length; + nframes_t pos; + nframes_t fade_length; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - } - else { + } else { pos = 0; } if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (pos); } - - if (pos > (arv->region().last_frame() - 64)) { + + if (pos > (arv->region()->last_frame() - 64)) { fade_length = 64; // this should really be a minimum fade defined somewhere } - else if (pos < arv->region().position()) { - fade_length = arv->region().length(); + else if (pos < arv->region()->position()) { + fade_length = arv->region()->length(); } else { - fade_length = arv->region().last_frame() - pos; + fade_length = arv->region()->last_frame() - pos; } + + /* mapover the region selection */ + + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + AudioRegionView* tmp = dynamic_cast (*i); + + if (!tmp) { + continue; + } - arv->reset_fade_out_shape_width (fade_length); + tmp->reset_fade_out_shape_width (fade_length); + } - show_verbose_duration_cursor (arv->region().last_frame() - fade_length, arv->region().last_frame(), 10); + show_verbose_duration_cursor (arv->region()->last_frame() - fade_length, arv->region()->last_frame(), 10); drag_info.first_move = false; } @@ -1883,10 +1820,10 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve if (drag_info.first_move) return; AudioRegionView* arv = static_cast(drag_info.data); - jack_nframes_t pos; - jack_nframes_t fade_length; + nframes_t pos; + nframes_t fade_length; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; } else { @@ -1897,23 +1834,36 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve snap_to (pos); } - if (pos > (arv->region().last_frame() - 64)) { + if (pos > (arv->region()->last_frame() - 64)) { fade_length = 64; // this should really be a minimum fade defined somewhere } - else if (pos < arv->region().position()) { - fade_length = arv->region().length(); + else if (pos < arv->region()->position()) { + fade_length = arv->region()->length(); } else { - fade_length = arv->region().last_frame() - pos; + fade_length = arv->region()->last_frame() - pos; } begin_reversible_command (_("change fade out length")); - session->add_undo (arv->region().get_memento()); - arv->audio_region().set_fade_out_length (fade_length); - session->add_redo_no_execute (arv->region().get_memento()); - commit_reversible_command (); - fade_out_drag_motion_callback (item, event); + for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + + AudioRegionView* tmp = dynamic_cast (*i); + + if (!tmp) { + continue; + } + + AutomationList& alist = tmp->audio_region()->fade_out(); + XMLNode &before = alist.get_state(); + + tmp->audio_region()->set_fade_out_length (fade_length); + + XMLNode &after = alist.get_state(); + session->add_command(new MementoCommand(alist, &before, &after)); + } + + commit_reversible_command (); } void @@ -1932,10 +1882,16 @@ Editor::start_cursor_grab (ArdourCanvas::Item* item, GdkEvent* event) Cursor* cursor = (Cursor *) drag_info.data; - if (session && cursor == playhead_cursor) { - if (drag_info.was_rolling) { + if (cursor == playhead_cursor) { + _dragging_playhead = true; + + if (session && drag_info.was_rolling) { session->request_stop (); - } + } + + if (session && session->is_auditioning()) { + session->cancel_audition (); + } } drag_info.pointer_frame_offset = drag_info.grab_frame - cursor->current_frame; @@ -1947,9 +1903,9 @@ void Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { Cursor* cursor = (Cursor *) drag_info.data; - jack_nframes_t adjusted_frame; + nframes_t adjusted_frame; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; } else { @@ -1968,6 +1924,8 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (cursor == edit_cursor) { edit_cursor_clock.set (cursor->current_frame); + } else { + UpdateAllTransportClocks (cursor->current_frame); } show_verbose_time_cursor (cursor->current_frame, 10); @@ -1982,6 +1940,8 @@ Editor::cursor_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event if (drag_info.first_move) return; cursor_drag_motion_callback (item, event); + + _dragging_playhead = false; if (item == &playhead_cursor->canvas_item) { if (session) { @@ -2052,7 +2012,7 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t f_delta; + nframes_t f_delta; Marker* marker = (Marker *) drag_info.data; Location *real_location; Location *copy_location; @@ -2060,15 +2020,14 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) bool move_both = false; - jack_nframes_t newframe; - if (drag_info.pointer_frame_offset <= (long) drag_info.current_pointer_frame) { + nframes_t newframe; + if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) { newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - } - else { + } else { newframe = 0; } - jack_nframes_t next = newframe; + nframes_t next = newframe; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (newframe, 0, true); @@ -2152,7 +2111,7 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event begin_reversible_command ( _("move marker") ); - session->add_undo( session->locations()->get_memento() ); + XMLNode &before = session->locations()->get_state(); Location * location = find_location_from_marker (marker, is_start); @@ -2164,7 +2123,8 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event } } - session->add_redo_no_execute( session->locations()->get_memento() ); + XMLNode &after = session->locations()->get_state(); + session->add_command(new MementoCommand(*(session->locations()), &before, &after)); commit_reversible_command (); marker_drag_line->hide(); @@ -2239,9 +2199,9 @@ void Editor::meter_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { MeterMarker* marker = (MeterMarker *) drag_info.data; - jack_nframes_t adjusted_frame; + nframes_t adjusted_frame; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; } else { @@ -2278,9 +2238,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* if (drag_info.copy == true) { begin_reversible_command (_("copy meter mark")); - session->add_undo (map.get_memento()); + XMLNode &before = map.get_state(); map.add_meter (marker->meter(), when); - session->add_redo_no_execute (map.get_memento()); + XMLNode &after = map.get_state(); + session->add_command(new MementoCommand(map, &before, &after)); commit_reversible_command (); // delete the dummy marker we used for visual representation of copying. @@ -2288,9 +2249,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* delete marker; } else { begin_reversible_command (_("move meter mark")); - session->add_undo (map.get_memento()); + XMLNode &before = map.get_state(); map.move_meter (marker->meter(), when); - session->add_redo_no_execute (map.get_memento()); + XMLNode &after = map.get_state(); + session->add_command(new MementoCommand(map, &before, &after)); commit_reversible_command (); } } @@ -2368,9 +2330,9 @@ void Editor::tempo_marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { TempoMarker* marker = (TempoMarker *) drag_info.data; - jack_nframes_t adjusted_frame; + nframes_t adjusted_frame; - if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { adjusted_frame = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; } else { @@ -2405,12 +2367,13 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* TempoMap& map (session->tempo_map()); map.bbt_time (drag_info.last_pointer_frame, when); - + if (drag_info.copy == true) { begin_reversible_command (_("copy tempo mark")); - session->add_undo (map.get_memento()); + XMLNode &before = map.get_state(); map.add_tempo (marker->tempo(), when); - session->add_redo_no_execute (map.get_memento()); + XMLNode &after = map.get_state(); + session->add_command (new MementoCommand(map, &before, &after)); commit_reversible_command (); // delete the dummy marker we used for visual representation of copying. @@ -2418,9 +2381,10 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* delete marker; } else { begin_reversible_command (_("move tempo mark")); - session->add_undo (map.get_memento()); + XMLNode &before = map.get_state(); map.move_tempo (marker->tempo(), when); - session->add_redo_no_execute (map.get_memento()); + XMLNode &after = map.get_state(); + session->add_command (new MementoCommand(map, &before, &after)); commit_reversible_command (); } } @@ -2461,7 +2425,7 @@ void Editor::start_control_point_grab (ArdourCanvas::Item* item, GdkEvent* event) { ControlPoint* control_point; - + if ((control_point = reinterpret_cast (item->get_data ("control_point"))) == 0) { fatal << _("programming error: control point canvas item has no control point object pointer!") << endmsg; /*NOTREACHED*/ @@ -2474,9 +2438,9 @@ Editor::start_control_point_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event, fader_cursor); - control_point->line.start_drag (control_point, 0); + control_point->line.start_drag (control_point, drag_info.grab_frame, 0); - float fraction = 1.0 - (control_point->get_y() / control_point->line.height()); + float fraction = 1.0 - ((control_point->get_y() - control_point->line.y_position()) / control_point->line.height()); set_verbose_canvas_cursor (control_point->line.get_verbose_cursor_string (fraction), drag_info.current_pointer_x + 20, drag_info.current_pointer_y + 20); @@ -2505,17 +2469,17 @@ Editor::control_point_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* cx = max (0.0, cx); cy = max (0.0, cy); - cy = min ((double) cp->line.height(), cy); + cy = min ((double) (cp->line.y_position() + cp->line.height()), cy); //translate cx to frames - jack_nframes_t cx_frames = unit_to_frame (cx); + nframes_t cx_frames = unit_to_frame (cx); if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !drag_info.x_constrained) { snap_to (cx_frames); } - float fraction = 1.0 - (cy / cp->line.height()); - + float const fraction = 1.0 - ((cy - cp->line.y_position()) / cp->line.height()); + bool push; if (Keyboard::modifier_state_contains (event->button.state, Keyboard::Control)) { @@ -2581,7 +2545,7 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event) { double cx; double cy; - jack_nframes_t frame_within_region; + nframes_t frame_within_region; /* need to get x coordinate in terms of parent (TimeAxisItemView) origin. @@ -2590,7 +2554,7 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event) cx = event->button.x; cy = event->button.y; line->parent_group().w2i (cx, cy); - frame_within_region = (jack_nframes_t) floor (cx * frames_per_unit); + frame_within_region = (nframes_t) floor (cx * frames_per_unit); if (!line->control_points_adjacent (frame_within_region, current_line_drag_info.before, current_line_drag_info.after)) { @@ -2605,9 +2569,9 @@ Editor::start_line_grab (AutomationLine* line, GdkEvent* event) start_grab (event, fader_cursor); - double fraction = 1.0 - (cy / line->height()); + double const fraction = 1.0 - ((cy - line->y_position()) / line->height()); - line->start_drag (0, fraction); + line->start_drag (0, drag_info.grab_frame, fraction); set_verbose_canvas_cursor (line->get_verbose_cursor_string (fraction), drag_info.current_pointer_x + 20, drag_info.current_pointer_y + 20); @@ -2623,8 +2587,7 @@ Editor::line_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) line->parent_group().w2i (cx, cy); - double fraction; - fraction = 1.0 - (cy / line->height()); + double const fraction = 1.0 - ((cy - line->y_position()) / line->height()); bool push; @@ -2663,14 +2626,14 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event); double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; + TimeAxisView* tvp = clicked_axisview; RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); + drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); // we want a move threshold @@ -2695,20 +2658,21 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab(event); TimeAxisView* tv = &clicked_regionview->get_time_axis_view(); - RouteTimeAxisView* atv = dynamic_cast(tv); + RouteTimeAxisView* rtv = dynamic_cast(tv); double speed = 1.0; - if (atv && atv->is_audio_track()) { - speed = atv->get_diskstream()->speed(); + if (rtv && rtv->is_track()) { + speed = rtv->get_diskstream()->speed(); } drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); + drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; // we want a move threshold drag_info.want_move_threshold = true; drag_info.motion_callback = &Editor::region_drag_motion_callback; drag_info.finished_callback = &Editor::region_drag_finished_callback; + show_verbose_time_cursor (drag_info.last_frame_position, 10); } void @@ -2727,14 +2691,14 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event); double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; + TimeAxisView* tvp = clicked_axisview; RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } - drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed); + drag_info.last_frame_position = (nframes_t) (clicked_regionview->region()->position() / speed); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; drag_info.last_trackview = &clicked_regionview->get_time_axis_view(); // we want a move threshold @@ -2747,80 +2711,50 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event) void Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { - /* FIXME: type specific (audio only) */ - double x_delta; double y_delta = 0; - AudioRegionView *rv = reinterpret_cast (drag_info.data); - assert(rv); - jack_nframes_t pending_region_position = 0; + RegionView* rv = reinterpret_cast (drag_info.data); + nframes_t pending_region_position = 0; int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order; int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen bool clamp_y_axis = false; vector height_list(512) ; vector::iterator j; - show_verbose_time_cursor (drag_info.last_frame_position, 10); - if (drag_info.copy && drag_info.move_threshold_passed && drag_info.want_move_threshold) { drag_info.want_move_threshold = false; // don't copy again - /* this is committed in the grab finished callback. */ - - begin_reversible_command (_("Drag region copy")); - /* duplicate the region(s) */ - + vector new_regionviews; - set affected_playlists; - pair::iterator,bool> insert_result; - for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { RegionView* rv; - + RegionView* nrv; + rv = (*i); - - Playlist* to_playlist = rv->region().playlist(); - RouteTimeAxisView* atv = dynamic_cast(&rv->get_time_axis_view()); - - insert_result = affected_playlists.insert (to_playlist); - if (insert_result.second) { - session->add_undo (to_playlist->get_memento ()); - } - - latest_regionview = 0; - - sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); - - /* create a new region with the same name. */ - - // FIXME: ew - Region* newregion = NULL; - if (dynamic_cast(&rv->region())) - newregion = new AudioRegion (dynamic_cast(rv->region())); - else if (dynamic_cast(&rv->region())) - newregion = new MidiRegion (dynamic_cast(rv->region())); - assert(newregion); - - /* if the original region was locked, we don't care */ - - newregion->set_locked (false); - - to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * atv->get_diskstream()->speed())); - - c.disconnect (); - - if (latest_regionview) { - new_regionviews.push_back (latest_regionview); + + AudioRegionView* arv = dynamic_cast(rv); + MidiRegionView* mrv = dynamic_cast(rv); + + if (arv) { + nrv = new AudioRegionView (*arv); + } else if (mrv) { + nrv = new MidiRegionView (*mrv); + } else { + continue; } + + nrv->get_canvas_group()->show (); + + new_regionviews.push_back (nrv); } - + if (new_regionviews.empty()) { return; } - + /* reset selection to new regionviews */ selection->set (new_regionviews); @@ -2828,21 +2762,22 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* reset drag_info data to reflect the fact that we are dragging the copies */ drag_info.data = new_regionviews.front(); + swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time); } /* Which trackview is this ? */ TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y); - AudioTimeAxisView* tv = dynamic_cast(tvp); + RouteTimeAxisView* tv = dynamic_cast(tvp); /* The region motion is only processed if the pointer is over an audio track. */ - if (!tv || !tv->is_audio_track()) { + if (!tv || !tv->is_track()) { /* To make sure we hide the verbose canvas cursor when the mouse is - not held over and audiotrack. + not held over a track. */ hide_verbose_canvas_cursor (); return; @@ -2870,30 +2805,30 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { TimeAxisView *tracklist_timeview; tracklist_timeview = (*i); - AudioTimeAxisView* atv2 = dynamic_cast(tracklist_timeview); + RouteTimeAxisView* rtv2 = dynamic_cast(tracklist_timeview); list children_list; /* zeroes are audio tracks. ones are other types. */ - if (!atv2->hidden()) { + if (!rtv2->hidden()) { - if (visible_y_high < atv2->order) { - visible_y_high = atv2->order; + if (visible_y_high < rtv2->order) { + visible_y_high = rtv2->order; } - if (visible_y_low > atv2->order) { - visible_y_low = atv2->order; + if (visible_y_low > rtv2->order) { + visible_y_low = rtv2->order; } - if (!atv2->is_audio_track()) { - tracks = tracks |= (0x01 << atv2->order); + if (!rtv2->is_track()) { + tracks = tracks |= (0x01 << rtv2->order); } - height_list[atv2->order] = (*i)->height; + height_list[rtv2->order] = (*i)->height; children = 1; - if ((children_list = atv2->get_child_list()).size() > 0) { + if ((children_list = rtv2->get_child_list()).size() > 0) { for (list::iterator j = children_list.begin(); j != children_list.end(); ++j) { - tracks = tracks |= (0x01 << (atv2->order + children)); - height_list[atv2->order + children] = (*j)->height; + tracks = tracks |= (0x01 << (rtv2->order + children)); + height_list[rtv2->order + children] = (*j)->height; numtracks++; children++; } @@ -2928,27 +2863,27 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv2->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - RouteTimeAxisView* atv2 = dynamic_cast(tvp2); + RouteTimeAxisView* rtv2 = dynamic_cast(tvp2); - if (atv2->order != original_pointer_order) { + if (rtv2->order != original_pointer_order) { /* this isn't the pointer track */ if (canvas_pointer_y_span > 0) { /* moving up the canvas */ - if ((atv2->order - canvas_pointer_y_span) >= visible_y_low) { + if ((rtv2->order - canvas_pointer_y_span) >= visible_y_low) { int32_t visible_tracks = 0; while (visible_tracks < canvas_pointer_y_span ) { visible_tracks++; - while (height_list[atv2->order - (visible_tracks - n)] == 0) { + while (height_list[rtv2->order - (visible_tracks - n)] == 0) { /* we're passing through a hidden track */ n--; } } - if (tracks[atv2->order - (canvas_pointer_y_span - n)] != 0x00) { + if (tracks[rtv2->order - (canvas_pointer_y_span - n)] != 0x00) { clamp_y_axis = true; } @@ -2960,7 +2895,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /*moving down the canvas*/ - if ((atv2->order - (canvas_pointer_y_span - n)) <= visible_y_high) { // we will overflow + if ((rtv2->order - (canvas_pointer_y_span - n)) <= visible_y_high) { // we will overflow int32_t visible_tracks = 0; @@ -2968,11 +2903,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) while (visible_tracks > canvas_pointer_y_span ) { visible_tracks--; - while (height_list[atv2->order - (visible_tracks - n)] == 0) { + while (height_list[rtv2->order - (visible_tracks - n)] == 0) { n++; } } - if ( tracks[atv2->order - ( canvas_pointer_y_span - n)] != 0x00) { + if ( tracks[rtv2->order - ( canvas_pointer_y_span - n)] != 0x00) { clamp_y_axis = true; } @@ -2985,9 +2920,9 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } else { /* this is the pointer's track */ - if ((atv2->order - pointer_y_span) > visible_y_high) { // we will overflow + if ((rtv2->order - pointer_y_span) > visible_y_high) { // we will overflow clamp_y_axis = true; - } else if ((atv2->order - pointer_y_span) < visible_y_low) { // we will underflow + } else if ((rtv2->order - pointer_y_span) < visible_y_low) { // we will underflow clamp_y_axis = true; } } @@ -3015,16 +2950,16 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) if (drag_info.move_threshold_passed) { - if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { - jack_nframes_t sync_frame; - jack_nframes_t sync_offset; + nframes_t sync_frame; + nframes_t sync_offset; int32_t sync_dir; pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - - sync_offset = rv->region().sync_offset (sync_dir); - sync_frame = rv->region().adjust_to_sync (pending_region_position); + + sync_offset = rv->region()->sync_offset (sync_dir); + sync_frame = rv->region()->adjust_to_sync (pending_region_position); /* we snap if the snap modifier is not enabled. */ @@ -3043,7 +2978,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) pending_region_position = 0; } - if (pending_region_position > max_frames - rv->region().length()) { + if (pending_region_position > max_frames - rv->region()->length()) { pending_region_position = drag_info.last_frame_position; } @@ -3054,13 +2989,13 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) /* now compute the canvas unit distance we need to move the regiondrag_info.last_trackview->order to make it appear at the new location. */ - + if (pending_region_position > drag_info.last_frame_position) { x_delta = ((double) (pending_region_position - drag_info.last_frame_position) / frames_per_unit); } else { x_delta = -((double) (drag_info.last_frame_position - pending_region_position) / frames_per_unit); } - + drag_info.last_frame_position = pending_region_position; } else { @@ -3084,6 +3019,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) return; } + if (x_delta < 0) { for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { @@ -3106,161 +3042,162 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) MOTION ************************************************************/ - pair::iterator,bool> insert_result; - const list& layered_regions = selection->regions.by_layer(); + bool do_move; - for (list::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) { + if (drag_info.first_move) { + if (drag_info.move_threshold_passed) { + do_move = true; + } else { + do_move = false; + } + } else { + do_move = true; + } + + if (do_move) { + + pair >::iterator,bool> insert_result; + const list& layered_regions = selection->regions.by_layer(); + + for (list::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) { - RegionView* rv = (*i); - double ix1, ix2, iy1, iy2; - int32_t temp_pointer_y_span = pointer_y_span; + RegionView* rv = (*i); + double ix1, ix2, iy1, iy2; + int32_t temp_pointer_y_span = pointer_y_span; - /* get item BBox, which will be relative to parent. so we have - to query on a child, then convert to world coordinates using - the parent. - */ + /* get item BBox, which will be relative to parent. so we have + to query on a child, then convert to world coordinates using + the parent. + */ - rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); - rv->get_canvas_group()->i2w (ix1, iy1); - TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* canvas_atv = dynamic_cast(tvp2); - AudioTimeAxisView* temp_atv; - - if ((pointer_y_span != 0) && !clamp_y_axis) { - y_delta = 0; - int32_t x = 0; - for (j = height_list.begin(); j!= height_list.end(); j++) { - if (x == canvas_atv->order) { - /* we found the track the region is on */ - if (x != original_pointer_order) { - /*this isn't from the same track we're dragging from */ - temp_pointer_y_span = canvas_pointer_y_span; - } - while (temp_pointer_y_span > 0) { - /* we're moving up canvas-wise, - so we need to find the next track height - */ - if (j != height_list.begin()) { - j--; - } - if (x != original_pointer_order) { - /* we're not from the dragged track, so ignore hidden tracks. */ - if ((*j) == 0) { - temp_pointer_y_span++; - } - } - y_delta -= (*j); - temp_pointer_y_span--; - } - while (temp_pointer_y_span < 0) { - y_delta += (*j); - if (x != original_pointer_order) { - if ((*j) == 0) { - temp_pointer_y_span--; + rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); + rv->get_canvas_group()->i2w (ix1, iy1); + TimeAxisView* tvp2 = trackview_by_y_position (iy1); + RouteTimeAxisView* canvas_rtv = dynamic_cast(tvp2); + RouteTimeAxisView* temp_rtv; + + if ((pointer_y_span != 0) && !clamp_y_axis) { + y_delta = 0; + int32_t x = 0; + for (j = height_list.begin(); j!= height_list.end(); j++) { + if (x == canvas_rtv->order) { + /* we found the track the region is on */ + if (x != original_pointer_order) { + /*this isn't from the same track we're dragging from */ + temp_pointer_y_span = canvas_pointer_y_span; + } + while (temp_pointer_y_span > 0) { + /* we're moving up canvas-wise, + so we need to find the next track height + */ + if (j != height_list.begin()) { + j--; } - } + if (x != original_pointer_order) { + /* we're not from the dragged track, so ignore hidden tracks. */ + if ((*j) == 0) { + temp_pointer_y_span++; + } + } + y_delta -= (*j); + temp_pointer_y_span--; + } + while (temp_pointer_y_span < 0) { + y_delta += (*j); + if (x != original_pointer_order) { + if ((*j) == 0) { + temp_pointer_y_span--; + } + } - if (j != height_list.end()) { - j++; + if (j != height_list.end()) { + j++; + } + temp_pointer_y_span++; } - temp_pointer_y_span++; - } - /* find out where we'll be when we move and set height accordingly */ + /* find out where we'll be when we move and set height accordingly */ - tvp2 = trackview_by_y_position (iy1 + y_delta); - temp_atv = dynamic_cast(tvp2); - rv->set_height (temp_atv->height); + tvp2 = trackview_by_y_position (iy1 + y_delta); + temp_rtv = dynamic_cast(tvp2); + rv->set_y_position_and_height (0, temp_rtv->height); - /* if you un-comment the following, the region colours will follow the track colours whilst dragging, - personally, i think this can confuse things, but never mind. - */ + /* if you un-comment the following, the region colours will follow the track colours whilst dragging, + personally, i think this can confuse things, but never mind. + */ - //const GdkColor& col (temp_atv->view->get_region_color()); - //rv->set_color (const_cast(col)); - break; + //const GdkColor& col (temp_rtv->view->get_region_color()); + //rv->set_color (const_cast(col)); + break; + } + x++; } - x++; } - } - /* prevent the regionview from being moved to before - the zero position on the canvas. - */ - /* clamp */ + /* prevent the regionview from being moved to before + the zero position on the canvas. + */ + /* clamp */ - if (x_delta < 0) { - if (-x_delta > ix1) { - x_delta = -ix1; + if (x_delta < 0) { + if (-x_delta > ix1) { + x_delta = -ix1; + } + } else if ((x_delta > 0) && (rv->region()->last_frame() > max_frames - x_delta)) { + x_delta = max_frames - rv->region()->last_frame(); } - } else if ((x_delta > 0) &&(rv->region().last_frame() > max_frames - x_delta)) { - x_delta = max_frames - rv->region().last_frame(); - } - - if (drag_info.first_move) { - /* hide any dependent views */ -// rv->get_time_axis_view().hide_dependent_views (*rv); - - /* this is subtle. raising the regionview itself won't help, - because raise_to_top() just puts the item on the top of - its parent's stack. so, we need to put the trackview canvas_display group - on the top, since its parent is the whole canvas. - */ + if (drag_info.first_move) { - rv->get_canvas_group()->raise_to_top(); - rv->get_time_axis_view().canvas_display->raise_to_top(); - cursor_group->raise_to_top(); + /* hide any dependent views */ + + rv->get_time_axis_view().hide_dependent_views (*rv); + + /* this is subtle. raising the regionview itself won't help, + because raise_to_top() just puts the item on the top of + its parent's stack. so, we need to put the trackview canvas_display group + on the top, since its parent is the whole canvas. + */ + + rv->get_canvas_group()->raise_to_top(); + rv->get_time_axis_view().canvas_display->raise_to_top(); + cursor_group->raise_to_top(); - /* freeze the playlists from notifying till - the motion is done. - */ + rv->fake_set_opaque (true); + } + + if (drag_info.brushing) { + mouse_brush_insert_region (rv, pending_region_position); + } else { + rv->move (x_delta, y_delta); + } - AudioTimeAxisView* atv = dynamic_cast (&rv->get_time_axis_view()); - if (atv && atv->is_audio_track()) { - AudioPlaylist* pl = dynamic_cast(atv->get_diskstream()->playlist()); - if (pl) { - /* only freeze and capture state once */ + } /* foreach region */ - insert_result = motion_frozen_playlists.insert (pl); - if (insert_result.second) { - pl->freeze(); - session->add_undo(pl->get_memento()); - } - } - } - } + } /* if do_move */ - if (drag_info.brushing) { - mouse_brush_insert_region (rv, pending_region_position); - } else { - rv->move (x_delta, y_delta); - } - } - - if (drag_info.first_move) { + if (drag_info.first_move && drag_info.move_threshold_passed) { cursor_group->raise_to_top(); + drag_info.first_move = false; } - - drag_info.first_move = false; - + if (x_delta != 0 && !drag_info.brushing) { show_verbose_time_cursor (drag_info.last_frame_position, 10); } - } void Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t where; + nframes_t where; RegionView* rv = reinterpret_cast (drag_info.data); - pair::iterator,bool> insert_result; + pair >::iterator,bool> insert_result; bool nocommit = true; double speed; - RouteTimeAxisView* atv; + RouteTimeAxisView* rtv; bool regionview_y_movement; bool regionview_x_movement; + vector copies; /* first_move is set to false if the regionview has been moved in the motion handler. @@ -3281,134 +3218,165 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event if (drag_info.brushing) { /* all changes were made during motion event handlers */ + + if (drag_info.copy) { + for (list::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) { + copies.push_back (*i); + } + } + goto out; } /* adjust for track speed */ speed = 1.0; - atv = dynamic_cast (drag_info.last_trackview); - if (atv && atv->get_diskstream()) { - speed = atv->get_diskstream()->speed(); + rtv = dynamic_cast (drag_info.last_trackview); + if (rtv && rtv->get_diskstream()) { + speed = rtv->get_diskstream()->speed(); } - regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region().position()/speed)); + regionview_x_movement = (drag_info.last_frame_position != (nframes_t) (rv->region()->position()/speed)); regionview_y_movement = (drag_info.last_trackview != &rv->get_time_axis_view()); //printf ("last_frame: %s position is %lu %g\n", rv->get_time_axis_view().name().c_str(), drag_info.last_frame_position, speed); //printf ("last_rackview: %s \n", drag_info.last_trackview->name().c_str()); - if (regionview_y_movement) { + char* op_string; + + if (drag_info.copy) { + if (drag_info.x_constrained) { + op_string = _("fixed time region copy"); + } else { + op_string = _("region copy"); + } + } else { + if (drag_info.x_constrained) { + op_string = _("fixed time region drag"); + } else { + op_string = _("region drag"); + } + } - /* motion between tracks */ + begin_reversible_command (op_string); + + if (regionview_y_movement) { - list new_selection; - /* moved to a different audio track. */ + + vector new_selection; for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) { - - RegionView* rv2 = (*i); - - /* the region that used to be in the old playlist is not - moved to the new one - we make a copy of it. as a result, - any existing editor for the region should no longer be - visible. - */ - - if (!drag_info.copy) { - rv2->hide_region_editor(); - } - new_selection.push_back (rv2); - i++; - } - - /* first, freeze the target tracks */ - - for (list::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { + + RegionView* rv = (*i); - Playlist* from_playlist; - Playlist* to_playlist; - double ix1, ix2, iy1, iy2; - - (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); - (*i)->get_canvas_group()->i2w (ix1, iy1); + + rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); + rv->get_canvas_group()->i2w (ix1, iy1); TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* atv2 = dynamic_cast(tvp2); - - from_playlist = (*i)->region().playlist(); - to_playlist = atv2->playlist(); + RouteTimeAxisView* rtv2 = dynamic_cast(tvp2); - /* the from_playlist was frozen in the "first_move" case - of the motion handler. the insert can fail, - but that doesn't matter. it just means - we already have the playlist in the list. - */ - - motion_frozen_playlists.insert (from_playlist); + boost::shared_ptr from_playlist = rv->region()->playlist(); + boost::shared_ptr to_playlist = rtv2->playlist(); - /* only freeze the to_playlist once */ + where = (nframes_t) (unit_to_frame (ix1) * speed); + boost::shared_ptr new_region (RegionFactory::create (rv->region())); - insert_result = motion_frozen_playlists.insert(to_playlist); - if (insert_result.second) { - to_playlist->freeze(); - session->add_undo(to_playlist->get_memento()); - } + /* undo the previous hide_dependent_views so that xfades don't + disappear on copying regions + */ - } + rv->get_time_axis_view().reveal_dependent_views (*rv); - /* now do it again with the actual operations */ + if (!drag_info.copy) { + + /* the region that used to be in the old playlist is not + moved to the new one - we make a copy of it. as a result, + any existing editor for the region should no longer be + visible. + */ + + rv->hide_region_editor(); + rv->fake_set_opaque (false); + + session->add_command (new MementoCommand(*from_playlist, &from_playlist->get_state(), 0)); + from_playlist->remove_region ((rv->region())); + session->add_command (new MementoCommand(*from_playlist, 0, &from_playlist->get_state())); - for (list::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) { + } else { - Playlist* from_playlist; - Playlist* to_playlist; + /* the regionview we dragged around is a temporary copy, queue it for deletion */ - double ix1, ix2, iy1, iy2; - - (*i)->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); - (*i)->get_canvas_group()->i2w (ix1, iy1); - TimeAxisView* tvp2 = trackview_by_y_position (iy1); - AudioTimeAxisView* atv2 = dynamic_cast(tvp2); - - from_playlist = (*i)->region().playlist(); - to_playlist = atv2->playlist(); + copies.push_back (rv); + } latest_regionview = 0; - - where = (jack_nframes_t) (unit_to_frame (ix1) * speed); - Region* new_region = createRegion ((*i)->region()); - - from_playlist->remove_region (&((*i)->region())); - - sigc::connection c = atv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); - to_playlist->add_region (*new_region, where); - c.disconnect (); + sigc::connection c = rtv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + session->add_command (new MementoCommand(*to_playlist, &to_playlist->get_state(), 0)); + to_playlist->add_region (new_region, where); + session->add_command (new MementoCommand(*to_playlist, 0, &to_playlist->get_state())); + c.disconnect (); + if (latest_regionview) { - selection->add (latest_regionview); + new_selection.push_back (latest_regionview); + } + + /* OK, this is where it gets tricky. If the playlist was being used by >1 tracks, and the region + was selected in all of them, then removing it from the playlist will have removed all + trace of it from the selection (i.e. there were N regions selected, we removed 1, + but since its the same playlist for N tracks, all N tracks updated themselves, removed the + corresponding regionview, and the selection is now empty). + + this could have invalidated any and all iterators into the region selection. + + the heuristic we use here is: if the region selection is empty, break out of the loop + here. if the region selection is not empty, then restart the loop because we know that + we must have removed at least the region(view) we've just been working on as well as any + that we processed on previous iterations. + + EXCEPT .... if we are doing a copy drag, then the selection hasn't been modified and + we can just iterate. + */ + + if (drag_info.copy) { + ++i; + } else { + if (selection->regions.empty()) { + break; + } else { + i = selection->regions.by_layer().begin(); + } } } + selection->set (new_selection); + } else { /* motion within a single track */ + + list regions = selection->regions.by_layer(); + + if (drag_info.copy) { + selection->clear_regions(); + } - for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { + for (list::iterator i = regions.begin(); i != regions.end(); ++i) { rv = (*i); - if (rv->region().locked()) { + if (!rv->region()->can_move()) { continue; } - + if (regionview_x_movement) { double ownspeed = 1.0; - AudioTimeAxisView* atv = dynamic_cast (&(rv->get_time_axis_view())); + rtv = dynamic_cast (&(rv->get_time_axis_view())); - if (atv && atv->get_diskstream()) { - ownspeed = atv->get_diskstream()->speed(); + if (rtv && rtv->get_diskstream()) { + ownspeed = rtv->get_diskstream()->speed(); } /* base the new region position on the current position of the regionview.*/ @@ -3417,32 +3385,72 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event rv->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2); rv->get_canvas_group()->i2w (ix1, iy1); - where = (jack_nframes_t) (unit_to_frame (ix1) * ownspeed); + where = (nframes_t) (unit_to_frame (ix1) * ownspeed); } else { - where = rv->region().position(); + where = rv->region()->position(); } - rv->get_time_axis_view().reveal_dependent_views (*rv); + boost::shared_ptr to_playlist = rv->region()->playlist(); - /* no need to add an undo here, we did that when we added this playlist to motion_frozen playlists */ - - rv->region().set_position (where, (void *) this); + assert (to_playlist); + + /* add the undo */ + + session->add_command (new MementoCommand(*to_playlist, &to_playlist->get_state(), 0)); + + if (drag_info.copy) { + + boost::shared_ptr newregion; + boost::shared_ptr ar; + + if ((ar = boost::dynamic_pointer_cast(rv->region())) != 0) { + newregion = RegionFactory::create (ar); + } else { + /* XXX MIDI HERE drobilla */ + continue; + } + + /* add it */ + + latest_regionview = 0; + sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + to_playlist->add_region (newregion, (nframes_t) (where * rtv->get_diskstream()->speed())); + c.disconnect (); + + if (latest_regionview) { + rtv->reveal_dependent_views (*latest_regionview); + selection->add (latest_regionview); + } + + } else { + + /* just change the model */ + + rv->region()->set_position (where, (void*) this); + + } + + /* add the redo */ + + session->add_command (new MementoCommand(*to_playlist, 0, &to_playlist->get_state())); + + if (drag_info.copy) { + copies.push_back (rv); + } } } out: - for (set::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { - (*p)->thaw (); - session->add_redo_no_execute ((*p)->get_memento()); - } - - motion_frozen_playlists.clear (); - + if (!nocommit) { commit_reversible_command (); } + + for (vector::iterator x = copies.begin(); x != copies.end(); ++x) { + delete *x; + } } void @@ -3454,40 +3462,42 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) if (Keyboard::modifier_state_contains (event->state, Keyboard::Control)) { TimeAxisView* tv = &rv.get_time_axis_view(); - AudioTimeAxisView* atv = dynamic_cast(tv); + RouteTimeAxisView* rtv = dynamic_cast(tv); double speed = 1.0; - if (atv && atv->is_audio_track()) { - speed = atv->get_diskstream()->speed(); + if (rtv && rtv->is_track()) { + speed = rtv->get_diskstream()->speed(); } if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) { - align_region (rv.region(), SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), SyncPoint, (nframes_t) (edit_cursor->current_frame * speed)); } else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) { - align_region (rv.region(), End, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), End, (nframes_t) (edit_cursor->current_frame * speed)); } else { - align_region (rv.region(), Start, (jack_nframes_t) (edit_cursor->current_frame * speed)); + align_region (rv.region(), Start, (nframes_t) (edit_cursor->current_frame * speed)); } } } void -Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xpos, double ypos) +Editor::show_verbose_time_cursor (nframes_t frame, double offset, double xpos, double ypos) { char buf[128]; SMPTE::Time smpte; BBT_Time bbt; + int hours, mins; + nframes_t frame_rate; float secs; if (session == 0) { return; } - switch (ARDOUR_UI::instance()->secondary_clock.mode ()) { + switch (Profile->get_small_screen() ? ARDOUR_UI::instance()->primary_clock.mode () : ARDOUR_UI::instance()->secondary_clock.mode ()) { case AudioClock::BBT: session->bbt_time (frame, bbt); snprintf (buf, sizeof (buf), "%02" PRIu32 "|%02" PRIu32 "|%02" PRIu32, bbt.bars, bbt.beats, bbt.ticks); @@ -3499,10 +3509,14 @@ Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xp break; case AudioClock::MinSec: - /* XXX fix this to compute min/sec properly */ - session->smpte_time (frame, smpte); - secs = smpte.seconds + ((float) smpte.frames / session->smpte_frames_per_second); - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs); + /* XXX this is copied from show_verbose_duration_cursor() */ + frame_rate = session->frame_rate(); + hours = frame / (frame_rate * 3600); + frame = frame % (frame_rate * 3600); + mins = frame / (frame_rate * 60); + frame = frame % (frame_rate * 60); + secs = (float) frame / (float) frame_rate; + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); break; default: @@ -3520,12 +3534,14 @@ Editor::show_verbose_time_cursor (jack_nframes_t frame, double offset, double xp } void -Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, double offset, double xpos, double ypos) +Editor::show_verbose_duration_cursor (nframes_t start, nframes_t end, double offset, double xpos, double ypos) { char buf[128]; SMPTE::Time smpte; BBT_Time sbbt; BBT_Time ebbt; + int hours, mins; + nframes_t distance, frame_rate; float secs; Meter meter_at_start(session->tempo_map().meter_at(start)); @@ -3566,10 +3582,15 @@ Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end, break; case AudioClock::MinSec: - /* XXX fix this to compute min/sec properly */ - session->smpte_duration (end - start, smpte); - secs = smpte.seconds + ((float) smpte.frames / session->smpte_frames_per_second); - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", smpte.hours, smpte.minutes, secs); + /* XXX this stuff should be elsewhere.. */ + distance = end - start; + frame_rate = session->frame_rate(); + hours = distance / (frame_rate * 3600); + distance = distance % (frame_rate * 3600); + mins = distance / (frame_rate * 60); + distance = distance % (frame_rate * 60); + secs = (float) distance / (float) frame_rate; + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); break; default: @@ -3601,7 +3622,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) /* lets try to create new Region for the selection */ - vector new_regions; + vector > new_regions; create_region_from_selection (new_regions); if (new_regions.empty()) { @@ -3610,7 +3631,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) /* XXX fix me one day to use all new regions */ - Region* region = new_regions.front(); + boost::shared_ptr region (new_regions.front()); /* add it to the current stream/playlist. @@ -3620,7 +3641,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) */ latest_regionview = 0; - sigc::connection c = clicked_audio_trackview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); + sigc::connection c = clicked_routeview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view)); /* A selection grab currently creates two undo/redo operations, one for creating the new region and another for moving it. @@ -3628,11 +3649,12 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) begin_reversible_command (_("selection grab")); - Playlist* playlist = clicked_trackview->playlist(); + boost::shared_ptr playlist = clicked_axisview->playlist(); - session->add_undo (playlist->get_memento ()); - clicked_trackview->playlist()->add_region (*region, selection->time[clicked_selection].start); - session->add_redo_no_execute (playlist->get_memento ()); + XMLNode *before = &(playlist->get_state()); + clicked_routeview->playlist()->add_region (region, selection->time[clicked_selection].start); + XMLNode *after = &(playlist->get_state()); + session->add_command(new MementoCommand(*playlist, before, after)); commit_reversible_command (); @@ -3654,8 +3676,8 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event) start_grab (event); - drag_info.last_trackview = clicked_trackview; - drag_info.last_frame_position = latest_regionview->region().position(); + drag_info.last_trackview = clicked_axisview; + drag_info.last_frame_position = latest_regionview->region()->position(); drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position; show_verbose_time_cursor (drag_info.last_frame_position, 10); @@ -3676,8 +3698,8 @@ Editor::cancel_selection () void Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, SelectionOp op) { - jack_nframes_t start = 0; - jack_nframes_t end = 0; + nframes_t start = 0; + nframes_t end = 0; if (session == 0) { return; @@ -3700,8 +3722,8 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection break; case SelectionStartTrim: - if (clicked_trackview) { - clicked_trackview->order_selection_trims (item, true); + if (clicked_axisview) { + clicked_axisview->order_selection_trims (item, true); } start_grab (event, trimmer_cursor); start = selection->time[clicked_selection].start; @@ -3709,8 +3731,8 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection break; case SelectionEndTrim: - if (clicked_trackview) { - clicked_trackview->order_selection_trims (item, false); + if (clicked_axisview) { + clicked_axisview->order_selection_trims (item, false); } start_grab (event, trimmer_cursor); end = selection->time[clicked_selection].end; @@ -3734,15 +3756,14 @@ Editor::start_selection_op (ArdourCanvas::Item* item, GdkEvent* event, Selection void Editor::drag_selection (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t start = 0; - jack_nframes_t end = 0; - jack_nframes_t length; - jack_nframes_t pending_position; + nframes_t start = 0; + nframes_t end = 0; + nframes_t length; + nframes_t pending_position; - if ((int32_t) drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { + if (drag_info.current_pointer_frame > drag_info.pointer_frame_offset) { pending_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset; - } - else { + } else { pending_position = 0; } @@ -3785,7 +3806,7 @@ Editor::drag_selection (ArdourCanvas::Item* item, GdkEvent* event) drag_info.copy = false; } else { /* new selection-> */ - clicked_selection = selection->set (clicked_trackview, start, end); + clicked_selection = selection->set (clicked_axisview, start, end); } } break; @@ -3889,19 +3910,17 @@ void Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event) { double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast(tvp); + TimeAxisView* tvp = clicked_axisview; + RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } - jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region().position() / speed); - jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region().last_frame() / speed); - jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region().length() / speed); + nframes_t region_start = (nframes_t) (clicked_regionview->region()->position() / speed); + nframes_t region_end = (nframes_t) (clicked_regionview->region()->last_frame() / speed); + nframes_t region_length = (nframes_t) (clicked_regionview->region()->length() / speed); - motion_frozen_playlists.clear(); - //drag_info.item = clicked_regionview->get_name_highlight(); drag_info.item = item; drag_info.motion_callback = &Editor::trim_motion_callback; @@ -3939,7 +3958,7 @@ void Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) { RegionView* rv = clicked_regionview; - jack_nframes_t frame_delta = 0; + nframes_t frame_delta = 0; bool left_direction; bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()); @@ -3949,11 +3968,11 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) */ double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; + TimeAxisView* tvp = clicked_axisview; RouteTimeAxisView* tv = dynamic_cast(tvp); - pair::iterator,bool> insert_result; + pair >::iterator,bool> insert_result; - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } @@ -3990,16 +4009,17 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) begin_reversible_command (trim_type); for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - (*i)->region().freeze (); + (*i)->fake_set_opaque(false); + (*i)->region()->freeze (); AudioRegionView* const arv = dynamic_cast(*i); if (arv) arv->temporarily_hide_envelope (); - Playlist * pl = (*i)->region().playlist(); + boost::shared_ptr pl = (*i)->region()->playlist(); insert_result = motion_frozen_playlists.insert (pl); if (insert_result.second) { - session->add_undo (pl->get_memento()); + session->add_command(new MementoCommand(*pl, &pl->get_state(), 0)); } } } @@ -4012,7 +4032,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) switch (trim_op) { case StartTrim: - if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region().first_frame()/speed)) { + if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region()->first_frame()/speed)) { break; } else { for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { @@ -4022,7 +4042,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } case EndTrim: - if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region().last_frame()/speed))) { + if ((left_direction == true) && (drag_info.current_pointer_frame > (nframes_t) (rv->region()->last_frame()/speed))) { break; } else { for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { @@ -4050,10 +4070,10 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) switch (trim_op) { case StartTrim: - show_verbose_time_cursor((jack_nframes_t) (rv->region().position()/speed), 10); + show_verbose_time_cursor((nframes_t) (rv->region()->position()/speed), 10); break; case EndTrim: - show_verbose_time_cursor((jack_nframes_t) (rv->region().last_frame()/speed), 10); + show_verbose_time_cursor((nframes_t) (rv->region()->last_frame()/speed), 10); break; case ContentsTrim: show_verbose_time_cursor(drag_info.current_pointer_frame, 10); @@ -4065,108 +4085,108 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::single_contents_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap) +Editor::single_contents_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap) { - Region& region (rv.region()); + boost::shared_ptr region (rv.region()); - if (region.locked()) { + if (region->locked()) { return; } - jack_nframes_t new_bound; + nframes_t new_bound; double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; + TimeAxisView* tvp = clicked_axisview; RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } if (left_direction) { if (swap_direction) { - new_bound = (jack_nframes_t) (region.position()/speed) + frame_delta; + new_bound = (nframes_t) (region->position()/speed) + frame_delta; } else { - new_bound = (jack_nframes_t) (region.position()/speed) - frame_delta; + new_bound = (nframes_t) (region->position()/speed) - frame_delta; } } else { if (swap_direction) { - new_bound = (jack_nframes_t) (region.position()/speed) - frame_delta; + new_bound = (nframes_t) (region->position()/speed) - frame_delta; } else { - new_bound = (jack_nframes_t) (region.position()/speed) + frame_delta; + new_bound = (nframes_t) (region->position()/speed) + frame_delta; } } if (obey_snap) { snap_to (new_bound); } - region.trim_start ((jack_nframes_t) (new_bound * speed), this); + region->trim_start ((nframes_t) (new_bound * speed), this); rv.region_changed (StartChanged); } void -Editor::single_start_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) +Editor::single_start_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap) { - Region& region (rv.region()); + boost::shared_ptr region (rv.region()); - if (region.locked()) { + if (region->locked()) { return; } - jack_nframes_t new_bound; + nframes_t new_bound; double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast(tvp); + TimeAxisView* tvp = clicked_axisview; + RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } if (left_direction) { - new_bound = (jack_nframes_t) (region.position()/speed) - frame_delta; + new_bound = (nframes_t) (region->position()/speed) - frame_delta; } else { - new_bound = (jack_nframes_t) (region.position()/speed) + frame_delta; + new_bound = (nframes_t) (region->position()/speed) + frame_delta; } if (obey_snap) { snap_to (new_bound, (left_direction ? 0 : 1)); } - region.trim_front ((jack_nframes_t) (new_bound * speed), this); + region->trim_front ((nframes_t) (new_bound * speed), this); rv.region_changed (Change (LengthChanged|PositionChanged|StartChanged)); } void -Editor::single_end_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap) +Editor::single_end_trim (RegionView& rv, nframes_t frame_delta, bool left_direction, bool obey_snap) { - Region& region (rv.region()); + boost::shared_ptr region (rv.region()); - if (region.locked()) { + if (region->locked()) { return; } - jack_nframes_t new_bound; + nframes_t new_bound; double speed = 1.0; - TimeAxisView* tvp = clicked_trackview; - AudioTimeAxisView* tv = dynamic_cast(tvp); + TimeAxisView* tvp = clicked_axisview; + RouteTimeAxisView* tv = dynamic_cast(tvp); - if (tv && tv->is_audio_track()) { + if (tv && tv->is_track()) { speed = tv->get_diskstream()->speed(); } if (left_direction) { - new_bound = (jack_nframes_t) ((region.last_frame() + 1)/speed) - frame_delta; + new_bound = (nframes_t) ((region->last_frame() + 1)/speed) - frame_delta; } else { - new_bound = (jack_nframes_t) ((region.last_frame() + 1)/speed) + frame_delta; + new_bound = (nframes_t) ((region->last_frame() + 1)/speed) + frame_delta; } if (obey_snap) { snap_to (new_bound); } - region.trim_end ((jack_nframes_t) (new_bound * speed), this); + region->trim_end ((nframes_t) (new_bound * speed), this); rv.region_changed (LengthChanged); } @@ -4184,13 +4204,14 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event) i != selection->regions.by_layer().end(); ++i) { thaw_region_after_trim (**i); + (*i)->fake_set_opaque (true); } } - for (set::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { + for (set >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) { //(*p)->thaw (); - session->add_redo_no_execute ((*p)->get_memento()); - } + session->add_command (new MementoCommand(*(*p).get(), 0, &(*p)->get_state())); + } motion_frozen_playlists.clear (); @@ -4205,7 +4226,7 @@ void Editor::point_trim (GdkEvent* event) { RegionView* rv = clicked_regionview; - jack_nframes_t new_bound = drag_info.current_pointer_frame; + nframes_t new_bound = drag_info.current_pointer_frame; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (new_bound); @@ -4222,19 +4243,23 @@ Editor::point_trim (GdkEvent* event) for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - if (!(*i)->region().locked()) { - session->add_undo ((*i)->region().playlist()->get_memento()); - (*i)->region().trim_front (new_bound, this); - session->add_redo_no_execute ((*i)->region().playlist()->get_memento()); + if (!(*i)->region()->locked()) { + boost::shared_ptr pl = (*i)->region()->playlist(); + XMLNode &before = pl->get_state(); + (*i)->region()->trim_front (new_bound, this); + XMLNode &after = pl->get_state(); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } } else { - if (!rv->region().locked()) { - session->add_undo (rv->region().playlist()->get_memento()); - rv->region().trim_front (new_bound, this); - session->add_redo_no_execute (rv->region().playlist()->get_memento()); + if (!rv->region()->locked()) { + boost::shared_ptr pl = rv->region()->playlist(); + XMLNode &before = pl->get_state(); + rv->region()->trim_front (new_bound, this); + XMLNode &after = pl->get_state(); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } @@ -4249,19 +4274,23 @@ Editor::point_trim (GdkEvent* event) for (list::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { - if (!(*i)->region().locked()) { - session->add_undo ((*i)->region().playlist()->get_memento()); - (*i)->region().trim_end (new_bound, this); - session->add_redo_no_execute ((*i)->region().playlist()->get_memento()); + if (!(*i)->region()->locked()) { + boost::shared_ptr pl = (*i)->region()->playlist(); + XMLNode &before = pl->get_state(); + (*i)->region()->trim_end (new_bound, this); + XMLNode &after = pl->get_state(); + session->add_command(new MementoCommand(*pl.get(), &before, &after)); } } } else { - if (!rv->region().locked()) { - session->add_undo (rv->region().playlist()->get_memento()); - rv->region().trim_end (new_bound, this); - session->add_redo_no_execute (rv->region().playlist()->get_memento()); + if (!rv->region()->locked()) { + boost::shared_ptr pl = rv->region()->playlist(); + XMLNode &before = pl->get_state(); + rv->region()->trim_end (new_bound, this); + XMLNode &after = pl->get_state(); + session->add_command (new MementoCommand(*pl.get(), &before, &after)); } } @@ -4276,14 +4305,15 @@ Editor::point_trim (GdkEvent* event) void Editor::thaw_region_after_trim (RegionView& rv) { - Region& region (rv.region()); + boost::shared_ptr region (rv.region()); - if (region.locked()) { + if (region->locked()) { return; } - region.thaw (_("trimmed region")); - session->add_redo_no_execute (region.playlist()->get_memento()); + region->thaw (_("trimmed region")); + XMLNode &after = region->playlist()->get_state(); + session->add_command (new MementoCommand(*(region->playlist()), 0, &after)); AudioRegionView* arv = dynamic_cast(&rv); if (arv) @@ -4343,8 +4373,8 @@ Editor::start_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event, Ran void Editor::drag_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t start = 0; - jack_nframes_t end = 0; + nframes_t start = 0; + nframes_t end = 0; ArdourCanvas::SimpleRect *crect = (range_marker_op == CreateRangeMarker) ? range_bar_drag_rect: transport_bar_drag_rect; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { @@ -4416,22 +4446,27 @@ void Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) { Location * newloc = 0; + string rangename; if (!drag_info.first_move) { drag_range_markerbar_op (item, event); switch (range_marker_op) { case CreateRangeMarker: + { begin_reversible_command (_("new range marker")); - session->add_undo (session->locations()->get_memento()); - newloc = new Location(temp_location->start(), temp_location->end(), "unnamed", Location::IsRangeMarker); + XMLNode &before = session->locations()->get_state(); + session->locations()->next_available_name(rangename,"unnamed"); + newloc = new Location(temp_location->start(), temp_location->end(), rangename, Location::IsRangeMarker); session->locations()->add (newloc, true); - session->add_redo_no_execute (session->locations()->get_memento()); + XMLNode &after = session->locations()->get_state(); + session->add_command(new MementoCommand(*(session->locations()), &before, &after)); commit_reversible_command (); range_bar_drag_rect->hide(); range_marker_drag_rect->hide(); break; + } case CreateTransportMarker: // popup menu to pick loop or punch @@ -4444,8 +4479,8 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) if (Keyboard::no_modifier_keys_pressed (&event->button)) { - jack_nframes_t start; - jack_nframes_t end; + nframes_t start; + nframes_t end; start = session->locations()->first_mark_before (drag_info.grab_frame); end = session->locations()->first_mark_after (drag_info.grab_frame); @@ -4461,8 +4496,7 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event) switch (mouse_mode) { case MouseObject: /* find the two markers on either side and then make the selection from it */ - cerr << "select between " << start << " .. " << end << endl; - select_all_within (start, end, 0.0f, FLT_MAX, Selection::Set); + select_all_within (start, end, 0.0f, FLT_MAX, track_views, Selection::Set); break; case MouseRange: @@ -4496,8 +4530,8 @@ Editor::start_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event) void Editor::drag_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t start; - jack_nframes_t end; + nframes_t start; + nframes_t end; if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { snap_to (drag_info.current_pointer_frame); @@ -4557,11 +4591,11 @@ Editor::end_mouse_zoom (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::reposition_zoom_rect (jack_nframes_t start, jack_nframes_t end) +Editor::reposition_zoom_rect (nframes_t start, nframes_t end) { double x1 = frame_to_pixel (start); double x2 = frame_to_pixel (end); - double y2 = canvas_height - 2; + double y2 = full_canvas_height - 1.0; zoom_rect->property_x1() = x1; zoom_rect->property_y1() = 1.0; @@ -4584,8 +4618,8 @@ Editor::start_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) void Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) { - jack_nframes_t start; - jack_nframes_t end; + nframes_t start; + nframes_t end; double y1; double y2; @@ -4595,16 +4629,15 @@ Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) return; } -// if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { -// snap_to (drag_info.current_pointer_frame); - -// if (drag_info.first_move) { -// snap_to (drag_info.grab_frame); -// } -// } - + if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { + if (drag_info.first_move) { + snap_to (drag_info.grab_frame); + } + snap_to (drag_info.current_pointer_frame); + } /* base start and end on initial click position */ + if (drag_info.current_pointer_frame < drag_info.grab_frame) { start = drag_info.current_pointer_frame; end = drag_info.grab_frame; @@ -4616,8 +4649,7 @@ Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) if (drag_info.current_pointer_y < drag_info.grab_y) { y1 = drag_info.current_pointer_y; y2 = drag_info.grab_y; - } - else { + } else { y2 = drag_info.current_pointer_y; y1 = drag_info.grab_y; } @@ -4664,12 +4696,12 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) Selection::Operation op = Keyboard::selection_type (event->button.state); bool commit; - begin_reversible_command (_("select regions")); + begin_reversible_command (_("rubberband selection")); if (drag_info.grab_frame < drag_info.last_pointer_frame) { - commit = select_all_within (drag_info.grab_frame, drag_info.last_pointer_frame, y1, y2, op); + commit = select_all_within (drag_info.grab_frame, drag_info.last_pointer_frame, y1, y2, track_views, op); } else { - commit = select_all_within (drag_info.last_pointer_frame, drag_info.grab_frame, y1, y2, op); + commit = select_all_within (drag_info.last_pointer_frame, drag_info.grab_frame, y1, y2, track_views, op); } if (commit) { @@ -4677,6 +4709,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event) } } else { + selection->clear_tracks(); selection->clear_regions(); selection->clear_points (); selection->clear_lines (); @@ -4694,7 +4727,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event) ArdourPrompter prompter (false); prompter.set_prompt (_("Name for region:")); - prompter.set_initial_text (clicked_regionview->region().name()); + prompter.set_initial_text (clicked_regionview->region()->name()); prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT); prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false); prompter.show_all (); @@ -4703,7 +4736,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event) string str; prompter.get_result(str); if (str.length()) { - clicked_regionview->region().set_name (str); + clicked_regionview->region()->set_name (str); } break; } @@ -4735,8 +4768,8 @@ Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event) return; } - if (drag_info.current_pointer_frame > rv->region().position()) { - rv->get_time_axis_view().show_timestretch (rv->region().position(), drag_info.current_pointer_frame); + if (drag_info.current_pointer_frame > rv->region()->position()) { + rv->get_time_axis_view().show_timestretch (rv->region()->position(), drag_info.current_pointer_frame); } drag_info.last_pointer_frame = drag_info.current_pointer_frame; @@ -4754,8 +4787,8 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event) return; } - jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region().position(); - float percentage = (float) ((double) newlen - (double) clicked_regionview->region().length()) / ((double) newlen) * 100.0f; + nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region()->position(); + float percentage = (float) ((double) newlen - (double) clicked_regionview->region()->length()) / ((double) newlen) * 100.0f; begin_reversible_command (_("timestretch")); @@ -4765,7 +4798,7 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event) } void -Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos) +Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos) { /* no brushing without a useful snap setting */ @@ -4792,26 +4825,27 @@ Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos) /* don't brush a copy over the original */ - if (pos == rv->region().position()) { + if (pos == rv->region()->position()) { return; } - RouteTimeAxisView* atv = dynamic_cast(&arv->get_time_axis_view()); + RouteTimeAxisView* rtv = dynamic_cast(&arv->get_time_axis_view()); - if (atv == 0 || !atv->is_audio_track()) { + if (rtv == 0 || !rtv->is_track()) { return; } - Playlist* playlist = atv->playlist(); - double speed = atv->get_diskstream()->speed(); + boost::shared_ptr playlist = rtv->playlist(); + double speed = rtv->get_diskstream()->speed(); - session->add_undo (playlist->get_memento()); - playlist->add_region (*(new AudioRegion (arv->audio_region())), (jack_nframes_t) (pos * speed)); - session->add_redo_no_execute (playlist->get_memento()); + XMLNode &before = playlist->get_state(); + playlist->add_region (boost::dynamic_pointer_cast (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed)); + XMLNode &after = playlist->get_state(); + session->add_command(new MementoCommand(*playlist.get(), &before, &after)); // playlist is frozen, so we have to update manually - playlist->StateChanged (Change (~0)); /* EMIT SIGNAL */ + playlist->Modified(); /* EMIT SIGNAL */ } gint