Skip to content

Commit

Permalink
Percussion panel - fix bug when switching voices while entering notes
Browse files Browse the repository at this point in the history
  • Loading branch information
mathesoncalum committed Jan 13, 2025
1 parent 68e434e commit 9dcbfac
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 24 deletions.
54 changes: 30 additions & 24 deletions src/engraving/dom/noteentry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ Note* Score::addPitch(NoteVal& nval, bool addFlag, InputState* externalInputStat
}

if (!is.cr()) {
return 0;
handleOverlappingChordRest(is);
}

Measure* measure = is.segment()->measure();
if (measure->isMeasureRepeatGroup(track2staff(track))) {
MeasureRepeat* mr = measure->measureRepeatElement(track2staff(track));
Expand Down Expand Up @@ -456,29 +457,7 @@ Ret Score::putNote(const Position& p, bool replace)

// If there's an overlapping ChordRest at the current input position, shorten it...
if (!cr) {
MasterScore* ms = masterScore();
ChordRest* prevCr = m_is.segment()->nextChordRest(m_is.track(), /*backwards*/ true, /*stopAtMeasureBoundary*/ true);
if (prevCr && prevCr->endTick() > m_is.tick()) {
const Fraction overlapDuration = prevCr->endTick() - m_is.tick();
const Fraction desiredDuration = prevCr->ticks() - overlapDuration;

const InputState inputStateToRestore = m_is; // because changeCRlen will alter the input state
ms->changeCRlen(prevCr, desiredDuration, /*fillWithRest*/ false);

// Fill the difference with tied notes if necessary...
const Fraction difference = desiredDuration - prevCr->ticks();
if (prevCr->isChord() && difference.isNotZero()) {
Fraction startTick = prevCr->endTick();
Chord* prevChord = toChord(prevCr);
const std::vector<TDuration> durationList = toDurationList(difference, true);
for (const TDuration& dur : durationList) {
prevChord = ms->addChord(startTick, dur, prevChord, /*genTie*/ bool(prevChord), prevChord->tuplet());
startTick += dur.fraction();
}
}

m_is = inputStateToRestore;
}
handleOverlappingChordRest(m_is);
}

auto checkTied = [&](){
Expand Down Expand Up @@ -587,6 +566,33 @@ Ret Score::putNote(const Position& p, bool replace)
return ret;
}

void Score::handleOverlappingChordRest(InputState& inputState)
{
MasterScore* ms = masterScore();
ChordRest* prevCr = inputState.segment()->nextChordRest(inputState.track(), /*backwards*/ true, /*stopAtMeasureBoundary*/ true);
if (prevCr && prevCr->endTick() > inputState.tick()) {
const Fraction overlapDuration = prevCr->endTick() - inputState.tick();
const Fraction desiredDuration = prevCr->ticks() - overlapDuration;

const InputState inputStateToRestore = inputState; // because changeCRlen will alter the input state
ms->changeCRlen(prevCr, desiredDuration, /*fillWithRest*/ true);

// Fill the difference with tied notes if necessary...
const Fraction difference = desiredDuration - prevCr->ticks();
if (prevCr->isChord() && difference.isNotZero()) {
Fraction startTick = prevCr->endTick();
Chord* prevChord = toChord(prevCr);
const std::vector<TDuration> durationList = toDurationList(difference, true);
for (const TDuration& dur : durationList) {
prevChord = ms->addChord(startTick, dur, prevChord, /*genTie*/ bool(prevChord), prevChord->tuplet());
startTick += dur.fraction();
}
}

inputState = inputStateToRestore;
}
}

//---------------------------------------------------------
// repitchNote
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/engraving/dom/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ class Score : public EngravingObject, public muse::Injectable
void selectRange(EngravingItem* e, staff_idx_t staffIdx);

muse::Ret putNote(const Position&, bool replace);
void handleOverlappingChordRest(InputState& inputState);

void resetTempo();
void resetTempoRange(const Fraction& tick1, const Fraction& tick2);
Expand Down

0 comments on commit 9dcbfac

Please sign in to comment.