Skip to content

Commit

Permalink
Fixed testing issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Eism committed Oct 16, 2023
1 parent cd14af7 commit 05b948c
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 47 deletions.
83 changes: 66 additions & 17 deletions src/engraving/dom/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1333,23 +1333,7 @@ bool Measure::acceptDrop(EditData& data) const
return true;

case ElementType::STRING_TUNINGS: {
const StringData* stringData = score()->staff(staffIdx)->part()->instrument(tick())->stringData();
if (!stringData || stringData->frettedStrings() == 0) {
return false;
}

// already a string tunings element in this measure
bool alreadyHasStringTunings = false;
for (const Segment& segment : m_segments) {
for (EngravingItem* element : segment.annotations()) {
if (element && element->isStringTunings()) {
alreadyHasStringTunings = true;
break;
}
}
}

if (alreadyHasStringTunings) {
if (!canAddStringTunings(staffIdx)) {
return false;
}

Expand Down Expand Up @@ -3211,6 +3195,71 @@ void Measure::checkTrailer()
}
}

void Measure::spaceRightAlignedSegments()
{
// Collect all the right-aligned segments starting from the back
std::vector<Segment*> rightAlignedSegments;
for (Segment* segment = m_segments.last(); segment; segment = segment->prev()) {
if (segment->enabled() && segment->isRightAligned()) {
rightAlignedSegments.push_back(segment);
}
}
// Compute spacing
static constexpr double arbitraryLowReal = -10000.0;
for (Segment* raSegment : rightAlignedSegments) {
// 1) right-align the segment against the following ones
double minDistAfter = arbitraryLowReal;
for (Segment* seg = raSegment->next(); seg; seg = seg->next()) {
double xDiff = seg->x() - raSegment->x();
double minDist = raSegment->minHorizontalCollidingDistance(seg);
minDistAfter = std::max(minDistAfter, minDist - xDiff);
}
if (minDistAfter != arbitraryLowReal && raSegment->prevActive()) {
Segment* prevSegment = raSegment->prev();
prevSegment->setWidth(prevSegment->width() - minDistAfter);
prevSegment->setWidthOffset(prevSegment->widthOffset() - minDistAfter);
raSegment->mutldata()->moveX(-minDistAfter);
raSegment->setWidth(raSegment->width() + minDistAfter);
}
// 2) Make sure the segment isn't colliding with anything behind
double minDistBefore = 0.0;
for (Segment* seg = raSegment->prevActive(); seg; seg = seg->prevActive()) {
double xDiff = raSegment->x() - seg->x();
double minDist = seg->minHorizontalCollidingDistance(raSegment);
minDistBefore = std::max(minDistBefore, minDist - xDiff);
}
Segment* prevSegment = raSegment->prevActive();
if (prevSegment) {
prevSegment->setWidth(prevSegment->width() + minDistBefore);
}
for (Segment* seg = raSegment; seg; seg = seg->next()) {
seg->mutldata()->moveX(minDistBefore);
}
setWidth(width() + minDistBefore);
}
}

bool Measure::canAddStringTunings(staff_idx_t staffIdx) const
{
const StringData* stringData = score()->staff(staffIdx)->part()->instrument(tick())->stringData();
if (!stringData || stringData->frettedStrings() == 0) {
return false;
}

// already a string tunings element in this measure
bool alreadyHasStringTunings = false;
for (const Segment& segment : m_segments) {
for (EngravingItem* element : segment.annotations()) {
if (element && element->isStringTunings()) {
alreadyHasStringTunings = true;
break;
}
}
}

return !alreadyHasStringTunings;
}

void Measure::stretchToTargetWidth(double targetWidth)
{
if (targetWidth < width()) {
Expand Down
4 changes: 4 additions & 0 deletions src/engraving/dom/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ class Measure final : public MeasureBase

void respaceSegments();

void spaceRightAlignedSegments();

bool canAddStringTunings(staff_idx_t staffIdx) const;

private:

friend class Factory;
Expand Down
14 changes: 14 additions & 0 deletions src/engraving/dom/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,17 @@ bool Note::acceptDrop(EditData& data) const
const Staff* st = staff();
bool isTablature = st->isTabStaff(tick());
bool tabFingering = st->staffTypeForElement(this)->showTabFingering();

if (type == ElementType::STRING_TUNINGS) {
staff_idx_t staffIdx;
Segment* seg;
if (!score()->pos2measure(data.pos, &staffIdx, 0, &seg, 0)) {
return false;
}

return chord()->measure()->canAddStringTunings(staffIdx);
}

return type == ElementType::ARTICULATION
|| type == ElementType::ORNAMENT
|| type == ElementType::FERMATA
Expand Down Expand Up @@ -1823,6 +1834,9 @@ EngravingItem* Note::drop(EditData& data)
toChordLine(e)->setNote(this);
return ch->drop(data);

case ElementType::STRING_TUNINGS:
return ch->measure()->drop(data);

default:
Spanner* spanner;
if (e->isSpanner() && (spanner = toSpanner(e))->anchor() == Spanner::Anchor::NOTE) {
Expand Down
13 changes: 13 additions & 0 deletions src/engraving/dom/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ bool Rest::acceptDrop(EditData& data) const
return true;
}

if (type == ElementType::STRING_TUNINGS) {
staff_idx_t staffIdx;
Segment* seg;
if (!score()->pos2measure(data.pos, &staffIdx, 0, &seg, 0)) {
return false;
}

return measure()->canAddStringTunings(staffIdx);
}

// prevent 'hanging' slurs, avoid crash on tie
static const std::set<ElementType> ignoredTypes {
ElementType::SLUR,
Expand Down Expand Up @@ -268,6 +278,9 @@ EngravingItem* Rest::drop(EditData& data)
score()->undoAddElement(e);
return e;

case ElementType::STRING_TUNINGS:
return measure()->drop(data);

default:
return ChordRest::drop(data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/stringtunings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ bool StringTunings::noStringVisible() const
String StringTunings::generateText() const
{
const StringData* stringData = this->stringData();
if (stringData->isNull()) {
if (!stringData || stringData->isNull()) {
return u"";
}

Expand Down
14 changes: 9 additions & 5 deletions src/engraving/rendering/dev/tlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ void TLayout::layoutItem(EngravingItem* item, LayoutContext& ctx)
layoutSticking(item_cast<const Sticking*>(item), static_cast<Sticking::LayoutData*>(ldata));
break;
case ElementType::STRING_TUNINGS:
layout(item_cast<StringTunings*>(item), ctx);
layoutStringTunings(item_cast<StringTunings*>(item), ctx);
break;
case ElementType::SYMBOL:
layoutSymbol(item_cast<const Symbol*>(item), static_cast<Symbol::LayoutData*>(ldata), ctx);
Expand Down Expand Up @@ -4973,10 +4973,11 @@ void TLayout::layoutStretched(StretchedBend* item, LayoutContext& ctx)
item->setPos(0.0, 0.0);
}

void TLayout::layout(StringTunings* item, LayoutContext& ctx)
void TLayout::layoutStringTunings(StringTunings* item, LayoutContext& ctx)
{
item->updateText();
layoutTextBase(item, ctx);

TLayout::layoutBaseTextBase(item, ctx);

if (item->noStringVisible()) {
double spatium = item->spatium();
Expand Down Expand Up @@ -5010,8 +5011,11 @@ void TLayout::layout(StringTunings* item, LayoutContext& ctx)

for (TextBlock& block : item->mutldata()->blocks) {
double xMove = 0.0;
for (auto& it = ++(block.fragments().begin()); it != block.fragments().end(); ++it) {
TextFragment& fragment = *it;
for (TextFragment& fragment : block.fragments()) {
if (block.fragments().front() == fragment) { // skip first
continue;
}

if (fragment.font(item).type() == mu::draw::Font::Type::MusicSymbol) {
xMove = secondStringXAlign - fragment.pos.x();
}
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/dev/tlayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class TLayout
static void layoutSticking(const Sticking* item, Sticking::LayoutData* ldata);
static void layoutStretchedBend(StretchedBend* item, LayoutContext& ctx);
static void layoutStretched(StretchedBend* item, LayoutContext& ctx);
static void layout(StringTunings* item, LayoutContext& ctx);
static void layoutStringTunings(StringTunings* item, LayoutContext& ctx);

static void layoutSymbol(const Symbol* item, Symbol::LayoutData* ldata, const LayoutContext& ctx);
static void layoutFSymbol(const FSymbol* item, FSymbol::LayoutData* ldata);
Expand Down
55 changes: 52 additions & 3 deletions src/engraving/rendering/stable/tlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ void TLayout::layoutItem(EngravingItem* item, LayoutContext& ctx)
break;
case ElementType::STICKING: layout(item_cast<Sticking*>(item), ctx);
break;
case ElementType::STRING_TUNINGS: layout(item_cast<StringTunings*>(item), ctx);
case ElementType::STRING_TUNINGS: layoutStringTunings(item_cast<StringTunings*>(item), ctx);
break;
case ElementType::SYMBOL: layout(item_cast<Symbol*>(item), ctx);
break;
Expand Down Expand Up @@ -4506,10 +4506,59 @@ void TLayout::layoutStretched(StretchedBend* item, LayoutContext& ctx)
item->setPos(0.0, 0.0);
}

void TLayout::layout(StringTunings* item, LayoutContext& ctx)
void TLayout::layoutStringTunings(StringTunings* item, LayoutContext& ctx)
{
item->updateText();
layoutTextBase(item, ctx);

TLayout::layoutTextBase(item, ctx);

if (item->noStringVisible()) {
double spatium = item->spatium();
mu::draw::Font font(item->font());

RectF rect;
rect.setTopLeft({ 0, item->ldata()->bbox().y() - font.weight() - spatium * .15 });
rect.setSize({ font.weight() - spatium, (font.weight() - spatium * .35) * 1.5 });

item->setbbox(rect);
}

for (TextBlock& block : item->mutldata()->blocks) {
for (TextFragment& fragment : block.fragments()) {
mu::draw::Font font = fragment.font(item);
if (font.type() == mu::draw::Font::Type::MusicSymbol) {
// HACK: the music symbol doesn't have a good baseline
// to go with text so we correct it here
const double baselineAdjustment = 0.35 * font.pointSizeF();
fragment.pos.setY(fragment.pos.y() + baselineAdjustment);
}
}
}

double secondStringXAlign = 0.0;
for (const TextFragment& fragment : item->fragmentList()) {
if (fragment.font(item).type() == mu::draw::Font::Type::MusicSymbol) {
secondStringXAlign = std::max(secondStringXAlign, fragment.pos.x());
}
}

for (TextBlock& block : item->mutldata()->blocks) {
double xMove = 0.0;
for (TextFragment& fragment : block.fragments()) {
if (block.fragments().front() == fragment) { // skip first
continue;
}

if (fragment.font(item).type() == mu::draw::Font::Type::MusicSymbol) {
xMove = secondStringXAlign - fragment.pos.x();
}
fragment.pos.setX(fragment.pos.x() + xMove);
}
}

Segment* parentSegment = item->segment();
item->move(PointF(-parentSegment->x(), 0.0));

Autoplace::autoplaceSegmentElement(item, item->mutldata());
}

Expand Down
2 changes: 1 addition & 1 deletion src/engraving/rendering/stable/tlayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ class TLayout
static void layout(Sticking* item, LayoutContext& ctx);
static void layout(StretchedBend* item, LayoutContext& ctx);
static void layoutStretched(StretchedBend* item, LayoutContext& ctx);
static void layout(StringTunings* item, LayoutContext& ctx);
static void layoutStringTunings(StringTunings* item, LayoutContext& ctx);

static void layout(Symbol* item, LayoutContext& ctx);
static void layout(FSymbol* item, LayoutContext& ctx);
Expand Down

0 comments on commit 05b948c

Please sign in to comment.