Skip to content

Commit

Permalink
add dot and stem direction to shadow note
Browse files Browse the repository at this point in the history
  • Loading branch information
lasconic committed Jun 2, 2016
1 parent a5b32d7 commit b3c74cd
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 79 deletions.
2 changes: 1 addition & 1 deletion libmscore/mscore.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static constexpr qreal DPMM = DPI / INCH;

static constexpr int MAX_STAVES = 4;

static const int SHADOW_NOTE_LIGHT = 120;
static const int SHADOW_NOTE_LIGHT = 150;

static const char mimeSymbolFormat[] = "application/musescore/symbol";
static const char mimeSymbolListFormat[] = "application/musescore/symbollist";
Expand Down
42 changes: 27 additions & 15 deletions libmscore/rest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,21 +381,8 @@ void Rest::layout()
}
}

switch(durationType().type()) {
case TDuration::DurationType::V_64TH:
case TDuration::DurationType::V_32ND:
dotline = -3;
break;
case TDuration::DurationType::V_1024TH:
case TDuration::DurationType::V_512TH:
case TDuration::DurationType::V_256TH:
case TDuration::DurationType::V_128TH:
dotline = -5;
break;
default:
dotline = -1;
break;
}
dotline = Rest::getDotline(durationType().type());

// DEBUG: no longer needed now that computeLineOffset returns an appropriate value?
//int stepOffset = 0;
//if (staff())
Expand Down Expand Up @@ -426,6 +413,31 @@ void Rest::layout()
setbbox(symBbox(_sym));
}

//---------------------------------------------------------
// getDotline
//---------------------------------------------------------

int Rest::getDotline(TDuration::DurationType durationType)
{
int dl = -1;
switch(durationType) {
case TDuration::DurationType::V_64TH:
case TDuration::DurationType::V_32ND:
dl = -3;
break;
case TDuration::DurationType::V_1024TH:
case TDuration::DurationType::V_512TH:
case TDuration::DurationType::V_256TH:
case TDuration::DurationType::V_128TH:
dl = -5;
break;
default:
dl = -1;
break;
}
return dl;
}

//---------------------------------------------------------
// centerX
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/rest.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class Rest : public ChordRest {
SymId getSymbol(TDuration::DurationType type, int line, int lines, int* yoffset);

int getDotline() const { return dotline; }
static int getDotline(TDuration::DurationType durationType);
SymId sym() const { return _sym; }
int computeLineOffset();
bool isFullMeasureRest() const { return durationType() == TDuration::DurationType::V_MEASURE; }
Expand Down
154 changes: 98 additions & 56 deletions libmscore/shadownote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "score.h"
#include "drumset.h"
#include "sym.h"
#include "rest.h"
#include "mscore.h"

namespace Ms {
Expand All @@ -23,68 +24,79 @@ namespace Ms {
//---------------------------------------------------------

ShadowNote::ShadowNote(Score* s)
: Element(s), _notehead(SymId::noSym),
_flag(SymId::noSym)
: Element(s), _notehead(SymId::noSym)
{
_line = 1000;
_duration = TDuration(TDuration::DurationType::V_INVALID);
_voice = 0;
_rest = false;
}

bool ShadowNote::isValid() const
{
return _notehead != SymId::noSym;
}

bool ShadowNote::noFlag() const
{
return _flag == SymId::noSym;
}

void ShadowNote::setSym(SymId id)
{
setSymbols(TDuration::DurationType::V_INVALID, id);
}

void ShadowNote::setSymbols(TDuration::DurationType type, SymId noteSymbol)
void ShadowNote::setState(SymId noteSymbol, int voice, TDuration duration, bool rest)
{
// clear symbols
_notehead = SymId::noSym;
_flag = SymId::noSym;

_notehead = noteSymbol;
_duration = duration;
_voice = voice;
_rest = rest;
}

SymId ShadowNote::getNoteFlag() const
{
SymId flag = SymId::noSym;
if (_rest)
return flag;
TDuration::DurationType type = _duration.type();
switch(type) {
case TDuration::DurationType::V_LONG:
_flag = SymId::flagInternalUp;
flag = SymId::lastSym;
break;
case TDuration::DurationType::V_BREVE:
_flag = SymId::noSym;
flag = SymId::noSym;
break;
case TDuration::DurationType::V_WHOLE:
_flag = SymId::noSym;
flag = SymId::noSym;
break;
case TDuration::DurationType::V_HALF:
_flag = SymId::flagInternalUp;
flag = SymId::lastSym;
break;
case TDuration::DurationType::V_QUARTER:
_flag = SymId::flagInternalUp;
flag = SymId::lastSym;
break;
case TDuration::DurationType::V_EIGHTH:
_flag = SymId::flag8thUp;
flag = computeUp() ? SymId::flag8thUp : SymId::flag8thDown;
break;
case TDuration::DurationType::V_16TH:
_flag = SymId::flag16thUp;
flag = computeUp() ? SymId::flag16thUp : SymId::flag16thDown;
break;
case TDuration::DurationType::V_32ND:
_flag = SymId::flag32ndUp;
flag = computeUp() ? SymId::flag32ndUp : SymId::flag32ndDown;
break;
case TDuration::DurationType::V_64TH:
_flag = SymId::flag64thUp;
flag = computeUp() ? SymId::flag64thUp : SymId::flag64thDown;
break;
case TDuration::DurationType::V_128TH:
_flag = SymId::flag128thUp;
flag = computeUp() ? SymId::flag128thUp : SymId::flag128thDown;
break;
default:
_flag = SymId::noSym;
flag = SymId::noSym;
}
return flag;
}

bool ShadowNote::computeUp() const
{
if (_voice % VOICES == 0)
return _line > 4;
else
return _voice % VOICES == 2;
}

//---------------------------------------------------------
Expand All @@ -98,32 +110,46 @@ void ShadowNote::draw(QPainter* painter) const

QPointF ap(pagePos());
painter->translate(ap);
InputState ps = score()->inputState();
int voice;
if (ps.drumNote() != -1 && ps.drumset() && ps.drumset()->isValid(ps.drumNote()))
voice = ps.drumset()->voice(ps.drumNote());
else
voice = ps.voice();

painter->drawRect(bbox());
qreal lw = score()->styleP(StyleIdx::stemWidth);
QPen pen(MScore::selectColor[voice].lighter(SHADOW_NOTE_LIGHT), lw, Qt::SolidLine, Qt::RoundCap);
QPen pen(MScore::selectColor[_voice].lighter(SHADOW_NOTE_LIGHT), lw, Qt::SolidLine, Qt::RoundCap);
painter->setPen(pen);

drawSymbol(_notehead, painter);

// draw the dots
qreal noteheadWidth = symWidth(_notehead);
if (!noFlag()) {
QPointF posDot;
if (_duration.dots() > 0) {
qreal d = score()->styleP(StyleIdx::dotNoteDistance) * mag();
qreal dd = score()->styleP(StyleIdx::dotDotDistance) * mag();
posDot.rx() += (noteheadWidth + d);
if (!_rest)
posDot.ry() -= (_line % 2 == 0 ? 0.5 * spatium() : 0);
else
posDot.ry() += Rest::getDotline(_duration.type()) * spatium() * mag() * .5;
for (int i = 0; i < _duration.dots(); i++) {
posDot.rx() += dd * i;
drawSymbol(SymId::augmentationDot, painter, posDot, 1);
posDot.rx() -= dd * i;
}
}

// stem and flag
SymId flag = getNoteFlag();
int up = computeUp() ? 1 : -1;
if (flag != SymId::noSym) {
QPointF pos;
pos.rx() = noteheadWidth - (lw / 2);
qreal yOffset = symStemUpSE(_notehead).y() * magS();
if(_flag != SymId::flagInternalUp) {
pos.ry() -= symHeight(_flag);
painter->drawLine(QLineF(pos.x(), yOffset, pos.x(), pos.y() - yOffset - lw/2));
pos.rx() = up == 1 ? (noteheadWidth - (lw / 2)) : lw / 2;
qreal yOffset = up == 1 ? symStemUpSE(_notehead).y() * magS() : symStemDownNW(_notehead).y() * magS();
if(flag != SymId::lastSym) {
pos.ry() -= up * (symHeight(flag) + (posDot.y() != 0 ? posDot.y() + spatium() : 0) + 0.5*spatium());
painter->drawLine(QLineF(pos.x(), yOffset, pos.x(), pos.y() - up * (yOffset + lw/2)));
pos.rx() -= (lw / 2); // flag offset?
drawSymbol(_flag, painter, pos, 1);
drawSymbol(flag, painter, pos, 1);
}
else {
painter->drawLine(QLineF(pos.x(), yOffset, pos.x(), -3 * spatium() * mag() + yOffset));
painter->drawLine(QLineF(pos.x(), yOffset, pos.x(), -3 * up * spatium() * mag() + yOffset));
}
}

Expand All @@ -133,10 +159,10 @@ void ShadowNote::draw(QPainter* painter) const
ms *= .5;

lw = score()->styleP(StyleIdx::ledgerLineWidth);
QPen penL(MScore::selectColor[voice].lighter(SHADOW_NOTE_LIGHT), lw);
QPen penL(MScore::selectColor[_voice].lighter(SHADOW_NOTE_LIGHT), lw);
painter->setPen(penL);

if (_line < 100 && _line > -100 && !ps.rest()) {
if (_line < 100 && _line > -100 && !_rest) {
for (int i = -2; i >= _line; i -= 2) {
qreal y = ms * mag() * (i - _line);
painter->drawLine(QLineF(x1, y, x2, y));
Expand All @@ -162,30 +188,46 @@ void ShadowNote::layout()
qreal _spatium = spatium();
QRectF b;
QRectF noteheadBbox = symBbox(_notehead);
if(noFlag()) {
b = noteheadBbox.toRect();
SymId flag = getNoteFlag();
qreal height = noteheadBbox.height();
qreal dotWidth = 0;
if (_duration.dots() > 0) {
qreal noteheadWidth = symWidth(_notehead);
qreal d = score()->styleP(StyleIdx::dotNoteDistance) * mag();
qreal dd = score()->styleP(StyleIdx::dotDotDistance) * mag();
dotWidth += (noteheadWidth + d);
for (int i = 0; i < _duration.dots(); i++)
dotWidth += dd * i;
height += (_line % 2 == 0 && !_rest ? 0.5 * spatium() : 0); // move flag up
}
if(flag == SymId::noSym) {
b.setRect(noteheadBbox.x(), noteheadBbox.y(), noteheadBbox.width() + dotWidth, noteheadBbox.height());
}
else {
qreal x = noteheadBbox.x();
qreal height = noteheadBbox.height();
qreal width = noteheadBbox.width();
qreal y = 0;
if (_flag != SymId::flagInternalUp) {
QRectF flagBbox = symBbox(_flag);
qreal lw = score()->styleP(StyleIdx::stemWidth);
y -= flagBbox.height();
height += flagBbox.height() + lw / 2;
width += flagBbox.width();
qreal flagWidth = 0;
int up = computeUp() ? 1 : 0;
qreal y = up ? 0 : -height;
if (flag != SymId::lastSym) {
QRectF flagBbox = symBbox(flag);
qreal lw = score()->styleP(StyleIdx::stemWidth) * mag();
qreal h = flagBbox.height() + lw / 2 + spatium() * mag();
y -= h * up;
height += h;
flagWidth = flagBbox.width();
}
else {
y -= 4 * spatium() * mag();
height += (-y);
qreal sh = 4 * spatium() * mag();
y -= up * sh;
height += sh;
}
width += qMax(flagWidth, dotWidth);

b.setRect(x, y, width, height);
}

qreal lw = point(score()->styleS(StyleIdx::ledgerLineWidth));
qreal lw = score()->styleP(StyleIdx::ledgerLineWidth);

qreal x1 = (noteheadBbox.width()) * .5 - (_spatium * mag()) - lw * .5;

Expand Down
12 changes: 7 additions & 5 deletions libmscore/shadownote.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ class ShadowNote : public Element {

int _line;
SymId _notehead;
SymId _flag;
TDuration _duration;
int _voice;
bool _rest;

public:
ShadowNote(Score*);
Expand All @@ -45,13 +47,13 @@ class ShadowNote : public Element {
void setLine(int n) { _line = n; }
virtual void draw(QPainter*) const;

void setSym(SymId id);
void setSymbols(TDuration::DurationType type, SymId noteSymbol);
void setState(SymId noteSymbol, int voice, TDuration duration, bool rest = false);

SymId getNoteFlag() const;
bool computeUp() const;

SymId notehead() const { return _notehead; }
SymId flag() const { return _flag; }
bool isValid() const;
bool noFlag() const;
};


Expand Down
11 changes: 9 additions & 2 deletions mscore/scoreview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,13 @@ void ScoreView::setShadowNote(const QPointF& p)
}

shadowNote->setLine(line);

int voice;
if (is.drumNote() != -1 && is.drumset() && is.drumset()->isValid(is.drumNote()))
voice = is.drumset()->voice(is.drumNote());
else
voice = is.voice();

SymId symNotehead;
TDuration d(is.duration());

Expand All @@ -1665,11 +1672,11 @@ void ScoreView::setShadowNote(const QPointF& p)
Rest rest(gscore, d.type());
rest.setDuration(d.fraction());
symNotehead = rest.getSymbol(is.duration().type(), 0, staff->lines(), &yo);
shadowNote->setSym(symNotehead);
shadowNote->setState(symNotehead, voice, d, true);
}
else {
symNotehead = Note::noteHead(0, noteheadGroup, noteHead);
shadowNote->setSymbols(d.type(), symNotehead);
shadowNote->setState(symNotehead, voice, d);
}

shadowNote->layout();
Expand Down

0 comments on commit b3c74cd

Please sign in to comment.