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; rxpos() += e->width() * .5;
break; 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); // doAutoplace
if (d > -minDistance) //
setUserOff(QPointF(0.0, -d - minDistance)); // Move Dynamic up or down to avoid collisions with other elements.
} // Minimum vertical distance is one spatium.
else { //-------------------------------------------------------------------
qreal d = s1.minVerticalDistance(s2);
if (d > -minDistance) void Dynamic::doAutoplace()
setUserOff(QPointF(0.0, d + minDistance)); {
} 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 QVariant propertyDefault(P_ID id) const override;
virtual QString accessibleInfo() const override; virtual QString accessibleInfo() const override;
void doAutoplace();
}; };
} // namespace Ms } // namespace Ms

View file

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

View file

@ -2979,6 +2979,29 @@ static bool notTopBeam(ChordRest* cr)
return false; 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 // collectSystem
//--------------------------------------------------------- //---------------------------------------------------------
@ -3319,10 +3342,33 @@ System* Score::collectSystem(LayoutContext& lc)
if (e->visible()) if (e->visible())
s->staffShape(tt->staffIdx()).add(tt->shape()); 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(); e->layout();
s->staffShape(e->staffIdx()).add(e->shape()); 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) for (SpannerSegment* ss : voltaSegments)
ss->setUserYoffset(y); ss->setUserYoffset(y);
} }
for (Spanner* sp : _unmanagedSpanner) { for (Spanner* sp : _unmanagedSpanner) {
if (sp->tick() >= etick || sp->tick2() < stick) if (sp->tick() >= etick || sp->tick2() < stick)
continue; continue;