void KeySig::draw(QPainter* p) const { p->setPen(curColor()); for (const KeySym& ks: _sig.keySymbols()) drawSymbol(ks.sym, p, QPointF(ks.pos.x(), ks.pos.y())); if (!parent() && (isAtonal() || isCustom()) && _sig.keySymbols().empty()) { // empty custom or atonal key signature - draw something for palette p->setPen(Qt::gray); drawSymbol(SymId::timeSigX, p, QPointF(symWidth(SymId::timeSigX) * -0.5, 2.0 * spatium())); } }
void KeySigEvent::print() const { qDebug("<KeySigEvent: "); if (!isValid()) qDebug("invalid>"); else { if (isAtonal()) qDebug("atonal>"); else if (custom()) qDebug("custom>"); else qDebug("accidental %d>", int(_key)); } }
bool KeySigEvent::operator==(const KeySigEvent& e) const { if (e._custom != _custom || e._mode != _mode) return false; if (_custom && !isAtonal()) { if (e._keySymbols.size() != _keySymbols.size()) return false; for (int i = 0; i < _keySymbols.size(); ++i) { if (e._keySymbols[i].sym != _keySymbols[i].sym) return false; // TODO: position matters } return true; } return e._key == _key; }
QString KeySig::accessibleInfo() const { QString keySigType; if (isAtonal()) return QString("%1: %2").arg(Element::accessibleInfo()).arg(qApp->translate("MuseScore", keyNames[15])); else if (isCustom()) return tr("%1: Custom").arg(Element::accessibleInfo()); if (key() == Key::C) return QString("%1: %2").arg(Element::accessibleInfo()).arg(qApp->translate("MuseScore", keyNames[14])); int keyInt = static_cast<int>(key()); if (keyInt < 0) keySigType = qApp->translate("MuseScore", keyNames[(7 + keyInt) * 2 + 1]); else keySigType = qApp->translate("MuseScore", keyNames[(keyInt - 1) * 2]); return QString("%1: %2").arg(Element::accessibleInfo()).arg(keySigType); }
void KeySig::layout() { qreal _spatium = spatium(); setbbox(QRectF()); if (isCustom() && !isAtonal()) { for (KeySym& ks: _sig.keySymbols()) { ks.pos = ks.spos * _spatium; addbbox(symBbox(ks.sym).translated(ks.pos)); } return; } _sig.keySymbols().clear(); if (staff() && !staff()->genKeySig()) // no key sigs on TAB staves return; // determine current clef for this staff ClefType clef = ClefType::G; if (staff()) clef = staff()->clef(segment()->tick()); int accidentals = 0, naturals = 0; int t1 = int(_sig.key()); switch (qAbs(t1)) { case 7: accidentals = 0x7f; break; case 6: accidentals = 0x3f; break; case 5: accidentals = 0x1f; break; case 4: accidentals = 0xf; break; case 3: accidentals = 0x7; break; case 2: accidentals = 0x3; break; case 1: accidentals = 0x1; break; case 0: accidentals = 0; break; default: qDebug("illegal t1 key %d", t1); break; } // manage display of naturals: // naturals are shown if there is some natural AND prev. measure has no section break // AND style says they are not off // OR key sig is CMaj/Amin (in which case they are always shown) bool naturalsOn = false; Measure* prevMeasure = measure() ? measure()->prevMeasure() : 0; // If we're not force hiding naturals (Continuous panel), use score style settings if (!_hideNaturals) naturalsOn = (prevMeasure && !prevMeasure->sectionBreak() && (score()->styleI(StyleIdx::keySigNaturals) != int(KeySigNatural::NONE))) || (t1 == 0); // Don't repeat naturals if shown in courtesy if (prevMeasure && prevMeasure->findSegment(Segment::Type::KeySigAnnounce, segment()->tick()) && !segment()->isKeySigAnnounceType()) naturalsOn = false; if (track() == -1) naturalsOn = false; int coffset = 0; Key t2 = Key::C; if (naturalsOn) { t2 = staff()->key(segment()->tick() - 1); if (t2 == Key::C) naturalsOn = false; else { switch (qAbs(int(t2))) { case 7: naturals = 0x7f; break; case 6: naturals = 0x3f; break; case 5: naturals = 0x1f; break; case 4: naturals = 0xf; break; case 3: naturals = 0x7; break; case 2: naturals = 0x3; break; case 1: naturals = 0x1; break; case 0: naturals = 0; break; default: qDebug("illegal t2 key %d", int(t2)); break; } // remove redundant naturals if (!((t1 > 0) ^ (t2 > 0))) naturals &= ~accidentals; if (t2 < 0) coffset = 7; } } // naturals should go BEFORE accidentals if style says so // OR going from sharps to flats or vice versa (i.e. t1 & t2 have opposite signs) bool prefixNaturals = naturalsOn && (score()->styleI(StyleIdx::keySigNaturals) == int(KeySigNatural::BEFORE) || t1 * int(t2) < 0); // naturals should go AFTER accidentals if they should not go before! bool suffixNaturals = naturalsOn && !prefixNaturals; const signed char* lines = ClefInfo::lines(clef); // add prefixed naturals, if any qreal xo = 0.0; if (prefixNaturals) { for (int i = 0; i < 7; ++i) { if (naturals & (1 << i)) { addLayout(SymId::accidentalNatural, xo, lines[i + coffset]); xo += 1.0; } } } // add accidentals static const qreal sspread = 1.0; static const qreal fspread = 1.0; switch(t1) { case 7: addLayout(SymId::accidentalSharp, xo + 6.0 * sspread, lines[6]); case 6: addLayout(SymId::accidentalSharp, xo + 5.0 * sspread, lines[5]); case 5: addLayout(SymId::accidentalSharp, xo + 4.0 * sspread, lines[4]); case 4: addLayout(SymId::accidentalSharp, xo + 3.0 * sspread, lines[3]); case 3: addLayout(SymId::accidentalSharp, xo + 2.0 * sspread, lines[2]); case 2: addLayout(SymId::accidentalSharp, xo + 1.0 * sspread, lines[1]); case 1: addLayout(SymId::accidentalSharp, xo, lines[0]); break; case -7: addLayout(SymId::accidentalFlat, xo + 6.0 * fspread, lines[13]); case -6: addLayout(SymId::accidentalFlat, xo + 5.0 * fspread, lines[12]); case -5: addLayout(SymId::accidentalFlat, xo + 4.0 * fspread, lines[11]); case -4: addLayout(SymId::accidentalFlat, xo + 3.0 * fspread, lines[10]); case -3: addLayout(SymId::accidentalFlat, xo + 2.0 * fspread, lines[9]); case -2: addLayout(SymId::accidentalFlat, xo + 1.0 * fspread, lines[8]); case -1: addLayout(SymId::accidentalFlat, xo, lines[7]); case 0: break; default: qDebug("illegal t1 key %d", t1); break; } // add suffixed naturals, if any if (suffixNaturals) { xo += qAbs(t1); // skip accidentals if (t1 > 0) { // after sharps, add a little more space xo += 0.15; // if last sharp (t1) is above next natural (t1+1)... if (lines[t1] < lines[t1+1]) xo += 0.2; // ... add more space } for (int i = 0; i < 7; ++i) { if (naturals & (1 << i)) { addLayout(SymId::accidentalNatural, xo, lines[i + coffset]); xo += 1.0; } } } // compute bbox for (KeySym& ks : _sig.keySymbols()) { ks.pos = ks.spos * _spatium; addbbox(symBbox(ks.sym).translated(ks.pos)); } }