void TempoText::textChanged() { if (!_followText) return; QString s = text(); static const TempoPattern tp[] = { TempoPattern("\\xd834\\xdd5f = (\\d+)", 1.0/60.0), // 1/4 TempoPattern("\\xd834\\xdd5e = (\\d+)", 1.0/30.0), // 1/2 TempoPattern("\\xd834\\xdd60 = (\\d+)", 1.0/120.0), // 1/8 TempoPattern("\\xd834\\xdd5f\\xd834\\xdd6d = (\\d+)", 1.5/60.0), // dotted 1/4 TempoPattern("\\xd834\\xdd5e\\xd834\\xdd6d = (\\d+)", 1.5/30.0), // dotted 1/2 TempoPattern("\\xd834\\xdd60\\xd834\\xdd6d = (\\d+)", 1.5/120.0), // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { QRegExp re(tp[i].pattern); // 1/4 if (re.indexIn(s) != -1) { QStringList sl = re.capturedTexts(); if (sl.size() == 2) { qreal nt = qreal(sl[1].toInt()) * tp[i].f; if (nt != _tempo) { _tempo = qreal(sl[1].toInt()) * tp[i].f; score()->setPlaylistDirty(true); } break; } } } }
Palette* MuseScore::newTempoPalette() { Palette* sp = new Palette; sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo")); sp->setMag(0.65); sp->setGrid(60, 30); sp->setDrawGrid(true); static const TempoPattern tp[] = { TempoPattern("<sym>noteHalfUp</sym> = 80", 80.0/30.0), // 1/2 TempoPattern("<sym>noteQuarterUp</sym> = 80", 80.0/60.0), // 1/4 TempoPattern("<sym>note8thUp</sym> = 80", 80.0/120.0), // 1/8 TempoPattern("<sym>noteHalfUp</sym><sym>textAugmentationDot</sym> = 80", 120/30.0), // dotted 1/2 TempoPattern("<sym>noteQuarterUp</sym><sym>textAugmentationDot</sym> = 80", 120/60.0), // dotted 1/4 TempoPattern("<sym>note8thUp</sym><sym>textAugmentationDot</sym> = 80", 120/120.0), // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { TempoText* tt = new TempoText(gscore); tt->setFollowText(true); tt->setTrack(0); tt->setTempo(tp[i].f); tt->setText(tp[i].pattern); sp->append(tt, tr("Tempo Text"), QString(), 1.5); } return sp; }
Palette* MuseScore::newTempoPalette() { Palette* sp = new Palette; sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo")); sp->setMag(0.65); sp->setGrid(60, 30); sp->setDrawGrid(true); static const TempoPattern tp[] = { TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0), // 1/4 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0), // 1/2 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0), // 1/8 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0), // dotted 1/4 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0), // dotted 1/2 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0) // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { TempoText* tt = new TempoText(gscore); tt->setFollowText(true); tt->setTrack(0); tt->setTempo(tp[i].f); tt->setText(tp[i].pattern); sp->append(tt, tr("Tempo Text"), QString(), 1.5); } return sp; }
Palette* MuseScore::newTempoPalette() { Palette* sp = new Palette; sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo")); sp->setMag(0.65); sp->setGrid(60, 30); sp->setDrawGrid(true); static const TempoPattern tp[] = { TempoPattern("<sym>metNoteHalfUp</sym> = 80", 80.0/30.0), // 1/2 TempoPattern("<sym>metNoteQuarterUp</sym> = 80", 80.0/60.0), // 1/4 TempoPattern("<sym>metNote8thUp</sym> = 80", 80.0/120.0), // 1/8 TempoPattern("<sym>metNoteHalfUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/30.0), // dotted 1/2 TempoPattern("<sym>metNoteQuarterUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/60.0), // dotted 1/4 TempoPattern("<sym>metNote8thUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/120.0), // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { TempoText* tt = new TempoText(gscore); tt->setFollowText(true); // leave track at default (-1) to make it possible // for drop() to tell that this came from palette // (it will then be set to 0 there) //tt->setTrack(0); tt->setTempo(tp[i].f); tt->setXmlText(tp[i].pattern); sp->append(tt, tr("Tempo text"), QString(), 1.5); } return sp; }
Palette* MuseScore::newTextPalette() { Palette* sp = new Palette; sp->setName(QT_TRANSLATE_NOOP("Palette", "Text")); sp->setMag(0.65); sp->setGrid(84, 28); sp->setDrawGrid(true); StaffText* st = new StaffText(gscore); st->setTextStyleType(TEXT_STYLE_STAFF); st->setText(tr("staff-text")); sp->append(st, tr("Staff Text")); st = new StaffText(gscore); st->setTextStyleType(TEXT_STYLE_SYSTEM); st->setText(tr("system-text")); sp->append(st, tr("System Text")); RehearsalMark* rhm = new RehearsalMark(gscore); rhm->setTrack(0); rhm->setText("B1"); sp->append(rhm, tr("Rehearsal Mark")); InstrumentChange* is = new InstrumentChange(gscore); is->setText(tr("Instrument")); sp->append(is, tr("Instrument Change")); Text* text = new Text(gscore); text->setTrack(0); text->setTextStyleType(TEXT_STYLE_LYRICS_VERSE_NUMBER); text->setText(tr("1.")); sp->append(text, tr("Lyrics Verse Number")); static const TempoPattern tp[] = { TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0), // 1/4 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0), // 1/2 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0), // 1/8 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0), // dotted 1/4 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0), // dotted 1/2 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0) // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { TempoText* tt = new TempoText(gscore); tt->setFollowText(true); tt->setTrack(0); tt->setTempo(tp[i].f); tt->setText(tp[i].pattern); sp->append(tt, tr("Tempo Text"), QString(), 1.5); } Harmony* harmony = new Harmony(gscore); harmony->setText("C7"); sp->append(harmony, tr("Chord Name")); return sp; }
namespace Ms { #define MIN_TEMPO 5.0/60 #define MAX_TEMPO 999.0/60 //--------------------------------------------------------- // TempoText //--------------------------------------------------------- TempoText::TempoText(Score* s) : Text(s) { _tempo = 2.0; // propertyDefault(P_TEMPO).toDouble(); _followText = false; _relative = 1.0; _isRelative = false; setPlacement(Element::Placement::ABOVE); setTextStyleType(TextStyleType::TEMPO); } //--------------------------------------------------------- // write //--------------------------------------------------------- void TempoText::write(Xml& xml) const { xml.stag("Tempo"); xml.tag("tempo", _tempo); if (_followText) xml.tag("followText", _followText); Text::writeProperties(xml); xml.etag(); } //--------------------------------------------------------- // read //--------------------------------------------------------- void TempoText::read(XmlReader& e) { while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "tempo") setTempo(e.readDouble()); else if (tag == "followText") _followText = e.readInt(); else if (!Text::readProperties(e)) e.unknown(); } if (score()->mscVersion() <= 114) { // // Reset text in old version to // style. // //TODO if (textStyle() != TextStyleType::INVALID) { // setStyled(true); // styleChanged(); // } } // check sanity if (xmlText().isEmpty()) { setXmlText(QString("<sym>metNoteQuarterUp</sym> = %1").arg(lrint(60 * _tempo))); setVisible(false); } } //--------------------------------------------------------- // TempoPattern //--------------------------------------------------------- struct TempoPattern { const char* pattern; qreal f; TDuration d; TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); } }; // note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp static const TempoPattern tp[] = { TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/60.0, TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4 TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/60.0, TDuration::DurationType::V_QUARTER, 1), // dotted 1/4 TempoPattern("<sym>metNoteQuarterUp</sym>", 1.0/60.0, TDuration::DurationType::V_QUARTER), // 1/4 TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/30.0, TDuration::DurationType::V_HALF, 2), // double dotted 1/2 TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/30.0, TDuration::DurationType::V_HALF, 1), // dotted 1/2 TempoPattern("<sym>metNoteHalfUp</sym>", 1.0/30.0, TDuration::DurationType::V_HALF), // 1/2 TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/120.0, TDuration::DurationType::V_EIGHTH, 2), // double dotted 1/8 TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/120.0, TDuration::DurationType::V_EIGHTH, 1), // dotted 1/8 TempoPattern("<sym>metNote8thUp</sym>", 1.0/120.0, TDuration::DurationType::V_EIGHTH), // 1/8 TempoPattern("<sym>metNoteWhole</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/15.0, TDuration::DurationType::V_WHOLE, 1), // dotted whole TempoPattern("<sym>metNoteWhole</sym>", 1.0/15.0, TDuration::DurationType::V_WHOLE), // whole TempoPattern("<sym>metNote16thUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/240.0, TDuration::DurationType::V_16TH, 1), // dotted 1/16 TempoPattern("<sym>metNote16thUp</sym>", 1.0/240.0, TDuration::DurationType::V_16TH), // 1/16 TempoPattern("<sym>metNote32ndUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/480.0, TDuration::DurationType::V_32ND, 1), // dotted 1/32 TempoPattern("<sym>metNote32ndUp</sym>", 1.0/480.0, TDuration::DurationType::V_32ND), // 1/32 TempoPattern("<sym>metNoteDoubleWholeSquare</sym>", 1.0/7.5, TDuration::DurationType::V_BREVE), // longa TempoPattern("<sym>metNoteDoubleWhole</sym>", 1.0/7.5, TDuration::DurationType::V_BREVE), // double whole TempoPattern("<sym>metNote64thUp</sym>", 1.0/960.0, TDuration::DurationType::V_64TH), // 1/64 TempoPattern("<sym>metNote128thUp</sym>", 1.0/1920.0,TDuration::DurationType::V_128TH), // 1/128 }; //--------------------------------------------------------- // findTempoDuration // find the duration part (note + dot) of a tempo text in string s // return the match position or -1 if not found // set len to the match length and dur to the duration value //--------------------------------------------------------- int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur) { len = 0; dur = TDuration(); for (const auto& i : tp) { QRegExp re(i.pattern); int pos = re.indexIn(s); if (pos != -1) { len = re.matchedLength(); dur = i.d; return pos; } } return -1; } //--------------------------------------------------------- // duration2tempoTextString // find the tempoText string representation for duration //--------------------------------------------------------- QString TempoText::duration2tempoTextString(const TDuration dur) { for (const TempoPattern& pa : tp) { if (pa.d == dur) { QString res = pa.pattern; res.remove("\\s*"); return res; } } return ""; } //--------------------------------------------------------- // updateScore //--------------------------------------------------------- void TempoText::updateScore() { if (segment()) score()->setTempo(segment(), _tempo); score()->fixTicks(); score()->setPlaylistDirty(); } //--------------------------------------------------------- // updateRelative //--------------------------------------------------------- void TempoText::updateRelative() { qreal tempoBefore = score()->tempo(tick() - 1); setTempo(tempoBefore * _relative); } //--------------------------------------------------------- // textChanged // text may have changed //--------------------------------------------------------- void TempoText::textChanged() { if (!_followText) return; QString s = plainText(); s.replace(",", "."); s.replace("<sym>space</sym>"," "); for (const TempoPattern& pa : tp) { QRegExp re(QString(pa.pattern)+"\\s*=\\s*(\\d+[.]{0,1}\\d*)\\s*"); if (re.indexIn(s) != -1) { QStringList sl = re.capturedTexts(); if (sl.size() == 2) { qreal nt = qreal(sl[1].toDouble()) * pa.f; if (nt != _tempo) { setTempo(qreal(sl[1].toDouble()) * pa.f); _relative = 1.0; _isRelative = false; updateScore(); } break; } } else { for (const TempoPattern& pa2 : tp) { QRegExp re(QString("%1\\s*=\\s*%2\\s*").arg(pa.pattern).arg(pa2.pattern)); if (re.indexIn(s) != -1) { _relative = pa2.f / pa.f; _isRelative = true; updateRelative(); updateScore(); return; } } } } } //--------------------------------------------------------- // setTempo //--------------------------------------------------------- void TempoText::setTempo(qreal v) { if (v < MIN_TEMPO) v = MIN_TEMPO; else if (v > MAX_TEMPO) v = MAX_TEMPO; _tempo = v; } //--------------------------------------------------------- // undoSetTempo //--------------------------------------------------------- void TempoText::undoSetTempo(qreal v) { undoChangeProperty(P_ID::TEMPO, v); } //--------------------------------------------------------- // undoSetFollowText //--------------------------------------------------------- void TempoText::undoSetFollowText(bool v) { undoChangeProperty(P_ID::TEMPO_FOLLOW_TEXT, v); } //--------------------------------------------------------- // getProperty //--------------------------------------------------------- QVariant TempoText::getProperty(P_ID propertyId) const { switch(propertyId) { case P_ID::TEMPO: return _tempo; case P_ID::TEMPO_FOLLOW_TEXT: return _followText; default: return Text::getProperty(propertyId); } } //--------------------------------------------------------- // setProperty //--------------------------------------------------------- bool TempoText::setProperty(P_ID propertyId, const QVariant& v) { switch(propertyId) { case P_ID::TEMPO: setTempo(v.toDouble()); score()->setTempo(segment(), _tempo); score()->fixTicks(); break; case P_ID::TEMPO_FOLLOW_TEXT: _followText = v.toBool(); break; default: if (!Text::setProperty(propertyId, v)) return false; break; } score()->setLayoutAll(); return true; } //--------------------------------------------------------- // propertyDefault //--------------------------------------------------------- QVariant TempoText::propertyDefault(P_ID id) const { switch(id) { case P_ID::TEMPO: return 2.0; case P_ID::TEMPO_FOLLOW_TEXT: return false; case P_ID::PLACEMENT: return int(Element::Placement::ABOVE); default: return Text::propertyDefault(id); } } //--------------------------------------------------------- // layout // called after Measure->stretchMeasure() //--------------------------------------------------------- void TempoText::layout() { setPos(textStyle().offset(spatium())); Text::layout1(); // tempo text on first chordrest of measure should align over time sig if present // Segment* s = segment(); if (s && !s->rtick()) { Segment* p = segment()->prev(Segment::Type::TimeSig); if (p) { rxpos() -= s->x() - p->x(); Element* e = p->element(staffIdx() * VOICES); if (e) rxpos() += e->x(); } } if (placement() == Element::Placement::BELOW) rypos() = -rypos() + 4 * spatium(); adjustReadPos(); } QString TempoText::duration2userName(const TDuration t) { QString dots; switch (t.dots()) { case 1: dots = tr("Dotted %1").arg(t.durationTypeUserName()); break; case 2: dots = tr("Double dotted %1").arg(t.durationTypeUserName()); break; case 3: dots = tr("Triple dotted %1").arg(t.durationTypeUserName()); break; case 4: dots = tr("Quadruple dotted %1").arg(t.durationTypeUserName()); break; default: dots = t.durationTypeUserName(); break; } return dots; } //--------------------------------------------------------- // accessibleInfo //--------------------------------------------------------- QString TempoText::accessibleInfo() const { TDuration t1; TDuration t2; int len1; int len2; QString text = plainText(); QString firstPart = text.split(" = ").first(); QString secondPart = text.split(" = ").back(); int x1 = findTempoDuration(firstPart, len1, t1); int x2 = -1; if (_relative) x2 = findTempoDuration(secondPart, len2, t2); if (x1 != -1) { QString dots1; QString dots2; dots1 = duration2userName(t1); if (x2 != -1) { dots2 = duration2userName(t2); return QString("%1: %2 %3 = %4 %5").arg(Element::accessibleInfo()).arg(dots1).arg(tr("note")).arg(dots2).arg(tr("note")); } else return QString("%1: %2 %3 = %4").arg(Element::accessibleInfo()).arg(dots1).arg(tr("note")).arg(secondPart); } else return Text::accessibleInfo(); } }
namespace Ms { //--------------------------------------------------------- // TempoText //--------------------------------------------------------- TempoText::TempoText(Score* s) : Text(s) { _tempo = 2.0; // propertyDefault(P_TEMPO).toDouble(); _followText = false; setPlacement(Placement::ABOVE); setTextStyleType(TEXT_STYLE_TEMPO); } //--------------------------------------------------------- // write //--------------------------------------------------------- void TempoText::write(Xml& xml) const { xml.stag("Tempo"); xml.tag("tempo", _tempo); if (_followText) xml.tag("followText", _followText); Text::writeProperties(xml); xml.etag(); } //--------------------------------------------------------- // read //--------------------------------------------------------- void TempoText::read(XmlReader& e) { while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "tempo") _tempo = e.readDouble(); else if (tag == "followText") _followText = e.readInt(); else if (!Text::readProperties(e)) e.unknown(); } if (score()->mscVersion() < 119) { // // Reset text in old version to // style. // //TODO if (textStyle() != TEXT_STYLE_INVALID) { // setStyled(true); // styleChanged(); // } } } //--------------------------------------------------------- // TempoPattern //--------------------------------------------------------- struct TempoPattern { const char* pattern; qreal f; TDuration d; TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); } }; // note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp static const TempoPattern tp[] = { TempoPattern("<sym>noteHalfUp</sym>\\s*<sym>textAugmentationDot</sym>", 1.5/30.0, TDuration::DurationType::V_HALF, 1), // dotted 1/2 TempoPattern("<sym>noteQuarterUp</sym>\\s*<sym>textAugmentationDot</sym>", 1.5/60.0, TDuration::DurationType::V_QUARTER, 1), // dotted 1/4 TempoPattern("<sym>note8thUp</sym>\\s*<sym>textAugmentationDot</sym>", 1.5/120.0, TDuration::DurationType::V_EIGHT, 1), // dotted 1/8 TempoPattern("<sym>noteHalfUp</sym>", 1.0/30.0, TDuration::DurationType::V_HALF), // 1/2 TempoPattern("<sym>noteQuarterUp</sym>", 1.0/60.0, TDuration::DurationType::V_QUARTER), // 1/4 TempoPattern("<sym>note8thUp</sym>", 1.0/120.0, TDuration::DurationType::V_EIGHT), // 1/8 }; //--------------------------------------------------------- // findTempoDuration // find the duration part (note + dot) of a tempo text in string s // return the match position or -1 if not found // set len to the match length and dur to the duration value //--------------------------------------------------------- int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur) { len = 0; dur = TDuration(); for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { QRegExp re(tp[i].pattern); int pos = re.indexIn(s); if (pos != -1) { len = re.matchedLength(); dur = tp[i].d; return pos; } } return -1; } //--------------------------------------------------------- // duration2tempoTextString // find the tempoText string representation for duration //--------------------------------------------------------- QString TempoText::duration2tempoTextString(const TDuration dur) { for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { if (tp[i].d == dur) { QString res = tp[i].pattern; res.remove("\\s*"); return res; } } return ""; } //--------------------------------------------------------- // textChanged // text may have changed //--------------------------------------------------------- void TempoText::textChanged() { if (!_followText) return; QString s = text(); for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { QRegExp re(QString(tp[i].pattern)+"\\s*=\\s*(\\d+)"); // 1/4 if (re.indexIn(s) != -1) { QStringList sl = re.capturedTexts(); if (sl.size() == 2) { qreal nt = qreal(sl[1].toInt()) * tp[i].f; if (nt != _tempo) { _tempo = qreal(sl[1].toInt()) * tp[i].f; if(segment()) score()->setTempo(segment(), _tempo); score()->setPlaylistDirty(true); } break; } } } } //--------------------------------------------------------- // undoSetTempo //--------------------------------------------------------- void TempoText::undoSetTempo(qreal v) { score()->undoChangeProperty(this, P_ID::TEMPO, v); } //--------------------------------------------------------- // undoSetFollowText //--------------------------------------------------------- void TempoText::undoSetFollowText(bool v) { score()->undoChangeProperty(this, P_ID::TEMPO_FOLLOW_TEXT, v); } //--------------------------------------------------------- // getProperty //--------------------------------------------------------- QVariant TempoText::getProperty(P_ID propertyId) const { switch(propertyId) { case P_ID::TEMPO: return _tempo; case P_ID::TEMPO_FOLLOW_TEXT: return _followText; default: return Text::getProperty(propertyId); } } //--------------------------------------------------------- // setProperty //--------------------------------------------------------- bool TempoText::setProperty(P_ID propertyId, const QVariant& v) { switch(propertyId) { case P_ID::TEMPO: _tempo = v.toDouble(); score()->setTempo(segment(), _tempo); break; case P_ID::TEMPO_FOLLOW_TEXT: _followText = v.toBool(); break; default: if (!Text::setProperty(propertyId, v)) return false; break; } score()->setLayoutAll(true); return true; } //--------------------------------------------------------- // propertyDefault //--------------------------------------------------------- QVariant TempoText::propertyDefault(P_ID id) const { switch(id) { case P_ID::TEMPO: return 120; case P_ID::TEMPO_FOLLOW_TEXT: return false; case P_ID::PLACEMENT: return int(Placement::ABOVE); default: return Text::propertyDefault(id); } } //--------------------------------------------------------- // layout //--------------------------------------------------------- void TempoText::layout() { Text::layout(); if (placement() == Placement::BELOW) { rypos() = -rypos() + 4 * spatium(); // rUserYoffset() *= -1; // text height ? } } }
namespace Ms { #define MIN_TEMPO 5.0/60 #define MAX_TEMPO 999.0/60 //TODO: textChanged() needs to be called during/after editing //--------------------------------------------------------- // TempoText //--------------------------------------------------------- TempoText::TempoText(Score* s) : TextBase(s, ElementFlags(ElementFlag::SYSTEM)) { initSubStyle(SubStyleId::TEMPO); _tempo = 2.0; // propertyDefault(P_TEMPO).toDouble(); _followText = false; _relative = 1.0; _isRelative = false; } //--------------------------------------------------------- // write //--------------------------------------------------------- void TempoText::write(XmlWriter& xml) const { xml.stag(name()); xml.tag("tempo", _tempo); if (_followText) xml.tag("followText", _followText); TextBase::writeProperties(xml); xml.etag(); } //--------------------------------------------------------- // read //--------------------------------------------------------- void TempoText::read(XmlReader& e) { while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "tempo") setTempo(e.readDouble()); else if (tag == "followText") _followText = e.readInt(); else if (!TextBase::readProperties(e)) e.unknown(); } // check sanity if (xmlText().isEmpty()) { setXmlText(QString("<sym>metNoteQuarterUp</sym> = %1").arg(lrint(60 * _tempo))); setVisible(false); } } //--------------------------------------------------------- // TempoPattern //--------------------------------------------------------- struct TempoPattern { const char* pattern; qreal f; TDuration d; TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); } }; // note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp static const TempoPattern tp[] = { TempoPattern("\uECA5\\s*\uECB7\\s*\uECB7", 1.75/60.0, TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4 TempoPattern("\uECA5\\s*\uECB7", 1.5/60.0, TDuration::DurationType::V_QUARTER, 1), // dotted 1/4 TempoPattern("\uECA5", 1.0/60.0, TDuration::DurationType::V_QUARTER), // 1/4 TempoPattern("\uECA3\\s*\uECB7\\s*\uECB7", 1.75/30.0, TDuration::DurationType::V_HALF, 2), // double dotted 1/2 TempoPattern("\uECA3\\s*\uECB7", 1.5/30.0, TDuration::DurationType::V_HALF, 1), // dotted 1/2 TempoPattern("\uECA3", 1.0/30.0, TDuration::DurationType::V_HALF), // 1/2 TempoPattern("\uECA7\\s*\uECB7\\s*\uECB7", 1.75/120.0, TDuration::DurationType::V_EIGHTH, 2), // double dotted 1/8 TempoPattern("\uECA7\\s*\uECB7", 1.5/120.0, TDuration::DurationType::V_EIGHTH, 1), // dotted 1/8 TempoPattern("\uECA7", 1.0/120.0, TDuration::DurationType::V_EIGHTH), // 1/8 TempoPattern("\uECA2\\s*\uECB7", 1.5/15.0, TDuration::DurationType::V_WHOLE, 1), // dotted whole TempoPattern("\uECA2", 1.0/15.0, TDuration::DurationType::V_WHOLE), // whole TempoPattern("\uECA9\\s*\uECB7", 1.5/240.0, TDuration::DurationType::V_16TH, 1), // dotted 1/16 TempoPattern("\uECA9", 1.0/240.0, TDuration::DurationType::V_16TH), // 1/16 TempoPattern("\uECAB\\s*\uECB7", 1.5/480.0, TDuration::DurationType::V_32ND, 1), // dotted 1/32 TempoPattern("\uECAB", 1.0/480.0, TDuration::DurationType::V_32ND), // 1/32 TempoPattern("\uECA1", 1.0/7.5, TDuration::DurationType::V_BREVE), // longa TempoPattern("\uECA0", 1.0/7.5, TDuration::DurationType::V_BREVE), // double whole TempoPattern("\uECAD", 1.0/960.0, TDuration::DurationType::V_64TH), // 1/64 TempoPattern("\uECAF", 1.0/1920.0, TDuration::DurationType::V_128TH), // 1/128 }; //--------------------------------------------------------- // findTempoDuration // find the duration part (note + dot) of a tempo text in string s // return the match position or -1 if not found // set len to the match length and dur to the duration value //--------------------------------------------------------- int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur) { len = 0; dur = TDuration(); for (const auto& i : tp) { QRegExp re(i.pattern); int pos = re.indexIn(s); if (pos != -1) { len = re.matchedLength(); dur = i.d; return pos; } } return -1; } static const TempoPattern tpSym[] = { TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/60.0, TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4 TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/60.0, TDuration::DurationType::V_QUARTER, 1), // dotted 1/4 TempoPattern("<sym>metNoteQuarterUp</sym>", 1.0/60.0, TDuration::DurationType::V_QUARTER), // 1/4 TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/30.0, TDuration::DurationType::V_HALF, 2), // double dotted 1/2 TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/30.0, TDuration::DurationType::V_HALF, 1), // dotted 1/2 TempoPattern("<sym>metNoteHalfUp</sym>", 1.0/30.0, TDuration::DurationType::V_HALF), // 1/2 TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>", 1.75/120.0, TDuration::DurationType::V_EIGHTH, 2), // double dotted 1/8 TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/120.0, TDuration::DurationType::V_EIGHTH, 1), // dotted 1/8 TempoPattern("<sym>metNote8thUp</sym>", 1.0/120.0, TDuration::DurationType::V_EIGHTH), // 1/8 TempoPattern("<sym>metNoteWhole</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/15.0, TDuration::DurationType::V_WHOLE, 1), // dotted whole TempoPattern("<sym>metNoteWhole</sym>", 1.0/15.0, TDuration::DurationType::V_WHOLE), // whole TempoPattern("<sym>metNote16thUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/240.0, TDuration::DurationType::V_16TH, 1), // dotted 1/16 TempoPattern("<sym>metNote16thUp</sym>", 1.0/240.0, TDuration::DurationType::V_16TH), // 1/16 TempoPattern("<sym>metNote32ndUp</sym>\\s*<sym>metAugmentationDot</sym>", 1.5/480.0, TDuration::DurationType::V_32ND, 1), // dotted 1/32 TempoPattern("<sym>metNote32ndUp</sym>", 1.0/480.0, TDuration::DurationType::V_32ND), // 1/32 TempoPattern("<sym>metNoteDoubleWholeSquare</sym>", 1.0/7.5, TDuration::DurationType::V_BREVE), // longa TempoPattern("<sym>metNoteDoubleWhole</sym>", 1.0/7.5, TDuration::DurationType::V_BREVE), // double whole TempoPattern("<sym>metNote64thUp</sym>", 1.0/960.0, TDuration::DurationType::V_64TH), // 1/64 TempoPattern("<sym>metNote128thUp</sym>", 1.0/1920.0,TDuration::DurationType::V_128TH), // 1/128 }; //--------------------------------------------------------- // duration2tempoTextString // find the tempoText string representation for duration //--------------------------------------------------------- QString TempoText::duration2tempoTextString(const TDuration dur) { for (const TempoPattern& pa : tpSym) { if (pa.d == dur) { QString res = pa.pattern; res.replace("\\s*", " "); return res; } } return ""; } //--------------------------------------------------------- // updateScore //--------------------------------------------------------- void TempoText::updateScore() { if (segment()) score()->setTempo(segment(), _tempo); score()->fixTicks(); score()->setPlaylistDirty(); } //--------------------------------------------------------- // updateRelative //--------------------------------------------------------- void TempoText::updateRelative() { qreal tempoBefore = score()->tempo(tick() - 1); setTempo(tempoBefore * _relative); } //--------------------------------------------------------- // textChanged // text may have changed //--------------------------------------------------------- void TempoText::textChanged() { if (!_followText) return; // cache regexp, they are costly to create static QHash<QString, QRegExp> regexps; static QHash<QString, QRegExp> regexps2; QString s = plainText(); s.replace(",", "."); s.replace("<sym>space</sym>"," "); for (const TempoPattern& pa : tp) { QRegExp re; if (!regexps.contains(pa.pattern)) { re = QRegExp(QString("%1\\s*=\\s*(\\d+[.]{0,1}\\d*)\\s*").arg(pa.pattern)); regexps[pa.pattern] = re; } re = regexps.value(pa.pattern); if (re.indexIn(s) != -1) { QStringList sl = re.capturedTexts(); if (sl.size() == 2) { qreal nt = qreal(sl[1].toDouble()) * pa.f; if (nt != _tempo) { setTempo(qreal(sl[1].toDouble()) * pa.f); _relative = 1.0; _isRelative = false; updateScore(); } break; } } else { for (const TempoPattern& pa2 : tp) { QString key = QString("%1_%2").arg(pa.pattern).arg(pa2.pattern); QRegExp re2; if (!regexps2.contains(key)) { re2 = QRegExp(QString("%1\\s*=\\s*%2\\s*").arg(pa.pattern).arg(pa2.pattern)); regexps2[key] = re2; } re2 = regexps2.value(key); if (re2.indexIn(s) != -1) { _relative = pa2.f / pa.f; _isRelative = true; updateRelative(); updateScore(); return; } } } } } //--------------------------------------------------------- // setTempo //--------------------------------------------------------- void TempoText::setTempo(qreal v) { if (v < MIN_TEMPO) v = MIN_TEMPO; else if (v > MAX_TEMPO) v = MAX_TEMPO; _tempo = v; } //--------------------------------------------------------- // undoSetTempo //--------------------------------------------------------- void TempoText::undoSetTempo(qreal v) { undoChangeProperty(Pid::TEMPO, v); } //--------------------------------------------------------- // undoSetFollowText //--------------------------------------------------------- void TempoText::undoSetFollowText(bool v) { undoChangeProperty(Pid::TEMPO_FOLLOW_TEXT, v); } //--------------------------------------------------------- // getProperty //--------------------------------------------------------- QVariant TempoText::getProperty(Pid propertyId) const { switch (propertyId) { case Pid::TEMPO: return _tempo; case Pid::TEMPO_FOLLOW_TEXT: return _followText; default: return TextBase::getProperty(propertyId); } } //--------------------------------------------------------- // setProperty //--------------------------------------------------------- bool TempoText::setProperty(Pid propertyId, const QVariant& v) { switch (propertyId) { case Pid::TEMPO: setTempo(v.toDouble()); score()->setTempo(segment(), _tempo); score()->fixTicks(); break; case Pid::TEMPO_FOLLOW_TEXT: _followText = v.toBool(); break; default: if (!TextBase::setProperty(propertyId, v)) return false; break; } triggerLayout(); return true; } //--------------------------------------------------------- // propertyDefault //--------------------------------------------------------- QVariant TempoText::propertyDefault(Pid id) const { switch(id) { case Pid::SUB_STYLE: return int(SubStyleId::TEMPO); case Pid::TEMPO: return 2.0; case Pid::TEMPO_FOLLOW_TEXT: return false; default: return TextBase::propertyDefault(id); } } //--------------------------------------------------------- // layout // called after Measure->stretchMeasure() //--------------------------------------------------------- void TempoText::layout() { qreal y = placeAbove() ? styleP(Sid::tempoPosAbove) : styleP(Sid::tempoPosBelow) + staff()->height(); setPos(QPointF(0.0, y)); TextBase::layout1(); Segment* s = segment(); if (!s) // for use in palette return; // tempo text on first chordrest of measure should align over time sig if present // if (!s->rtick()) { Segment* p = segment()->prev(SegmentType::TimeSig); if (p) { rxpos() -= s->x() - p->x(); Element* e = p->element(staffIdx() * VOICES); if (e) rxpos() += e->x(); } } autoplaceSegmentElement(styleP(Sid::tempoMinDistance)); } //--------------------------------------------------------- // duration2userName //--------------------------------------------------------- QString TempoText::duration2userName(const TDuration t) { QString dots; switch (t.dots()) { case 1: dots = QObject::tr("Dotted %1").arg(t.durationTypeUserName()); break; case 2: dots = QObject::tr("Double dotted %1").arg(t.durationTypeUserName()); break; case 3: dots = QObject::tr("Triple dotted %1").arg(t.durationTypeUserName()); break; case 4: dots = QObject::tr("Quadruple dotted %1").arg(t.durationTypeUserName()); break; default: dots = t.durationTypeUserName(); break; } return dots; } //--------------------------------------------------------- // accessibleInfo //--------------------------------------------------------- QString TempoText::accessibleInfo() const { TDuration t1; TDuration t2; int len1; int len2; QString text = plainText(); QString firstPart = text.split(" = ").first(); QString secondPart = text.split(" = ").back(); int x1 = findTempoDuration(firstPart, len1, t1); int x2 = -1; if (_relative) x2 = findTempoDuration(secondPart, len2, t2); if (x1 != -1) { QString dots1; QString dots2; dots1 = duration2userName(t1); if (x2 != -1) { dots2 = duration2userName(t2); return QString("%1: %2 %3 = %4 %5").arg(Element::accessibleInfo()).arg(dots1).arg(QObject::tr("note")).arg(dots2).arg(QObject::tr("note")); } else return QString("%1: %2 %3 = %4").arg(Element::accessibleInfo()).arg(dots1).arg(QObject::tr("note")).arg(secondPart); } else return TextBase::accessibleInfo(); } }
void MuseScore::populatePalette() { //----------------------------------- // notes //----------------------------------- Palette* notePalette = new Palette; notePalette->setName(tr("Grace Notes")); notePalette->setGrid(32, 40); notePalette->setDrawGrid(true); static const IconAction gna[] = { { ICON_ACCIACCATURA, "acciaccatura" }, { ICON_APPOGGIATURA, "appoggiatura" }, { ICON_GRACE4, "grace4" }, { ICON_GRACE16, "grace16" }, { ICON_GRACE32, "grace32" }, { -1, "" } }; populateIconPalette(notePalette, gna); paletteBox->addPalette(notePalette); //----------------------------------- // clefs //----------------------------------- Palette* sp = new Palette; sp->setName(tr("Clefs")); sp->setMag(0.8); sp->setGrid(33, 60); sp->setYOffset(1.0); static const ClefType clefs[21] = { CLEF_G, CLEF_G1, CLEF_G2, CLEF_G3, CLEF_G4, CLEF_C1, CLEF_C2, CLEF_C3, CLEF_C4, CLEF_C5, CLEF_F, CLEF_F_8VA, CLEF_F_15MA, CLEF_F8, CLEF_F15, CLEF_F_B, CLEF_F_C, CLEF_PERC, CLEF_TAB, CLEF_TAB2, CLEF_PERC2 }; for (int i = 0; i < 20; ++i) { ClefType j = clefs[i]; Clef* k = new ::Clef(gscore); k->setClefType(ClefTypeList(j, j)); sp->append(k, qApp->translate("clefTable", clefTable[j].name)); } paletteBox->addPalette(sp); //----------------------------------- // key signatures //----------------------------------- sp = newKeySigPalette(); paletteBox->addPalette(sp); //----------------------------------- // Time //----------------------------------- sp = new Palette; sp->setName(tr("Time Signatures")); sp->setMag(.8); sp->setGrid(42, 38); TimeSig* ts; ts = new TimeSig(gscore); ts->setSig(2, 2); sp->append(ts, "2/2"); sp->append(new TimeSig(gscore, 2, 4), "2/4"); sp->append(new TimeSig(gscore, 3, 4), "3/4"); sp->append(new TimeSig(gscore, 4, 4), "4/4"); sp->append(new TimeSig(gscore, 5, 4), "5/4"); sp->append(new TimeSig(gscore, 6, 4), "6/4"); sp->append(new TimeSig(gscore, 3, 8), "3/8"); sp->append(new TimeSig(gscore, 6, 8), "6/8"); sp->append(new TimeSig(gscore, 9, 8), "9/8"); sp->append(new TimeSig(gscore, 12, 8), "12/8"); sp->append(new TimeSig(gscore, TSIG_FOUR_FOUR), tr("4/4 common time")); sp->append(new TimeSig(gscore, TSIG_ALLA_BREVE), tr("2/2 alla breve")); paletteBox->addPalette(sp); //----------------------------------- // Bar Lines //----------------------------------- sp = new Palette; sp->setName(tr("Barlines")); sp->setMag(0.8); sp->setGrid(42, 38); struct { BarLineType type; const char* name; } t[] = { { NORMAL_BAR, QT_TR_NOOP("Normal") }, { BROKEN_BAR, QT_TR_NOOP("Dashed") }, { END_BAR, QT_TR_NOOP("End Bar") }, { DOUBLE_BAR, QT_TR_NOOP("Double Bar") }, { START_REPEAT, QT_TR_NOOP("Start Repeat") }, { END_REPEAT, QT_TR_NOOP("End Repeat") }, { END_START_REPEAT, QT_TR_NOOP("End-Start Repeat") }, }; for (unsigned i = 0; i < sizeof(t)/sizeof(*t); ++i) { BarLine* b = new BarLine(gscore); b->setSubtype(t[i].type); sp->append(b, tr(t[i].name)); } paletteBox->addPalette(sp); //----------------------------------- // Lines //----------------------------------- sp = new Palette; sp->setName(tr("Lines")); sp->setMag(.8); sp->setGrid(82, 23); Slur* slur = new Slur(gscore); slur->setId(0); sp->append(slur, tr("Slur")); Hairpin* gabel0 = new Hairpin(gscore); gabel0->setSubtype(0); sp->append(gabel0, tr("Crescendo")); Hairpin* gabel1 = new Hairpin(gscore); gabel1->setSubtype(1); sp->append(gabel1, tr("Diminuendo")); Volta* volta = new Volta(gscore); volta->setSubtype(VOLTA_CLOSED); volta->setText("1."); QList<int> il; il.append(1); volta->setEndings(il); sp->append(volta, tr("Prima volta")); volta = new Volta(gscore); volta->setSubtype(VOLTA_CLOSED); volta->setText("2."); il.clear(); il.append(2); volta->setEndings(il); sp->append(volta, tr("Seconda volta")); volta = new Volta(gscore); volta->setSubtype(VOLTA_CLOSED); volta->setText("3."); il.clear(); il.append(3); volta->setEndings(il); sp->append(volta, tr("Terza volta")); volta = new Volta(gscore); volta->setSubtype(VOLTA_OPEN); volta->setText("2."); il.clear(); il.append(2); volta->setEndings(il); sp->append(volta, tr("Seconda volta 2")); Ottava* ottava = new Ottava(gscore); ottava->setSubtype(0); sp->append(ottava, tr("8va")); ottava = new Ottava(gscore); ottava->setSubtype(1); sp->append(ottava, tr("15ma")); ottava = new Ottava(gscore); ottava->setSubtype(2); sp->append(ottava, tr("8vb")); ottava = new Ottava(gscore); ottava->setSubtype(3); sp->append(ottava, tr("15mb")); Pedal* pedal = new Pedal(gscore); //pedal->setLen(l); sp->append(pedal, tr("Pedal")); pedal = new Pedal(gscore); //pedal->setLen(l); pedal->setEndHookType(HOOK_45); sp->append(pedal, tr("Pedal")); pedal = new Pedal(gscore); //pedal->setLen(l); pedal->setBeginSymbol(-1); pedal->setBeginHook(true); pedal->setBeginHookType(HOOK_45); pedal->setEndHookType(HOOK_45); sp->append(pedal, tr("Pedal")); pedal = new Pedal(gscore); //pedal->setLen(l); pedal->setBeginSymbol(-1); pedal->setBeginHook(true); pedal->setBeginHookType(HOOK_45); sp->append(pedal, tr("Pedal")); Trill* trill = new Trill(gscore); sp->append(trill, tr("Trill line")); trill = new Trill(gscore); trill->setSubtype("upprall"); sp->append(trill, tr("Upprall line")); trill = new Trill(gscore); trill->setSubtype("downprall"); sp->append(trill, tr("Downprall line")); trill = new Trill(gscore); trill->setSubtype("prallprall"); sp->append(trill, tr("Prallprall line")); TextLine* textLine = new TextLine(gscore); textLine->setBeginText("VII"); textLine->setEndHook(true); sp->append(textLine, tr("Text line")); TextLine* line = new TextLine(gscore); line->setDiagonal(true); sp->append(line, tr("Line")); paletteBox->addPalette(sp); //----------------------------------- // Arpeggio && Glissando //----------------------------------- sp = new Palette(); sp->setName(tr("Arpeggio && Glissando")); sp->setGrid(27, 60); for (int i = 0; i < 4; ++i) { Arpeggio* a = new Arpeggio(gscore); a->setSubtype(ArpeggioType(i)); sp->append(a, tr("Arpeggio")); } for (int i = 0; i < 2; ++i) { Glissando* a = new Glissando(gscore); a->setSubtype(i); sp->append(a, tr("Glissando")); } paletteBox->addPalette(sp); //----------------------------------- // Symbols: Breath //----------------------------------- sp = new Palette(); sp->setName(tr("Breath && Pauses")); sp->setGrid(42, 40); for (int i = 0; i < 4; ++i) { Breath* a = new Breath(gscore); a->setSubtype(i); if (i < 2) sp->append(a, tr("Breath")); else sp->append(a, tr("Caesura")); } paletteBox->addPalette(sp); //----------------------------------- // Brackets //----------------------------------- sp = new Palette; sp->setName(tr("Brackets")); sp->setMag(0.7); sp->setGrid(42, 60); Bracket* b1 = new Bracket(gscore); b1->setSubtype(BRACKET_NORMAL); Bracket* b2 = new Bracket(gscore); b2->setSubtype(BRACKET_AKKOLADE); // b1->setHeight(_spatium * 7); // b2->setHeight(_spatium * 7); sp->append(b1, tr("Square bracket")); sp->append(b2, tr("Curly bracket")); paletteBox->addPalette(sp); //----------------------------------- // Attributes, Ornaments //----------------------------------- sp = new Palette; sp->setName(tr("Articulations && Ornaments")); sp->setGrid(42, 25); for (int i = 0; i < ARTICULATIONS; ++i) { Articulation* s = new Articulation(gscore); s->setSubtype(ArticulationType(i)); sp->append(s, qApp->translate("articulation", qPrintable(s->subtypeUserName()))); } Bend* bend = new Bend(gscore); bend->points().append(PitchValue(0, 0, false)); bend->points().append(PitchValue(15, 100, false)); bend->points().append(PitchValue(60, 100, false)); sp->append(bend, qApp->translate("articulation", "Bend")); TremoloBar* tb = new TremoloBar(gscore); tb->points().append(PitchValue(0, 0, false)); // "Dip" tb->points().append(PitchValue(30, -100, false)); tb->points().append(PitchValue(60, 0, false)); sp->append(tb, qApp->translate("articulation", "Tremolo Bar")); paletteBox->addPalette(sp); //----------------------------------- // Accidentals //----------------------------------- sp = newAccidentalsPalette(); paletteBox->addPalette(sp); //----------------------------------- // Dynamics //----------------------------------- sp = new Palette; sp->setName(tr("Dynamics")); sp->setMag(.8); sp->setGrid(42, 28); static const char* dynS[] = { "ppp", "pp", "p", "mp", "mf", "f", "ff", "fff" }; for (unsigned i = 0; i < sizeof(dynS)/sizeof(*dynS); ++i) { Dynamic* dynamic = new Dynamic(gscore); dynamic->setSubtype(dynS[i]); sp->append(dynamic, dynamic->subtypeName()); } paletteBox->addPalette(sp); //----------------------------------- // Fingering //----------------------------------- sp = new Palette; sp->setName(tr("Fingering")); sp->setMag(1.5); sp->setGrid(28, 30); sp->setDrawGrid(true); const char finger[] = "012345pimac"; for (unsigned i = 0; i < strlen(finger); ++i) { Fingering* f = new Fingering(gscore); f->setText(QString(finger[i])); sp->append(f, tr("Fingering %1").arg(finger[i])); } const char stringnumber[] = "0123456"; for (unsigned i = 0; i < strlen(stringnumber); ++i) { Fingering* f = new Fingering(gscore); f->setTextStyle(TEXT_STYLE_STRING_NUMBER); f->setText(QString(stringnumber[i])); sp->append(f, tr("String number %1").arg(stringnumber[i])); } Symbol* symbol = new Symbol(gscore, thumbSym); sp->append(symbol, tr("Thumb")); paletteBox->addPalette(sp); //----------------------------------- // Noteheads //----------------------------------- sp = new Palette; sp->setName(tr("Note Heads")); sp->setMag(1.3); sp->setGrid(33, 36); sp->setDrawGrid(true); for (int i = 0; i < HEAD_GROUPS; ++i) { int sym = noteHeads[0][i][1]; if (i == HEAD_BREVIS_ALT) sym = noteHeads[0][i][3]; NoteHead* nh = new NoteHead(gscore); nh->setSym(sym); sp->append(nh, qApp->translate("symbol", symbols[0][sym].name())); } paletteBox->addPalette(sp); //----------------------------------- // Tremolo //----------------------------------- sp = new Palette; sp->setName(tr("Tremolo")); sp->setGrid(27, 40); sp->setDrawGrid(true); const char* tremoloName[] = { QT_TR_NOOP("1/8 through stem"), QT_TR_NOOP("1/16 through stem"), QT_TR_NOOP("1/32 through stem"), QT_TR_NOOP("1/64 through stem"), QT_TR_NOOP("1/8 between notes"), QT_TR_NOOP("1/16 between notes"), QT_TR_NOOP("1/32 between notes"), QT_TR_NOOP("1/64 between notes") }; for (int i = TREMOLO_R8; i <= TREMOLO_C64; ++i) { Tremolo* tremolo = new Tremolo(gscore); tremolo->setSubtype(TremoloType(i)); sp->append(tremolo, tr(tremoloName[i - TREMOLO_R8])); } paletteBox->addPalette(sp); //----------------------------------- // Fall, Doit //----------------------------------- sp = new Palette; sp->setName(tr("Fall/Doit")); sp->setGrid(27, 40); sp->setDrawGrid(true); const char* scorelineNames[] = { QT_TR_NOOP("fall"), QT_TR_NOOP("doit"), }; ChordLine* cl = new ChordLine(gscore); cl->setSubtype(1); sp->append(cl, tr(scorelineNames[0])); cl = new ChordLine(gscore); cl->setSubtype(2); sp->append(cl, tr(scorelineNames[1])); paletteBox->addPalette(sp); //----------------------------------- // Repeats //----------------------------------- sp = new Palette; sp->setName(tr("Repeats")); sp->setMag(0.65); sp->setGrid(84, 28); sp->setDrawGrid(true); RepeatMeasure* rm = new RepeatMeasure(gscore); sp->append(rm, tr("Repeat measure sign")); Marker* mk = new Marker(gscore); mk->setMarkerType(MARKER_SEGNO); sp->append(mk, tr("Segno")); mk = new Marker(gscore); mk->setMarkerType(MARKER_VARSEGNO); sp->append(mk, tr("Segno Variation")); mk = new Marker(gscore); mk->setMarkerType(MARKER_CODA); sp->append(mk, tr("Coda")); mk = new Marker(gscore); mk->setMarkerType(MARKER_VARCODA); sp->append(mk, tr("Varied coda")); mk = new Marker(gscore); mk->setMarkerType(MARKER_CODETTA); sp->append(mk, tr("Codetta")); mk = new Marker(gscore); mk->setMarkerType(MARKER_FINE); sp->append(mk, tr("Fine")); Jump* jp = new Jump(gscore); jp->setJumpType(JUMP_DC); sp->append(jp, tr("Da Capo")); jp = new Jump(gscore); jp->setJumpType(JUMP_DC_AL_FINE); sp->append(jp, tr("Da Capo al Fine")); jp = new Jump(gscore); jp->setJumpType(JUMP_DC_AL_CODA); sp->append(jp, tr("Da Capo al Coda")); jp = new Jump(gscore); jp->setJumpType(JUMP_DS_AL_CODA); sp->append(jp, tr("D.S al Coda")); jp = new Jump(gscore); jp->setJumpType(JUMP_DS_AL_FINE); sp->append(jp, tr("D.S al Fine")); jp = new Jump(gscore); jp->setJumpType(JUMP_DS); sp->append(jp, tr("D.S")); mk = new Marker(gscore); mk->setMarkerType(MARKER_TOCODA); sp->append(mk, tr("To Coda")); paletteBox->addPalette(sp); //----------------------------------- // Text //----------------------------------- sp = new Palette; sp->setName(tr("Text")); sp->setMag(0.65); sp->setGrid(84, 28); sp->setDrawGrid(true); StaffText* st = new StaffText(gscore); st->setSystemFlag(false); st->setTextStyle(TEXT_STYLE_STAFF); //TODO st->setSubtype(TEXT_STAFF); st->setText(tr("staff-text")); sp->append(st, tr("Staff Text")); st = new StaffText(gscore); st->setSystemFlag(true); st->setTextStyle(TEXT_STYLE_SYSTEM); // st->setSubtype(TEXT_SYSTEM); st->setText(tr("system-text")); sp->append(st, tr("System Text")); RehearsalMark* rhm = new RehearsalMark(gscore); rhm->setTrack(0); rhm->setText("B1"); sp->append(rhm, tr("RRehearsal Mark")); InstrumentChange* is = new InstrumentChange(gscore); is->setText(tr("Instrument")); sp->append(is, tr("Instrument Change")); Text* text = new Text(gscore); text->setTrack(0); text->setTextStyle(TEXT_STYLE_LYRICS_VERSE_NUMBER); text->setText(tr("1.")); text->setSystemFlag(true); sp->append(text, tr("Lyrics Verse Number")); static const TempoPattern tp[] = { TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0), // 1/4 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0), // 1/2 TempoPattern(QString("%1%2 = 80"). arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0), // 1/8 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0), // dotted 1/4 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0), // dotted 1/2 TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0) // dotted 1/8 }; for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) { TempoText* tt = new TempoText(gscore); tt->setFollowText(true); tt->setTrack(0); tt->setTempo(tp[i].f); tt->setText(tp[i].pattern); sp->append(tt, tr("Tempo Text"), QString(), 1.5); } Harmony* harmony = new Harmony(gscore); harmony->setText("c7"); sp->append(harmony, tr("Chord Name")); paletteBox->addPalette(sp); //----------------------------------- // breaks //----------------------------------- qreal _spatium = gscore->spatium(); sp = new Palette; sp->setName(tr("Breaks && Spacer")); sp->setMag(.7); sp->setGrid(42, 36); sp->setDrawGrid(true); LayoutBreak* lb = new LayoutBreak(gscore); lb->setSubtype(LAYOUT_BREAK_LINE); sp->append(lb, tr("Line break")); lb = new LayoutBreak(gscore); lb->setSubtype(LAYOUT_BREAK_PAGE); sp->append(lb, tr("Page break")); lb = new LayoutBreak(gscore); lb->setSubtype(LAYOUT_BREAK_SECTION); sp->append(lb, tr("Section break")); Spacer* spacer = new Spacer(gscore); spacer->setGap(3 * _spatium); spacer->setSubtype(SPACER_DOWN); sp->append(spacer, tr("Staff spacer down")); spacer = new Spacer(gscore); spacer->setGap(3 * _spatium); spacer->setSubtype(SPACER_UP); sp->append(spacer, tr("Staff spacer up")); paletteBox->addPalette(sp); //----------------------------------- // staff state changes //----------------------------------- #if 0 sp = new Palette; sp->setName(tr("Staff Changes")); sp->setMag(.7); sp->setGrid(42, 36); sp->setDrawGrid(true); StaffState* st = new StaffState(gscore); st->setSubtype(STAFF_STATE_VISIBLE); sp->append(st, tr("set visible")); st = new StaffState(gscore); st->setSubtype(STAFF_STATE_INVISIBLE); sp->append(st, tr("set invisible")); st = new StaffState(gscore); st->setSubtype(STAFF_STATE_TYPE); sp->append(st, tr("change staff type")); st = new StaffState(gscore); st->setSubtype(STAFF_STATE_INSTRUMENT); sp->append(st, tr("change instrument")); paletteBox->addPalette(sp); #endif //----------------------------------- // beam properties //----------------------------------- sp = new Palette; sp->setName(tr("Beam Properties")); sp->setGrid(27, 40); sp->setDrawGrid(true); static const IconAction bpa[] = { { ICON_SBEAM, "beam-start" }, { ICON_MBEAM, "beam-mid" }, { ICON_NBEAM, "no-beam" }, { ICON_BEAM32, "beam32" }, { ICON_BEAM64, "beam64" }, { ICON_AUTOBEAM, "auto-beam" }, { ICON_FBEAM1, "fbeam1" }, { ICON_FBEAM2, "fbeam2" }, { -1, ""} }; populateIconPalette(sp, bpa); paletteBox->addPalette(sp); //----------------------------------- // Symbols //----------------------------------- sp = new Palette; sp->setName(tr("Symbols")); sp->setGrid(42, 45); sp->setDrawGrid(true); sp->append(accDiscantSym); sp->append(accDotSym); sp->append(accFreebaseSym); sp->append(accStdbaseSym); sp->append(accBayanbaseSym); sp->append(accOldEESym); sp->append(accpushSym); sp->append(accpullSym); FretDiagram* fret = new FretDiagram(gscore); fret->setDot(5, 1); fret->setDot(2, 2); fret->setDot(1, 3); fret->setMarker(0, 'X'); fret->setMarker(3, 'O'); fret->setMarker(4, 'O'); sp->append(fret, tr("Fret Diagram")); paletteBox->addPalette(sp); }