MuseScore/libmscore/articulation.cpp

582 lines
22 KiB
C++
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
2013-11-13 15:08:08 +01:00
// Copyright (C) 2002-2013 Werner Schweer
2012-05-26 14:26:10 +02:00
//
// 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 "articulation.h"
#include "score.h"
#include "chordrest.h"
#include "system.h"
#include "measure.h"
#include "staff.h"
#include "stafftype.h"
#include "undo.h"
#include "page.h"
#include "barline.h"
2013-11-11 16:53:03 +01:00
#include "sym.h"
2012-05-26 14:26:10 +02:00
2013-05-13 18:49:17 +02:00
namespace Ms {
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// Articulation::articulationList
//---------------------------------------------------------
ArticulationInfo Articulation::articulationList[ARTICULATIONS] = {
2013-11-06 15:58:05 +01:00
{ SymId::fermataAbove, SymId::fermataBelow,
2012-05-26 14:26:10 +02:00
"fermata", QT_TRANSLATE_NOOP("articulation", "fermata"),
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
{ SymId::fermataShortAbove, SymId::fermataShortBelow,
"shortfermata", QT_TRANSLATE_NOOP("articulation", "short fermata"),
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
{ SymId::fermataLongAbove, SymId::fermataLongBelow,
"longfermata", QT_TRANSLATE_NOOP("articulation", "long fermata"),
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
{ SymId::fermataVeryLongAbove, SymId::fermataVeryLongBelow,
"verylongfermata", QT_TRANSLATE_NOOP("articulation", "very long fermata"),
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::stringsThumbPosition, SymId::stringsThumbPosition,
2012-05-26 14:26:10 +02:00
"thumb", QT_TRANSLATE_NOOP("articulation", "thumb"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::articAccent, SymId::articAccent,
2012-05-26 14:26:10 +02:00
"sforzato", QT_TRANSLATE_NOOP("articulation", "sforzato"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
// <> not available in smufl?
// { esprSym, esprSym ,
// "espressivo", QT_TRANSLATE_NOOP("articulation", "espressivo"),
// 1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
// },
2013-11-06 15:58:05 +01:00
{ SymId::articStaccato, SymId::articStaccato,
2012-05-26 14:26:10 +02:00
"staccato", QT_TRANSLATE_NOOP("articulation", "staccato"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::articStaccatissimoAbove, SymId::articStaccatissimoBelow,
2012-05-26 14:26:10 +02:00
"staccatissimo", QT_TRANSLATE_NOOP("articulation", "staccatissimo"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
{ SymId::articTenuto, SymId::articTenuto,
2012-05-26 14:26:10 +02:00
"tenuto", QT_TRANSLATE_NOOP("articulation", "tenuto"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::articTenutoSlurAbove, SymId::articTenutoSlurBelow,
2012-05-26 14:26:10 +02:00
"portato", QT_TRANSLATE_NOOP("articulation", "portato"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::articMarcatoAbove, SymId::articMarcatoBelow,
2012-05-26 14:26:10 +02:00
"marcato", QT_TRANSLATE_NOOP("articulation", "marcato"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-13 15:08:08 +01:00
{ SymId::brassMuteOpen, SymId::brassMuteOpen,
"ouvert", QT_TRANSLATE_NOOP("articulation", "ouvert"),
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
},
{ SymId::brassMuteClosed, SymId::brassMuteClosed,
2013-12-05 19:02:55 +01:00
"plusstop", QT_TRANSLATE_NOOP("articulation", "stopped/pizzicato left hand"),
2013-11-13 15:08:08 +01:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
},
2013-11-11 15:11:28 +01:00
{ SymId::stringsUpBow, SymId::stringsUpBow,
"upbow", QT_TRANSLATE_NOOP("articulation", "up bow"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::stringsDownBow, SymId::stringsDownBow,
"downbow", QT_TRANSLATE_NOOP("articulation", "down bow"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentTurnInverted, SymId::ornamentTurnInverted,
"reverseturn", QT_TRANSLATE_NOOP("articulation", "reverse turn"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
{ SymId::ornamentTurn, SymId::ornamentTurn,
2012-05-26 14:26:10 +02:00
"turn", QT_TRANSLATE_NOOP("articulation", "turn"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentTrill, SymId::ornamentTrill,
2012-05-26 14:26:10 +02:00
"trill", QT_TRANSLATE_NOOP("articulation", "trill"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentMordent, SymId::ornamentMordent,
2012-05-26 14:26:10 +02:00
"prall", QT_TRANSLATE_NOOP("articulation", "prall"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentMordentInverted, SymId::ornamentMordentInverted,
2012-05-26 14:26:10 +02:00
"mordent", QT_TRANSLATE_NOOP("articulation", "mordent"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentTremblement, SymId::ornamentTremblement,
"prallprall", QT_TRANSLATE_NOOP("articulation", "prall prall"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentPrallMordent, SymId::ornamentPrallMordent,
"prallmordent", QT_TRANSLATE_NOOP("articulation", "prall mordent"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentUpPrall, SymId::ornamentUpPrall,
"upprall", QT_TRANSLATE_NOOP("articulation", "up prall"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentDownPrall, SymId::ornamentDownPrall,
"downprall", QT_TRANSLATE_NOOP("articulation", "down prall"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentUpMordent, SymId::ornamentUpMordent,
"upmordent", QT_TRANSLATE_NOOP("articulation", "up mordent"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentDownMordent, SymId::ornamentDownMordent,
"downmordent", QT_TRANSLATE_NOOP("articulation", "down mordent"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentPrallDown, SymId::ornamentPrallDown,
"pralldown", QT_TRANSLATE_NOOP("articulation", "prall down"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentPrallUp, SymId::ornamentPrallUp,
"prallup", QT_TRANSLATE_NOOP("articulation", "prall up"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentLinePrall, SymId::ornamentLinePrall,
"lineprall", QT_TRANSLATE_NOOP("articulation", "line prall"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-11 15:11:28 +01:00
{ SymId::ornamentPrecompSlide, SymId::ornamentPrecompSlide,
2012-05-26 14:26:10 +02:00
"schleifer", QT_TRANSLATE_NOOP("articulation", "schleifer"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
{ SymId::pluckedSnapPizzicatoAbove, SymId::pluckedSnapPizzicatoAbove,
"snappizzicato", QT_TRANSLATE_NOOP("articulation", "snap pizzicato"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_PITCHED_STAFF | ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
#if 0
2012-05-26 14:26:10 +02:00
{ letterTSym, letterTSym,
"tapping", QT_TRANSLATE_NOOP("articulation", "tapping"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
{ letterSSym, letterSSym,
"slapping", QT_TRANSLATE_NOOP("articulation", "slapping"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
{ letterPSym, letterPSym,
"popping", QT_TRANSLATE_NOOP("articulation", "popping"),
2013-06-03 14:39:59 +02:00
1.0, ARTICULATION_SHOW_IN_TABLATURE
2012-05-26 14:26:10 +02:00
},
2013-11-06 15:58:05 +01:00
#endif
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
// Articulation
//---------------------------------------------------------
Articulation::Articulation(Score* s)
: Element(s)
{
2012-08-04 15:46:43 +02:00
_direction = MScore::AUTO;
2012-05-26 14:26:10 +02:00
_up = true;
setFlags(ELEMENT_MOVABLE | ELEMENT_SELECTABLE);
setArticulationType(Articulation_Fermata);
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// setArticulationType
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
void Articulation::setArticulationType(ArticulationType idx)
2012-05-26 14:26:10 +02:00
{
_articulationType = idx;
_anchor = score()->style()->articulationAnchor(_articulationType);
anchorStyle = PropertyStyle::STYLED;
2013-06-03 14:39:59 +02:00
_timeStretch = articulationList[articulationType()].timeStretch;
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// read
//---------------------------------------------------------
2013-01-11 18:10:18 +01:00
void Articulation::read(XmlReader& e)
2012-05-26 14:26:10 +02:00
{
setArticulationType(Articulation_Fermata); // default // backward compatibility (no type = ufermata in 1.2)
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")
2013-01-11 18:10:18 +01:00
setSubtype(e.readElementText());
else if (tag == "channel") {
2012-05-26 14:26:10 +02:00
_channelName = e.attribute("name");
2013-01-11 18:10:18 +01:00
e.readNext();
}
else if (tag == "anchor") {
2013-01-11 18:10:18 +01:00
_anchor = ArticulationAnchor(e.readInt());
anchorStyle = PropertyStyle::UNSTYLED;
}
2012-05-26 14:26:10 +02:00
else if (tag == "direction") {
2013-06-06 11:55:02 +02:00
setProperty(P_DIRECTION, Ms::getProperty(P_DIRECTION, e));
2012-05-26 14:26:10 +02:00
}
2013-06-03 14:39:59 +02:00
else if (tag == "timeStretch")
_timeStretch = e.readDouble();
2012-05-26 14:26:10 +02:00
else if (!Element::readProperties(e))
2013-01-11 18:10:18 +01:00
e.unknown();
2012-05-26 14:26:10 +02:00
}
}
//---------------------------------------------------------
// write
//---------------------------------------------------------
void Articulation::write(Xml& xml) const
{
xml.stag("Articulation");
if (!_channelName.isEmpty())
xml.tagE(QString("channel name=\"%1\"").arg(_channelName));
2013-06-06 11:55:02 +02:00
writeProperty(xml, P_DIRECTION);
2013-07-17 09:41:06 +02:00
xml.tag("subtype", subtypeName());
2013-06-03 14:39:59 +02:00
if (_timeStretch != 1.0)
xml.tag("timeStretch", _timeStretch);
2012-05-26 14:26:10 +02:00
Element::writeProperties(xml);
if (anchorStyle == PropertyStyle::UNSTYLED)
2012-05-26 14:26:10 +02:00
xml.tag("anchor", int(_anchor));
xml.etag();
}
//---------------------------------------------------------
// subtypeName
//---------------------------------------------------------
QString Articulation::subtypeName() const
{
return articulationList[articulationType()].name;
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// setSubtype
//---------------------------------------------------------
void Articulation::setSubtype(const QString& s)
{
2013-11-12 13:05:29 +01:00
if (s.isEmpty()) {
qDebug("Articulation::setSubtype: empty subtype");
2013-11-19 12:12:07 +01:00
setArticulationType(Articulation_Fermata); // something to debug...
2013-11-12 13:05:29 +01:00
return;
}
2012-05-26 14:26:10 +02:00
if (s[0].isDigit()) { // for backward compatibility
setArticulationType(ArticulationType(s.toInt()));
2012-05-26 14:26:10 +02:00
return;
}
int st;
for (st = 0; st < ARTICULATIONS; ++st) {
if (articulationList[st].name == s)
break;
}
if (st == ARTICULATIONS) {
struct {
const char* name;
bool up;
ArticulationType type;
} al[] = {
{ "umarcato", true, Articulation_Marcato },
{ "dmarcato", false, Articulation_Marcato },
{ "ufermata", true, Articulation_Fermata },
{ "dfermata", false, Articulation_Fermata },
{ "ushortfermata", true, Articulation_Shortfermata },
{ "dshortfermata", false, Articulation_Shortfermata },
{ "ulongfermata", true, Articulation_Longfermata },
{ "dlongfermata", false, Articulation_Longfermata },
{ "uverylongfermata", true, Articulation_Verylongfermata },
{ "dverylongfermata", false, Articulation_Verylongfermata },
// watch out, bug in 1.2 uportato and dportato are reversed
2012-08-04 15:46:43 +02:00
{ "dportato", true, Articulation_Portato },
{ "uportato", false, Articulation_Portato },
2012-05-26 14:26:10 +02:00
{ "ustaccatissimo", true, Articulation_Staccatissimo },
{ "dstaccatissimo", false, Articulation_Staccatissimo }
};
int i;
int n = sizeof(al) / sizeof(*al);
for (i = 0; i < n; ++i) {
if (s == al[i].name) {
_up = al[i].up;
2012-08-04 15:46:43 +02:00
_direction = (_up ? MScore::UP : MScore::DOWN);
2012-05-26 14:26:10 +02:00
st = int(al[i].type);
break;
}
}
if (i == n) {
st = 0;
2013-11-06 15:58:05 +01:00
qDebug("Articulation: unknown <%s>", qPrintable(s));
2012-05-26 14:26:10 +02:00
}
}
setArticulationType(ArticulationType(st));
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// idx2name
//---------------------------------------------------------
QString Articulation::idx2name(int idx)
{
return articulationList[idx].name;
}
//---------------------------------------------------------
// pagePos
//---------------------------------------------------------
QPointF Articulation::pagePos() const
{
if (parent() == 0)
return pos();
return parent()->pagePos() + pos();
}
//---------------------------------------------------------
// canvasPos
//---------------------------------------------------------
QPointF Articulation::canvasPos() const
{
if (parent() == 0)
return pos();
return parent()->canvasPos() + pos();
}
//---------------------------------------------------------
// Symbol::draw
//---------------------------------------------------------
void Articulation::draw(QPainter* painter) const
{
SymId sym = _up ? articulationList[articulationType()].upSym : articulationList[articulationType()].downSym;
int flags = articulationList[articulationType()].flags;
2012-05-26 14:26:10 +02:00
if (staff()) {
Re-factor presets and staff types. 1) Built-in staff types have been removed. 2) Presets are internally used as source for the staff types of a new score, to match data in Instruments.xml and as reference to check for modifications. 3) Each new score is given by default one staff type for each preset with the same name. 4) The Instrument page of the New Score Wizard lists (under the name of "Staff types") the default staff types applicable to the instrument (actually it lists the preset, as the score does not have any staff type yet). 5) The "Add | Instruments" dlg box lists all the staff types applicable to the instrument: = to the list of 4) + any user-created staff type. 6) The Staff Properties dlg box lists all the staff types applicable to the instrument: = list in 5) 7) The Staff Type Editor lists all the staff types This should ensure consistency among the several lists of staff types and avoid duplication of similar items Terminology: 7) A new staff type created in the editor is named by default with the group name ("Standard-", "Perc-", "Tab-") + the index of the new type in its group + the suffix "[*]" marking a user customisation. The user is anyway able to rename it, if he want. 8) The pitched staff type has been renamed everywhere (hopefully!) to "Standard" 9) The term 'preset' have been removed from the UI, except from the Staff Type Editor where it keeps its meaning of ready-made collections of parameters The commit affects many files, but a fair number of them have only changes in names of literals. The files with significant code changes are: libmscore/score.cpp libmscore/stafftype.cpp/.h mscore/editstafftype.cpp (code for naming a new staff type) mscore/instrdialog.cpp (building type list) Note: as score files store staff type indications as integer indices and the number and order of new default staff types is different from the old built-in types, there is a compatibility issue with old 2.0 score which use percussion and tab staves. In Score::read() (libmscore/scorefile.cpp), there is a rudimentary attempt to cope with this.Old scores will need manual fix anyway. There should not be any (new) compatibility issue with 1.x scores, as they did not use staff types.
2013-08-18 11:55:31 +02:00
if (staff()->staffGroup() == TAB_STAFF_GROUP) {
2012-05-26 14:26:10 +02:00
if (!(flags & ARTICULATION_SHOW_IN_TABLATURE))
return;
}
else {
if (!(flags & ARTICULATION_SHOW_IN_PITCHED_STAFF))
return;
}
}
painter->setPen(curColor());
2013-11-08 10:33:08 +01:00
drawSymbol(sym, painter, QPointF(-0.5 * width(), _up ? 0.0 : height()));
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// chordRest
//---------------------------------------------------------
ChordRest* Articulation::chordRest() const
{
if (parent() && parent()->isChordRest())
return static_cast<ChordRest*>(parent());
return 0;
}
//---------------------------------------------------------
// subtypeUserName
//---------------------------------------------------------
QString Articulation::subtypeUserName() const
{
return articulationList[articulationType()].description;
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// layout
// height() and width() should return sensible
// values when calling this method
//---------------------------------------------------------
void Articulation::layout()
{
SymId sym = _up ? articulationList[articulationType()].upSym : articulationList[articulationType()].downSym;
2013-11-11 15:11:28 +01:00
QRectF b(symBbox(sym));
setbbox(b.translated(-0.5 * b.width(), _up ? 0.0 : b.height()));
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// setDirection
//---------------------------------------------------------
2012-08-04 15:46:43 +02:00
void Articulation::setDirection(MScore::Direction d)
2012-05-26 14:26:10 +02:00
{
_direction = d;
2012-08-04 15:46:43 +02:00
if (d != MScore::AUTO)
_up = (d == MScore::UP);
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
2012-11-19 10:08:15 +01:00
// reset
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-11-19 10:08:15 +01:00
void Articulation::reset()
2012-05-26 14:26:10 +02:00
{
2012-08-04 15:46:43 +02:00
if (_direction != MScore::AUTO)
score()->undoChangeProperty(this, P_DIRECTION, int(MScore::AUTO));
ArticulationAnchor a = score()->style()->articulationAnchor(articulationType());
2012-05-26 14:26:10 +02:00
if (_anchor != a)
score()->undoChangeProperty(this, P_ARTICULATION_ANCHOR, int(a));
2012-11-19 10:08:15 +01:00
Element::reset();
2012-05-26 14:26:10 +02:00
if (chordRest())
chordRest()->layoutArticulations();
score()->addRefresh(canvasBoundingRect());
}
//---------------------------------------------------------
// dragAnchor
//---------------------------------------------------------
QLineF Articulation::dragAnchor() const
{
return QLineF(canvasPos(), parent()->canvasPos());
}
//---------------------------------------------------------
// getProperty
//---------------------------------------------------------
QVariant Articulation::getProperty(P_ID propertyId) const
{
switch(propertyId) {
case P_DIRECTION: return int(direction());
case P_ARTICULATION_ANCHOR: return int(anchor());
2013-06-03 14:39:59 +02:00
case P_TIME_STRETCH: return timeStretch();
2012-05-26 14:26:10 +02:00
default:
return Element::getProperty(propertyId);
}
}
//---------------------------------------------------------
// setProperty
//---------------------------------------------------------
bool Articulation::setProperty(P_ID propertyId, const QVariant& v)
{
score()->addRefresh(canvasBoundingRect());
switch (propertyId) {
case P_DIRECTION:
setDirection(MScore::Direction(v.toInt()));
break;
case P_ARTICULATION_ANCHOR:
anchorStyle = PropertyStyle::UNSTYLED;
setAnchor(ArticulationAnchor(v.toInt()));
break;
2013-06-03 14:39:59 +02:00
case P_TIME_STRETCH:
setTimeStretch(v.toDouble());
score()->fixTicks();
break;
2012-05-26 14:26:10 +02:00
default:
return Element::setProperty(propertyId, v);
}
score()->addRefresh(canvasBoundingRect());
// layout:
if (chordRest())
chordRest()->layoutArticulations();
else if (parent() && parent()->type() == BAR_LINE)
static_cast<BarLine*>(parent())->layout();
score()->addRefresh(canvasBoundingRect());
score()->setLayoutAll(false); //DEBUG
return true;
}
//---------------------------------------------------------
// propertyDefault
//---------------------------------------------------------
QVariant Articulation::propertyDefault(P_ID propertyId) const
{
switch(propertyId) {
case P_DIRECTION:
return int(MScore::AUTO);
case P_ARTICULATION_ANCHOR:
return int(score()->style()->articulationAnchor(_articulationType));
2013-06-03 14:39:59 +02:00
case P_TIME_STRETCH:
return articulationList[articulationType()].timeStretch;
default:
break;
}
return Element::propertyDefault(propertyId);
}
//---------------------------------------------------------
// propertyStyle
//---------------------------------------------------------
PropertyStyle Articulation::propertyStyle(P_ID id) const
{
switch (id) {
case P_DIRECTION:
case P_TIME_STRETCH:
return PropertyStyle::NOSTYLE;
case P_ARTICULATION_ANCHOR:
return anchorStyle;
default:
break;
}
return Element::propertyStyle(id);
}
//---------------------------------------------------------
// resetProperty
//---------------------------------------------------------
void Articulation::resetProperty(P_ID id)
{
switch (id) {
case P_DIRECTION:
case P_TIME_STRETCH:
return;
case P_ARTICULATION_ANCHOR:
setProperty(id, propertyDefault(id));
anchorStyle = PropertyStyle::STYLED;
return;
default:
break;
}
Element::resetProperty(id);
}
//---------------------------------------------------------
// styleChanged
// reset all styled values to actual style
//---------------------------------------------------------
void Articulation::styleChanged()
{
if (anchorStyle == PropertyStyle::STYLED)
_anchor = score()->style()->articulationAnchor(_articulationType);
}
//---------------------------------------------------------
// mag
//---------------------------------------------------------
qreal Articulation::mag() const
{
return parent() ? parent()->mag() * score()->styleD(ST_articulationMag): 1.0;
}
2013-05-13 18:49:17 +02:00
}