void HairpinSegment::draw(QPainter* painter) const { if (hairpin()->useTextLine()) { TextLineSegment::draw(painter); return; } QColor color; if (selected() && !(score() && score()->printing())) color = (track() > -1) ? MScore::selectColor[voice()] : MScore::selectColor[0]; else if (!visible()) color = Qt::gray; else color = hairpin()->curColor(); QPen pen(color, point(hairpin()->lineWidth()), hairpin()->lineStyle()); if (hairpin()->lineStyle() == Qt::CustomDashLine) { QVector<qreal> pattern; pattern << 5.0 << 20.0; pen.setDashPattern(pattern); } painter->setPen(pen); painter->drawLine(l1); painter->drawLine(l2); if( drawCircledTip ) { painter->setBrush(Qt::NoBrush); painter->drawEllipse( circledTip,circledTipRadius,circledTipRadius ); } }
void HairpinSegment::layout() { QTransform t; qreal _spatium = spatium(); qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5; qreal len; qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); len = sqrt(x * x + y * y); t.rotateRadians(asin(y/len)); if (hairpin()->hairpinType() == 0) { // crescendo switch (spannerSegmentType()) { case SEGMENT_SINGLE: case SEGMENT_BEGIN: l1.setLine(.0, .0, len, h1); l2.setLine(.0, .0, len, -h1); break; case SEGMENT_MIDDLE: case SEGMENT_END: l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } else { // decrescendo switch(spannerSegmentType()) { case SEGMENT_SINGLE: case SEGMENT_END: l1.setLine(.0, h1, len, 0.0); l2.setLine(.0, -h1, len, 0.0); break; case SEGMENT_BEGIN: case SEGMENT_MIDDLE: l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } l1 = t.map(l1); l2 = t.map(l2); QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = point(score()->styleS(ST_hairpinLineWidth)); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleS(ST_hairpinY).val() * _spatium; adjustReadPos(); }
void HairpinSegment::editDrag(const EditData& ed) { if (ed.curGrip == Grip::APERTURE) { qreal newHeight = hairpin()->hairpinHeight().val() + ed.delta.y()/spatium()/.5; if (newHeight < 0.5) newHeight = 0.5; hairpin()->setHairpinHeight(Spatium(newHeight)); score()->setLayoutAll(true); } LineSegment::editDrag(ed); }
void HairpinSegment::draw(QPainter* painter) const { QColor color; if (selected() && !(score() && score()->printing())) color = MScore::selectColor[0]; else if (!visible()) color = Qt::gray; else color = hairpin()->curColor(); QPen pen(color, point(hairpin()->lineWidth()), hairpin()->lineStyle()); painter->setPen(pen); painter->drawLine(l1); painter->drawLine(l2); }
void HairpinSegment::draw(QPainter* painter) const { TextLineSegment::draw(painter); QColor color; if (selected() && !(score() && score()->printing())) color = (track() > -1) ? MScore::selectColor[voice()] : MScore::selectColor[0]; else if (!hairpin()->visible()) // || !hairpin()->lineVisible() color = Qt::gray; else color = hairpin()->lineColor(); QPen pen(color, point(hairpin()->lineWidth()), hairpin()->lineStyle()); painter->setPen(pen); if (drawCircledTip) { painter->setBrush(Qt::NoBrush); painter->drawEllipse( circledTip,circledTipRadius,circledTipRadius ); } }
PropertyStyle HairpinSegment::propertyStyle(P_ID id) const { switch (id) { case P_ID::LINE_WIDTH: case P_ID::HAIRPIN_HEIGHT: case P_ID::HAIRPIN_CONT_HEIGHT: return hairpin()->propertyStyle(id); default: return TextLineSegment::propertyStyle(id); } }
void HairpinSegment::resetProperty(P_ID id) { switch (id) { case P_ID::LINE_WIDTH: case P_ID::HAIRPIN_HEIGHT: case P_ID::HAIRPIN_CONT_HEIGHT: return hairpin()->resetProperty(id); default: return TextLineSegment::resetProperty(id); } }
bool HairpinSegment::setProperty(P_ID id, const QVariant& v) { switch (id) { case P_HAIRPIN_TYPE: case P_VELO_CHANGE: case P_DYNAMIC_RANGE: case P_DIAGONAL: return hairpin()->setProperty(id, v); default: return LineSegment::setProperty(id, v); } }
Shape HairpinSegment::shape() const { switch (hairpin()->hairpinType()) { case Hairpin::Type::CRESC_HAIRPIN: case Hairpin::Type::DECRESC_HAIRPIN: return Shape(bbox()); case Hairpin::Type::DECRESC_LINE: case Hairpin::Type::CRESC_LINE: default: return TextLineSegment::shape(); } }
QVariant HairpinSegment::propertyDefault(P_ID id) const { switch (id) { case P_HAIRPIN_TYPE: case P_VELO_CHANGE: case P_DYNAMIC_RANGE: case P_DIAGONAL: return hairpin()->propertyDefault(id); default: return LineSegment::propertyDefault(id); } }
void HairpinSegment::updateGrips(Grip* defaultGrip, QVector<QRectF>& grip) const { *defaultGrip = Grip::END; QPointF pp(pagePos()); qreal _spatium = spatium(); qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); QPointF p(x, y); // Calc QPointF for Grip Aperture QTransform doRotation; QPointF gripLineAperturePoint; qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal len = sqrt( x * x + y * y ); doRotation.rotateRadians( asin(y/len) ); qreal lineApertureX; qreal offsetX = 10; // Horizontal offset for x Grip if(len < offsetX * 3 ) // For small hairpin, offset = 30% of len offsetX = len/3; // else offset is fixed to 10 if( hairpin()->hairpinType() == Hairpin::Type::CRESCENDO ) lineApertureX = len - offsetX; // End of CRESCENDO - Offset else lineApertureX = offsetX; // Begin of DECRESCENDO + Offset qreal lineApertureH = ( len - offsetX ) * h1/len; // Vertical position for y grip gripLineAperturePoint.setX( lineApertureX ); gripLineAperturePoint.setY( lineApertureH ); gripLineAperturePoint = doRotation.map( gripLineAperturePoint ); // End calc position grip aperture grip[int(Grip::START)].translate( pp ); grip[int(Grip::END)].translate( p + pp ); grip[int(Grip::MIDDLE)].translate( p * .5 + pp ); grip[int(Grip::APERTURE)].translate( gripLineAperturePoint + pp ); }
QVariant HairpinSegment::getProperty(P_ID id) const { switch (id) { case P_HAIRPIN_TYPE: case P_VELO_CHANGE: case P_DYNAMIC_RANGE: case P_DIAGONAL: case P_HAIRPIN_HEIGHT: case P_HAIRPIN_CONT_HEIGHT: return hairpin()->getProperty(id); default: return LineSegment::getProperty(id); } }
QVariant HairpinSegment::getProperty(P_ID id) const { switch (id) { case P_ID::HAIRPIN_TEXTLINE: case P_ID::HAIRPIN_CIRCLEDTIP: case P_ID::HAIRPIN_TYPE: case P_ID::VELO_CHANGE: case P_ID::DYNAMIC_RANGE: case P_ID::DIAGONAL: case P_ID::HAIRPIN_HEIGHT: case P_ID::HAIRPIN_CONT_HEIGHT: return hairpin()->getProperty(id); default: return TextLineSegment::getProperty(id); } }
bool HairpinSegment::setProperty(P_ID id, const QVariant& v) { switch (id) { case P_ID::HAIRPIN_CIRCLEDTIP: case P_ID::HAIRPIN_TYPE: case P_ID::VELO_CHANGE: case P_ID::DYNAMIC_RANGE: case P_ID::DIAGONAL: case P_ID::LINE_WIDTH: case P_ID::HAIRPIN_HEIGHT: case P_ID::HAIRPIN_CONT_HEIGHT: return hairpin()->setProperty(id, v); default: return TextLineSegment::setProperty(id, v); } }
void HairpinSegment::layout() { if (hairpin()->useTextLine()) { if (parent()) rypos() += score()->styleS(StyleIdx::hairpinY).val() * spatium(); TextLineSegment::layout(); return; } QTransform t; qreal _spatium = spatium(); qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5; qreal len; qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); len = sqrt(x * x + y * y); t.rotateRadians(asin(y/len)); drawCircledTip = hairpin()->hairpinCircledTip(); circledTipRadius = 0; if( drawCircledTip ) circledTipRadius = 0.6 * _spatium * .5; if (hairpin()->hairpinType() == Hairpin::Type::CRESCENDO) { // crescendo switch (spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::BEGIN: l1.setLine(.0 + circledTipRadius*2, .0, len, h1); l2.setLine(.0 + circledTipRadius*2, .0, len, -h1); circledTip.setX( 0 + circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::MIDDLE: case SpannerSegmentType::END: drawCircledTip = false; l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } else { // decrescendo switch(spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::END: l1.setLine(.0, h1, len - circledTipRadius*2, 0.0); l2.setLine(.0, -h1, len - circledTipRadius*2, 0.0); circledTip.setX( len - circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::BEGIN: case SpannerSegmentType::MIDDLE: drawCircledTip = false; l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } // Do Coord rotation l1 = t.map(l1); l2 = t.map(l2); if( drawCircledTip ) circledTip = t.map(circledTip); QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth)); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleS(StyleIdx::hairpinY).val() * _spatium; adjustReadPos(); }
void HairpinSegment::layout() { Dynamic* sd = 0; Dynamic* ed = 0; qreal _spatium = spatium(); if (autoplace()) { setUserOff(QPointF()); setUserOff2(QPointF()); } if (isSingleType() || isBeginType()) { sd = lookupDynamic(hairpin()->startElement()); if (sd) { if (autoplace()) { qreal dx = sd->bbox().right() + sd->pos().x() + sd->segment()->pos().x() + sd->measure()->pos().x(); // hardcoded distance between Dynamic and Hairpin: 0.5sp qreal dist = dx - pos().x() + score()->styleP(StyleIdx::autoplaceHairpinDynamicsDistance); rUserXoffset() = dist; rUserXoffset2() = -dist; } else sd->doAutoplace(); } } if (isSingleType() || isEndType()) { ed = lookupDynamic(hairpin()->endElement()); if (ed) { if (autoplace()) { rUserXoffset2() -= ed->bbox().width(); qreal dx = ed->bbox().left() + ed->pos().x() + ed->segment()->pos().x() + ed->measure()->pos().x(); // hardcoded distance between Hairpin and Dynamic: 0.5sp ed->rUserXoffset() = pos2().x() + pos().x() - dx + score()->styleP(StyleIdx::autoplaceHairpinDynamicsDistance); } else ed->doAutoplace(); } } Hairpin::Type type = hairpin()->hairpinType(); if (type == Hairpin::Type::DECRESC_LINE || type == Hairpin::Type::CRESC_LINE) { twoLines = false; TextLineSegment::layout(); drawCircledTip = false; if (parent()) rypos() += score()->styleP(StyleIdx::hairpinY); } else { delete _text; delete _endText; _text = 0; _endText = 0; QTransform t; qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5; qreal len; qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); len = sqrt(x * x + y * y); t.rotateRadians(asin(y/len)); drawCircledTip = hairpin()->hairpinCircledTip(); circledTipRadius = drawCircledTip ? 0.6 * _spatium * .5 : 0.0; QLine l1, l2; twoLines = true; switch (type) { case Hairpin::Type::CRESC_HAIRPIN: { switch (spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::BEGIN: l1.setLine(circledTipRadius * 2.0, 0.0, len, h1); l2.setLine(circledTipRadius * 2.0, 0.0, len, -h1); circledTip.setX(circledTipRadius ); circledTip.setY(0.0); break; case SpannerSegmentType::MIDDLE: case SpannerSegmentType::END: drawCircledTip = false; l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } break; case Hairpin::Type::DECRESC_HAIRPIN: { switch(spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::END: l1.setLine(0.0, h1, len - circledTipRadius * 2, 0.0); l2.setLine(0.0, -h1, len - circledTipRadius * 2, 0.0); circledTip.setX(len - circledTipRadius); circledTip.setY(0.0); break; case SpannerSegmentType::BEGIN: case SpannerSegmentType::MIDDLE: drawCircledTip = false; l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } break; default: break; } // Do Coord rotation l1 = t.map(l1); l2 = t.map(l2); if (drawCircledTip ) circledTip = t.map(circledTip); points[0] = l1.p1(); points[1] = l1.p2(); points[2] = l2.p1(); points[3] = l2.p2(); npoints = 4; QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = score()->styleP(StyleIdx::hairpinLineWidth); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleP(StyleIdx::hairpinY); } if (autoplace() && parent()) { qreal minDistance = spatium() * .7; Shape s1 = shape().translated(pos()); qreal d = system()->bottomDistance(staffIdx(), s1); qreal ymax = pos().y(); if (d > -minDistance) ymax += d + minDistance; qreal sdy; if (sd) { sdy = -sd->bbox().top() * .4; sd->doAutoplace(); if (sd->pos().y() - sdy > ymax) ymax = sd->pos().y() - sdy; } qreal edy; if (ed) { edy = -ed->bbox().top() * .4; ed->doAutoplace(); if (ed->pos().y() - edy > ymax) ymax = ed->pos().y() - edy; } rUserYoffset() = ymax - pos().y(); if (sd) moveDynamic(sd, ymax - sd->ipos().y() + sdy); if (ed) moveDynamic(ed, ymax - ed->ipos().y() + edy); } else adjustReadPos(); }
void HairpinSegment::layout() { if (hairpin()->useTextLine()) { // layout as textline rather than true hairpin // use dynamics text style for position, so the text aligns with dynamics // TODO: new style setting specifically for vertical offset of textline hairpins? // or, use hairpinY but adjust by 0.5sp, which currently yields same vertical position as dynamics if (parent()) rypos() += score()->textStyle(TextStyleType::DYNAMICS).offset(spatium()).y(); TextLineSegment::layout(); return; } QTransform t; qreal _spatium = spatium(); qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5; qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5; qreal len; qreal x = pos2().x(); if (x < _spatium) // minimum size of hairpin x = _spatium; qreal y = pos2().y(); len = sqrt(x * x + y * y); t.rotateRadians(asin(y/len)); drawCircledTip = hairpin()->hairpinCircledTip(); circledTipRadius = 0; if( drawCircledTip ) circledTipRadius = 0.6 * _spatium * .5; if (hairpin()->hairpinType() == Hairpin::Type::CRESCENDO) { // crescendo switch (spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::BEGIN: l1.setLine(.0 + circledTipRadius*2, .0, len, h1); l2.setLine(.0 + circledTipRadius*2, .0, len, -h1); circledTip.setX( 0 + circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::MIDDLE: case SpannerSegmentType::END: drawCircledTip = false; l1.setLine(.0, h2, len, h1); l2.setLine(.0, -h2, len, -h1); break; } } else { // decrescendo switch(spannerSegmentType()) { case SpannerSegmentType::SINGLE: case SpannerSegmentType::END: l1.setLine(.0, h1, len - circledTipRadius*2, 0.0); l2.setLine(.0, -h1, len - circledTipRadius*2, 0.0); circledTip.setX( len - circledTipRadius ); circledTip.setY( 0 ); break; case SpannerSegmentType::BEGIN: case SpannerSegmentType::MIDDLE: drawCircledTip = false; l1.setLine(.0, h1, len, + h2); l2.setLine(.0, -h1, len, - h2); break; } } // Do Coord rotation l1 = t.map(l1); l2 = t.map(l2); if( drawCircledTip ) circledTip = t.map(circledTip); QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized(); qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth)); setbbox(r.adjusted(-w*.5, -w*.5, w, w)); if (parent()) rypos() += score()->styleS(StyleIdx::hairpinY).val() * _spatium; adjustReadPos(); }