Skip to content

Commit

Permalink
Merge pull request #23899 from miiizen/20596-grace-ties
Browse files Browse the repository at this point in the history
Link grace note ties when cloning measures and staves
  • Loading branch information
mike-spa authored Aug 9, 2024
2 parents a5a1130 + e15e52a commit 0d4d8be
Show file tree
Hide file tree
Showing 8 changed files with 1,476 additions and 72 deletions.
9 changes: 9 additions & 0 deletions src/engraving/dom/chord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2572,6 +2572,15 @@ GraceNotesGroup& Chord::graceNotesAfter(bool filterUnplayable) const
return m_graceNotesAfter;
}

Chord* Chord::graceNoteAt(size_t idx) const
{
if (idx > m_graceNotes.size()) {
return nullptr;
}

return m_graceNotes.at(idx);
}

//---------------------------------------------------------
// setShowStemSlashInAdvance
//---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/dom/chord.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class Chord final : public ChordRest
size_t graceIndex() const { return m_graceIndex; }
void setGraceIndex(size_t val) { m_graceIndex = val; }

Chord* graceNoteAt(size_t idx) const;

int upLine() const override;
int downLine() const override;
PointF stemPos() const override; ///< page coordinates
Expand Down
40 changes: 20 additions & 20 deletions src/engraving/dom/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5684,28 +5684,28 @@ static void undoChangeNoteVisibility(Note* note, bool visible)
ElementType::LEDGER_LINE, // temporary objects, impossible to change visibility
};

for (Chord* chord : chords) {
if (chord != noteChord) {
chordHasVisibleNote_ = chordHasVisibleNote(chord);
}

for (EngravingObject* child : chord->scanChildren()) {
ElementType type = child->type();

if (muse::contains(IGNORED_TYPES, type)) {
continue;
}

if (beam) {
if (type == ElementType::STEM || type == ElementType::BEAM) {
child->undoChangeProperty(Pid::VISIBLE, beamHasVisibleNote_);
for (const Chord* chord : chords) {
for (const EngravingObject* obj : chord->linkList()) {
const Chord* linkedChord = toChord(obj);
chordHasVisibleNote_ = chordHasVisibleNote(linkedChord);
for (EngravingObject* child : linkedChord->scanChildren()) {
const ElementType type = child->type();

if (muse::contains(IGNORED_TYPES, type)) {
continue;
}
}
if (child->isOrnament()) {
undoChangeOrnamentVisibility(toOrnament(child), visible);
} else {
child->undoChangeProperty(Pid::VISIBLE, chordHasVisibleNote_);

if (beam) {
if (type == ElementType::STEM || type == ElementType::BEAM) {
child->undoChangeProperty(Pid::VISIBLE, beamHasVisibleNote_);
continue;
}
}
if (child->isOrnament()) {
undoChangeOrnamentVisibility(toOrnament(child), visible);
} else {
child->undoChangeProperty(Pid::VISIBLE, chordHasVisibleNote_);
}
}
}
}
Expand Down
101 changes: 49 additions & 52 deletions src/engraving/dom/excerpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,45 @@ static void processLinkedClone(EngravingItem* ne, Score* score, track_idx_t stra
ne->setScore(score);
}

static void addTies(Note* originalNote, Note* newNote, TieMap& tieMap, Score* score)
{
if (originalNote->tieFor()) {
Tie* tie = toTie(originalNote->tieFor()->linkedClone());
tie->setScore(score);
newNote->setTieFor(tie);
tie->setStartNote(newNote);
tie->setTrack(newNote->track());
tieMap.add(originalNote->tieFor(), tie);
}
if (originalNote->tieBack()) {
Tie* tie = tieMap.findNew(originalNote->tieBack());
if (tie) {
newNote->setTieBack(tie);
tie->setEndNote(newNote);
} else {
LOGD("addTiesToMap: cannot find tie");
}
}
}

static void addGraceNoteTies(GraceNotesGroup& originalGraceNotes, Chord* newChord, TieMap& tieMap, Score* score)
{
for (Chord* oldGrace : originalGraceNotes) {
Chord* newGrace = newChord->graceNoteAt(oldGrace->graceIndex());
if (!newGrace) {
continue;
}

size_t notes = oldGrace->notes().size();
for (size_t i = 0; i < notes; ++i) {
Note* originalNote = oldGrace->notes().at(i);
Note* newNote = newGrace->notes().at(i);

addTies(originalNote, newNote, tieMap, score);
}
}
}

static MeasureBase* cloneMeasure(MeasureBase* mb, Score* score, const Score* oscore,
const std::vector<staff_idx_t>& sourceStavesIndexes,
const TracksMap& trackList, TieMap& tieMap)
Expand Down Expand Up @@ -934,28 +973,13 @@ static MeasureBase* cloneMeasure(MeasureBase* mb, Score* score, const Score* osc
if (oe->isChord()) {
Chord* och = toChord(ocr);
Chord* nch = toChord(ncr);

addGraceNoteTies(och->graceNotesBefore(), nch, tieMap, score);
size_t n = och->notes().size();
for (size_t i = 0; i < n; ++i) {
Note* on = och->notes().at(i);
Note* nn = nch->notes().at(i);
if (on->tieFor()) {
Tie* tie = toTie(on->tieFor()->linkedClone());
tie->setScore(score);
nn->setTieFor(tie);
tie->setStartNote(nn);
tie->setTrack(nn->track());
tieMap.add(on->tieFor(), tie);
}
if (on->tieBack()) {
Tie* tie = tieMap.findNew(on->tieBack());
if (tie) {
nn->setTieBack(tie);
tie->setEndNote(nn);
} else {
LOGD("cloneStaves: cannot find tie");
}
}

addTies(on, nn, tieMap, score);
// add back spanners (going back from end to start spanner element
// makes sure the 'other' spanner anchor element is already set up)
// 'on' is the old spanner end note and 'nn' is the new spanner end note
Expand Down Expand Up @@ -988,6 +1012,7 @@ static MeasureBase* cloneMeasure(MeasureBase* mb, Score* score, const Score* osc
}
}
}
addGraceNoteTies(och->graceNotesAfter(), nch, tieMap, score);
// two note tremolo
if (och->tremoloTwoChord()) {
if (och == och->tremoloTwoChord()->chord1()) {
Expand Down Expand Up @@ -1298,27 +1323,12 @@ void Excerpt::cloneStaff(Staff* srcStaff, Staff* dstStaff, bool cloneSpanners)
if (oe->isChord()) {
Chord* och = toChord(ocr);
Chord* nch = toChord(ncr);
addGraceNoteTies(och->graceNotesBefore(), nch, tieMap, score);
size_t n = och->notes().size();
for (size_t i = 0; i < n; ++i) {
Note* on = och->notes().at(i);
Note* nn = nch->notes().at(i);
if (on->tieFor()) {
Tie* tie = toTie(on->tieFor()->linkedClone());
tie->setScore(score);
nn->setTieFor(tie);
tie->setStartNote(nn);
tie->setTrack(nn->track());
tieMap.add(on->tieFor(), tie);
}
if (on->tieBack()) {
Tie* tie = tieMap.findNew(on->tieBack());
if (tie) {
nn->setTieBack(tie);
tie->setEndNote(nn);
} else {
LOGD("cloneStaff: cannot find tie");
}
}
addTies(on, nn, tieMap, score);
// add back spanners (going back from end to start spanner element
// makes sure the 'other' spanner anchor element is already set up)
// 'on' is the old spanner end note and 'nn' is the new spanner end note
Expand All @@ -1333,6 +1343,7 @@ void Excerpt::cloneStaff(Staff* srcStaff, Staff* dstStaff, bool cloneSpanners)
}
}
}
addGraceNoteTies(och->graceNotesAfter(), nch, tieMap, score);
// two note tremolo
if (och->tremoloTwoChord()) {
if (och == och->tremoloTwoChord()->chord1()) {
Expand Down Expand Up @@ -1569,27 +1580,12 @@ void Excerpt::cloneStaff2(Staff* srcStaff, Staff* dstStaff, const Fraction& star
if (oe->isChord()) {
Chord* och = toChord(ocr);
Chord* nch = toChord(ncr);
addGraceNoteTies(och->graceNotesBefore(), nch, tieMap, score);
size_t n = och->notes().size();
for (size_t i = 0; i < n; ++i) {
Note* on = och->notes().at(i);
Note* nn = nch->notes().at(i);
if (on->tieFor()) {
Tie* tie = toTie(on->tieFor()->linkedClone());
tie->setScore(score);
nn->setTieFor(tie);
tie->setStartNote(nn);
tie->setTrack(nn->track());
tieMap.add(on->tieFor(), tie);
}
if (on->tieBack()) {
Tie* tie = tieMap.findNew(on->tieBack());
if (tie) {
nn->setTieBack(tie);
tie->setEndNote(nn);
} else {
LOGD("cloneStaff2: cannot find tie");
}
}
addTies(on, nn, tieMap, score);
// add back spanners (going back from end to start spanner element
// makes sure the 'other' spanner anchor element is already set up)
// 'on' is the old spanner end note and 'nn' is the new spanner end note
Expand Down Expand Up @@ -1629,6 +1625,7 @@ void Excerpt::cloneStaff2(Staff* srcStaff, Staff* dstStaff, const Fraction& star
nn->addSpannerFor(newBend);
}
}
addGraceNoteTies(och->graceNotesAfter(), nch, tieMap, score);
// two note tremolo
if (och->tremoloTwoChord()) {
if (och == och->tremoloTwoChord()->chord1()) {
Expand Down
Loading

0 comments on commit 0d4d8be

Please sign in to comment.