X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fregion_selection.cc;h=9ac96d682ba35db73a54687c48dbe9862593c4f4;hb=896a0a991cc44418f58903fe5dd1c58001c87314;hp=b0afa26999e5eb4fa71f346b9b7b3e6273640dc2;hpb=209d967b1bb80a9735d690d8f4f0455ecb9970ca;p=ardour.git diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc index b0afa26999..9ac96d682b 100644 --- a/gtk2_ardour/region_selection.cc +++ b/gtk2_ardour/region_selection.cc @@ -1,178 +1,219 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include -#include +#include "ardour/region.h" -#include "regionview.h" +#include "gui_thread.h" +#include "region_view.h" #include "region_selection.h" +#include "time_axis_view.h" +using namespace std; using namespace ARDOUR; -using namespace SigC; - +using namespace PBD; -bool -AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionView* b) const +/** Construct an empty RegionSelection. + */ +RegionSelection::RegionSelection () { - if (a == b) { - return false; - } else { - return a < b; - } -} + RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context()); -AudioRegionSelection::AudioRegionSelection () -{ _current_start = 0; _current_end = 0; } -AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other) +/** Copy constructor. + * @param other RegionSelection to copy. + */ +RegionSelection::RegionSelection (const RegionSelection& other) + : std::list() { + RegionView::RegionViewGoingAway.connect (death_connection, MISSING_INVALIDATOR, ui_bind (&RegionSelection::remove_it, this, _1), gui_context()); - for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { - add (*i, false); - } _current_start = other._current_start; _current_end = other._current_end; -} - + for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { + add (*i); + } +} -AudioRegionSelection& -AudioRegionSelection::operator= (const AudioRegionSelection& other) +/** operator= to set a RegionSelection to be the same as another. + * @param other Other RegionSelection. + */ +RegionSelection& +RegionSelection::operator= (const RegionSelection& other) { if (this != &other) { clear_all(); - - for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { - add (*i, false); - } _current_start = other._current_start; _current_end = other._current_end; + + for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) { + add (*i); + } } return *this; } +/** Empty this RegionSelection. + */ void -AudioRegionSelection::clear_all() +RegionSelection::clear_all() { clear(); _bylayer.clear(); + _current_start = 0; + _current_end = 0; } -bool AudioRegionSelection::contains (AudioRegionView* rv) +/** + * @param rv RegionView. + * @return true if this selection contains rv. + */ +bool RegionSelection::contains (RegionView* rv) const { - if (this->find (rv) != end()) { - return true; - } - else { - return false; - } - + return find (begin(), end(), rv) != end(); } -void -AudioRegionSelection::add (AudioRegionView* rv, bool dosort) +/** Add a region to the selection. + * @param rv Region to add. + * @return false if we already had the region, otherwise true. + */ +bool +RegionSelection::add (RegionView* rv) { - if (this->find (rv) != end()) { + if (contains (rv)) { /* we already have it */ - return; + return false; } - rv->AudioRegionViewGoingAway.connect (slot (*this, &AudioRegionSelection::remove_it)); - - if (rv->region.first_frame() < _current_start || empty()) { - _current_start = rv->region.first_frame(); + if (rv->region()->first_frame() < _current_start || empty()) { + _current_start = rv->region()->first_frame(); } - - if (rv->region.last_frame() > _current_end || empty()) { - _current_end = rv->region.last_frame(); + + if (rv->region()->last_frame() > _current_end || empty()) { + _current_end = rv->region()->last_frame(); } - - insert (rv); - // add to layer sorted list + push_back (rv); + + /* add to layer sorted list */ + add_to_layer (rv); - + + return true; } +/** Remove a region from the selection. + * @param rv Region to remove. + */ void -AudioRegionSelection::remove_it (AudioRegionView *rv) +RegionSelection::remove_it (RegionView *rv) { remove (rv); } +/** Remove a region from the selection. + * @param rv Region to remove. + * @return true if the region was in the selection, false if not. + */ bool -AudioRegionSelection::remove (AudioRegionView* rv) +RegionSelection::remove (RegionView* rv) { - AudioRegionSelection::iterator i; - - if ((i = this->find (rv)) != end()) { + RegionSelection::iterator r; - erase (i); + if ((r = find (begin(), end(), rv)) != end()) { // remove from layer sorted list _bylayer.remove (rv); - - if (empty()) { + + if (size() == 1) { + + /* this is the last one, so when we delete it + we will be empty. + */ _current_start = 0; _current_end = 0; } else { - - AudioRegion& region ((*i)->region); - if (region.first_frame() == _current_start) { - + boost::shared_ptr region ((*r)->region()); + + if (region->first_frame() == _current_start) { + /* reset current start */ - - jack_nframes_t ref = max_frames; - - for (i = begin (); i != end(); ++i) { - if (region.first_frame() < ref) { - ref = region.first_frame(); + + nframes_t ref = max_frames; + + for (RegionSelection::iterator i = begin (); i != end(); ++i) { + if (region->first_frame() < ref) { + ref = region->first_frame(); } } - + _current_start = ref; - + } - - if (region.last_frame() == _current_end) { + + if (region->last_frame() == _current_end) { /* reset current end */ - - jack_nframes_t ref = 0; - - for (i = begin (); i != end(); ++i) { - if (region.first_frame() > ref) { - ref = region.first_frame(); + + nframes_t ref = 0; + + for (RegionSelection::iterator i = begin (); i != end(); ++i) { + if (region->first_frame() > ref) { + ref = region->first_frame(); } } - + _current_end = ref; } } + erase (r); + return true; } return false; } +/** Add a region to the list sorted by layer. + * @param rv Region to add. + */ void -AudioRegionSelection::add_to_layer (AudioRegionView * rv) +RegionSelection::add_to_layer (RegionView * rv) { // insert it into layer sorted position - list::iterator i; + list::iterator i; for (i = _bylayer.begin(); i != _bylayer.end(); ++i) { - if (rv->region.layer() < (*i)->region.layer()) { + if (rv->region()->layer() < (*i)->region()->layer()) { _bylayer.insert(i, rv); return; } @@ -183,16 +224,20 @@ AudioRegionSelection::add_to_layer (AudioRegionView * rv) } struct RegionSortByTime { - bool operator() (const AudioRegionView* a, const AudioRegionView* b) { - return a->region.position() < b->region.position(); + bool operator() (const RegionView* a, const RegionView* b) const { + return a->region()->position() < b->region()->position(); } }; +/** + * @param foo List which will be filled with the selection's regions + * sorted by position. + */ void -AudioRegionSelection::by_position (list& foo) const +RegionSelection::by_position (list& foo) const { - list::const_iterator i; + list::const_iterator i; RegionSortByTime sorter; for (i = _bylayer.begin(); i != _bylayer.end(); ++i) { @@ -202,3 +247,61 @@ AudioRegionSelection::by_position (list& foo) const foo.sort (sorter); return; } + +struct RegionSortByTrack { + bool operator() (const RegionView* a, const RegionView* b) const { + + /* really, track and position */ + + if (a->get_trackview().order() == b->get_trackview().order()) { + return a->region()->position() < b->region()->position(); + } else { + return a->get_trackview().order() < b->get_trackview().order(); + } + } +}; + + +/** + * @param List which will be filled with the selection's regions + * sorted by track and position. + */ +void +RegionSelection::by_track (list& foo) const +{ + list::const_iterator i; + RegionSortByTrack sorter; + + for (i = _bylayer.begin(); i != _bylayer.end(); ++i) { + foo.push_back (*i); + } + + foo.sort (sorter); + return; +} + +/** + * @param Sort the selection by position and track. + */ +void +RegionSelection::sort_by_position_and_track () +{ + RegionSortByTrack sorter; + sort (sorter); +} + +/** + * @param tv Track. + * @return true if any of the selection's regions are on tv. + */ +bool +RegionSelection::involves (const TimeAxisView& tv) const +{ + for (RegionSelection::const_iterator i = begin(); i != end(); ++i) { + if (&(*i)->get_trackview() == &tv) { + return true; + } + } + return false; +} +