2012-05-26 14:26:10 +02:00
|
|
|
//=============================================================================
|
|
|
|
// MuseScore
|
|
|
|
// Music Composition & Notation
|
|
|
|
//
|
|
|
|
// Copyright (C) 2002-2011 Werner Schweer
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License version 2
|
|
|
|
// as published by the Free Software Foundation and appearing in
|
|
|
|
// the file LICENCE.GPL
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "hairpin.h"
|
|
|
|
#include "style.h"
|
|
|
|
#include "xml.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "score.h"
|
|
|
|
#include "measure.h"
|
|
|
|
#include "segment.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "undo.h"
|
|
|
|
#include "staff.h"
|
|
|
|
#include "mscore.h"
|
2016-07-15 14:05:51 +02:00
|
|
|
#include "chord.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
2018-08-01 11:46:07 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// hairpinStyle
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
static const ElementStyle hairpinStyle {
|
|
|
|
{ Sid::hairpinFontFace, Pid::BEGIN_FONT_FACE },
|
|
|
|
{ Sid::hairpinFontSize, Pid::BEGIN_FONT_SIZE },
|
|
|
|
{ Sid::hairpinFontBold, Pid::BEGIN_FONT_BOLD },
|
|
|
|
{ Sid::hairpinFontItalic, Pid::BEGIN_FONT_ITALIC },
|
|
|
|
{ Sid::hairpinFontUnderline, Pid::BEGIN_FONT_UNDERLINE },
|
|
|
|
{ Sid::hairpinTextAlign, Pid::BEGIN_TEXT_ALIGN },
|
|
|
|
{ Sid::hairpinFontFace, Pid::CONTINUE_FONT_FACE },
|
|
|
|
{ Sid::hairpinFontSize, Pid::CONTINUE_FONT_SIZE },
|
|
|
|
{ Sid::hairpinFontBold, Pid::CONTINUE_FONT_BOLD },
|
|
|
|
{ Sid::hairpinFontItalic, Pid::CONTINUE_FONT_ITALIC },
|
|
|
|
{ Sid::hairpinFontUnderline, Pid::CONTINUE_FONT_UNDERLINE },
|
|
|
|
{ Sid::hairpinTextAlign, Pid::CONTINUE_TEXT_ALIGN },
|
|
|
|
{ Sid::hairpinFontFace, Pid::END_FONT_FACE },
|
|
|
|
{ Sid::hairpinFontSize, Pid::END_FONT_SIZE },
|
|
|
|
{ Sid::hairpinFontBold, Pid::END_FONT_BOLD },
|
|
|
|
{ Sid::hairpinFontItalic, Pid::END_FONT_ITALIC },
|
|
|
|
{ Sid::hairpinFontUnderline, Pid::END_FONT_UNDERLINE },
|
|
|
|
{ Sid::hairpinTextAlign, Pid::END_TEXT_ALIGN },
|
|
|
|
{ Sid::hairpinLineWidth, Pid::LINE_WIDTH },
|
|
|
|
{ Sid::hairpinHeight, Pid::HAIRPIN_HEIGHT },
|
|
|
|
{ Sid::hairpinContHeight, Pid::HAIRPIN_CONT_HEIGHT },
|
|
|
|
{ Sid::hairpinPlacement, Pid::PLACEMENT },
|
2018-11-05 11:49:28 +01:00
|
|
|
{ Sid::hairpinPosAbove, Pid::OFFSET },
|
2018-08-01 11:46:07 +02:00
|
|
|
};
|
|
|
|
|
2017-02-07 18:48:23 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// HairpinSegment
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
HairpinSegment::HairpinSegment(Score* s)
|
2018-07-16 16:29:16 +02:00
|
|
|
: TextLineBaseSegment(s, ElementFlag::MOVABLE | ElementFlag::ON_STAFF)
|
2017-02-07 18:48:23 +01:00
|
|
|
{
|
|
|
|
}
|
2016-09-22 17:28:44 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void HairpinSegment::layout()
|
|
|
|
{
|
2018-11-14 12:59:52 +01:00
|
|
|
qreal _spatium = spatium();
|
2016-09-22 17:28:44 +02:00
|
|
|
HairpinType type = hairpin()->hairpinType();
|
|
|
|
if (type == HairpinType::DECRESC_LINE || type == HairpinType::CRESC_LINE) {
|
2016-07-15 14:05:51 +02:00
|
|
|
twoLines = false;
|
2016-08-30 14:03:26 +02:00
|
|
|
TextLineBaseSegment::layout();
|
2016-10-14 10:56:00 +02:00
|
|
|
drawCircledTip = false;
|
|
|
|
circledTipRadius = 0.0;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
else {
|
2016-10-14 10:56:00 +02:00
|
|
|
twoLines = true;
|
2016-07-15 14:05:51 +02:00
|
|
|
|
2017-03-04 15:01:42 +01:00
|
|
|
qreal x1 = 0.0;
|
|
|
|
TextLineBaseSegment::layout();
|
|
|
|
if (!_text->empty())
|
|
|
|
x1 = _text->width();
|
|
|
|
|
2016-07-15 14:05:51 +02:00
|
|
|
QTransform t;
|
2016-07-20 12:45:34 +02:00
|
|
|
qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5;
|
2016-07-15 14:05:51 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
switch (type) {
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::CRESC_HAIRPIN: {
|
2016-07-15 14:05:51 +02:00
|
|
|
switch (spannerSegmentType()) {
|
2016-07-20 12:45:34 +02:00
|
|
|
case SpannerSegmentType::SINGLE:
|
|
|
|
case SpannerSegmentType::BEGIN:
|
2017-03-04 15:01:42 +01:00
|
|
|
l1.setLine(x1 + circledTipRadius * 2.0, 0.0, len, h1);
|
|
|
|
l2.setLine(x1 + circledTipRadius * 2.0, 0.0, len, -h1);
|
2016-07-20 12:45:34 +02:00
|
|
|
circledTip.setX(circledTipRadius );
|
2016-07-15 14:05:51 +02:00
|
|
|
circledTip.setY(0.0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SpannerSegmentType::MIDDLE:
|
2016-07-20 12:45:34 +02:00
|
|
|
case SpannerSegmentType::END:
|
2016-07-15 14:05:51 +02:00
|
|
|
drawCircledTip = false;
|
2017-03-04 15:01:42 +01:00
|
|
|
l1.setLine(x1, h2, len, h1);
|
|
|
|
l2.setLine(x1, -h2, len, -h1);
|
2016-07-15 14:05:51 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
break;
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::DECRESC_HAIRPIN: {
|
|
|
|
switch (spannerSegmentType()) {
|
2016-07-15 14:05:51 +02:00
|
|
|
case SpannerSegmentType::SINGLE:
|
|
|
|
case SpannerSegmentType::END:
|
2017-03-04 15:01:42 +01:00
|
|
|
l1.setLine(x1, h1, len - circledTipRadius * 2, 0.0);
|
|
|
|
l2.setLine(x1, -h1, len - circledTipRadius * 2, 0.0);
|
2016-07-15 14:05:51 +02:00
|
|
|
circledTip.setX(len - circledTipRadius);
|
|
|
|
circledTip.setY(0.0);
|
|
|
|
break;
|
|
|
|
case SpannerSegmentType::BEGIN:
|
|
|
|
case SpannerSegmentType::MIDDLE:
|
|
|
|
drawCircledTip = false;
|
2017-03-04 15:01:42 +01:00
|
|
|
l1.setLine(x1, h1, len, + h2);
|
|
|
|
l2.setLine(x1, -h1, len, - h2);
|
2016-07-15 14:05:51 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2012-05-26 14:26:10 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-07-15 14:05:51 +02:00
|
|
|
|
|
|
|
// Do Coord rotation
|
|
|
|
l1 = t.map(l1);
|
|
|
|
l2 = t.map(l2);
|
|
|
|
if (drawCircledTip )
|
|
|
|
circledTip = t.map(circledTip);
|
|
|
|
|
2016-07-20 12:45:34 +02:00
|
|
|
points[0] = l1.p1();
|
|
|
|
points[1] = l1.p2();
|
|
|
|
points[2] = l2.p1();
|
|
|
|
points[3] = l2.p2();
|
|
|
|
npoints = 4;
|
|
|
|
|
2016-07-15 14:05:51 +02:00
|
|
|
QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized();
|
2017-03-04 15:01:42 +01:00
|
|
|
if (!_text->empty())
|
|
|
|
r |= _text->bbox();
|
2018-03-27 15:36:00 +02:00
|
|
|
qreal w = score()->styleP(Sid::hairpinLineWidth);
|
2016-07-15 14:05:51 +02:00
|
|
|
setbbox(r.adjusted(-w*.5, -w*.5, w, w));
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2018-11-05 12:04:51 +01:00
|
|
|
if (!parent()) {
|
|
|
|
rpos() = QPointF();
|
|
|
|
roffset() = QPointF();
|
2018-09-17 14:35:02 +02:00
|
|
|
return;
|
2018-11-05 12:04:51 +01:00
|
|
|
}
|
2018-09-11 16:26:27 +02:00
|
|
|
|
2018-11-05 11:49:28 +01:00
|
|
|
if (isStyled(Pid::OFFSET))
|
|
|
|
roffset() = hairpin()->propertyDefault(Pid::OFFSET).toPointF();
|
2018-09-17 14:35:02 +02:00
|
|
|
if (autoplace()) {
|
|
|
|
qreal minDistance = spatium() * .7;
|
|
|
|
qreal ymax = pos().y();
|
2018-09-11 16:26:27 +02:00
|
|
|
|
2018-09-17 14:35:02 +02:00
|
|
|
SkylineLine sl(!hairpin()->placeAbove());
|
|
|
|
sl.add(shape().translated(pos()));
|
|
|
|
if (hairpin()->placeAbove()) {
|
|
|
|
qreal d = system()->topDistance(staffIdx(), sl);
|
|
|
|
if (d > -minDistance)
|
|
|
|
ymax -= d + minDistance;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
qreal d = system()->bottomDistance(staffIdx(), sl);
|
|
|
|
if (d > -minDistance)
|
|
|
|
ymax += d + minDistance;
|
2016-07-15 14:05:51 +02:00
|
|
|
}
|
2018-10-25 15:43:59 +02:00
|
|
|
rypos() += ymax - pos().y();
|
2016-07-15 14:05:51 +02:00
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2016-07-20 12:45:34 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// shape
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Shape HairpinSegment::shape() const
|
|
|
|
{
|
|
|
|
switch (hairpin()->hairpinType()) {
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::CRESC_HAIRPIN:
|
|
|
|
case HairpinType::DECRESC_HAIRPIN:
|
2016-07-20 12:45:34 +02:00
|
|
|
return Shape(bbox());
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::DECRESC_LINE:
|
|
|
|
case HairpinType::CRESC_LINE:
|
2016-07-20 12:45:34 +02:00
|
|
|
default:
|
2016-08-30 14:03:26 +02:00
|
|
|
return TextLineBaseSegment::shape();
|
2016-07-20 12:45:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-26 15:26:18 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// updateGrips
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
void HairpinSegment::updateGrips(EditData& ed) const
|
2013-07-26 15:26:18 +02:00
|
|
|
{
|
|
|
|
qreal _spatium = spatium();
|
|
|
|
qreal x = pos2().x();
|
|
|
|
if (x < _spatium) // minimum size of hairpin
|
|
|
|
x = _spatium;
|
|
|
|
qreal y = pos2().y();
|
|
|
|
QPointF p(x, y);
|
2014-02-26 21:28:00 +01:00
|
|
|
|
2017-06-13 17:23:11 +02:00
|
|
|
// Calc QPointF for Grip Aperture
|
2014-02-26 21:28:00 +01:00
|
|
|
QTransform doRotation;
|
|
|
|
QPointF gripLineAperturePoint;
|
|
|
|
qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5;
|
|
|
|
qreal len = sqrt( x * x + y * y );
|
2017-06-13 17:23:11 +02:00
|
|
|
doRotation.rotateRadians(asin(y/len));
|
2014-02-26 21:28:00 +01:00
|
|
|
qreal lineApertureX;
|
|
|
|
qreal offsetX = 10; // Horizontal offset for x Grip
|
2017-06-13 17:23:11 +02:00
|
|
|
if (len < offsetX * 3) // For small hairpin, offset = 30% of len
|
2014-03-06 21:10:33 +01:00
|
|
|
offsetX = len/3; // else offset is fixed to 10
|
2014-02-26 21:28:00 +01:00
|
|
|
|
2016-09-22 17:28:44 +02:00
|
|
|
if (hairpin()->hairpinType() == HairpinType::CRESC_HAIRPIN)
|
2014-02-26 21:28:00 +01:00
|
|
|
lineApertureX = len - offsetX; // End of CRESCENDO - Offset
|
2016-07-15 14:05:51 +02:00
|
|
|
else
|
2014-02-26 21:28:00 +01:00
|
|
|
lineApertureX = offsetX; // Begin of DECRESCENDO + Offset
|
|
|
|
qreal lineApertureH = ( len - offsetX ) * h1/len; // Vertical position for y grip
|
|
|
|
gripLineAperturePoint.setX( lineApertureX );
|
|
|
|
gripLineAperturePoint.setY( lineApertureH );
|
2018-11-05 18:51:35 +01:00
|
|
|
gripLineAperturePoint = doRotation.map(gripLineAperturePoint);
|
2014-02-26 21:28:00 +01:00
|
|
|
|
2017-06-13 17:23:11 +02:00
|
|
|
// End calc position grip aperture
|
2018-11-05 18:51:35 +01:00
|
|
|
QPointF pp(pagePos());
|
|
|
|
ed.grip[int(Grip::START)].translate(pp);
|
|
|
|
ed.grip[int(Grip::END)].translate(p + pp);
|
|
|
|
ed.grip[int(Grip::MIDDLE)].translate(p * .5 + pp);
|
2017-06-13 17:23:11 +02:00
|
|
|
ed.grip[int(Grip::APERTURE)].translate(gripLineAperturePoint + pp);
|
2017-03-31 13:03:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// startEdit
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void HairpinSegment::startEdit(EditData& ed)
|
|
|
|
{
|
|
|
|
ed.grips = 4;
|
|
|
|
ed.curGrip = Grip::END;
|
2017-07-26 09:59:24 +02:00
|
|
|
Element::startEdit(ed);
|
2017-03-31 13:03:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// startEditDrag
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void HairpinSegment::startEditDrag(EditData& ed)
|
|
|
|
{
|
|
|
|
TextLineBaseSegment::startEditDrag(ed);
|
2017-07-26 09:59:24 +02:00
|
|
|
ElementEditData* eed = ed.getData(this);
|
2017-03-31 13:03:15 +02:00
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
eed->pushProperty(Pid::HAIRPIN_HEIGHT);
|
|
|
|
eed->pushProperty(Pid::HAIRPIN_CONT_HEIGHT);
|
2014-02-26 21:28:00 +01:00
|
|
|
}
|
2015-01-19 12:37:17 +01:00
|
|
|
|
2014-02-26 21:28:00 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// editDrag
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
void HairpinSegment::editDrag(EditData& ed)
|
2014-02-26 21:28:00 +01:00
|
|
|
{
|
2015-01-19 12:37:17 +01:00
|
|
|
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));
|
2016-06-14 10:32:34 +02:00
|
|
|
triggerLayout();
|
2015-01-19 12:37:17 +01:00
|
|
|
}
|
2017-06-13 17:23:11 +02:00
|
|
|
TextLineBaseSegment::editDrag(ed);
|
2013-07-26 15:26:18 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// draw
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void HairpinSegment::draw(QPainter* painter) const
|
|
|
|
{
|
2016-08-30 14:03:26 +02:00
|
|
|
TextLineBaseSegment::draw(painter);
|
2015-08-29 06:18:59 +02:00
|
|
|
|
2013-05-02 16:12:17 +02:00
|
|
|
QColor color;
|
2017-10-22 22:38:29 +02:00
|
|
|
if ((selected() && !(score() && score()->printing())) || !hairpin()->visible())
|
|
|
|
color = curColor();
|
2013-05-02 16:12:17 +02:00
|
|
|
else
|
2015-08-29 06:18:59 +02:00
|
|
|
color = hairpin()->lineColor();
|
2018-05-07 19:05:34 +02:00
|
|
|
QPen pen(color, hairpin()->lineWidth(), hairpin()->lineStyle());
|
2012-05-26 14:26:10 +02:00
|
|
|
painter->setPen(pen);
|
2016-07-15 14:05:51 +02:00
|
|
|
|
|
|
|
if (drawCircledTip) {
|
2015-08-23 22:08:14 +02:00
|
|
|
painter->setBrush(Qt::NoBrush);
|
|
|
|
painter->drawEllipse( circledTip,circledTipRadius,circledTipRadius );
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2013-03-27 17:52:26 +01:00
|
|
|
//---------------------------------------------------------
|
2018-07-24 15:48:24 +02:00
|
|
|
// propertyDelegate
|
2013-03-27 17:52:26 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2018-07-24 15:48:24 +02:00
|
|
|
Element* HairpinSegment::propertyDelegate(Pid pid)
|
2013-03-27 17:52:26 +01:00
|
|
|
{
|
2018-08-08 14:16:17 +02:00
|
|
|
if (pid == Pid::HAIRPIN_TYPE
|
|
|
|
|| pid == Pid::VELO_CHANGE
|
|
|
|
|| pid == Pid::HAIRPIN_CIRCLEDTIP
|
2018-08-01 11:46:07 +02:00
|
|
|
|| pid == Pid::HAIRPIN_HEIGHT
|
|
|
|
|| pid == Pid::HAIRPIN_CONT_HEIGHT
|
|
|
|
|| pid == Pid::DYNAMIC_RANGE)
|
2018-07-24 15:48:24 +02:00
|
|
|
return spanner();
|
|
|
|
return TextLineBaseSegment::propertyDelegate(pid);
|
2013-08-09 11:42:24 +02:00
|
|
|
}
|
|
|
|
|
2018-11-05 11:49:28 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// getPropertyStyle
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Sid HairpinSegment::getPropertyStyle(Pid pid) const
|
|
|
|
{
|
|
|
|
if (pid == Pid::OFFSET)
|
|
|
|
return spanner()->placeAbove() ? Sid::hairpinPosAbove : Sid::hairpinPosBelow;
|
|
|
|
return TextLineBaseSegment::getPropertyStyle(pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
Sid Hairpin::getPropertyStyle(Pid pid) const
|
|
|
|
{
|
|
|
|
if (pid == Pid::OFFSET)
|
|
|
|
return placeAbove() ? Sid::hairpinPosAbove : Sid::hairpinPosBelow;
|
|
|
|
return TextLineBase::getPropertyStyle(pid);
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// Hairpin
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Hairpin::Hairpin(Score* s)
|
2016-08-30 14:03:26 +02:00
|
|
|
: TextLineBase(s)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2018-08-01 11:46:07 +02:00
|
|
|
initElementStyle(&hairpinStyle);
|
2018-05-07 11:28:27 +02:00
|
|
|
|
2018-04-27 14:08:23 +02:00
|
|
|
resetProperty(Pid::BEGIN_TEXT_PLACE);
|
2018-05-07 11:28:27 +02:00
|
|
|
resetProperty(Pid::HAIRPIN_TYPE);
|
|
|
|
resetProperty(Pid::LINE_VISIBLE);
|
2018-10-25 15:43:59 +02:00
|
|
|
// resetProperty(Pid::LINE_WITH);
|
2018-04-27 14:08:23 +02:00
|
|
|
|
2017-03-04 15:01:42 +01:00
|
|
|
_hairpinCircledTip = false;
|
|
|
|
_veloChange = 0;
|
|
|
|
_dynRange = Dynamic::Range::PART;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2016-07-15 14:05:51 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setHairpinType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-09-22 17:28:44 +02:00
|
|
|
void Hairpin::setHairpinType(HairpinType val)
|
2016-07-15 14:05:51 +02:00
|
|
|
{
|
|
|
|
if (_hairpinType == val)
|
|
|
|
return;
|
|
|
|
_hairpinType = val;
|
|
|
|
switch (_hairpinType) {
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::CRESC_HAIRPIN:
|
|
|
|
case HairpinType::DECRESC_HAIRPIN:
|
2016-07-15 14:05:51 +02:00
|
|
|
setBeginText("");
|
|
|
|
setContinueText("");
|
|
|
|
setLineStyle(Qt::SolidLine);
|
|
|
|
break;
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::CRESC_LINE:
|
2016-07-15 14:05:51 +02:00
|
|
|
setBeginText("cresc.");
|
|
|
|
setContinueText("(cresc.)");
|
|
|
|
setLineStyle(Qt::CustomDashLine);
|
|
|
|
break;
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::DECRESC_LINE:
|
2016-07-15 14:05:51 +02:00
|
|
|
setBeginText("dim.");
|
|
|
|
setContinueText("(dim.)");
|
|
|
|
setLineStyle(Qt::CustomDashLine);
|
|
|
|
break;
|
2018-05-07 19:05:34 +02:00
|
|
|
case HairpinType::INVALID:
|
|
|
|
break;
|
2016-07-15 14:05:51 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// layout
|
|
|
|
// compute segments from tick() to _tick2
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Hairpin::layout()
|
|
|
|
{
|
|
|
|
setPos(0.0, 0.0);
|
2016-08-30 14:03:26 +02:00
|
|
|
TextLineBase::layout();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// createLineSegment
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2018-11-05 11:49:28 +01:00
|
|
|
static const ElementStyle hairpinSegmentStyle {
|
|
|
|
{ Sid::hairpinPosBelow, Pid::OFFSET },
|
|
|
|
};
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
LineSegment* Hairpin::createLineSegment()
|
|
|
|
{
|
2018-10-25 15:43:59 +02:00
|
|
|
HairpinSegment* h = new HairpinSegment(score());
|
2018-11-05 11:49:28 +01:00
|
|
|
h->initElementStyle(&hairpinSegmentStyle);
|
2018-10-25 15:43:59 +02:00
|
|
|
return h;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// write
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-11-19 11:51:21 +01:00
|
|
|
void Hairpin::write(XmlWriter& xml) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2014-08-13 15:42:40 +02:00
|
|
|
if (!xml.canWrite(this))
|
|
|
|
return;
|
2018-09-26 12:20:00 +02:00
|
|
|
xml.stag(this);
|
2014-05-21 15:45:01 +02:00
|
|
|
xml.tag("subtype", int(_hairpinType));
|
2018-03-27 15:36:00 +02:00
|
|
|
writeProperty(xml, Pid::VELO_CHANGE);
|
|
|
|
writeProperty(xml, Pid::HAIRPIN_CIRCLEDTIP);
|
|
|
|
writeProperty(xml, Pid::DYNAMIC_RANGE);
|
|
|
|
writeProperty(xml, Pid::BEGIN_TEXT);
|
|
|
|
writeProperty(xml, Pid::CONTINUE_TEXT);
|
2018-03-27 14:40:34 +02:00
|
|
|
|
2018-10-25 15:43:59 +02:00
|
|
|
for (const StyledProperty& spp : *styledProperties()) {
|
|
|
|
if (!isStyled(spp.pid))
|
|
|
|
writeProperty(xml, spp.pid);
|
|
|
|
}
|
2018-11-12 11:56:31 +01:00
|
|
|
SLine::writeProperties(xml);
|
2012-05-26 14:26:10 +02:00
|
|
|
xml.etag();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// read
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-01-11 18:10:18 +01:00
|
|
|
void Hairpin::read(XmlReader& e)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
foreach(SpannerSegment* seg, spannerSegments())
|
|
|
|
delete seg;
|
|
|
|
spannerSegments().clear();
|
2013-01-11 18:10:18 +01:00
|
|
|
|
|
|
|
while (e.readNextStartElement()) {
|
|
|
|
const QStringRef& tag(e.name());
|
2012-05-26 14:26:10 +02:00
|
|
|
if (tag == "subtype")
|
2016-09-22 17:28:44 +02:00
|
|
|
setHairpinType(HairpinType(e.readInt()));
|
2018-03-27 14:40:34 +02:00
|
|
|
else if (readStyledProperty(e, tag))
|
|
|
|
;
|
2014-02-24 11:13:46 +01:00
|
|
|
else if (tag == "hairpinCircledTip")
|
|
|
|
_hairpinCircledTip = e.readInt();
|
2012-05-26 14:26:10 +02:00
|
|
|
else if (tag == "veloChange")
|
2013-01-11 18:10:18 +01:00
|
|
|
_veloChange = e.readInt();
|
2012-10-31 10:15:45 +01:00
|
|
|
else if (tag == "dynType")
|
2014-06-24 16:42:47 +02:00
|
|
|
_dynRange = Dynamic::Range(e.readInt());
|
2016-07-25 12:29:24 +02:00
|
|
|
else if (tag == "useTextLine") { // obsolete
|
|
|
|
e.readInt();
|
2016-09-22 17:28:44 +02:00
|
|
|
if (hairpinType() == HairpinType::CRESC_HAIRPIN)
|
|
|
|
setHairpinType(HairpinType::CRESC_LINE);
|
|
|
|
else if (hairpinType() == HairpinType::DECRESC_HAIRPIN)
|
|
|
|
setHairpinType(HairpinType::DECRESC_LINE);
|
2016-07-25 12:29:24 +02:00
|
|
|
}
|
2016-08-30 14:03:26 +02:00
|
|
|
else if (!TextLineBase::readProperties(e))
|
2013-01-11 18:10:18 +01:00
|
|
|
e.unknown();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-18 09:28:28 +02:00
|
|
|
//---------------------------------------------------------
|
2013-03-05 20:23:59 +01:00
|
|
|
// undoSetHairpinType
|
2012-09-18 09:28:28 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-09-22 17:28:44 +02:00
|
|
|
void Hairpin::undoSetHairpinType(HairpinType val)
|
2012-09-18 09:28:28 +02:00
|
|
|
{
|
2018-03-27 15:36:00 +02:00
|
|
|
undoChangeProperty(Pid::HAIRPIN_TYPE, int(val));
|
2012-09-18 09:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// undoSetVeloChange
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Hairpin::undoSetVeloChange(int val)
|
|
|
|
{
|
2018-03-27 15:36:00 +02:00
|
|
|
undoChangeProperty(Pid::VELO_CHANGE, val);
|
2012-09-18 09:28:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// undoSetDynType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-06-24 16:42:47 +02:00
|
|
|
void Hairpin::undoSetDynRange(Dynamic::Range val)
|
2012-09-18 09:28:28 +02:00
|
|
|
{
|
2018-03-27 15:36:00 +02:00
|
|
|
undoChangeProperty(Pid::DYNAMIC_RANGE, int(val));
|
2012-10-31 10:15:45 +01:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// getProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
QVariant Hairpin::getProperty(Pid id) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2013-05-02 16:12:17 +02:00
|
|
|
switch (id) {
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_CIRCLEDTIP:
|
2014-02-24 11:13:46 +01:00
|
|
|
return _hairpinCircledTip;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_TYPE:
|
2014-05-21 15:45:01 +02:00
|
|
|
return int(_hairpinType);
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::VELO_CHANGE:
|
2012-09-18 09:28:28 +02:00
|
|
|
return _veloChange;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::DYNAMIC_RANGE:
|
2014-05-21 15:48:18 +02:00
|
|
|
return int(_dynRange);
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_HEIGHT:
|
2016-03-05 15:31:26 +01:00
|
|
|
return _hairpinHeight;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_CONT_HEIGHT:
|
2016-03-05 15:31:26 +01:00
|
|
|
return _hairpinContHeight;
|
2012-09-18 09:28:28 +02:00
|
|
|
default:
|
2016-08-30 14:03:26 +02:00
|
|
|
return TextLineBase::getProperty(id);
|
2012-09-18 09:28:28 +02:00
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
bool Hairpin::setProperty(Pid id, const QVariant& v)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2013-05-02 16:12:17 +02:00
|
|
|
switch (id) {
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_CIRCLEDTIP:
|
2014-02-24 11:13:46 +01:00
|
|
|
_hairpinCircledTip = v.toBool();
|
|
|
|
break;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_TYPE:
|
2016-09-22 17:28:44 +02:00
|
|
|
setHairpinType(HairpinType(v.toInt()));
|
2012-09-18 09:28:28 +02:00
|
|
|
setGenerated(false);
|
|
|
|
break;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::VELO_CHANGE:
|
2012-09-18 09:28:28 +02:00
|
|
|
_veloChange = v.toInt();
|
|
|
|
break;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::DYNAMIC_RANGE:
|
2014-06-24 16:42:47 +02:00
|
|
|
_dynRange = Dynamic::Range(v.toInt());
|
2012-10-31 10:15:45 +01:00
|
|
|
break;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_HEIGHT:
|
2016-03-05 15:31:26 +01:00
|
|
|
_hairpinHeight = v.value<Spatium>();
|
2013-08-13 14:26:40 +02:00
|
|
|
break;
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_CONT_HEIGHT:
|
2016-03-05 15:31:26 +01:00
|
|
|
_hairpinContHeight = v.value<Spatium>();
|
2013-08-13 14:26:40 +02:00
|
|
|
break;
|
2012-09-18 09:28:28 +02:00
|
|
|
default:
|
2016-08-30 14:03:26 +02:00
|
|
|
return TextLineBase::setProperty(id, v);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2016-06-14 10:32:34 +02:00
|
|
|
triggerLayout();
|
2012-09-18 09:28:28 +02:00
|
|
|
return true;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2012-10-31 10:15:45 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// propertyDefault
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
QVariant Hairpin::propertyDefault(Pid id) const
|
2012-10-31 10:15:45 +01:00
|
|
|
{
|
2013-05-02 16:12:17 +02:00
|
|
|
switch (id) {
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::HAIRPIN_CIRCLEDTIP:
|
2016-10-13 11:13:45 +02:00
|
|
|
return false;
|
2018-08-08 14:16:17 +02:00
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::VELO_CHANGE:
|
2016-10-13 11:13:45 +02:00
|
|
|
return 0;
|
2018-08-08 14:16:17 +02:00
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::DYNAMIC_RANGE:
|
2016-10-13 11:13:45 +02:00
|
|
|
return int(Dynamic::Range::PART);
|
2018-08-08 14:16:17 +02:00
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::LINE_STYLE:
|
2016-09-22 17:28:44 +02:00
|
|
|
if (_hairpinType == HairpinType::CRESC_HAIRPIN || _hairpinType == HairpinType::DECRESC_HAIRPIN)
|
2016-07-15 14:05:51 +02:00
|
|
|
return int(Qt::SolidLine);
|
|
|
|
return int(Qt::CustomDashLine);
|
2018-08-08 14:16:17 +02:00
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
case Pid::BEGIN_TEXT:
|
|
|
|
case Pid::CONTINUE_TEXT:
|
2018-03-27 14:40:34 +02:00
|
|
|
return QString("");
|
2013-08-09 11:42:24 +02:00
|
|
|
|
2018-04-27 14:08:23 +02:00
|
|
|
case Pid::BEGIN_TEXT_PLACE:
|
|
|
|
return int(PlaceText::LEFT);
|
|
|
|
|
2018-05-07 11:28:27 +02:00
|
|
|
case Pid::LINE_VISIBLE:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case Pid::HAIRPIN_TYPE:
|
|
|
|
return int(HairpinType::CRESC_HAIRPIN);
|
|
|
|
|
2016-07-20 12:45:34 +02:00
|
|
|
default:
|
2018-03-28 10:43:28 +02:00
|
|
|
return TextLineBase::propertyDefault(id);
|
2016-07-20 12:45:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 11:20:21 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// accessibleInfo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-02-04 17:06:32 +01:00
|
|
|
QString Hairpin::accessibleInfo() const
|
2014-07-10 14:13:37 +02:00
|
|
|
{
|
2016-08-30 14:03:26 +02:00
|
|
|
QString rez = TextLineBase::accessibleInfo();
|
2014-07-10 14:13:37 +02:00
|
|
|
switch (hairpinType()) {
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::CRESC_HAIRPIN:
|
2017-02-17 15:09:28 +01:00
|
|
|
rez += ": " + QObject::tr("Crescendo");
|
2014-07-10 14:13:37 +02:00
|
|
|
break;
|
2016-09-22 17:28:44 +02:00
|
|
|
case HairpinType::DECRESC_HAIRPIN:
|
2017-02-17 15:09:28 +01:00
|
|
|
rez += ": " + QObject::tr("Decrescendo");
|
2014-07-10 14:13:37 +02:00
|
|
|
break;
|
|
|
|
default:
|
2017-02-17 15:09:28 +01:00
|
|
|
rez += ": " + QObject::tr("Custom");
|
2014-07-10 14:13:37 +02:00
|
|
|
}
|
|
|
|
return rez;
|
|
|
|
}
|
2015-01-22 11:20:21 +01:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
|
|
|
|