fix #279182: layout of cross-staff slurs and ties
This commit is contained in:
parent
745aee8c6a
commit
f1ccc25997
5 changed files with 73 additions and 7 deletions
|
@ -3665,8 +3665,15 @@ void Score::layoutSystemElements(System* system, LayoutContext& lc)
|
|||
sp->computeEndElement();
|
||||
lc.processedSpanners.insert(sp);
|
||||
if (sp->tick() < etick && sp->tick2() >= stick) {
|
||||
if (sp->isSlur())
|
||||
if (sp->isSlur()) {
|
||||
// skip cross-staff slurs
|
||||
ChordRest* scr = sp->startCR();
|
||||
ChordRest* ecr = sp->endCR();
|
||||
int idx = sp->vStaffIdx();
|
||||
if (scr && ecr && (scr->vStaffIdx() != idx || ecr->vStaffIdx() != idx))
|
||||
continue;
|
||||
spanner.push_back(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
processLines(system, spanner, false);
|
||||
|
|
|
@ -641,6 +641,7 @@ void Measure::layout2()
|
|||
// layout ties
|
||||
//---------------------------------------------------
|
||||
|
||||
Fraction stick = system()->measures().front()->tick();
|
||||
int tracks = score()->ntracks();
|
||||
static const SegmentType st { SegmentType::ChordRest };
|
||||
for (int track = 0; track < tracks; ++track) {
|
||||
|
@ -656,9 +657,18 @@ void Measure::layout2()
|
|||
if (cr->isChord()) {
|
||||
Chord* c = toChord(cr);
|
||||
for (const Note* note : c->notes()) {
|
||||
Tie* tie = note->tieFor();
|
||||
if (tie)
|
||||
tie->layout();
|
||||
Tie* t = note->tieFor();
|
||||
if (t) {
|
||||
TieSegment* ts = t->layoutFor(system());
|
||||
//system->staff(ch->staffIdx())->skyline().add(ts->shape().translated(ts->pos()));
|
||||
}
|
||||
t = note->tieBack();
|
||||
if (t) {
|
||||
if (t->startNote()->tick() < stick) {
|
||||
TieSegment* ts = t->layoutBack(system());
|
||||
//system->staff(ch->staffIdx())->skyline().add(ts->shape().translated(ts->pos()));
|
||||
}
|
||||
}
|
||||
for (Spanner* sp : note->spannerFor())
|
||||
sp->layout();
|
||||
}
|
||||
|
|
|
@ -596,6 +596,16 @@ void Slur::slurPos(SlurPos* sp)
|
|||
sp->p1 = scr->pos() + scr->segment()->pos() + scr->measure()->pos();
|
||||
sp->p2 = ecr->pos() + ecr->segment()->pos() + ecr->measure()->pos();
|
||||
|
||||
// adjust for cross-staff
|
||||
if (scr->vStaffIdx() != vStaffIdx() && sp->system1) {
|
||||
qreal diff = sp->system1->staff(scr->vStaffIdx())->y() - sp->system1->staff(vStaffIdx())->y();
|
||||
sp->p1.ry() += diff;
|
||||
}
|
||||
if (ecr->vStaffIdx() != vStaffIdx() && sp->system2) {
|
||||
qreal diff = sp->system2->staff(ecr->vStaffIdx())->y() - sp->system2->staff(vStaffIdx())->y();
|
||||
sp->p2.ry() += diff;
|
||||
}
|
||||
|
||||
// account for centering or other adjustments (other than mirroring)
|
||||
if (note1 && !note1->mirror())
|
||||
sp->p1.rx() += note1->x();
|
||||
|
|
|
@ -633,6 +633,29 @@ void System::layout2()
|
|||
}
|
||||
staffIdx += nstaves;
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
// layout cross-staff slurs and ties
|
||||
//---------------------------------------------------
|
||||
|
||||
Fraction stick = measures().front()->tick();
|
||||
Fraction etick = measures().back()->endTick();
|
||||
auto spanners = score()->spannerMap().findOverlapping(stick.ticks(), etick.ticks());
|
||||
|
||||
std::vector<Spanner*> spanner;
|
||||
for (auto interval : spanners) {
|
||||
Spanner* sp = interval.value;
|
||||
if (sp->tick() < etick && sp->tick2() >= stick) {
|
||||
if (sp->isSlur()) {
|
||||
ChordRest* scr = sp->startCR();
|
||||
ChordRest* ecr = sp->endCR();
|
||||
int idx = sp->vStaffIdx();
|
||||
if (scr && ecr && (scr->vStaffIdx() != idx || ecr->vStaffIdx() != idx))
|
||||
sp->layoutSystem(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -491,13 +491,29 @@ void Tie::slurPos(SlurPos* sp)
|
|||
sp->system2 = ec->measure()->system();
|
||||
|
||||
hw = endNote()->tabHeadWidth(stt);
|
||||
if ((ec->notes().size() > 1) || (ec->stem() && !ec->up() && !_up))
|
||||
if ((ec->notes().size() > 1) || (ec->stem() && !ec->up() && !_up)) {
|
||||
xo = endNote()->x() - hw * 0.12;
|
||||
else if (shortStart)
|
||||
yo = endNote()->pos().y() + yOffInside;
|
||||
}
|
||||
else if (shortStart) {
|
||||
xo = endNote()->x() + hw * 0.15;
|
||||
else
|
||||
yo = endNote()->pos().y() + yOffOutside;
|
||||
}
|
||||
else {
|
||||
xo = endNote()->x() + hw * 0.35;
|
||||
yo = endNote()->pos().y() + yOffOutside;
|
||||
}
|
||||
sp->p2 += QPointF(xo, yo);
|
||||
|
||||
// adjust for cross-staff
|
||||
if (sc->vStaffIdx() != vStaffIdx() && sp->system1) {
|
||||
qreal diff = sp->system1->staff(sc->vStaffIdx())->y() - sp->system1->staff(vStaffIdx())->y();
|
||||
sp->p1.ry() += diff;
|
||||
}
|
||||
if (ec->vStaffIdx() != vStaffIdx() && sp->system2) {
|
||||
qreal diff = sp->system2->staff(ec->vStaffIdx())->y() - sp->system2->staff(vStaffIdx())->y();
|
||||
sp->p2.ry() += diff;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue