MuseScore/libmscore/spannermap.cpp
ws ec3be9a99a Replacd integer midi tick values by fractions.
- tick names a position on the time axis
- tick is always a Fraction()
- only Measure() and Segment() (and Tuplet?) have a tick value
- tick() for an generic element return only a sensible value if isMeasure() or isSegment() or isSegment(parent())

- "ticks" names a duration stored in a Fraction()
- the tick value for an Segment is relative to its measure

- rename "duration" to "ticks"
- rename afrac() to tick()
- rename rfrac() to rtick()
- rename some variables, changing "fraction" into "tick"
  (example: actualFraction() into actualTicks())

- Lyrics ticks are written as Fraction, on read if xmlreader sees a "/" it reads a fraction
  else midi ticks for backwards compatibility
2019-02-18 11:46:05 +01:00

120 lines
3.4 KiB
C++

//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2013 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include "spannermap.h"
#include "spanner.h"
namespace Ms {
//---------------------------------------------------------
// SpannerMap
//---------------------------------------------------------
SpannerMap::SpannerMap()
: std::multimap<int, Spanner*>()
{
dirty = true;
}
//---------------------------------------------------------
// update
// updates the internal lookup tree, not the map itself
//---------------------------------------------------------
void SpannerMap::update() const
{
std::vector< ::Interval<Spanner*> > intervals;
for (auto i : *this)
intervals.push_back(Interval<Spanner*>(i.second->tick().ticks(), i.second->tick2().ticks(), i.second));
tree = IntervalTree<Spanner*>(intervals);
dirty = false;
}
//---------------------------------------------------------
// findContained
//---------------------------------------------------------
const std::vector<Interval<Spanner*>>& SpannerMap::findContained(int start, int stop)
{
if (dirty)
update();
results.clear();
tree.findContained(start, stop, results);
return results;
}
//---------------------------------------------------------
// findOverlapping
//---------------------------------------------------------
const std::vector<Interval<Spanner*>>& SpannerMap::findOverlapping(int start, int stop)
{
if (dirty)
update();
results.clear();
tree.findOverlapping(start, stop, results);
return results;
}
//---------------------------------------------------------
// addSpanner
//---------------------------------------------------------
void SpannerMap::addSpanner(Spanner* s)
{
#if 0
#ifndef NDEBUG
// check if spanner already in list
for (auto i = begin(); i != end(); ++i) {
if (i->second == s) {
qFatal("SpannerMap::addSpanner: %s already in list %p", s->name(), s);
}
}
#endif
#endif
insert(std::pair<int,Spanner*>(s->tick().ticks(), s));
dirty = true;
}
//---------------------------------------------------------
// removeSpanner
//---------------------------------------------------------
bool SpannerMap::removeSpanner(Spanner* s)
{
for (auto i = begin(); i != end(); ++i) {
if (i->second == s) {
erase(i);
dirty = true;
return true;
}
}
qDebug("%s (%p) not found", s->name(), s);
return false;
}
#ifndef NDEBUG
//---------------------------------------------------------
// dump
//---------------------------------------------------------
void SpannerMap::dump() const
{
qDebug("SpannerMap::dump");
for (auto i = begin(); i != end(); ++i)
qDebug(" %5d: %s %p", i->first, i->second->name(), i->second);
}
#endif
} // namespace Ms