diff --git a/changes b/changes index 22903b8d49d936b3e950f544e8df832e3f52ec09..12dbb33d3348695c9bd2005c91547763bd789a46 100644 --- a/changes +++ b/changes @@ -1,4 +1,5 @@ 1.5.2 alpha3 + - extended grand staff, beaming notes on every staff separately - score supports bowing symbols, read them from XML - improved level creator diff --git a/src/libs/core/score/tbeamobject.cpp b/src/libs/core/score/tbeamobject.cpp index 59b059398e6499b426f3095e86af978842722a24..db5644db3ce64ab47f96f7b013dab12ffc8127f2 100644 --- a/src/libs/core/score/tbeamobject.cpp +++ b/src/libs/core/score/tbeamobject.cpp @@ -118,7 +118,8 @@ void TbeamObject::prepareBeam() { bool stemsUpPossible = true; qreal hiNote = 99.0, loNote = 0.0; for (TnotePair* np : qAsConst(m_notes)) { - stemDirStrength += np->item()->notePosY() - (m_measure->staff()->upperLine() + 4.0); + stemDirStrength += np->item()->notePosY() - (m_measure->staff()->upperLine() + + (m_measure->score()->isPianoStaff() && np->item()->notePosY() > m_measure->staff()->upperLine() + 13.0 ? 26.0 : 4.0)); if (np->item()->notePosY() < MIN_STEM_HEIGHT) stemsUpPossible = false; hiNote = qMin(hiNote, np->item()->notePosY()); @@ -129,8 +130,15 @@ void TbeamObject::prepareBeam() { if (stemDirStrength < 0) allStemsDown = true; // stems down are always possible qreal stemTop = allStemsDown ? loNote + minStemHeight : hiNote - minStemHeight; - if ((allStemsDown && stemTop < m_measure->staff()->upperLine() + 4.0) || (!allStemsDown && stemTop > m_measure->staff()->upperLine() + 4.0)) - stemTop = m_measure->staff()->upperLine() + 4.0; // keep beam on staff middle line + if (m_measure->score()->isPianoStaff() && !first()->note()->onUpperStaff()) { // when note lays on the lower staff + qreal lowerMidLine = m_measure->staff()->upperLine() + 26.0; + if ((allStemsDown && stemTop < lowerMidLine) || (!allStemsDown && stemTop > lowerMidLine)) + stemTop = lowerMidLine; // keep beam on the lower staff middle line + } else { + qreal upperMidLine = m_measure->staff()->upperLine() + 4.0; + if ((allStemsDown && stemTop < upperMidLine) || (!allStemsDown && stemTop > upperMidLine)) + stemTop = upperMidLine; // keep beam on staff middle line + } for (TnotePair* np : qAsConst(m_notes)) { np->note()->rtm.setStemDown(allStemsDown); np->addChange(TnotePair::e_stemDirChanged); diff --git a/src/libs/core/score/tmeasureobject.cpp b/src/libs/core/score/tmeasureobject.cpp index 5268d0406b2b3d6da30b89f218a4be75b976c0e8..0b3ad18af3d8de81f486ae6b02a2cf8b7bbe2b30 100644 --- a/src/libs/core/score/tmeasureobject.cpp +++ b/src/libs/core/score/tmeasureobject.cpp @@ -243,7 +243,9 @@ int TmeasureObject::beamGroup(int segmentId) { auto prevSeg = m_notes[segId - 1]; if (!noteSeg->note()->isRest() && !prevSeg->note()->isRest() // not a rest && noteSeg->note()->rhythm() > Trhythm::Quarter // sixteenth or eighth - && prevSeg->note()->rhythm() > Trhythm::Quarter) + && prevSeg->note()->rhythm() > Trhythm::Quarter + && (!m_score->isPianoStaff() || noteSeg->note()->onUpperStaff() == prevSeg->note()->onUpperStaff()) + ) { if (prevSeg->note()->rtm.beam() == Trhythm::e_noBeam) // start beam group prevSeg->setBeam(new TbeamObject(prevSeg, this)); diff --git a/src/libs/core/score/tnoteitem.cpp b/src/libs/core/score/tnoteitem.cpp index 4f4418f112635cf6dc6b618454406731efd2cc75..17625a58bf2ce3bb029fd330bc8ee1fc85ba1844 100644 --- a/src/libs/core/score/tnoteitem.cpp +++ b/src/libs/core/score/tnoteitem.cpp @@ -210,7 +210,8 @@ void TnoteItem::setNote(const Tnote& n) { bool updateHead = n.rhythm() != m_note->rhythm() || n.isRest() != m_note->isRest() || n.hasDot() != m_note->hasDot(); bool fixBeam = n.isRest() != m_note->isRest(); bool updateStem = updateHead || fixBeam || ((n.rtm.beam() != Trhythm::e_noBeam) != (m_note->rtm.beam() != Trhythm::e_noBeam)) - || (n.rtm.stemDown() != m_note->rtm.stemDown() || m_stem->height() != m_stemHeight); + || (n.rtm.stemDown() != m_note->rtm.stemDown() || m_stem->height() != m_stemHeight) + || n.onUpperStaff() != m_note->onUpperStaff(); bool updateTie = n.rtm.tie() != m_note->rtm.tie(); *m_note = n; @@ -234,7 +235,7 @@ void TnoteItem::setNote(const Tnote& n) { else { if (m_note->isValid()) { m_notePosY = staff()->score()->clefOffset().total() + staff()->upperLine() - (n.octave() * 7 + (n.note() - 1)); - if (staff()->score()->isPianoStaff()) { + if (staff()->isPianoStaff()) { if (m_note->onUpperStaff()) { if (m_notePosY > staff()->upperLine() + 13.0) m_notePosY += 10.0; @@ -326,7 +327,7 @@ void TnoteItem::setHeight(qreal hh) { m_upLines[l]->setY(2 * (l + 1) - 0.1); m_loLines[l]->setY(staff()->upperLine() + 10.0 + 2 * l - 0.1); } - if (staff()->score()->isPianoStaff()) { + if (staff()->isPianoStaff()) { if (m_underLoLines.isEmpty()) { m_staff->score()->component()->setData("import QtQuick 2.9; Rectangle {}", QUrl()); for (int l = 0; l < 2; ++l) { @@ -783,8 +784,10 @@ void TnoteItem::updateTieScale() { void TnoteItem::checkStem() { if (m_notePosY && !m_note->isRest() && m_note->rhythm() > Trhythm::Whole ) { if (m_note->rtm.beam() == Trhythm::e_noBeam) { - m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0); - m_stem->setHeight(qMax(STEM_HEIGHT, qAbs(m_notePosY - (staff()->upperLine() + 4.0)))); + m_note->rtm.setStemDown(m_notePosY < staff()->upperLine() + 4.0 + || (staff()->isPianoStaff() && m_notePosY > staff()->upperLine() + 13.0 && m_notePosY < staff()->upperLine() + 26.0)); + m_stem->setHeight(qMax(STEM_HEIGHT, qAbs(m_notePosY + - (staff()->upperLine() + (staff()->isPianoStaff() && m_notePosY > staff()->upperLine() + 13.0 ? 26.0 : 4.0))))); QString flagText = getFlagText(); m_flag->setProperty("text", flagText); if (!flagText.isEmpty()) @@ -834,11 +837,11 @@ void TnoteItem::updateNamePos() { */ void TnoteItem::checkAddLinesVisibility() { bool v = m_head->isVisible() && !m_note->isRest(); - bool betweenStaves = staff()->score()->isPianoStaff() && m_notePosY >= staff()->upperLine() + 10.0 && m_notePosY < staff()->upperLine() + 21.0; + bool betweenStaves = staff()->isPianoStaff() && m_notePosY >= staff()->upperLine() + 10.0 && m_notePosY < staff()->upperLine() + 21.0; for (int i = 0; i < 7; ++i) { m_upLines[i]->setVisible(v && m_notePosY > 0.0 && i >= qFloor((m_notePosY - 1.0) / 2.0)); qreal upp1 = staff()->upperLine() + 10.0 + i * 2; - if (staff()->score()->isPianoStaff()) { + if (staff()->isPianoStaff()) { if (m_notePosY < staff()->upperLine() + 14.0) m_loLines[i]->setVisible(v && betweenStaves && m_notePosY >= upp1 && m_notePosY < staff()->upperLine() + 14.0); else diff --git a/src/libs/core/score/tstaffitem.cpp b/src/libs/core/score/tstaffitem.cpp index 85199dce0e233425853a6d8a3321f3b84ead77f7..251ff02196c927a9a0b73898761f4141a88961b2 100644 --- a/src/libs/core/score/tstaffitem.cpp +++ b/src/libs/core/score/tstaffitem.cpp @@ -101,6 +101,11 @@ void TstaffItem::setNotesIndent(qreal ni) { } +bool TstaffItem::isPianoStaff() const { + return m_scoreObj->isPianoStaff(); +} + + char TstaffItem::debug() { QTextStream o(stdout); o << "\033[01;34m[" << number() + 1 << " STAFF]\033[01;00m"; diff --git a/src/libs/core/score/tstaffitem.h b/src/libs/core/score/tstaffitem.h index b1a95a1688393086ec18d7fff0e79496dcc7294e..ddb33854d08d432077a5786e1964d84270cdff40 100644 --- a/src/libs/core/score/tstaffitem.h +++ b/src/libs/core/score/tstaffitem.h @@ -122,6 +122,8 @@ public: qreal gapsSum() const { return m_gapsSum; } + bool isPianoStaff() const; + /** * Prints to std out debug info about this staff: [nr STAFF] in color */