diff --git a/src/engraving/dom/chord.cpp b/src/engraving/dom/chord.cpp index 810b5bee6f2c..43e323ace7d6 100644 --- a/src/engraving/dom/chord.cpp +++ b/src/engraving/dom/chord.cpp @@ -2623,6 +2623,11 @@ bool Chord::preOrGraceBendSpacingExceptionInTab() const return bends.size() < endChord->notes().size(); } +void Chord::setIsTrillCueNote(bool v) +{ + m_isTrillCueNote = v; +} + //--------------------------------------------------------- // tremoloChordType //--------------------------------------------------------- diff --git a/src/engraving/dom/chord.h b/src/engraving/dom/chord.h index 3eec16eb0c18..de168963f566 100644 --- a/src/engraving/dom/chord.h +++ b/src/engraving/dom/chord.h @@ -213,6 +213,9 @@ class Chord final : public ChordRest bool isPreBendOrGraceBendStart() const; bool preOrGraceBendSpacingExceptionInTab() const; + bool isTrillCueNote() const { return m_isTrillCueNote; } + void setIsTrillCueNote(bool v); + void setTrack(track_idx_t val) override; double dotPosX() const { return m_dotPosX; } @@ -348,6 +351,8 @@ class Chord final : public ChordRest mutable GraceNotesGroup m_graceNotesAfter = GraceNotesGroup(this); // will store after-chord grace notes size_t m_graceIndex = 0; // if this is a grace note, index in parent list + bool m_isTrillCueNote = false; + DirectionV m_stemDirection = DirectionV::AUTO; NoteType m_noteType = NoteType::NORMAL; // mark grace notes: acciaccatura and appoggiatura bool m_noStem = false; diff --git a/src/engraving/dom/note.cpp b/src/engraving/dom/note.cpp index 877541ab1246..6f9cb6b9ccc3 100644 --- a/src/engraving/dom/note.cpp +++ b/src/engraving/dom/note.cpp @@ -3599,6 +3599,14 @@ mu::PointF Note::posInStaffCoordinates() return mu::PointF(X, y()); } +void Note::setIsTrillCueNote(bool v) +{ + m_isTrillCueNote = v; + if (chord()) { + chord()->setIsTrillCueNote(v); + } +} + void Note::addLineAttachPoint(PointF point, EngravingItem* line) { // IMPORTANT: the point is expected in *staff* coordinates diff --git a/src/engraving/dom/note.h b/src/engraving/dom/note.h index 354f2fbdc391..6bb7040bd086 100644 --- a/src/engraving/dom/note.h +++ b/src/engraving/dom/note.h @@ -437,7 +437,7 @@ class Note final : public EngravingItem mu::PointF posInStaffCoordinates(); bool isTrillCueNote() const { return m_isTrillCueNote; } - void setIsTrillCueNote(bool v) { m_isTrillCueNote = v; } + void setIsTrillCueNote(bool v); SymId noteHead() const; bool isNoteName() const; diff --git a/src/engraving/dom/score.cpp b/src/engraving/dom/score.cpp index 14d60e510369..3f60a6e4052b 100644 --- a/src/engraving/dom/score.cpp +++ b/src/engraving/dom/score.cpp @@ -2964,6 +2964,14 @@ void Score::cmdConcertPitchChanged(bool flag) void Score::padToggle(Pad p, const EditData& ed) { + if (!noteEntryMode()) { + for (ChordRest* cr : getSelectedChordRests()) { + if (cr->isChord() && toChord(cr)->isTrillCueNote()) { + return; + } + } + } + int oldDots = m_is.duration().dots(); switch (p) { case Pad::NOTE00: @@ -5064,7 +5072,7 @@ void Score::changeSelectedNotesVoice(voice_idx_t voice) Chord* chord = note->chord(); // move grace notes with main chord only - if (chord->isGrace()) { + if (chord->isGrace() || chord->isTrillCueNote()) { continue; } diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp index 6e907ae7b4d9..9fabafb90c8b 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -2034,12 +2034,16 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) } } - if (firstChordRest && (firstChordRest != secondChordRest)) { + bool firstCrTrill = firstChordRest && firstChordRest->isChord() && toChord(firstChordRest)->isTrillCueNote(); + bool secondCrTrill = secondChordRest && secondChordRest->isChord() && toChord(secondChordRest)->isTrillCueNote(); + + if (firstChordRest && (firstChordRest != secondChordRest) + && !(firstCrTrill || secondCrTrill)) { doAddSlur(firstChordRest, secondChordRest, slurTemplate); } } } else if (sel.isSingle()) { - if (sel.element()->isNote()) { + if (sel.element()->isNote() && !toNote(sel.element())->isTrillCueNote()) { doAddSlur(toNote(sel.element())->chord(), nullptr, slurTemplate); } } else { @@ -2063,7 +2067,10 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) secondChordRest = mu::engraving::nextChordRest(firstChordRest); } - if (firstChordRest) { + bool firstCrTrill = firstChordRest && firstChordRest->isChord() && toChord(firstChordRest)->isTrillCueNote(); + bool secondCrTrill = secondChordRest && secondChordRest->isChord() && toChord(secondChordRest)->isTrillCueNote(); + + if (firstChordRest && !(firstCrTrill || secondCrTrill)) { doAddSlur(firstChordRest, secondChordRest, slurTemplate); } } @@ -3889,6 +3896,9 @@ void NotationInteraction::changeSelectedNotesArticulation(SymbolId articulationS std::set chords; for (Note* note: notes) { + if (note->isTrillCueNote()) { + return; + } Chord* chord = note->chord(); if (chords.find(chord) == chords.end()) { chords.insert(chord); @@ -3939,7 +3949,7 @@ void NotationInteraction::addGraceNotesToSelectedNotes(GraceNoteType type) bool NotationInteraction::canAddTupletToSelectedChordRests() const { for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (chordRest->isGrace()) { + if (chordRest->isGrace() || (chordRest->isChord() && toChord(chordRest)->isTrillCueNote())) { continue; } @@ -3961,7 +3971,7 @@ void NotationInteraction::addTupletToSelectedChordRests(const TupletOptions& opt startEdit(); for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (!chordRest->isGrace()) { + if (!chordRest->isGrace() && !(chordRest->isChord() && toChord(chordRest)->isTrillCueNote())) { Fraction ratio = options.ratio; if (options.autoBaseLen) { ratio.setDenominator(Tuplet::computeTupletDenominator(ratio.numerator(), chordRest->ticks()));