fix #25278: chords won't overlap barline

This commit is contained in:
Marc Sabatella 2014-04-26 19:29:13 -06:00
parent 2bf563b515
commit 2185d1c6be
3 changed files with 79 additions and 20 deletions

View file

@ -3421,8 +3421,10 @@ qreal Score::computeMinWidth(Segment* fs)
}
bool rest2[_nstaves];
bool hRest2[_nstaves];
bool spaceHarmony = false;
Segment::SegmentType segType = s->segmentType();
qreal segmentWidth = 0.0;
qreal harmonyWidth = 0.0;
qreal stretchDistance = 0.0;
int pt = pSeg ? pSeg->segmentType() : Segment::SegBarLine;
@ -3437,6 +3439,7 @@ qreal Score::computeMinWidth(Segment* fs)
bool found = false;
bool hFound = false;
bool eFound = false;
if (segType & (Segment::SegChordRest)) {
qreal llw = 0.0;
qreal rrw = 0.0;
@ -3525,11 +3528,16 @@ qreal Score::computeMinWidth(Segment* fs)
else
hBbox = b;
hFound = true;
// allow chord at the beginning of a measure to be dragged left
hSpace.max(Space(s->rtick()?-b.left():0.0, b.right()));
spaceHarmony = true;
// allow chord to be dragged
qreal xoff = h->pos().x();
qreal bl = -b.left() + qMin(xoff, 0.0);
qreal br = b.right() - qMax(xoff, 0.0);
hSpace.max(Space(bl, br));
}
}
else {
// current segment (s) is not a ChordRest
Element* e = s->element(track);
if ((segType == Segment::SegClef) && (pt != Segment::SegChordRest))
minDistance = styleP(ST_clefLeftMargin);
@ -3572,13 +3580,17 @@ qreal Score::computeMinWidth(Segment* fs)
qreal sp = 0.0;
// space chord symbols unless they miss each other vertically
if (eFound || (hBbox.top() < hLastBbox[staffIdx].bottom() && hBbox.bottom() > hLastBbox[staffIdx].top()))
if (hFound && hBbox.top() < hLastBbox[staffIdx].bottom() && hBbox.bottom() > hLastBbox[staffIdx].top())
sp = hRest[staffIdx] + minHarmonyDistance + hSpace.lw();
hLastBbox[staffIdx] = hBbox;
// barline, allocate half the width of previous harmony to this measure
else if (eFound && !hFound && spaceHarmony)
sp = hRest[staffIdx] * 0.5 + hSpace.lw(); // - styleS(ST_noteBarDistance).val() * _spatium;
hLastBbox[staffIdx] = hBbox;
hRest[staffIdx] = hSpace.rw();
hRest2[staffIdx] = false;
segmentWidth = qMax(segmentWidth, sp);
harmonyWidth = qMax(harmonyWidth, sp);
}
else
hRest2[staffIdx] = true;
@ -3586,6 +3598,10 @@ qreal Score::computeMinWidth(Segment* fs)
clefWidth[staffIdx] = 0.0;
}
// make room for harmony if needed
segmentWidth = qMax(segmentWidth, harmonyWidth);
x += segmentWidth;
// if (segmentIdx && pSeg)
@ -3595,10 +3611,11 @@ qreal Score::computeMinWidth(Segment* fs)
if (!staff(staffIdx)->show())
continue;
if (rest2[staffIdx])
rest[staffIdx] -= qMin(rest[staffIdx],segmentWidth);
rest[staffIdx] -= qMin(rest[staffIdx], segmentWidth);
if (hRest2[staffIdx])
hRest[staffIdx] -= qMin(hRest[staffIdx],segmentWidth);
hRest[staffIdx] -= qMin(hRest[staffIdx], segmentWidth);
}
//
// set pSeg only to used segments
//

View file

@ -3105,14 +3105,17 @@ void Measure::layoutX(qreal stretch)
pSeg = s;
continue;
}
bool gotHarmony = false;
bool rest2[nstaves];
bool hRest2[nstaves];
bool spaceHarmony = false;
Segment::SegmentType segType = s->segmentType();
qreal segmentWidth = 0.0;
qreal harmonyWidth = 0.0;
qreal stretchDistance = 0.0;
int pt = pSeg ? pSeg->segmentType() : Segment::SegBarLine;
#if 0
qreal firstHarmonyDistance = 0.0;
#endif
for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
if (!score()->staff(staffIdx)->show())
@ -3125,6 +3128,9 @@ void Measure::layoutX(qreal stretch)
bool found = false;
bool hFound = false;
bool eFound = false;
#if 0
qreal harmonyCarryOver = system()->firstMeasure() == this ? 0.0 : // calculate value for this staff; but how to duplicate in Score::computeMinWidth?
#endif
if (segType & (Segment::SegChordRest)) {
qreal llw = 0.0;
@ -3227,12 +3233,32 @@ void Measure::layoutX(qreal stretch)
else
hBbox = b;
hFound = true;
gotHarmony = true;
// allow chord at the beginning of a measure to be dragged left
spaceHarmony = true;
// allow chord to be dragged
qreal xoff = h->pos().x();
qreal bl = -b.left() + qMin(xoff, 0.0);
qreal br = b.right() - qMax(xoff, 0.0);
hSpace.max(Space(bl, br));
#if 0
hSpace.max(Space(s->rtick()?-b.left():0.0, b.right()));
// account for carryover from last measure
if (harmonyCarryOver > 0.0) {
if (!s->rtick()) {
// first ChordRest of measure
// use minDistance to clear carryover harmony
minDistance = qMax(minDistance, harmonyCarryOver - x);
}
else {
// otherwise, use stretch
firstHarmonyDistance = qMax(firstHarmonyDistance, harmonyCarryOver + minHarmonyDistance);
}
harmonyCarryOver = 0.0;
}
#endif
}
}
else {
// current segment (s) is not a ChordRest
Element* e = s->element(track);
if ((segType == Segment::SegClef) && (pt != Segment::SegChordRest))
minDistance = score()->styleS(ST_clefLeftMargin).val() * _spatium;
@ -3254,7 +3280,8 @@ void Measure::layoutX(qreal stretch)
}
if (e) {
eFound = true;
gotHarmony = true; // to avoid closing barline
if (!s->next()) // (segType & (Segment::SegBarLine | Segment::SegEndBarLine))
spaceHarmony = true; // to space last Harmony to end of measure
space.max(e->space());
}
}
@ -3277,10 +3304,14 @@ void Measure::layoutX(qreal stretch)
qreal sp = 0.0;
// space chord symbols unless they miss each other vertically
if (eFound || (hBbox.top() < hLastBbox[staffIdx].bottom() && hBbox.bottom() > hLastBbox[staffIdx].top()))
if (hFound && hBbox.top() < hLastBbox[staffIdx].bottom() && hBbox.bottom() > hLastBbox[staffIdx].top())
sp = hRest[staffIdx] + minHarmonyDistance + hSpace.lw();
hLastBbox[staffIdx] = hBbox;
// barline, allocate half the width of previous harmony to this measure
else if (eFound && !hFound && spaceHarmony)
sp = hRest[staffIdx] * 0.5 + hSpace.lw(); // - score()->styleS(ST_noteBarDistance).val() * _spatium;
hLastBbox[staffIdx] = hBbox;
hRest[staffIdx] = hSpace.rw();
hRest2[staffIdx] = false;
harmonyWidth = qMax(harmonyWidth, sp);
@ -3290,6 +3321,7 @@ void Measure::layoutX(qreal stretch)
clefWidth[staffIdx] = 0.0;
}
// set previous seg width before adding in harmony, to allow stretching
if (segmentIdx) {
width[segmentIdx-1] = segmentWidth;
@ -3298,7 +3330,7 @@ void Measure::layoutX(qreal stretch)
}
// make room for harmony if needed
segmentWidth = qMax(segmentWidth,harmonyWidth);
segmentWidth = qMax(segmentWidth, harmonyWidth);
x += segmentWidth;
xpos[segmentIdx] = x;
@ -3307,10 +3339,11 @@ void Measure::layoutX(qreal stretch)
if (!score()->staff(staffIdx)->show())
continue;
if (rest2[staffIdx])
rest[staffIdx] -= qMin(rest[staffIdx],segmentWidth);
rest[staffIdx] -= qMin(rest[staffIdx], segmentWidth);
if (hRest2[staffIdx])
hRest[staffIdx] -= qMin(hRest[staffIdx],segmentWidth);
hRest[staffIdx] -= qMin(hRest[staffIdx], segmentWidth);
}
if ((s->segmentType() == Segment::SegChordRest)) {
const Segment* nseg = s;
for (;;) {
@ -3339,10 +3372,19 @@ void Measure::layoutX(qreal stretch)
ticksList[segmentIdx] = 0;
// if we are on a chord symbol, stretch the notes below it if necessary
if (gotHarmony) {
if (hLastIdx >= 0)
if (spaceHarmony) {
if (hLastIdx >= 0) {
qDebug("measure %d, segments %d-%d: stretching to %f", _no, hLastIdx, segmentIdx, x-lastx);
computeStretch(hMinTick, 0.0, x-lastx, hLastIdx, segmentIdx, ticksList, xpos, width);
}
#if 0
else if (s->rtick() && firstHarmonyDistance > 0.0) {
// account for carryover from previous measure
qDebug("measure %d, initial %d segments: stretching to %f", _no, segmentIdx, firstHarmonyDistance);
computeStretch(0, 0.0, firstHarmonyDistance, 0, segmentIdx, ticksList, xpos, width);
firstHarmonyDistance = 0.0;
}
#endif
hMinTick = 10000;
lastx = x;
hLastIdx = segmentIdx;

View file

@ -4388,7 +4388,7 @@
<string>sp</string>
</property>
<property name="minimum">
<double>-10.000000000000000</double>
<double>-50.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>