layout hairpin+dynamics update

This commit is contained in:
werner 2016-07-19 14:36:09 +02:00
parent 8646f2f8a3
commit 305fad4fba
4 changed files with 104 additions and 41 deletions

View file

@ -186,22 +186,35 @@ void Dynamic::layout()
rxpos() += e->width() * .5;
break;
}
if (autoplace()) {
qreal minDistance = spatium();
Shape s1 = s->staffShape(staffIdx()).translated(s->pos());
Shape s2 = shape().translated(s->pos());
}
}
if (placement() == Element::Placement::ABOVE) {
qreal d = s2.minVerticalDistance(s1);
if (d > -minDistance)
setUserOff(QPointF(0.0, -d - minDistance));
}
else {
qreal d = s1.minVerticalDistance(s2);
if (d > -minDistance)
setUserOff(QPointF(0.0, d + minDistance));
}
}
//-------------------------------------------------------------------
// doAutoplace
//
// Move Dynamic up or down to avoid collisions with other elements.
// Minimum vertical distance is one spatium.
//-------------------------------------------------------------------
void Dynamic::doAutoplace()
{
Segment* s = segment();
if (!(s && autoplace()))
return;
qreal minDistance = spatium();
Shape s1 = s->staffShape(staffIdx()).translated(s->pos());
Shape s2 = shape().translated(s->pos());
if (placement() == Element::Placement::ABOVE) {
qreal d = s2.minVerticalDistance(s1);
if (d > -minDistance)
rUserYoffset() = -d - minDistance;
}
else {
qreal d = s1.minVerticalDistance(s2);
if (d > -minDistance)
rUserYoffset() = d + minDistance;
}
}

View file

@ -113,6 +113,7 @@ class Dynamic : public Text {
virtual QVariant propertyDefault(P_ID id) const override;
virtual QString accessibleInfo() const override;
void doAutoplace();
};
} // namespace Ms

View file

@ -46,15 +46,7 @@ static Dynamic* lookupDynamic(Element* e)
}
}
}
if (d) {
int staffIdx = d->staffIdx();
Shape& ss = d->segment()->staffShape(staffIdx);
Shape& ms = d->measure()->staffShape(staffIdx);
QPointF spos = d->segment()->pos();
ss.remove(d->shape());
ms.remove(d->shape().translated(spos));
}
d->layout();
return d;
}
@ -64,14 +56,16 @@ static Dynamic* lookupDynamic(Element* e)
static void moveDynamic(Dynamic* d, qreal dy)
{
int staffIdx = d->staffIdx();
Shape& ss = d->segment()->staffShape(staffIdx);
Shape& ms = d->measure()->staffShape(staffIdx);
QPointF spos = d->segment()->pos();
if (d && d->autoplace()) {
int staffIdx = d->staffIdx();
Shape& ss = d->segment()->staffShape(staffIdx);
Shape& ms = d->measure()->staffShape(staffIdx);
QPointF spos = d->segment()->pos();
d->rUserYoffset() = dy;
ss.add(d->shape());
ms.add(d->shape().translated(spos));
d->rUserYoffset() = dy;
ss.add(d->shape());
ms.add(d->shape().translated(spos));
}
}
//---------------------------------------------------------
@ -203,7 +197,7 @@ void HairpinSegment::layout()
circledTip = t.map(circledTip);
QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized();
qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth));
qreal w = score()->styleP(StyleIdx::hairpinLineWidth);
setbbox(r.adjusted(-w*.5, -w*.5, w, w));
if (parent())
rypos() += score()->styleP(StyleIdx::hairpinY);
@ -212,14 +206,24 @@ void HairpinSegment::layout()
qreal minDistance = spatium() * .7;
Shape s1 = shape().translated(pos());
qreal d = system()->bottomDistance(staffIdx(), s1);
if (d > -minDistance) {
qreal dy = d + minDistance;
rUserYoffset() = dy;
if (sd && sd->autoplace())
moveDynamic(sd, dy);
if (ed && ed->autoplace())
moveDynamic(ed, dy);
qreal ymax = 0.0;
if (d > -minDistance)
ymax = d + minDistance;
if (sd) {
sd->doAutoplace();
if (sd && sd->autoplace() && sd->rUserYoffset() > ymax)
ymax = sd->rUserYoffset();
}
if (ed) {
ed->doAutoplace();
if (ed && ed->autoplace() && ed->rUserYoffset() > ymax)
ymax = ed->rUserYoffset();
}
rUserYoffset() = ymax;
moveDynamic(sd, ymax);
moveDynamic(ed, ymax);
}
else
adjustReadPos();

View file

@ -2979,6 +2979,29 @@ static bool notTopBeam(ChordRest* cr)
return false;
}
//---------------------------------------------------------
// lookupDynamic
// return Dynamic at chord e position
//---------------------------------------------------------
static Dynamic* lookupDynamic(Element* e)
{
Dynamic* d = 0;
Segment* s = 0;
if (e && e->isChord())
s = toChord(e)->segment();
if (s) {
for (Element* ee : s->annotations()) {
if (ee->isDynamic() && ee->track() == e->track()) {
d = toDynamic(ee);
break;
}
}
}
d->layout();
return d;
}
//---------------------------------------------------------
// collectSystem
//---------------------------------------------------------
@ -3319,10 +3342,33 @@ System* Score::collectSystem(LayoutContext& lc)
if (e->visible())
s->staffShape(tt->staffIdx()).add(tt->shape());
}
else if (e->visible() && (e->isRehearsalMark() || e->isDynamic() || e->isStaffText())) {
else if (e->visible() && (e->isRehearsalMark() || e->isStaffText())) {
e->layout();
s->staffShape(e->staffIdx()).add(e->shape());
}
else if (e->visible() && e->isDynamic()) {
Dynamic* d = toDynamic(e);
d->layout();
// If dynamic is at start or end of a hairpin
// don't autoplace. This is done later on layout of hairpin
// and allows horizontal alignment of dynamic and hairpin.
int tick = d->tick();
auto si = score()->spannerMap().findOverlapping(tick, tick);
for (auto is : si) {
Spanner* sp = is.value;
sp->computeStartElement();
sp->computeEndElement();
if (!sp->isHairpin()
|| !(lookupDynamic(sp->startElement()) == d
|| lookupDynamic(sp->endElement()) == d)) {
d->doAutoplace();
d->segment()->staffShape(d->staffIdx()).add(d->shape());
}
}
}
}
}
}
@ -3371,7 +3417,6 @@ System* Score::collectSystem(LayoutContext& lc)
for (SpannerSegment* ss : voltaSegments)
ss->setUserYoffset(y);
}
for (Spanner* sp : _unmanagedSpanner) {
if (sp->tick() >= etick || sp->tick2() < stick)
continue;