Fix #15022 and 29526 - Improve layout of grace notes after chord
An attempt to improve the layout of grace notes after chord. It probably does not cover all the possible interactions with other score elements, particularly in tight scores, but it should achieve reasonable results for common cases with a rather simple algorithm. For some discussion and examples, see the original issue at http://musescore.org/en/node/15022 and the forum thread at http://musescore.org/en/node/45346
This commit is contained in:
parent
a78eec8ad7
commit
1d070a3e96
3 changed files with 47 additions and 26 deletions
|
@ -1553,6 +1553,41 @@ void Chord::layout2()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// position after-chord grace notes
|
||||
// room for them has been reserved in Chord::layout()
|
||||
//
|
||||
|
||||
QList<Chord*> graceNotesAfter;
|
||||
int gna = getGraceNotesAfter(&graceNotesAfter);
|
||||
if (gna) {
|
||||
qreal minNoteDist = score()->styleS(StyleIdx::minNoteDistance).val() * _spatium
|
||||
* score()->styleD(StyleIdx::graceNoteMag);
|
||||
// position grace notes from the rightmost to the leftmost
|
||||
// get segment (of whatever type) at the end of this chord; if none, get measure last segment
|
||||
Segment* s = measure()->tick2segment(segment()->tick() + actualTicks(), Segment::Type::All);
|
||||
if (s == nullptr)
|
||||
s = measure()->last();
|
||||
if (s == segment()) // if our segment is the last, no adjacent segment found
|
||||
s = nullptr;
|
||||
// start from the right (if next segment found, x of it relative to this chord;
|
||||
// chord right space otherwise)
|
||||
qreal xOff = (s != nullptr) ? s->pos().x() - (segment()->pos().x() + pos().x()) : space().rw();
|
||||
// final distance: if near to another chord, leave minNoteDist at right of last grace
|
||||
// else leave note-to-barline distance;
|
||||
xOff -= (s != nullptr && s->segmentType() != Segment::Type::ChordRest)
|
||||
? score()->styleS(StyleIdx::noteBarDistance).val() * _spatium
|
||||
: minNoteDist;
|
||||
// scan grace note list from the end
|
||||
for (int i = gna-1; i >= 0; i--) {
|
||||
Chord* g = graceNotesAfter.value(i);
|
||||
xOff -= g->space().rw(); // move to left by grace note left space (incl. grace own width)
|
||||
g->rxpos() = xOff;
|
||||
xOff -= minNoteDist + g->space().lw(); // move to left by grace note right space and inter-grace distance
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -1999,34 +2034,20 @@ void Chord::layoutPitched()
|
|||
if (gnb){
|
||||
qreal xl = -(_space.lw() + minNoteDistance) - chordX;
|
||||
for (int i = gnb-1; i >= 0; --i) {
|
||||
Chord* c = graceNotesBefore.value(i);
|
||||
xl -= c->space().rw()/* * 1.2*/;
|
||||
c->setPos(xl, 0);
|
||||
xl -= c->space().lw() + minNoteDistance * graceMag;
|
||||
Chord* g = graceNotesBefore.value(i);
|
||||
xl -= g->space().rw()/* * 1.2*/;
|
||||
g->setPos(xl, 0);
|
||||
xl -= g->space().lw() + minNoteDistance * graceMag;
|
||||
}
|
||||
if (-xl > _space.lw())
|
||||
_space.setLw(-xl);
|
||||
}
|
||||
if (gna){
|
||||
// get factor for start distance after main note. Values found by testing.
|
||||
qreal fc;
|
||||
switch (durationType().type()) {
|
||||
case TDuration::DurationType::V_LONG: fc = 3.8; break;
|
||||
case TDuration::DurationType::V_BREVE: fc = 3.8; break;
|
||||
case TDuration::DurationType::V_WHOLE: fc = 3.8; break;
|
||||
case TDuration::DurationType::V_HALF: fc = 3.6; break;
|
||||
case TDuration::DurationType::V_QUARTER: fc = 2.1; break;
|
||||
case TDuration::DurationType::V_EIGHTH: fc = 1.4; break;
|
||||
case TDuration::DurationType::V_16TH: fc = 1.2; break;
|
||||
default: fc = 1;
|
||||
}
|
||||
qreal xr = fc * (_space.rw() + minNoteDistance);
|
||||
for (int i = 0; i <= gna - 1; i++) {
|
||||
Chord* c = graceNotesAfter.value(i);
|
||||
xr += c->space().lw() * (i == 0 ? 1.3 : 1);
|
||||
c->setPos(xr, 0);
|
||||
xr += c->space().rw() + minNoteDistance * graceMag;
|
||||
}
|
||||
qreal xr = _space.rw();
|
||||
for (int i = 0; i <= gna - 1; i++) {
|
||||
Chord* g = graceNotesAfter.value(i);
|
||||
xr += g->space().lw() + g->space().rw() + minNoteDistance * graceMag;
|
||||
}
|
||||
if (xr > _space.rw())
|
||||
_space.setRw(xr);
|
||||
}
|
||||
|
|
|
@ -700,11 +700,11 @@ ChordRest* Measure::findChordRest(int tick, int track)
|
|||
// tick2segment
|
||||
//---------------------------------------------------------
|
||||
|
||||
Segment* Measure::tick2segment(int tick) const
|
||||
Segment* Measure::tick2segment(int tick, Segment::Type st) const
|
||||
{
|
||||
for (Segment* s = first(); s; s = s->next()) {
|
||||
if (s->tick() == tick) {
|
||||
if (s->segmentType() == Segment::Type::ChordRest)
|
||||
if ( (s->segmentType() & st) != 0)
|
||||
return s;
|
||||
}
|
||||
if (s->tick() > tick)
|
||||
|
|
|
@ -242,7 +242,7 @@ class Measure : public MeasureBase {
|
|||
void insertStaves(int s, int e);
|
||||
|
||||
qreal tick2pos(int) const;
|
||||
Segment* tick2segment(int) const;
|
||||
Segment* tick2segment(int tick, Segment::Type st = Segment::Type::ChordRest) const;
|
||||
|
||||
void sortStaves(QList<int>& dst);
|
||||
|
||||
|
|
Loading…
Reference in a new issue