Skip to content

Commit

Permalink
fix accidentals for trills
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Aug 30, 2013
1 parent 1eafb0e commit 63fe67a
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 81 deletions.
11 changes: 5 additions & 6 deletions libmscore/accidental.cpp
Expand Up @@ -291,9 +291,12 @@ void Accidental::layout()
return;
}

qreal m = magS();
qreal m = parent() ? parent()->mag() : 1.0;
if (_small)
m *= score()->styleD(ST_smallNoteMag);
setMag(m);

m = magS();
QPointF pos;
if (_hasBracket) {
SymElement e(leftparenSym, 0.0);
Expand Down Expand Up @@ -377,13 +380,9 @@ void Accidental::draw(QPainter* painter) const
{
if (staff() && staff()->isTabStaff()) //in TAB, accidentals are not shown
return;

qreal m = magS();
if (_small)
m *= score()->styleD(ST_smallNoteMag);
painter->setPen(curColor());
foreach(const SymElement& e, el)
symbols[score()->symIdx()][e.sym].draw(painter, m, QPointF(e.x, 0.0));
symbols[score()->symIdx()][e.sym].draw(painter, magS(), QPointF(e.x, 0.0));
}

//---------------------------------------------------------
Expand Down
2 changes: 0 additions & 2 deletions libmscore/accidental.h
Expand Up @@ -106,8 +106,6 @@ class Accidental : public Element {
virtual Accidental* clone() const { return new Accidental(*this); }
virtual ElementType type() const { return ACCIDENTAL; }

virtual qreal mag() const { return parent() ? parent()->mag() : 1.0; }

const char* subtypeUserName() const;
void setSubtype(const QString& s);
void setAccidentalType(AccidentalType t) { _accidentalType = t; }
Expand Down
5 changes: 4 additions & 1 deletion libmscore/edit.cpp
Expand Up @@ -1202,7 +1202,10 @@ void Score::deleteItem(Element* el)
break;

case Element::ACCIDENTAL:
changeAccidental(static_cast<Note*>(el->parent()), Accidental::ACC_NONE);
if (el->parent()->type() == Element::NOTE)
changeAccidental(static_cast<Note*>(el->parent()), Accidental::ACC_NONE);
else
undoRemoveElement(el);
break;

case Element::BAR_LINE:
Expand Down
6 changes: 3 additions & 3 deletions libmscore/element.cpp
Expand Up @@ -447,9 +447,9 @@ QColor Element::curColor() const
return MScore::dropColor;
bool marked = false;
if (type() == Element::NOTE) {
const Note* note = static_cast<const Note*>(this);
marked = note->mark();
}
const Note* note = static_cast<const Note*>(this);
marked = note->mark();
}
if (_selected || marked ) {
if (track() == -1)
return MScore::selectColor[0];
Expand Down
2 changes: 1 addition & 1 deletion libmscore/element.h
Expand Up @@ -494,7 +494,7 @@ class Element : public QObject {

virtual qreal mag() const { return _mag; }
qreal magS() const;
virtual void setMag(qreal val) { _mag = val; }
void setMag(qreal val) { _mag = val; }

bool isText() const;

Expand Down
8 changes: 4 additions & 4 deletions libmscore/system.cpp
Expand Up @@ -971,19 +971,19 @@ void System::scanElements(void* data, void (*func)(void*, Element*), bool all)
func(data, t);
++idx;
}
foreach(SpannerSegment* ss, _spannerSegments) {
foreach (SpannerSegment* ss, _spannerSegments) {
int staffIdx = ss->spanner()->staffIdx();
if (staffIdx == -1) {
qDebug("System::scanElements: staffIDx == -1: %s %p", ss->spanner()->name(), ss->spanner());
staffIdx = 0;
}
bool v = true;
Spanner* spanner = ss->spanner();
if(spanner->anchor() == Spanner::ANCHOR_SEGMENT || spanner->anchor() == Spanner::ANCHOR_CHORD) {
if (spanner->anchor() == Spanner::ANCHOR_SEGMENT || spanner->anchor() == Spanner::ANCHOR_CHORD) {
Element* se = spanner->startElement();
Element* ee = spanner->endElement();
bool v1 = true;
if(se && (se->type() == Element::CHORD || se->type() == Element::REST)) {
if (se && (se->type() == Element::CHORD || se->type() == Element::REST)) {
ChordRest* cr = static_cast<ChordRest*>(se);
Measure* m = cr->measure();
MStaff* mstaff = m->mstaff(cr->staffIdx());
Expand All @@ -999,7 +999,7 @@ void System::scanElements(void* data, void (*func)(void*, Element*), bool all)
v = v1 || v2; // hide spanner if both chords are hidden
}
if (all || (score()->staff(staffIdx)->show() && v) || (spanner->type() == Element::VOLTA))
func(data, ss);
ss->spanner()->scanElements(data, func, all);

This comment has been minimized.

Copy link
@mgavioli

mgavioli Sep 1, 2013

Contributor

This change seems to be the origin of issue http://musescore.org/en/node/22485 as reverting this line fixes the issue.

When the slur/tie is across a page change, 'climbing' from the SlurSegment to its parent Spanner links in both segments into both pages, each page getting one 'right' and one 'wrong' SlurSegment. Apparently, the 'wrong' SlurSegment's are not completely filtered out by the following BSP tree processing (which I was not able to understand).

This comment has been minimized.

Copy link
@wschweer

wschweer Sep 2, 2013

Author Contributor

Its better to call scanElements(...) on an element instead of calling func() directly. This make sure all potential sub-elements are handled. In this special case i wanted to include an accidental which is a potential sub-element of Trill. I will try to fix this by calling ss->scanElements(...) instead of ss->spanner()->scanElements(). ss->scanElements() then has to include the potential accidental.

This comment has been minimized.

Copy link
@mgavioli

mgavioli Sep 2, 2013

Contributor

Thanks for the reply

I understand your point. In practice, the Trill::_accidental var has to be 'reflected' into the relevant TrillSegment (or a TrillSegment::scanElements() method has to access its parent _accidental var, if it 'thinks' it needs to)

}
}

Expand Down
89 changes: 62 additions & 27 deletions libmscore/trill.cpp
Expand Up @@ -37,12 +37,16 @@ void TrillSegment::draw(QPainter* painter) const
qreal x2 = pos2().x();

QColor color;
if (selected() && !(score() && score()->printing()))
if (flag(ELEMENT_DROP_TARGET))
color = MScore::dropColor;
else if (selected() && !(score() && score()->printing()))
color = MScore::selectColor[0];
else if (!visible())
color = Qt::gray;
else
else {
color = trill()->curColor();
}

painter->setPen(color);
if (spannerSegmentType() == SEGMENT_SINGLE || spannerSegmentType() == SEGMENT_BEGIN) {
int sym = 0;
Expand Down Expand Up @@ -104,6 +108,31 @@ void TrillSegment::draw(QPainter* painter) const
}
}

//---------------------------------------------------------
// add
//---------------------------------------------------------

void TrillSegment::add(Element* e)
{
e->setParent(this);
if (e->type() == ACCIDENTAL) {
// accidental is part of trill
trill()->setAccidental(static_cast<Accidental*>(e));
}
}

//---------------------------------------------------------
// remove
//---------------------------------------------------------

void TrillSegment::remove(Element* e)
{
if (trill()->accidental() == e) {
// accidental is part of trill
trill()->setAccidental(0);
}
}

//---------------------------------------------------------
// layout
//---------------------------------------------------------
Expand All @@ -116,6 +145,16 @@ void TrillSegment::layout()
setbbox(rr);
if (parent())
rypos() += score()->styleS(ST_trillY).val() * spatium();
if (spannerSegmentType() == SEGMENT_SINGLE || spannerSegmentType() == SEGMENT_BEGIN) {
Accidental* a = trill()->accidental();
if (a) {
a->layout();
a->setMag(a->mag() * .6);
qreal _spatium = spatium();
a->setPos(_spatium*1.3, -2.2*_spatium);
a->adjustReadPos();
}
}
adjustReadPos();
}

Expand All @@ -125,10 +164,8 @@ void TrillSegment::layout()

bool TrillSegment::acceptDrop(MuseScoreView*, const QPointF&, Element* e) const
{
if (e->type() == ACCIDENTAL) {
printf("========accept drop\n");
if (e->type() == ACCIDENTAL)
return true;
}
return false;
}

Expand All @@ -141,7 +178,6 @@ Element* TrillSegment::drop(const DropData& data)
Element* e = data.element;
switch(e->type()) {
case ACCIDENTAL:
printf("========drop\n");
e->setParent(trill());
score()->undoAddElement(e);
break;
Expand Down Expand Up @@ -204,6 +240,12 @@ Trill::Trill(Score* s)
: SLine(s)
{
_trillType = TRILL_LINE;
_accidental = 0;
}

Trill::~Trill()
{
delete _accidental;
}

//---------------------------------------------------------
Expand All @@ -214,7 +256,7 @@ void Trill::add(Element* e)
{
if (e->type() == ACCIDENTAL) {
e->setParent(this);
_el.push_back(e);
_accidental = static_cast<Accidental*>(e);
}
else
SLine::add(e);
Expand All @@ -226,8 +268,8 @@ void Trill::add(Element* e)

void Trill::remove(Element* e)
{
if (!_el.remove(e))
Spanner::remove(e);
if (e == _accidental)
_accidental = 0;
}

//---------------------------------------------------------
Expand All @@ -237,11 +279,11 @@ void Trill::remove(Element* e)
void Trill::layout()
{
qreal _spatium = spatium();
// setPos(0.0, yoff() * _spatium);

SLine::layout();
if (score() == gscore)
return;
TrillSegment* ls = static_cast<TrillSegment*>(frontSegment());
//
// special case:
// if end segment is first chord/rest segment in measure,
Expand All @@ -260,17 +302,12 @@ void Trill::layout()
Segment* s2 = m->last();
qreal x2 = s2->pagePos().x();
qreal dx = x1 - x2 + _spatium * .3;
TrillSegment* ls = static_cast<TrillSegment*>(frontSegment());
ls->setPos2(ls->ipos2() + QPointF(-dx, 0.0));
ls->layout();
}
}
foreach(Element* e, _el) {
e->setMag(.6);
e->layout();
e->setPos(_spatium*1.3, -2.2*_spatium);
e->adjustReadPos();
}
if (_accidental)
_accidental->setParent(ls);
}

//---------------------------------------------------------
Expand All @@ -294,8 +331,8 @@ void Trill::write(Xml& xml) const
xml.stag(QString("%1 id=\"%2\"").arg(name()).arg(id()));
xml.tag("subtype", trillTypeName());
SLine::writeProperties(xml);
foreach(Element* e, _el)
e->write(xml);
if (_accidental)
_accidental->write(xml);
xml.etag();
}

Expand All @@ -314,9 +351,9 @@ void Trill::read(XmlReader& e)
if (tag == "subtype")
setTrillType(e.readElementText());
else if (tag == "Accidental") {
Accidental* a = new Accidental(score());
a->read(e);
add(a);
_accidental = new Accidental(score());
_accidental->read(e);
_accidental->setParent(this);
}
else if (!SLine::readProperties(e))
e.unknown();
Expand Down Expand Up @@ -372,9 +409,9 @@ QString Trill::trillTypeName() const

void Trill::scanElements(void* data, void (*func)(void*, Element*), bool all)
{
foreach(Element* e, _el)
e->scanElements(data, func, all);
func(data, this);
if (_accidental)
_accidental->scanElements(data, func, all);
func(data, this); // ?
SLine::scanElements(data, func, all);
}

Expand Down Expand Up @@ -444,7 +481,5 @@ void Trill::setYoff(qreal val)
{
rUserYoffset() += (val - score()->styleS(ST_trillY).val()) * spatium();
}


}

51 changes: 28 additions & 23 deletions libmscore/trill.h
Expand Up @@ -33,15 +33,17 @@ class TrillSegment : public LineSegment {
public:
TrillSegment(Score* s) : LineSegment(s) {}
Trill* trill() const { return (Trill*)spanner(); }
virtual ElementType type() const { return TRILL_SEGMENT; }
virtual TrillSegment* clone() const { return new TrillSegment(*this); }
virtual void draw(QPainter*) const;
virtual bool acceptDrop(MuseScoreView*, const QPointF&, Element*) const;
virtual Element* drop(const DropData&);
virtual void layout();
virtual QVariant getProperty(P_ID propertyId) const;
virtual bool setProperty(P_ID propertyId, const QVariant&);
virtual QVariant propertyDefault(P_ID) const;
virtual ElementType type() const override { return TRILL_SEGMENT; }
virtual TrillSegment* clone() const override { return new TrillSegment(*this); }
virtual void draw(QPainter*) const override;
virtual bool acceptDrop(MuseScoreView*, const QPointF&, Element*) const override;
virtual Element* drop(const DropData&) override;
virtual void layout() override;
virtual QVariant getProperty(P_ID propertyId) const override;
virtual bool setProperty(P_ID propertyId, const QVariant&) override;
virtual QVariant propertyDefault(P_ID) const override;
virtual void add(Element*) override;
virtual void remove(Element*) override;
};

//---------------------------------------------------------
Expand All @@ -61,33 +63,36 @@ class Trill : public SLine {
private:
Q_PROPERTY(TrillType trillType READ trillType WRITE undoSetTrillType)
TrillType _trillType;
ElementList _el; // accidentals etc.
Accidental* _accidental;

public:
Trill(Score* s);
virtual Trill* clone() const { return new Trill(*this); }
virtual ElementType type() const { return TRILL; }
virtual ~Trill();
virtual Trill* clone() const override { return new Trill(*this); }
virtual ElementType type() const override { return TRILL; }

virtual void layout();
virtual LineSegment* createLineSegment();
virtual void add(Element*);
virtual void remove(Element*);
virtual void write(Xml&) const;
virtual void read(XmlReader&);
virtual void layout() override;
virtual LineSegment* createLineSegment() override;
virtual void add(Element*) override;
virtual void remove(Element*) override;
virtual void write(Xml&) const override;
virtual void read(XmlReader&) override;

void setTrillType(const QString& s);
void undoSetTrillType(TrillType val);
void setTrillType(TrillType tt) { _trillType = tt; }
TrillType trillType() const { return _trillType; }
QString trillTypeName() const;
Accidental* accidental() const { return _accidental; }
void setAccidental(Accidental* a) { _accidental = a; }

Segment* segment() const { return (Segment*)parent(); }
virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true);
virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;

virtual QVariant getProperty(P_ID propertyId) const;
virtual bool setProperty(P_ID propertyId, const QVariant&);
virtual QVariant propertyDefault(P_ID) const;
virtual void setYoff(qreal);
virtual QVariant getProperty(P_ID propertyId) const override;
virtual bool setProperty(P_ID propertyId, const QVariant&) override;
virtual QVariant propertyDefault(P_ID) const override;
virtual void setYoff(qreal) override;
};


Expand Down

0 comments on commit 63fe67a

Please sign in to comment.