layout hairpin+dynamics update
This commit is contained in:
parent
8646f2f8a3
commit
305fad4fba
4 changed files with 104 additions and 41 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue