Skip to content

Commit

Permalink
[palette] added layout for ChordLine
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkorsukov committed Jul 10, 2023
1 parent b1112ba commit 5664ed0
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 94 deletions.
98 changes: 4 additions & 94 deletions src/engraving/layout/pal/tlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,100 +623,10 @@ void TLayout::layout(Chord*, LayoutContext&)
//ChordLayout::layout(item, ctx);
}

void TLayout::layout(ChordLine* item, LayoutContext& ctx)
{
item->setMag(item->chord() ? item->chord()->mag() : 1);
if (!item->modified()) {
double x2 = 0;
double y2 = 0;
double baseLength = item->spatium() * (item->chord() ? item->chord()->intrinsicMag() : 1);
double horBaseLength = 1.2 * baseLength; // let the symbols extend a bit more horizontally
x2 += item->isToTheLeft() ? -horBaseLength : horBaseLength;
y2 += item->isBelow() ? baseLength : -baseLength;
if (item->chordLineType() != ChordLineType::NOTYPE && !item->isWavy()) {
PainterPath path;
if (!item->isToTheLeft()) {
if (item->isStraight()) {
path.lineTo(x2, y2);
} else {
path.cubicTo(x2 / 2, 0.0, x2, y2 / 2, x2, y2);
}
} else {
if (item->isStraight()) {
path.lineTo(x2, y2);
} else {
path.cubicTo(0.0, y2 / 2, x2 / 2, y2, x2, y2);
}
}
item->setPath(path);
}
}

if (item->explicitParent()) {
Note* note = nullptr;

if (item->note()) {
note = item->chord()->findNote(item->note()->pitch());
}

if (!note) {
note = item->chord()->upNote();
}

double x = 0.0;
double y = note->pos().y();
double horOffset = 0.33 * item->spatium(); // one third of a space away from the note
double vertOffset = 0.25 * item->spatium(); // one quarter of a space from the center line
// Get chord shape
Shape chordShape = item->chord()->shape();
// ...but remove from the shape items that the chordline shouldn't try to avoid
// (especially the chordline itself)
mu::remove_if(chordShape, [](ShapeElement& shapeEl){
if (!shapeEl.toItem) {
return true;
}
const EngravingItem* item = shapeEl.toItem;
if (item->isChordLine() || item->isHarmony() || item->isLyrics()) {
return true;
}
return false;
});
x += item->isToTheLeft() ? -chordShape.left() - horOffset : chordShape.right() + horOffset;
y += item->isBelow() ? vertOffset : -vertOffset;

/// TODO: calculate properly the position for wavy type
if (item->isWavy()) {
bool upDir = item->chordLineType() == ChordLineType::DOIT;
y += note->height() * (upDir ? 0.8 : -0.3);
}

item->setPos(x, y);
} else {
item->setPos(0.0, 0.0);
}

if (!item->isWavy()) {
RectF r = item->path().boundingRect();
int x1 = 0, y1 = 0, width = 0, height = 0;

x1 = r.x();
y1 = r.y();
width = r.width();
height = r.height();
item->bbox().setRect(x1, y1, width, height);
} else {
RectF r = ctx.engravingFont()->bbox(ChordLine::WAVE_SYMBOLS, item->magS());
double angle = ChordLine::WAVE_ANGEL * M_PI / 180;

r.setHeight(r.height() + r.width() * sin(angle));

/// TODO: calculate properly the rect for wavy type
if (item->chordLineType() == ChordLineType::DOIT) {
r.setY(item->y() - r.height() * (item->onTabStaff() ? 1.25 : 1));
}

item->setbbox(r);
}
void TLayout::layout(ChordLine*, LayoutContext&)
{
//! NOTE Moved to PaletteLayout
UNREACHABLE;
}

void TLayout::layout(Clef*, LayoutContext&)
Expand Down
58 changes: 58 additions & 0 deletions src/palette/internal/palettelayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "engraving/libmscore/barline.h"
#include "engraving/libmscore/bracket.h"
#include "engraving/libmscore/capo.h"
#include "engraving/libmscore/chordline.h"
#include "engraving/libmscore/clef.h"
#include "engraving/libmscore/dynamic.h"
#include "engraving/libmscore/expression.h"
Expand Down Expand Up @@ -102,6 +103,8 @@ void PaletteLayout::layoutItem(EngravingItem* item)
break;
case ElementType::CAPO: layout(toCapo(item), ctx);
break;
case ElementType::CHORDLINE: layout(toChordLine(item), ctx);
break;
case ElementType::CLEF: layout(toClef(item), ctx);
break;
case ElementType::DYNAMIC: layout(toDynamic(item), ctx);
Expand Down Expand Up @@ -482,6 +485,61 @@ void PaletteLayout::layout(Capo* item, const Context& ctx)
layoutTextBase(item, ctx);
}

void PaletteLayout::layout(ChordLine* item, const Context& ctx)
{
item->setMag(1.0);
if (!item->modified()) {
double x2 = 0;
double y2 = 0;
double baseLength = item->spatium();
double horBaseLength = 1.2 * baseLength; // let the symbols extend a bit more horizontally
x2 += item->isToTheLeft() ? -horBaseLength : horBaseLength;
y2 += item->isBelow() ? baseLength : -baseLength;
if (item->chordLineType() != ChordLineType::NOTYPE && !item->isWavy()) {
PainterPath path;
if (!item->isToTheLeft()) {
if (item->isStraight()) {
path.lineTo(x2, y2);
} else {
path.cubicTo(x2 / 2, 0.0, x2, y2 / 2, x2, y2);
}
} else {
if (item->isStraight()) {
path.lineTo(x2, y2);
} else {
path.cubicTo(0.0, y2 / 2, x2 / 2, y2, x2, y2);
}
}
item->setPath(path);
}
}

item->setPos(0.0, 0.0);

if (!item->isWavy()) {
RectF r = item->path().boundingRect();
int x1 = 0, y1 = 0, width = 0, height = 0;

x1 = r.x();
y1 = r.y();
width = r.width();
height = r.height();
item->bbox().setRect(x1, y1, width, height);
} else {
RectF r = ctx.engravingFont()->bbox(ChordLine::WAVE_SYMBOLS, item->magS());
double angle = ChordLine::WAVE_ANGEL * M_PI / 180;

r.setHeight(r.height() + r.width() * sin(angle));

/// TODO: calculate properly the rect for wavy type
if (item->chordLineType() == ChordLineType::DOIT) {
r.setY(item->y() - r.height() * (item->onTabStaff() ? 1.25 : 1));
}

item->setbbox(r);
}
}

void PaletteLayout::layout(Clef* item, const Context& ctx)
{
constexpr int lines = 5;
Expand Down
2 changes: 2 additions & 0 deletions src/palette/internal/palettelayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class BarLine;
class Bracket;

class Capo;
class ChordLine;
class Clef;

class Dynamic;
Expand Down Expand Up @@ -130,6 +131,7 @@ class PaletteLayout
static void layout(engraving::Bracket* item, const Context& ctx);

static void layout(engraving::Capo* item, const Context& ctx);
static void layout(engraving::ChordLine* item, const Context& ctx);
static void layout(engraving::Clef* item, const Context& ctx);

static void layout(engraving::Dynamic* item, const Context& ctx);
Expand Down

0 comments on commit 5664ed0

Please sign in to comment.