void BarLine::layout() { qreal y1, y2; getY(&y1, &y2); qreal _spatium = spatium(); qreal dw = layoutWidth(score(), barLineType(), magS()); QRectF r(0.0, y1, dw, y2-y1); if (score()->styleB(ST_repeatBarTips)) { qreal mags = magS(); int si = score()->symIdx(); switch (barLineType()) { case START_REPEAT: r |= symbols[si][brackettipsRightUp].bbox(mags).translated(0, y1); r |= symbols[si][brackettipsRightDown].bbox(mags).translated(0, y2); break; case END_REPEAT: r |= symbols[si][brackettipsLeftUp].bbox(mags).translated(0, y1); r |= symbols[si][brackettipsLeftDown].bbox(mags).translated(0, y2); break; case END_START_REPEAT: { qreal lw = point(score()->styleS(ST_barWidth)); qreal lw2 = point(score()->styleS(ST_endBarWidth)); qreal d1 = point(score()->styleS(ST_endBarDistance)); const Sym& dotsym = symbols[score()->symIdx()][dotSym]; qreal dotw = dotsym.width(mags); qreal x = dotw + 2 * d1 + lw + lw2 * .5; // thick bar r |= symbols[si][brackettipsRightUp].bbox(mags).translated(x, y1); r |= symbols[si][brackettipsRightDown].bbox(mags).translated(x, y2); r |= symbols[si][brackettipsLeftUp].bbox(mags).translated(x, y1); r |= symbols[si][brackettipsLeftDown].bbox(mags).translated(x, y2); } break; default: break; } } foreach(Element* e, _el) { e->layout(); if (e->type() == ARTICULATION) { Articulation* a = static_cast<Articulation*>(e); MScore::Direction dir = a->direction(); qreal distance = 0.5 * _spatium; qreal x = width() * .5; if (dir == MScore::DOWN) { qreal botY = y2 + distance; a->setPos(QPointF(x, botY)); } else { qreal topY = y1 - distance; a->setPos(QPointF(x, topY)); } } }
void BarLine::read(XmlReader& e) { // if bar line belongs to a staff, span values default to staff values if (staff()) { _span = staff()->barLineSpan(); _spanFrom = staff()->barLineFrom(); _spanTo = staff()->barLineTo(); } while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "subtype") { bool ok; const QString& val(e.readElementText()); int i = val.toInt(&ok); if (!ok) setBarLineType(val); else { BarLineType ct = NORMAL_BAR; switch (i) { default: case 0: ct = NORMAL_BAR; break; case 1: ct = DOUBLE_BAR; break; case 2: ct = START_REPEAT; break; case 3: ct = END_REPEAT; break; case 4: ct = BROKEN_BAR; break; case 5: ct = END_BAR; break; case 6: ct = END_START_REPEAT; break; case 7: ct = DOTTED_BAR; break; } setBarLineType(ct); } if (parent() && parent()->type() == SEGMENT) { Measure* m = static_cast<Segment*>(parent())->measure(); if (barLineType() != m->endBarLineType()) _customSubtype = true; } } else if (tag == "customSubtype") _customSubtype = e.readInt(); else if (tag == "span") { _span = e.readInt(); _spanFrom = e.intAttribute("from", _spanFrom); _spanTo = e.intAttribute("to", _spanTo); // WARNING: following statements assume staff and staff bar line spans are correctly set if (staff() && (_span != staff()->barLineSpan() || _spanFrom != staff()->barLineFrom() || _spanTo != staff()->barLineTo())) _customSpan = true; } else if (tag == "Articulation") { Articulation* a = new Articulation(score()); a->read(e); add(a); } else if (!Element::readProperties(e)) e.unknown(); } }
Element* BarLine::drop(const DropData& data) { Element* e = data.element; int type = e->type(); if (type == BAR_LINE) { BarLine* bl = static_cast<BarLine*>(e); BarLineType st = bl->barLineType(); // if no change in subtype or no change in span, do nothing if (st == barLineType() && bl->spanFrom() == 0 && bl->spanTo() == DEFAULT_BARLINE_TO) { delete e; return 0; } // system left-side bar line if (parent()->type() == SYSTEM) { BarLine* b = static_cast<System*>(parent())->barLine(); score()->undoChangeProperty(b, P_SUBTYPE, int(bl->barLineType())); delete e; return 0; } // check if the new property can apply to this single bar line bool oldRepeat = (barLineType() == START_REPEAT || barLineType() == END_REPEAT || barLineType() == END_START_REPEAT); bool newRepeat = (bl->barLineType() == START_REPEAT || bl->barLineType() == END_REPEAT || bl->barLineType() == END_START_REPEAT); // if repeats are not involved or drop refers to span rather than subtype => // single bar line drop if( (!oldRepeat && !newRepeat) || (bl->spanFrom() != 0 || bl->spanTo() != DEFAULT_BARLINE_TO) ) { // if drop refers to span, update this bar line span if(bl->spanFrom() != 0 || bl->spanTo() != DEFAULT_BARLINE_TO) { // if dropped spanFrom or spanTo are below the middle of standard staff (5 lines) // adjust to the number of syaff lines int bottomSpan = (staff()->lines()-1) * 2; int spanFrom = bl->spanFrom() > 4 ? bottomSpan - (8 - bl->spanFrom()) : bl->spanFrom(); int spanTo = bl->spanTo() > 4 ? bottomSpan - (8 - bl->spanTo()) : bl->spanTo(); score()->undoChangeSingleBarLineSpan(this, 1, spanFrom, spanTo); } // if drop refer to subtype, update this bar line subtype else { score()->undoChangeProperty(this, P_SUBTYPE, int(bl->barLineType())); // setCustomSubtype(true); } delete e; return 0; } // drop applies to all bar lines of the measure Measure* m = static_cast<Segment*>(parent())->measure(); if (st == START_REPEAT) { m = m->nextMeasure(); if (m == 0) { delete e; return 0; } } m->drop(data); } else if (type == ARTICULATION) { Articulation* atr = static_cast<Articulation*>(e); atr->setParent(this); atr->setTrack(track()); score()->undoAddElement(atr); return atr; } return 0; }
void BarLine::draw(QPainter* painter) const { qreal lw = point(score()->styleS(ST_barWidth)); qreal y1, y2; getY(&y1, &y2); QPen pen(curColor(), lw, Qt::SolidLine, Qt::FlatCap); painter->setPen(pen); qreal mags = magS(); switch(barLineType()) { case BROKEN_BAR: pen.setStyle(Qt::DashLine); painter->setPen(pen); painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); break; case DOTTED_BAR: pen.setStyle(Qt::DotLine); painter->setPen(pen); case NORMAL_BAR: painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); break; case END_BAR: { qreal lw2 = point(score()->styleS(ST_endBarWidth)); qreal d = point(score()->styleS(ST_endBarDistance)); painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); pen.setWidthF(lw2); painter->setPen(pen); qreal x = d + lw2 * .5 + lw; painter->drawLine(QLineF(x, y1, x, y2)); } break; case DOUBLE_BAR: { lw = point(score()->styleS(ST_doubleBarWidth)); qreal d = point(score()->styleS(ST_doubleBarDistance)); pen.setWidthF(lw); painter->setPen(pen); qreal x = lw * .5; painter->drawLine(QLineF(x, y1, x, y2)); x += d + lw; painter->drawLine(QLineF(x, y1, x, y2)); } break; case START_REPEAT: { qreal lw2 = point(score()->styleS(ST_endBarWidth)); qreal d1 = point(score()->styleS(ST_endBarDistance)); qreal x2 = lw2 * .5; // thick line (lw2) qreal x1 = lw2 + d1 + lw * .5; // thin line (lw) qreal x0 = lw2 + d1 + lw + d1; // dot position drawDots(painter, x0); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); if (score()->styleB(ST_repeatBarTips)) { symbols[score()->symIdx()][brackettipsRightUp].draw(painter, mags, QPointF(0.0, y1)); symbols[score()->symIdx()][brackettipsRightDown].draw(painter, mags, QPointF(0.0, y2)); } } break; case END_REPEAT: { qreal lw2 = point(score()->styleS(ST_endBarWidth)); qreal d1 = point(score()->styleS(ST_endBarDistance)); const Sym& dotsym = symbols[score()->symIdx()][dotSym]; qreal dotw = dotsym.width(mags); qreal x1 = dotw + d1 + lw * .5; qreal x2 = dotw + d1 + lw + d1 + lw2 * .5; drawDots(painter, 0.0); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); if (score()->styleB(ST_repeatBarTips)) { qreal x = x2 + lw2 * .5; symbols[score()->symIdx()][brackettipsLeftUp].draw(painter, mags, QPointF(x, y1)); symbols[score()->symIdx()][brackettipsLeftDown].draw(painter, mags, QPointF(x, y2)); } } break; case END_START_REPEAT: { qreal lw2 = point(score()->styleS(ST_endBarWidth)); qreal d1 = point(score()->styleS(ST_endBarDistance)); const Sym& dotsym = symbols[score()->symIdx()][dotSym]; qreal dotw = dotsym.width(mags); qreal x1 = dotw + d1 + lw * .5; // thin bar qreal x2 = dotw + d1 + lw + d1 + lw2 * .5; // thick bar qreal x3 = dotw + d1 + lw + d1 + lw2 + d1 + lw * .5; // thin bar qreal x4 = dotw + d1 + lw + d1 + lw2 + d1 + lw + d1; // dot position drawDots(painter, .0); drawDots(painter, x4); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); pen.setWidthF(lw); painter->setPen(pen); painter->drawLine(QLineF(x3, y1, x3, y2)); if (score()->styleB(ST_repeatBarTips)) { qreal x = x2; symbols[score()->symIdx()][brackettipsRightUp].draw(painter, mags, QPointF(x, y1)); symbols[score()->symIdx()][brackettipsRightDown].draw(painter, mags, QPointF(x, y2)); symbols[score()->symIdx()][brackettipsLeftUp].draw(painter, mags, QPointF(x, y1)); symbols[score()->symIdx()][brackettipsLeftDown].draw(painter, mags, QPointF(x, y2)); } } break; } }
void BarLine::layout() { qreal y1, y2; getY(&y1, &y2); // if bar line does not belong to a system, has a staff and staff is set to hide bar lines, set null bbox if (parent() && parent()->type() != Element::Type::SYSTEM && staff() && !staff()->staffType()->showBarlines()) setbbox(QRectF()); // bar lines not hidden else { qreal dw = layoutWidth(score(), barLineType(), magS()); QRectF r(0.0, y1, dw, y2-y1); if (score()->styleB(StyleIdx::repeatBarTips)) { switch (barLineType()) { case BarLineType::START_REPEAT: r |= symBbox(SymId::bracketTop).translated(0, y1); r |= symBbox(SymId::bracketBottom).translated(0, y2); break; case BarLineType::END_REPEAT: { qreal w1 = symBbox(SymId::reversedBracketTop).width(); r |= symBbox(SymId::reversedBracketTop).translated(dw - w1, y1); r |= symBbox(SymId::reversedBracketBottom).translated(dw - w1, y2); break; } case BarLineType::END_START_REPEAT: { qreal lw = point(score()->styleS(StyleIdx::barWidth)); qreal lw2 = point(score()->styleS(StyleIdx::endBarWidth)); qreal d1 = point(score()->styleS(StyleIdx::endBarDistance)); qreal dotw = symWidth(SymId::repeatDot); qreal x = dotw + 2 * d1 + lw + lw2 * .5; // thick bar qreal w1 = symBbox(SymId::reversedBracketTop).width(); r |= symBbox(SymId::bracketTop).translated(x, y1); r |= symBbox(SymId::bracketBottom).translated(x, y2); r |= symBbox(SymId::reversedBracketTop).translated(x - w1 , y1); r |= symBbox(SymId::reversedBracketBottom).translated(x - w1, y2); } break; default: break; } } setbbox(r); } // in any case, lay out attached elements foreach(Element* e, _el) { e->layout(); if (e->type() == Element::Type::ARTICULATION) { Articulation* a = static_cast<Articulation*>(e); MScore::Direction dir = a->direction(); qreal distance = 0.5 * spatium(); qreal x = width() * .5; if (dir == MScore::Direction::DOWN) { qreal botY = y2 + distance; a->setPos(QPointF(x, botY)); } else { qreal topY = y1 - distance; a->setPos(QPointF(x, topY)); } } }
void BarLine::draw(QPainter* painter) const { // get line length and do nothing if 0 (or near enough) qreal y1, y2; getY(&y1, &y2); if (y2-y1 < 0.1) return; qreal _spatium = score()->spatium(); qreal lw = score()->styleS(StyleIdx::barWidth).val() * _spatium; QPen pen(curColor(), lw, Qt::SolidLine, Qt::FlatCap); painter->setPen(pen); switch(barLineType()) { case BarLineType::BROKEN: pen.setStyle(Qt::DashLine); painter->setPen(pen); painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); break; case BarLineType::DOTTED: pen.setStyle(Qt::DotLine); painter->setPen(pen); case BarLineType::NORMAL: painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); break; case BarLineType::END: { qreal lw2 = score()->styleS(StyleIdx::endBarWidth).val() * _spatium; qreal d = score()->styleS(StyleIdx::endBarDistance).val() * _spatium; painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2)); pen.setWidthF(lw2); painter->setPen(pen); qreal x = d + lw2 * .5 + lw; painter->drawLine(QLineF(x, y1, x, y2)); } break; case BarLineType::DOUBLE: { lw = point(score()->styleS(StyleIdx::doubleBarWidth)); qreal d = point(score()->styleS(StyleIdx::doubleBarDistance)); pen.setWidthF(lw); painter->setPen(pen); qreal x = lw * .5; painter->drawLine(QLineF(x, y1, x, y2)); x += d + lw; painter->drawLine(QLineF(x, y1, x, y2)); } break; case BarLineType::START_REPEAT: { qreal lw2 = point(score()->styleS(StyleIdx::endBarWidth)); qreal d1 = point(score()->styleS(StyleIdx::endBarDistance)); qreal x2 = lw2 * .5; // thick line (lw2) qreal x1 = lw2 + d1 + lw * .5; // thin line (lw) qreal x0 = lw2 + d1 + lw + d1; // dot position drawDots(painter, x0); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); if (score()->styleB(StyleIdx::repeatBarTips)) { drawSymbol(SymId::bracketTop, painter, QPointF(0.0, y1)); drawSymbol(SymId::bracketBottom, painter, QPointF(0.0, y2)); } } break; case BarLineType::END_REPEAT: { qreal lw2 = point(score()->styleS(StyleIdx::endBarWidth)); qreal d1 = point(score()->styleS(StyleIdx::endBarDistance)); qreal dotw = symWidth(SymId::repeatDot); qreal x1 = dotw + d1 + lw * .5; qreal x2 = dotw + d1 + lw + d1 + lw2 * .5; drawDots(painter, 0.0); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); if (score()->styleB(StyleIdx::repeatBarTips)) { qreal x = x2 + lw2 * .5; qreal w1 = symBbox(SymId::reversedBracketTop).width(); drawSymbol(SymId::reversedBracketTop, painter, QPointF(x - w1, y1)); drawSymbol(SymId::reversedBracketBottom, painter, QPointF(x - w1, y2)); } } break; case BarLineType::END_START_REPEAT: { qreal lw2 = point(score()->styleS(StyleIdx::endBarWidth)); qreal d1 = point(score()->styleS(StyleIdx::endBarDistance)); qreal dotw = symWidth(SymId::repeatDot); qreal x1 = dotw + d1 + lw * .5; // thin bar qreal x2 = dotw + d1 + lw + d1 + lw2 * .5; // thick bar qreal x3 = dotw + d1 + lw + d1 + lw2 + d1 + lw * .5; // thin bar qreal x4 = dotw + d1 + lw + d1 + lw2 + d1 + lw + d1; // dot position drawDots(painter, .0); drawDots(painter, x4); painter->drawLine(QLineF(x1, y1, x1, y2)); pen.setWidthF(lw2); painter->setPen(pen); painter->drawLine(QLineF(x2, y1, x2, y2)); pen.setWidthF(lw); painter->setPen(pen); painter->drawLine(QLineF(x3, y1, x3, y2)); if (score()->styleB(StyleIdx::repeatBarTips)) { qreal x = x2; qreal w1 = symBbox(SymId::reversedBracketTop).width(); drawSymbol(SymId::bracketTop, painter, QPointF(x, y1)); drawSymbol(SymId::bracketBottom, painter, QPointF(x, y2)); drawSymbol(SymId::reversedBracketTop, painter, QPointF(x - w1, y1)); drawSymbol(SymId::reversedBracketBottom, painter, QPointF(x - w1, y2)); } } break; } }