From c810afd8fdb67dfa84c878a750d318f3efcc4573 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 6 Sep 2023 17:09:16 +0100 Subject: [PATCH 1/3] Disable most editing options for trill cue notes --- src/engraving/dom/chordrest.cpp | 9 +++++++++ src/engraving/dom/chordrest.h | 5 +++++ src/engraving/dom/note.cpp | 8 ++++++++ src/engraving/dom/note.h | 2 +- src/engraving/dom/score.cpp | 10 +++++++++- src/notation/internal/notationinteraction.cpp | 7 +++++-- 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/engraving/dom/chordrest.cpp b/src/engraving/dom/chordrest.cpp index 9cfbc81b1c73..6ca8df8d9eb9 100644 --- a/src/engraving/dom/chordrest.cpp +++ b/src/engraving/dom/chordrest.cpp @@ -780,6 +780,15 @@ Breath* ChordRest::hasBreathMark() const return s ? toBreath(s->element(track())) : 0; } +void ChordRest::setIsTrillCueNote(bool v) +{ + if (isChord()) { + m_isTrillCueNote = v; + } else { + m_isTrillCueNote = false; + } +} + //--------------------------------------------------------- // nextSegmentAfterCR // returns first segment at tick CR->tick + CR->actualTicks diff --git a/src/engraving/dom/chordrest.h b/src/engraving/dom/chordrest.h index e285281c28c3..237fc7caf32e 100644 --- a/src/engraving/dom/chordrest.h +++ b/src/engraving/dom/chordrest.h @@ -177,6 +177,9 @@ class ChordRest : public DurationElement bool isGraceAfter() const; Breath* hasBreathMark() const; + bool isTrillCueNote() const { return m_isTrillCueNote; } + void setIsTrillCueNote(bool v); + Segment* nextSegmentAfterCR(SegmentType types) const; void setScore(Score* s) override; @@ -232,6 +235,8 @@ class ChordRest : public DurationElement TDuration m_durationType; int m_staffMove = 0; // -1, 0, +1, used for crossbeaming int m_storedStaffMove = 0; // used to remember and re-apply staff move if needed + + bool m_isTrillCueNote = false; }; } // namespace mu::engraving #endif 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..e7121ee3d886 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->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..97ce6adef67b 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -3889,6 +3889,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 +3942,7 @@ void NotationInteraction::addGraceNotesToSelectedNotes(GraceNoteType type) bool NotationInteraction::canAddTupletToSelectedChordRests() const { for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (chordRest->isGrace()) { + if (chordRest->isGrace() || chordRest->isTrillCueNote()) { continue; } @@ -3961,7 +3964,7 @@ void NotationInteraction::addTupletToSelectedChordRests(const TupletOptions& opt startEdit(); for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (!chordRest->isGrace()) { + if (!chordRest->isGrace() && !chordRest->isTrillCueNote()) { Fraction ratio = options.ratio; if (options.autoBaseLen) { ratio.setDenominator(Tuplet::computeTupletDenominator(ratio.numerator(), chordRest->ticks())); From 922d31ed19bbf5cc49cce67e5efd911c4009d829 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 11 Sep 2023 14:23:43 +0100 Subject: [PATCH 2/3] Disable slur to/from cue --- src/notation/internal/notationinteraction.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp index 97ce6adef67b..70f448343262 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -2034,12 +2034,13 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) } } - if (firstChordRest && (firstChordRest != secondChordRest)) { + if (firstChordRest && (firstChordRest != secondChordRest) + && !(firstChordRest->isTrillCueNote() || (secondChordRest || secondChordRest->isTrillCueNote()))) { 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 +2064,7 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) secondChordRest = mu::engraving::nextChordRest(firstChordRest); } - if (firstChordRest) { + if (firstChordRest && !(firstChordRest->isTrillCueNote() || (secondChordRest && secondChordRest->isTrillCueNote()))) { doAddSlur(firstChordRest, secondChordRest, slurTemplate); } } From fa0d0f5c1ab9d5b2ceea8b88ec3b0a90cb2e9ff6 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 23 Oct 2023 10:28:03 +0100 Subject: [PATCH 3/3] Move isTrillCueNote to chord --- src/engraving/dom/chord.cpp | 5 +++++ src/engraving/dom/chord.h | 5 +++++ src/engraving/dom/chordrest.cpp | 9 --------- src/engraving/dom/chordrest.h | 5 ----- src/engraving/dom/score.cpp | 2 +- src/notation/internal/notationinteraction.cpp | 14 ++++++++++---- 6 files changed, 21 insertions(+), 19 deletions(-) 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/chordrest.cpp b/src/engraving/dom/chordrest.cpp index 6ca8df8d9eb9..9cfbc81b1c73 100644 --- a/src/engraving/dom/chordrest.cpp +++ b/src/engraving/dom/chordrest.cpp @@ -780,15 +780,6 @@ Breath* ChordRest::hasBreathMark() const return s ? toBreath(s->element(track())) : 0; } -void ChordRest::setIsTrillCueNote(bool v) -{ - if (isChord()) { - m_isTrillCueNote = v; - } else { - m_isTrillCueNote = false; - } -} - //--------------------------------------------------------- // nextSegmentAfterCR // returns first segment at tick CR->tick + CR->actualTicks diff --git a/src/engraving/dom/chordrest.h b/src/engraving/dom/chordrest.h index 237fc7caf32e..e285281c28c3 100644 --- a/src/engraving/dom/chordrest.h +++ b/src/engraving/dom/chordrest.h @@ -177,9 +177,6 @@ class ChordRest : public DurationElement bool isGraceAfter() const; Breath* hasBreathMark() const; - bool isTrillCueNote() const { return m_isTrillCueNote; } - void setIsTrillCueNote(bool v); - Segment* nextSegmentAfterCR(SegmentType types) const; void setScore(Score* s) override; @@ -235,8 +232,6 @@ class ChordRest : public DurationElement TDuration m_durationType; int m_staffMove = 0; // -1, 0, +1, used for crossbeaming int m_storedStaffMove = 0; // used to remember and re-apply staff move if needed - - bool m_isTrillCueNote = false; }; } // namespace mu::engraving #endif diff --git a/src/engraving/dom/score.cpp b/src/engraving/dom/score.cpp index e7121ee3d886..3f60a6e4052b 100644 --- a/src/engraving/dom/score.cpp +++ b/src/engraving/dom/score.cpp @@ -2966,7 +2966,7 @@ void Score::padToggle(Pad p, const EditData& ed) { if (!noteEntryMode()) { for (ChordRest* cr : getSelectedChordRests()) { - if (cr->isTrillCueNote()) { + if (cr->isChord() && toChord(cr)->isTrillCueNote()) { return; } } diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp index 70f448343262..9fabafb90c8b 100644 --- a/src/notation/internal/notationinteraction.cpp +++ b/src/notation/internal/notationinteraction.cpp @@ -2034,8 +2034,11 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) } } + bool firstCrTrill = firstChordRest && firstChordRest->isChord() && toChord(firstChordRest)->isTrillCueNote(); + bool secondCrTrill = secondChordRest && secondChordRest->isChord() && toChord(secondChordRest)->isTrillCueNote(); + if (firstChordRest && (firstChordRest != secondChordRest) - && !(firstChordRest->isTrillCueNote() || (secondChordRest || secondChordRest->isTrillCueNote()))) { + && !(firstCrTrill || secondCrTrill)) { doAddSlur(firstChordRest, secondChordRest, slurTemplate); } } @@ -2064,7 +2067,10 @@ void NotationInteraction::doAddSlur(const mu::engraving::Slur* slurTemplate) secondChordRest = mu::engraving::nextChordRest(firstChordRest); } - if (firstChordRest && !(firstChordRest->isTrillCueNote() || (secondChordRest && secondChordRest->isTrillCueNote()))) { + bool firstCrTrill = firstChordRest && firstChordRest->isChord() && toChord(firstChordRest)->isTrillCueNote(); + bool secondCrTrill = secondChordRest && secondChordRest->isChord() && toChord(secondChordRest)->isTrillCueNote(); + + if (firstChordRest && !(firstCrTrill || secondCrTrill)) { doAddSlur(firstChordRest, secondChordRest, slurTemplate); } } @@ -3943,7 +3949,7 @@ void NotationInteraction::addGraceNotesToSelectedNotes(GraceNoteType type) bool NotationInteraction::canAddTupletToSelectedChordRests() const { for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (chordRest->isGrace() || chordRest->isTrillCueNote()) { + if (chordRest->isGrace() || (chordRest->isChord() && toChord(chordRest)->isTrillCueNote())) { continue; } @@ -3965,7 +3971,7 @@ void NotationInteraction::addTupletToSelectedChordRests(const TupletOptions& opt startEdit(); for (ChordRest* chordRest : score()->getSelectedChordRests()) { - if (!chordRest->isGrace() && !chordRest->isTrillCueNote()) { + if (!chordRest->isGrace() && !(chordRest->isChord() && toChord(chordRest)->isTrillCueNote())) { Fraction ratio = options.ratio; if (options.autoBaseLen) { ratio.setDenominator(Tuplet::computeTupletDenominator(ratio.numerator(), chordRest->ticks()));