diff --git a/libmscore/layout.cpp b/libmscore/layout.cpp
index 406f245e46..3a1f7f0ab5 100644
--- a/libmscore/layout.cpp
+++ b/libmscore/layout.cpp
@@ -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
//
diff --git a/libmscore/measure.cpp b/libmscore/measure.cpp
index 294d50d9c9..a97d39ad41 100644
--- a/libmscore/measure.cpp
+++ b/libmscore/measure.cpp
@@ -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;
diff --git a/mscore/editstyle.ui b/mscore/editstyle.ui
index 1773c35e93..3d2d230d6e 100644
--- a/mscore/editstyle.ui
+++ b/mscore/editstyle.ui
@@ -4388,7 +4388,7 @@
sp
- -10.000000000000000
+ -50.000000000000000
10.000000000000000