X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_ops.cc;h=08d6297faae3162c388f7a76b9cf411307d224b1;hb=152935e736eaf06f85bc7f5cb27337a62d95edd4;hp=e1daeca75c75dc6e20b20b991c2503e5b4abef6e;hpb=19bb2b33a89a1291451f0740739a36daebe00bae;p=ardour.git diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index e1daeca75c..08d6297faa 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -58,37 +58,38 @@ #include "canvas/canvas.h" #include "ardour_ui.h" -#include "debug.h" -#include "editor.h" -#include "time_axis_view.h" -#include "route_time_axis.h" +#include "audio_region_view.h" +#include "audio_streamview.h" #include "audio_time_axis.h" #include "automation_time_axis.h" #include "control_point.h" -#include "streamview.h" -#include "audio_streamview.h" -#include "audio_region_view.h" -#include "midi_region_view.h" -#include "rgb_macros.h" -#include "selection_templates.h" -#include "selection.h" +#include "debug.h" #include "editing.h" -#include "gtk-custom-hruler.h" -#include "gui_thread.h" -#include "keyboard.h" -#include "utils.h" +#include "editor.h" +#include "editor_cursors.h" #include "editor_drag.h" -#include "strip_silence_dialog.h" -#include "editor_routes.h" #include "editor_regions.h" -#include "quantize_dialog.h" -#include "interthread_progress_window.h" +#include "editor_routes.h" +#include "gtk-custom-hruler.h" +#include "gui_thread.h" #include "insert_time_dialog.h" -#include "normalize_dialog.h" -#include "editor_cursors.h" +#include "interthread_progress_window.h" +#include "keyboard.h" +#include "midi_region_view.h" #include "mouse_cursors.h" +#include "normalize_dialog.h" #include "patch_change_dialog.h" +#include "quantize_dialog.h" +#include "region_gain_line.h" +#include "rgb_macros.h" +#include "route_time_axis.h" +#include "selection.h" +#include "selection_templates.h" +#include "streamview.h" +#include "strip_silence_dialog.h" +#include "time_axis_view.h" #include "transpose_dialog.h" +#include "utils.h" #include "i18n.h" @@ -511,6 +512,60 @@ Editor::nudge_backward_capture_offset () commit_reversible_command (); } +struct RegionSelectionPositionSorter { + bool operator() (RegionView* a, RegionView* b) { + return a->region()->position() < b->region()->position(); + } +}; + +void +Editor::sequence_regions () +{ + framepos_t r_end; + framepos_t r_end_prev; + + int iCount=0; + + if (!_session) { + return; + } + + RegionSelection rs = get_regions_from_selection_and_entered (); + rs.sort(RegionSelectionPositionSorter()); + + if (!rs.empty()) { + + begin_reversible_command (_("sequence regions")); + for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { + boost::shared_ptr r ((*i)->region()); + + r->clear_changes(); + + if(r->locked()) + { + continue; + } + if(r->position_locked()) + { + continue; + } + if(iCount>0) + { + r_end_prev=r_end; + r->set_position(r_end_prev); + } + + _session->add_command (new StatefulDiffCommand (r)); + + r_end=r->position() + r->length(); + + iCount++; + } + commit_reversible_command (); + } +} + + /* DISPLAY MOTION */ void @@ -1275,6 +1330,69 @@ Editor::scroll_tracks_up_line () reset_y_origin (vertical_adjustment.get_value() - 60); } +bool +Editor::scroll_down_one_track () +{ + double vertical_pos = vertical_adjustment.get_value () + vertical_adjustment.get_page_size() - 1.0; + + TrackViewList::reverse_iterator next = track_views.rend(); + std::pair res; + + for (TrackViewList::reverse_iterator t = track_views.rbegin(); t != track_views.rend(); ++t) { + if ((*t)->hidden()) { + continue; + } + + res = (*t)->covers_y_position (vertical_pos); + + if (res.first) { + break; + } + + next = t; + } + + /* move to the track below the first one that covers the */ + + if (next != track_views.rend()) { + ensure_track_visible (*next); + return true; + } + + return false; +} + +bool +Editor::scroll_up_one_track () +{ + double vertical_pos = vertical_adjustment.get_value (); + + TrackViewList::iterator prev = track_views.end(); + std::pair res; + + for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) { + + if ((*t)->hidden()) { + continue; + } + + res = (*t)->covers_y_position(vertical_pos); + + if (res.first) { + break; + } + + prev = t; + } + + if (prev != track_views.end()) { + ensure_track_visible (*prev); + return true; + } + + return false; +} + /* ZOOM */ void @@ -1391,8 +1509,12 @@ Editor::temporal_zoom (framecnt_t fpp) // Imposing an arbitrary limit to zoom out as too much zoom out produces // segfaults for lack of memory. If somebody decides this is not high enough I // believe it can be raisen to higher values but some limit must be in place. + // + // This constant represents 1 day @ 48kHz on a 1600 pixel wide display + // all of which is used for the editor track displays. The whole day + // would be 4147200000 samples, so 2592000 samples per pixel. - nfpp = min (fpp, (framecnt_t) 8589934592); + nfpp = min (fpp, (framecnt_t) 2592000); nfpp = max ((framecnt_t) 1, fpp); new_page_size = (framepos_t) floor (_visible_canvas_width * nfpp); @@ -1972,7 +2094,7 @@ Editor::insert_region_list_drag (boost::shared_ptr region, int x, int y) event.button.x = x; event.button.y = y; - where = window_event_frame (&event, &cx, &cy); + where = window_event_sample (&event, &cx, &cy); if (where < leftmost_frame || where > leftmost_frame + current_page_samples()) { /* clearly outside canvas area */ @@ -2013,7 +2135,7 @@ Editor::insert_route_list_drag (boost::shared_ptr route, int x, int y) event.button.x = x; event.button.y = y; - window_event_frame (&event, &cx, &cy); + window_event_sample (&event, &cx, &cy); std::pair const tv = trackview_by_y_position (cy); if (tv.first == 0) { @@ -2100,7 +2222,7 @@ Editor::transition_to_rolling (bool fwd) if (_session->config.get_external_sync()) { switch (Config->get_sync_source()) { - case JACK: + case Engine: break; default: /* transport controlled by the master */ @@ -3473,7 +3595,7 @@ Editor::freeze_route () /* wait for just a little while, because the above call is asynchronous */ - ::usleep (250000); + Glib::usleep (250000); if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) { return; @@ -3715,110 +3837,96 @@ Editor::cut_copy (CutCopyOp op) switch (effective_mouse_mode()) { case MouseObject: case MouseRange: + begin_reversible_command (opname + ' ' + X_("MIDI")); cut_copy_midi (op); + commit_reversible_command (); break; default: break; } - } else { + return; + } - RegionSelection rs; + bool did_edit = false; - /* we only want to cut regions if some are selected */ + switch (effective_mouse_mode()) { + case MouseGain: + if (!selection->points.empty()) { + begin_reversible_command (opname + _(" points")); + did_edit = true; + cut_copy_points (op); + if (op == Cut || op == Delete) { + selection->clear_points (); + } + } + break; + + case MouseObject: - if (!selection->regions.empty()) { - rs = selection->regions; - } + if (!selection->regions.empty() || !selection->points.empty()) { - switch (effective_mouse_mode()) { -/* - * case MouseGain: { - //find regions's gain line - AudioRegionView *rview = dynamic_cast(clicked_regionview); - AutomationTimeAxisView *tview = dynamic_cast(clicked_trackview); - if (rview) { - AudioRegionGainLine *line = rview->get_gain_line(); - if (!line) break; - - //cut region gain points in the selection - AutomationList& alist (line->the_list()); - XMLNode &before = alist.get_state(); - AutomationList* what_we_got = 0; - if ((what_we_got = alist.cut (selection->time.front().start - rview->audio_region()->position(), selection->time.front().end - rview->audio_region()->position())) != 0) { - session->add_command(new MementoCommand(alist, &before, &alist.get_state())); - delete what_we_got; - what_we_got = 0; - } - - rview->set_envelope_visible(true); - rview->audio_region()->set_envelope_active(true); - - } else if (tview) { - AutomationLine *line = *(tview->lines.begin()); - if (!line) break; - - //cut auto points in the selection - AutomationList& alist (line->the_list()); - XMLNode &before = alist.get_state(); - AutomationList* what_we_got = 0; - if ((what_we_got = alist.cut (selection->time.front().start, selection->time.front().end)) != 0) { - session->add_command(new MementoCommand(alist, &before, &alist.get_state())); - delete what_we_got; - what_we_got = 0; - } - } else - break; - } break; -*/ - case MouseObject: - case MouseRange: - if (!rs.empty() || !selection->points.empty()) { - begin_reversible_command (opname + _(" objects")); - - if (!rs.empty()) { - cut_copy_regions (op, rs); - - if (op == Cut || op == Delete) { - selection->clear_regions (); - } - } + string thing_name; - if (!selection->points.empty()) { - cut_copy_points (op); + if (selection->regions.empty()) { + thing_name = _("points"); + } else if (selection->points.empty()) { + thing_name = _("regions"); + } else { + thing_name = _("objects"); + } + + begin_reversible_command (opname + ' ' + thing_name); + did_edit = true; - if (op == Cut || op == Delete) { - selection->clear_points (); - } + if (!selection->regions.empty()) { + cut_copy_regions (op, selection->regions); + + if (op == Cut || op == Delete) { + selection->clear_regions (); } - - commit_reversible_command (); - break; - } + } - if (selection->time.empty()) { - framepos_t start, end; - if (!get_edit_op_range (start, end)) { - return; + if (!selection->points.empty()) { + cut_copy_points (op); + + if (op == Cut || op == Delete) { + selection->clear_points (); } + } + } + break; + + case MouseRange: + if (selection->time.empty()) { + framepos_t start, end; + /* no time selection, see if we can get an edit range + and use that. + */ + if (get_edit_op_range (start, end)) { selection->set (start, end); } - + } + if (!selection->time.empty()) { begin_reversible_command (opname + _(" range")); + + did_edit = true; cut_copy_ranges (op); - commit_reversible_command (); if (op == Cut || op == Delete) { selection->clear_time (); } - - break; - - default: - break; } + break; + + default: + break; } - + + if (did_edit) { + commit_reversible_command (); + } + if (op == Delete || op == Cut || op == Clear) { _drags->abort (); } @@ -4704,7 +4812,7 @@ Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv vector::Notes> v; v.push_back (selected); - framepos_t pos_frames = mrv.midi_region()->position(); + framepos_t pos_frames = mrv.midi_region()->position() - mrv.midi_region()->start(); double pos_beats = _session->tempo_map().framewalk_to_beats(0, pos_frames); return op (mrv.midi_region()->model(), pos_beats, v); @@ -4764,12 +4872,17 @@ Editor::fork_region () MidiRegionView* const mrv = dynamic_cast(*r); if (mrv) { - boost::shared_ptr playlist = mrv->region()->playlist(); - boost::shared_ptr newregion = mrv->midi_region()->clone (); - - playlist->clear_changes (); - playlist->replace_region (mrv->region(), newregion, mrv->region()->position()); - _session->add_command(new StatefulDiffCommand (playlist)); + try { + boost::shared_ptr playlist = mrv->region()->playlist(); + boost::shared_ptr new_source = _session->create_midi_source_by_stealing_name (mrv->midi_view()->track()); + boost::shared_ptr newregion = mrv->midi_region()->clone (new_source); + + playlist->clear_changes (); + playlist->replace_region (mrv->region(), newregion, mrv->region()->position()); + _session->add_command(new StatefulDiffCommand (playlist)); + } catch (...) { + error << string_compose (_("Could not unlink %1"), mrv->region()->name()) << endmsg; + } } r = tmp; @@ -5520,7 +5633,7 @@ Editor::split_region () struct EditorOrderRouteSorter { bool operator() (boost::shared_ptr a, boost::shared_ptr b) { - return a->order_key (EditorSort) < b->order_key (EditorSort); + return a->order_key () < b->order_key (); } }; @@ -6441,12 +6554,13 @@ Editor::remove_tracks () for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { RouteTimeAxisView* rtv = dynamic_cast (*x); - if (rtv) { - if (rtv->is_track()) { - ntracks++; - } else { - nbusses++; - } + if (!rtv) { + continue; + } + if (rtv->is_track()) { + ntracks++; + } else { + nbusses++; } routes.push_back (rtv->_route);