Mercurial > hg > svcore
changeset 1291:22f66068b464 subdivide-instants
Implement "Subdivide Selected Instants". Also add the relabel command to the history, which I previously forgot to do!
author | Chris Cannam |
---|---|
date | Fri, 25 Nov 2016 09:38:53 +0000 |
parents | fa574c909c3d |
children | 4b0c968a581a |
files | data/model/Labeller.h |
diffstat | 1 files changed, 62 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/data/model/Labeller.h Thu Nov 24 17:06:31 2016 +0000 +++ b/data/model/Labeller.h Fri Nov 25 09:38:53 2016 +0000 @@ -171,8 +171,14 @@ } } + /** + * Relabel all points in the given model that lie within the given + * multi-selection, according to the labelling properties of this + * labeller. Return a command that has been executed but not yet + * added to the history. + */ template <typename PointType> - void labelAll(SparseModel<PointType> &model, MultiSelection *ms) { + Command *labelAll(SparseModel<PointType> &model, MultiSelection *ms) { typename SparseModel<PointType>::PointList::iterator i; typename SparseModel<PointType>::PointList pl(model.getPoints()); @@ -215,7 +221,61 @@ prevPoint = p; } - command->finish(); + return command->finish(); + } + + /** + * For each point in the given model (except the last), if that + * point lies within the given multi-selection, add n-1 new points + * at equally spaced intervals between it and the following point. + * Return a command that has been executed but not yet added to + * the history. + */ + template <typename PointType> + Command *subdivide(SparseModel<PointType> &model, MultiSelection *ms, int n) { + + typename SparseModel<PointType>::PointList::iterator i; + typename SparseModel<PointType>::PointList pl(model.getPoints()); + + typename SparseModel<PointType>::EditCommand *command = + new typename SparseModel<PointType>::EditCommand + (&model, tr("Subdivide")); + + for (i = pl.begin(); i != pl.end(); ++i) { + + auto j = i; + // require a "next point" even if it's not in selection + if (++j == pl.end()) { + break; + } + + bool inRange = true; + if (ms) { + Selection s(ms->getContainingSelection(i->frame, false)); + if (s.isEmpty() || !s.contains(i->frame)) { + inRange = false; + } + } + if (!inRange) { + continue; + } + + PointType p(*i); + PointType nextP(*j); + + // n is the number of subdivisions, so we add n-1 new + // points equally spaced between p and nextP + + for (int m = 1; m < n; ++m) { + sv_frame_t f = p.frame + (m * (nextP.frame - p.frame)) / n; + PointType newPoint(p); + newPoint.frame = f; + newPoint.label = tr("%1.%2").arg(p.label).arg(m+1); + command->addPoint(newPoint); + } + } + + return command->finish(); } template <typename PointType>