Port 'Cut time' code from Mixbus

Copy the 'Cut time' code from Mixbus, making a few obvious fixes to work in
A3 (e.g. nframes_t => framepos_t / framecnt_t).

Seems to work to move & remove markers, tempo & meter markers, and regions on
selected tracks.

Still TODO:
 - use existing A3 'Insert time' dialogue
 - make it respect 'No selection = all tracks'
 - rename the command to something like 'Remove time' or 'Delete time': 'Cut'
   sounds to me as if the removed range should end up on the clipboard ready
   to be pasted somewhere, which of course it doesn't.
This commit is contained in:
Colin Fletcher
2013-10-16 22:25:35 +01:00
committed by Ben Loftis
parent 17546f47b6
commit 84f0dceefb
6 changed files with 231 additions and 1 deletions

View File

@@ -323,7 +323,8 @@ class LIBARDOUR_API TempoMap : public PBD::StatefulDestructible
void change_initial_tempo (double bpm, double note_type);
void insert_time (framepos_t, framecnt_t);
bool cut_time (framepos_t where, framecnt_t amount); //returns true if anything was moved
int n_tempos () const;
int n_meters () const;

View File

@@ -1900,6 +1900,58 @@ TempoMap::insert_time (framepos_t where, framecnt_t amount)
PropertyChanged (PropertyChange ());
}
bool
TempoMap::cut_time (framepos_t where, framecnt_t amount)
{
bool moved = false;
std::list<MetricSection*> metric_kill_list;
TempoSection* last_tempo = NULL;
MeterSection* last_meter = NULL;
{
Glib::Threads::RWLock::WriterLock lm (lock);
for (Metrics::iterator i = metrics.begin(); i != metrics.end(); ++i) {
if ((*i)->frame() >= where && (*i)->frame() < where+amount) {
metric_kill_list.push_back(*i);
TempoSection *lt = dynamic_cast<TempoSection*> (*i);
if (lt)
last_tempo = lt;
MeterSection *lm = dynamic_cast<MeterSection*> (*i);
if (lm)
last_meter = lm;
}
else if ((*i)->frame() >= where) {
(*i)->set_frame ((*i)->frame() - amount);
moved = true;
}
}
//find the last TEMPO and METER metric (if any) and move it to the cut point so future stuff is correct
if (last_tempo) {
metric_kill_list.remove(last_tempo);
last_tempo->set_frame(where);
moved = true;
}
if (last_meter) {
metric_kill_list.remove(last_meter);
last_meter->set_frame(where);
moved = true;
}
//remove all the remaining metrics
for (std::list<MetricSection*>::iterator i = metric_kill_list.begin(); i != metric_kill_list.end(); ++i) {
metrics.remove(*i);
moved = true;
}
if (moved) {
recompute_map (true);
}
}
PropertyChanged (PropertyChange ());
return moved;
}
/** Add some (fractional) beats to a session frame position, and return the result in frames.
* pos can be -ve, if required.