Skip to content

Commit

Permalink
Fix #281639: Better handling of Clefs, Barlines and (not yet) brackets
Browse files Browse the repository at this point in the history
  • Loading branch information
elerouxx committed Aug 17, 2020
1 parent bd675e7 commit af9be72
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 9 deletions.
8 changes: 5 additions & 3 deletions libmscore/barline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,11 @@ int nextVisibleSpannedStaff(const BarLine* bl)
int nstaves = score->nstaves();
int staffIdx = bl->staffIdx();
Segment* segment = bl->segment();
for (int i = staffIdx + 1; i < nstaves; ++i) {
Measure* nm = bl->measure()->nextMeasure();
for (int i = staffIdx + 1; i < nstaves; ++i) {
Staff* s = score->staff(i);
if (s->part()->show() && bl->measure()->visible(i))
if (s->part()->show() && (bl->measure()->visible(i)
|| ((nm ? nm->visible(i) : false) && (nm ? nm->system() == bl->measure()->system() : false))))
return i;
BarLine* nbl = toBarLine(segment->element(i * VOICES));
if (!nbl || !nbl->spanStaff())
Expand Down Expand Up @@ -1151,7 +1153,7 @@ void BarLine::endEditDrag(EditData& ed)
newSpanTo = 0;
}

bool localDrag = ed.control() || segment()->isBarLine();
bool localDrag = ed.control() || segment()->isBarLineType();
if (localDrag) {
Segment* s = segment();
for (int staffIdx = staffIdx1; staffIdx < staffIdx2; ++staffIdx) {
Expand Down
50 changes: 45 additions & 5 deletions libmscore/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,14 @@ Measure::Measure(const Measure& m)

void Measure::layoutStaffLines()
{
for (MStaff* ms : _mstaves)
ms->lines()->layout();
int staffIdx = 0;
for (MStaff* ms : _mstaves) {
if (score()->staff(staffIdx)->cutaway() && isCourtesyClef(staffIdx))
ms->lines()->layoutPartialWidth(width(), 4.0 ,false); // draw short staff lines (4.0 sp wide) only for courtesy clef
else
ms->lines()->layout();
staffIdx += 1;
}
}

//---------------------------------------------------------
Expand Down Expand Up @@ -2505,16 +2511,19 @@ void Measure::scanElements(void* data, void (*func)(void*, Element*), bool all)

int nstaves = score()->nstaves();
for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
if (!all && !(visible(staffIdx) && score()->staff(staffIdx)->show()))
if (!all && !score()->staff(staffIdx)->show())
continue;
MStaff* ms = _mstaves[staffIdx];
func(data, ms->lines());
// show spacers and measure number even on invisible measures
if (ms->vspacerUp())
func(data, ms->vspacerUp());
if (ms->vspacerDown())
func(data, ms->vspacerDown());
if (ms->noText())
if (ms->noText())
func(data, ms->noText());

if (visible(staffIdx) || isCourtesyClef(staffIdx))
func(data, ms->lines());
}

for (Segment* s = first(); s; s = s->next()) {
Expand Down Expand Up @@ -2768,6 +2777,37 @@ bool Measure::isEmpty(int staffIdx) const
return true;
}

//---------------------------------------------------------
// isCourtesyClef
// Check for empty measure with only
// a Courtesy Clef before the End Bar Line
//---------------------------------------------------------

bool Measure::isCourtesyClef(int staffIdx) const
{
if (!isEmpty(staffIdx))
return false;
int strack;
int etrack;
if (staffIdx < 0) {
strack = 0;
etrack = score()->nstaves() * VOICES;
}
else {
strack = staffIdx * VOICES;
etrack = strack + VOICES;
}
Segment* s = last()->prev();
if (!s)
return false;
for (int track = strack; track < etrack; ++track) {
Element* e = s->element(track);
if (e && e->isClef())
return true;
}
return false;
}

//---------------------------------------------------------
// isFullMeasureRest
// Check for an empty measure, filled with full measure
Expand Down
1 change: 1 addition & 0 deletions libmscore/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class Measure final : public MeasureBase {
void checkMultiVoices(int staffIdx);
bool hasVoice(int track) const;
bool isEmpty(int staffIdx) const;
bool isCourtesyClef(int staffIdx) const;
bool isFullMeasureRest() const;
bool isRepeatMeasure(const Staff* staff) const;
bool visible(int staffIdx) const;
Expand Down
19 changes: 18 additions & 1 deletion libmscore/segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1137,13 +1137,30 @@ void Segment::scanElements(void* data, void (*func)(void*, Element*), bool all)
{
for (int track = 0; track < score()->nstaves() * VOICES; ++track) {
int staffIdx = track/VOICES;
if (!all && !(measure()->visible(staffIdx) && score()->staff(staffIdx)->show())) {
if (!all && !(/*measure()->visible(staffIdx) &&*/ score()->staff(staffIdx)->show())) {
track += VOICES - 1;
continue;
}
Element* e = element(track);
if (e == 0)
continue;
// if measure is not visible, handle visible End Bar Lines and Courtesy Clefs in certain conditions (for ossias and cutaway)
if (!measure()->visible(staffIdx)) {
// if (!isClefType() && !isEndBarLineType())
// continue;
if (isEndBarLineType()) {
if (!measure()->nextMeasure())
continue; // skip EndBarLines if next measure == NULL
else if (!measure()->nextMeasure()->visible(staffIdx) || measure()->nextMeasure()->system() != measure()->system())
continue; // skip if next measure not visible or not in the same system
}
else if (isClefType()) {
if (!measure()->isCourtesyClef(staffIdx))
continue; // skip clefs except for courtesy clefs on the end of the measure
}
else
continue;
}
e->scanElements(data, func, all);
}
for (Element* e : annotations()) {
Expand Down
45 changes: 45 additions & 0 deletions libmscore/stafflines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,51 @@ void StaffLines::layoutForWidth(qreal w)
}
}

//---------------------------------------------------------
// layoutPartialWidth
//---------------------------------------------------------

void StaffLines::layoutPartialWidth(qreal w, qreal wPartial, bool alignLeft)
{
const Staff* s = staff();
qreal _spatium = spatium();
wPartial *= spatium();
qreal dist = _spatium;
setPos(QPointF(0.0, 0.0));
int _lines;
if (s) {
setMag(s->mag(measure()->tick()));
setColor(s->color());
const StaffType* st = s->staffType(measure()->tick());
dist *= st->lineDistance().val();
_lines = st->lines();
rypos() = st->yoffset().val() * _spatium;
}
else {
_lines = 5;
setColor(MScore::defaultColor);
}
lw = score()->styleS(Sid::staffLineWidth).val() * _spatium;
qreal x1 = pos().x();
qreal x2 = x1 + w;
qreal y = pos().y();
bbox().setRect(x1, -lw * .5 + y, w, (_lines-1) * dist + lw);

if (_lines == 1) {
qreal extraSize = _spatium;
bbox().adjust(0, -extraSize, 0, extraSize);
}

lines.clear();
for (int i = 0; i < _lines; ++i) {
if (alignLeft)
lines.push_back(QLineF(x1, y, x1 + wPartial, y));
else
lines.push_back(QLineF(x2-wPartial, y, x2, y));
y += dist;
}
}

//---------------------------------------------------------
// draw
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/stafflines.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class StaffLines final : public Element {
Measure* measure() const { return (Measure*)parent(); }
qreal y1() const;
void layoutForWidth(qreal width);
void layoutPartialWidth(qreal w, qreal wPartial, bool alignLeft);
};

} // namespace Ms
Expand Down

0 comments on commit af9be72

Please sign in to comment.