Skip to content

Commit

Permalink
Fix align issues by ensuring that the property is reset if needed
Browse files Browse the repository at this point in the history
(after end editing)
  • Loading branch information
asattely committed Mar 20, 2023
1 parent 57f59b8 commit 590e6b3
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 29 deletions.
96 changes: 67 additions & 29 deletions src/engraving/libmscore/lyrics.cpp
Expand Up @@ -214,11 +214,11 @@ bool Lyrics::isMelisma() const

// hyphenated?
// if so, it is a melisma only if there is no lyric in same verse on next CR
if (_syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
if (_separator && (_syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE)) {
// find next CR on same track and check for existence of lyric in same verse
ChordRest* cr = chordRest();
ChordRest* cr = chordRest();
if (cr) {
Segment* s = cr->segment()->next1();
Segment* s = cr->segment()->next1();
ChordRest* ncr = s ? s->nextChordRest(cr->track()) : 0;
if (ncr && !ncr->lyrics(_no, placement())) {
return true;
Expand All @@ -230,6 +230,31 @@ bool Lyrics::isMelisma() const
return false;
}

//---------------------------------------------------------
// prevLyrics
// - find the lyric (if any) before this one (not including lines)
// - currently used to determine the first lyric of a melisma
//---------------------------------------------------------

Lyrics* Lyrics::prevLyrics() const
{
track_idx_t currTrack = track();
Segment* seg = segment();
if (!seg) {
return nullptr;
}
PropertyFlags pFlags = propertyFlags(mu::engraving::Pid::PLACEMENT);
Segment* prevSegment = seg;
while ((prevSegment = prevSegment->prev1(mu::engraving::SegmentType::ChordRest))) {
EngravingItem* el = prevSegment->element(currTrack);
Lyrics* prevLyrics = el && el->isChord() ? toChordRest(el)->lyrics(no(), placement()) : nullptr;
if (prevLyrics) {
return prevLyrics;
}
}
return nullptr;
}

//---------------------------------------------------------
// layout
// - does not touch vertical position
Expand Down Expand Up @@ -306,6 +331,33 @@ void Lyrics::layout()
styleChanged();
}

ChordRest* cr = chordRest();
if (_removeInvalidSegments) {
removeInvalidSegments();
} else if (_ticks > Fraction(0, 1) || _syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
if (!_separator) {
_separator = new LyricsLine(score()->dummy());
_separator->setTick(cr->tick());
score()->addUnmanagedSpanner(_separator);
}
_separator->setParent(this);
_separator->setTick(cr->tick());
// HACK separator should have non-zero length to get its layout
// always triggered. A proper ticks length will be set later on the
// separator layout.
_separator->setTicks(Fraction::fromTicks(1));
_separator->setTrack(track());
_separator->setTrack2(track());
_separator->setVisible(visible());
// bbox().setWidth(bbox().width()); // ??
} else {
if (_separator) {
_separator->removeUnmanaged();
delete _separator;
_separator = 0;
}
}

if (isMelisma() || hasNumber) {
// use the melisma style alignment setting
if (isStyled(Pid::ALIGN)) {
Expand Down Expand Up @@ -343,8 +395,6 @@ void Lyrics::layout()
}
}

ChordRest* cr = chordRest();

if (align() == AlignH::HCENTER) {
//
// center under notehead, not origin
Expand All @@ -360,30 +410,6 @@ void Lyrics::layout()

setPosX(x);

if (_ticks > Fraction(0, 1) || _syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) {
if (!_separator) {
_separator = new LyricsLine(score()->dummy());
_separator->setTick(cr->tick());
score()->addUnmanagedSpanner(_separator);
}
_separator->setParent(this);
_separator->setTick(cr->tick());
// HACK separator should have non-zero length to get its layout
// always triggered. A proper ticks length will be set later on the
// separator layout.
_separator->setTicks(Fraction::fromTicks(1));
_separator->setTrack(track());
_separator->setTrack2(track());
_separator->setVisible(visible());
// bbox().setWidth(bbox().width()); // ??
} else {
if (_separator) {
_separator->removeUnmanaged();
delete _separator;
_separator = 0;
}
}

if (_ticks.isNotZero()) {
// set melisma end
ChordRest* ecr = score()->findCR(endTick(), track());
Expand Down Expand Up @@ -766,4 +792,16 @@ KerningType Lyrics::doComputeKerningType(const EngravingItem* nextItem) const
}
return KerningType::KERNING;
}

void Lyrics::removeInvalidSegments()
{
_removeInvalidSegments = false;
if (_separator && isMelisma() && _ticks < _separator->startCR()->ticks()) {
setTicks(Fraction(0, 1));
_separator->removeUnmanaged();
delete _separator;
_separator = nullptr;
setAlign(propertyDefault(Pid::ALIGN).value<Align>());
}
}
}
4 changes: 4 additions & 0 deletions src/engraving/libmscore/lyrics.h
Expand Up @@ -59,12 +59,14 @@ class Lyrics final : public TextBase
///< (melisma)
Syllabic _syllabic;
LyricsLine* _separator;
bool _removeInvalidSegments = false;

friend class Factory;
Lyrics(ChordRest* parent);
Lyrics(const Lyrics&);

bool isMelisma() const;
void removeInvalidSegments();
void undoChangeProperty(Pid id, const PropertyValue&, PropertyFlags ps) override;

protected:
Expand All @@ -83,6 +85,7 @@ class Lyrics final : public TextBase
Segment* segment() const { return toSegment(explicitParent()->explicitParent()); }
Measure* measure() const { return toMeasure(explicitParent()->explicitParent()->explicitParent()); }
ChordRest* chordRest() const { return toChordRest(explicitParent()); }
Lyrics* prevLyrics() const;

void layout() override;
void layout2(int);
Expand All @@ -108,6 +111,7 @@ class Lyrics final : public TextBase
void setTicks(const Fraction& tick) { _ticks = tick; }
Fraction endTick() const;
void removeFromScore();
void setRemoveInvalidSegments() { _removeInvalidSegments = true; }

using EngravingObject::undoChangeProperty;
void paste(EditData& ed, const String& txt) override;
Expand Down
8 changes: 8 additions & 0 deletions src/engraving/libmscore/textedit.cpp
Expand Up @@ -26,6 +26,7 @@
#include "score.h"
#include "iengravingfont.h"
#include "types/symnames.h"
#include "lyrics.h"

#include "log.h"

Expand Down Expand Up @@ -187,6 +188,13 @@ void TextBase::endEdit(EditData& ed)
}

commitText();
if (isLyrics()) {
Lyrics* prevLyrics = toLyrics(this)->prevLyrics();
if (prevLyrics) {
prevLyrics->setRemoveInvalidSegments();
prevLyrics->layout();
}
}
return;
}

Expand Down

0 comments on commit 590e6b3

Please sign in to comment.