diff options
author | David Robillard <d@drobilla.net> | 2007-01-28 17:44:13 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-01-28 17:44:13 +0000 |
commit | f9f5ec85fbfd15d0008f70d4185a84eeadfd3891 (patch) | |
tree | adb7e13707b1361604c1ec57c0ea405125a4e98e /gtk2_ardour/editor_ops.cc | |
parent | cd37c36326a165ddf6eb83c176213b0732a6db0d (diff) |
Merged with trunk R1393.
git-svn-id: svn://localhost/ardour2/branches/midi@1395 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/editor_ops.cc')
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 626 |
1 files changed, 266 insertions, 360 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index aff997a125..3a2658c204 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -757,6 +757,39 @@ Editor::cursor_to_selection_end (Cursor *cursor) } void +Editor::scroll_playhead (bool forward) +{ + nframes_t pos = playhead_cursor->current_frame; + nframes_t delta = (nframes_t) floor (current_page_frames() / 0.8); + + if (forward) { + if (pos == max_frames) { + return; + } + + if (pos < max_frames - delta) { + pos += delta ; + } else { + pos = max_frames; + } + + } else { + + if (pos == 0) { + return; + } + + if (pos > delta) { + pos -= delta; + } else { + pos = 0; + } + } + + session->request_locate (pos); +} + +void Editor::playhead_backward () { nframes_t pos; @@ -1258,311 +1291,6 @@ Editor::add_location_from_audio_region () } void -Editor::select_all_in_track (Selection::Operation op) -{ - list<Selectable *> touched; - - if (!clicked_axisview) { - return; - } - - clicked_axisview->get_selectables (0, max_frames, 0, DBL_MAX, touched); - - switch (op) { - case Selection::Toggle: - selection->add (touched); - break; - case Selection::Set: - selection->set (touched); - break; - case Selection::Extend: - /* not defined yet */ - break; - case Selection::Add: - selection->add (touched); - break; - } -} - -void -Editor::select_all (Selection::Operation op) -{ - list<Selectable *> touched; - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (0, max_frames, 0, DBL_MAX, touched); - } - begin_reversible_command (_("select all")); - switch (op) { - case Selection::Add: - case Selection::Toggle: - selection->add (touched); - break; - case Selection::Set: - selection->set (touched); - break; - case Selection::Extend: - /* not defined yet */ - break; - } - commit_reversible_command (); -} - -void -Editor::invert_selection_in_track () -{ - list<Selectable *> touched; - - if (!clicked_axisview) { - return; - } - - clicked_axisview->get_inverted_selectables (*selection, touched); - selection->set (touched); -} - -void -Editor::invert_selection () -{ - list<Selectable *> touched; - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_inverted_selectables (*selection, touched); - } - - selection->set (touched); -} - -bool -Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, Selection::Operation op) -{ - list<Selectable *> touched; - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (start, end, top, bot, touched); - } - - cerr << "select all within found " << touched.size() << endl; - - begin_reversible_command (_("select all within")); - switch (op) { - case Selection::Add: - case Selection::Toggle: - cerr << "toggle\n"; - selection->add (touched); - break; - case Selection::Set: - cerr << "set\n"; - selection->set (touched); - break; - case Selection::Extend: - cerr << "extend\n"; - /* not defined yet */ - break; - } - - cerr << "selection now has " << selection->points.size() << endl; - - commit_reversible_command (); - return !touched.empty(); -} - -void -Editor::set_selection_from_audio_region () -{ - if (selection->regions.empty()) { - return; - } - - RegionView* rv = *(selection->regions.begin()); - boost::shared_ptr<Region> region = rv->region(); - - begin_reversible_command (_("set selection from region")); - selection->set (0, region->position(), region->last_frame()); - commit_reversible_command (); - - set_mouse_mode (Editing::MouseRange, false); -} - -void -Editor::set_selection_from_punch() -{ - Location* location; - - if ((location = session->locations()->auto_punch_location()) == 0) { - return; - } - - set_selection_from_range (*location); -} - -void -Editor::set_selection_from_loop() -{ - Location* location; - - if ((location = session->locations()->auto_loop_location()) == 0) { - return; - } - set_selection_from_range (*location); -} - -void -Editor::set_selection_from_range (Location& loc) -{ - begin_reversible_command (_("set selection from range")); - selection->set (0, loc.start(), loc.end()); - commit_reversible_command (); - - set_mouse_mode (Editing::MouseRange, false); -} - -void -Editor::select_all_selectables_using_time_selection () -{ - list<Selectable *> touched; - - if (selection->time.empty()) { - return; - } - - nframes_t start = selection->time[clicked_selection].start; - nframes_t end = selection->time[clicked_selection].end; - - if (end - start < 1) { - return; - } - - for (TrackViewList::iterator iter = selection->tracks.begin(); iter != selection->tracks.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched); - } - - begin_reversible_command (_("select all from range")); - selection->set (touched); - commit_reversible_command (); -} - - -void -Editor::select_all_selectables_using_punch() -{ - Location* location = session->locations()->auto_punch_location(); - list<Selectable *> touched; - - if (location == 0 || (location->end() - location->start() <= 1)) { - return; - } - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched); - } - begin_reversible_command (_("select all from punch")); - selection->set (touched); - commit_reversible_command (); - -} - -void -Editor::select_all_selectables_using_loop() -{ - Location* location = session->locations()->auto_loop_location(); - list<Selectable *> touched; - - if (location == 0 || (location->end() - location->start() <= 1)) { - return; - } - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched); - } - begin_reversible_command (_("select all from loop")); - selection->set (touched); - commit_reversible_command (); - -} - -void -Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after) -{ - nframes_t start; - nframes_t end; - list<Selectable *> touched; - - if (after) { - begin_reversible_command (_("select all after cursor")); - start = cursor->current_frame ; - end = session->current_end_frame(); - } else { - if (cursor->current_frame > 0) { - begin_reversible_command (_("select all before cursor")); - start = 0; - end = cursor->current_frame - 1; - } else { - return; - } - } - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (start, end, 0, DBL_MAX, touched); - } - selection->set (touched); - commit_reversible_command (); -} - -void -Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cursor) -{ - nframes_t start; - nframes_t end; - list<Selectable *> touched; - bool other_cursor_is_first = cursor->current_frame > other_cursor->current_frame; - - if (cursor->current_frame == other_cursor->current_frame) { - return; - } - - begin_reversible_command (_("select all between cursors")); - if (other_cursor_is_first) { - start = other_cursor->current_frame; - end = cursor->current_frame - 1; - - } else { - start = cursor->current_frame; - end = other_cursor->current_frame - 1; - } - - for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - if ((*iter)->hidden()) { - continue; - } - (*iter)->get_selectables (start, end, 0, DBL_MAX, touched); - } - selection->set (touched); - commit_reversible_command (); -} - -void Editor::amplitude_zoom_step (bool in) { gdouble zoom = 1.0; @@ -1856,6 +1584,30 @@ Editor::edit_envelope () /* PLAYBACK */ void +Editor::transition_to_rolling (bool fwd) +{ + if (!session) { + return; + } + + switch (Config->get_slave_source()) { + case None: + case JACK: + break; + default: + /* transport controlled by the master */ + return; + } + + if (session->is_auditioning()) { + session->cancel_audition (); + return; + } + + session->request_transport_speed (fwd ? 1.0f : -1.0f); +} + +void Editor::toggle_playback (bool with_abort) { if (!session) { @@ -2166,6 +1918,8 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n nframes_t start = selection->time[clicked_selection].start; nframes_t end = selection->time[clicked_selection].end; + sort_track_selection (); + for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { boost::shared_ptr<AudioRegion> current; @@ -2196,17 +1950,22 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n void Editor::split_multichannel_region () { - vector<AudioRegion*> v; - - AudioRegionView* clicked_arv = dynamic_cast<AudioRegionView*>(clicked_regionview); - - if (!clicked_arv || clicked_arv->audio_region()->n_channels() < 2) { + if (selection->regions.empty()) { return; } - clicked_arv->audio_region()->separate_by_channel (*session, v); + vector<boost::shared_ptr<AudioRegion> > v; + + for (list<RegionView*>::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { - /* nothing else to do, really */ + AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*x); + + if (!arv || arv->audio_region()->n_channels() < 2) { + continue; + } + + (arv)->audio_region()->separate_by_channel (*session, v); + } } void @@ -2229,6 +1988,8 @@ Editor::separate_region_from_selection () boost::shared_ptr<Playlist> playlist; + sort_track_selection (); + for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { AudioTimeAxisView* atv; @@ -2337,6 +2098,8 @@ Editor::crop_region_to_selection () } else { + sort_track_selection (); + for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*i); @@ -2949,21 +2712,37 @@ struct lt_playlist { } }; +struct PlaylistMapping { + TimeAxisView* tv; + boost::shared_ptr<Playlist> pl; + + PlaylistMapping (TimeAxisView* tvp) : tv (tvp) {} +}; + void Editor::cut_copy_regions (CutCopyOp op) -{ - typedef std::map<boost::shared_ptr<AudioPlaylist>,boost::shared_ptr<AudioPlaylist> > PlaylistMapping; - PlaylistMapping pmap; - nframes_t first_position = max_frames; +{ + /* we can't use a std::map here because the ordering is important, and we can't trivially sort + a map when we want ordered access to both elements. i think. + */ + + vector<PlaylistMapping> pmap; + nframes_t first_position = max_frames; + set<PlaylistState, lt_playlist> freezelist; pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result; + + /* get ordering correct before we cut/copy */ + + selection->regions.sort_by_position_and_track (); for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + first_position = min ((*x)->region()->position(), first_position); if (op == Cut || op == Clear) { - boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist()); + boost::shared_ptr<Playlist> pl = (*x)->region()->playlist(); if (pl) { @@ -2972,67 +2751,94 @@ Editor::cut_copy_regions (CutCopyOp op) before.before = &pl->get_state(); insert_result = freezelist.insert (before); - + if (insert_result.second) { pl->freeze (); } } } + + TimeAxisView* tv = &(*x)->get_trackview(); + vector<PlaylistMapping>::iterator z; + + for (z = pmap.begin(); z != pmap.end(); ++z) { + if ((*z).tv == tv) { + break; + } + } + + if (z == pmap.end()) { + pmap.push_back (PlaylistMapping (tv)); + } } for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) { - boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist()); - boost::shared_ptr<AudioPlaylist> npl; + boost::shared_ptr<Playlist> pl = (*x)->region()->playlist(); + + if (!pl) { + /* impossible, but this handles it for the future */ + continue; + } + + TimeAxisView& tv = (*x)->get_trackview(); + boost::shared_ptr<Playlist> npl; RegionSelection::iterator tmp; tmp = x; ++tmp; - if (pl) { - - PlaylistMapping::iterator pi = pmap.find (pl); - - if (pi == pmap.end()) { - // FIXME - npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, *session, "cutlist", true)); - npl->freeze(); - pmap[pl] = npl; - } else { - npl = pi->second; - } - - // FIXME - boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>((*x)->region()); - switch (op) { - case Cut: - if (!ar) break; - - npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position); - pl->remove_region (((*x)->region())); - break; - - case Copy: - if (!ar) break; - - npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position); - break; - - case Clear: - pl->remove_region (((*x)->region())); + vector<PlaylistMapping>::iterator z; + + for (z = pmap.begin(); z != pmap.end(); ++z) { + if ((*z).tv == &tv) { break; } } + + assert (z != pmap.end()); + + if (!(*z).pl) { + npl = PlaylistFactory::create (pl->data_type(), *session, "cutlist", true); + npl->freeze(); + (*z).pl = npl; + } else { + npl = (*z).pl; + } + + boost::shared_ptr<Region> r = (*x)->region(); + + switch (op) { + case Cut: + if (!r) break; + + npl->add_region (RegionFactory::create (r), r->position() - first_position); + pl->remove_region (r); + break; + + case Copy: + if (!r) break; + + npl->add_region (RegionFactory::create (r), r->position() - first_position); + break; + + case Clear: + pl->remove_region (r); + break; + } x = tmp; } - + list<boost::shared_ptr<Playlist> > foo; - - for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) { - foo.push_back (i->second); + + /* the pmap is in the same order as the tracks in which selected regions occured */ + + for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) { + (*i).pl->thaw(); + foo.push_back ((*i).pl); } - + if (!foo.empty()) { cut_buffer->set (foo); } @@ -3096,15 +2902,19 @@ Editor::paste_internal (nframes_t position, float times) TrackSelection::iterator i; size_t nth; + /* get everything in the correct order */ + + sort_track_selection (); + for (nth = 0, i = selection->tracks.begin(); i != selection->tracks.end(); ++i, ++nth) { - + /* undo/redo is handled by individual tracks */ if ((*i)->paste (position, times, *cut_buffer, nth)) { commit = true; } } - + if (commit) { commit_reversible_command (); } @@ -3130,6 +2940,8 @@ Editor::paste_named_selection (float times) chunk = ns->playlists.begin(); begin_reversible_command (_("paste chunk")); + + sort_track_selection (); for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) { @@ -3242,8 +3054,6 @@ Editor::reset_point_selection () { /* reset all selected points to the relevant default value */ - cerr << "point selection has " << selection->points.size() << " entries\n"; - for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) { AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track); @@ -3610,3 +3420,99 @@ Editor::toggle_region_opaque () } } } + +void +Editor::set_fade_in_shape (AudioRegion::FadeShape shape) +{ + begin_reversible_command (_("set fade in shape")); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x); + + if (!tmp) { + return; + } + + AutomationList& alist = tmp->audio_region()->fade_in(); + XMLNode &before = alist.get_state(); + + tmp->audio_region()->set_fade_in_shape (shape); + + XMLNode &after = alist.get_state(); + session->add_command(new MementoCommand<AutomationList>(alist, &before, &after)); + } + + commit_reversible_command (); +} + +void +Editor::set_fade_out_shape (AudioRegion::FadeShape shape) +{ + begin_reversible_command (_("set fade out shape")); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x); + + if (!tmp) { + return; + } + + AutomationList& alist = tmp->audio_region()->fade_out(); + XMLNode &before = alist.get_state(); + + tmp->audio_region()->set_fade_out_shape (shape); + + XMLNode &after = alist.get_state(); + session->add_command(new MementoCommand<AutomationList>(alist, &before, &after)); + } + + commit_reversible_command (); +} + +void +Editor::set_fade_in_active (bool yn) +{ + begin_reversible_command (_("set fade in active")); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x); + + if (!tmp) { + return; + } + + + boost::shared_ptr<AudioRegion> ar (tmp->audio_region()); + + XMLNode &before = ar->get_state(); + + ar->set_fade_in_active (yn); + + XMLNode &after = ar->get_state(); + session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after)); + } +} + +void +Editor::set_fade_out_active (bool yn) +{ + begin_reversible_command (_("set fade out active")); + + for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) { + AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x); + + if (!tmp) { + return; + } + + boost::shared_ptr<AudioRegion> ar (tmp->audio_region()); + + XMLNode &before = ar->get_state(); + + ar->set_fade_out_active (yn); + + XMLNode &after = ar->get_state(); + session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after)); + } +} + |