parent
96fbafde91
commit
62f5d132bf
9 changed files with 122 additions and 41 deletions
|
@ -274,8 +274,12 @@ Chord::Chord(const Chord& c, bool link)
|
|||
Tremolo* t = new Tremolo(*(c._tremolo));
|
||||
if (link) {
|
||||
score()->undo(new Link(t, const_cast<Tremolo*>(c._tremolo)));
|
||||
if (c._tremolo->twoNotes())
|
||||
t->setChords(0, 0);
|
||||
if (c._tremolo->twoNotes()) {
|
||||
if (c._tremolo->chord1() == &c)
|
||||
t->setChords(this, nullptr);
|
||||
else
|
||||
t->setChords(nullptr, this);
|
||||
}
|
||||
}
|
||||
add(t);
|
||||
}
|
||||
|
@ -420,6 +424,60 @@ QPointF Chord::stemPosBeam() const
|
|||
return p;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// setTremolo
|
||||
//---------------------------------------------------------
|
||||
|
||||
void Chord::setTremolo(Tremolo* tr)
|
||||
{
|
||||
if (tr == _tremolo)
|
||||
return;
|
||||
|
||||
if (_tremolo) {
|
||||
if (_tremolo->twoNotes()) {
|
||||
TDuration d;
|
||||
const Fraction f = duration();
|
||||
if (f.numerator() > 0)
|
||||
d = TDuration(f);
|
||||
else {
|
||||
d = _tremolo->durationType();
|
||||
const int dots = d.dots();
|
||||
d = d.shift(1);
|
||||
d.setDots(dots);
|
||||
}
|
||||
|
||||
setDurationType(d);
|
||||
Chord* other = _tremolo->chord1() == this ? _tremolo->chord2() : _tremolo->chord1();
|
||||
_tremolo = nullptr;
|
||||
if (other)
|
||||
other->setTremolo(nullptr);
|
||||
}
|
||||
else
|
||||
_tremolo = nullptr;
|
||||
}
|
||||
|
||||
if (tr) {
|
||||
if (tr->twoNotes()) {
|
||||
TDuration d = tr->durationType();
|
||||
if (!d.isValid()) {
|
||||
d = durationType();
|
||||
const int dots = d.dots();
|
||||
d = d.shift(-1);
|
||||
d.setDots(dots);
|
||||
tr->setDurationType(d);
|
||||
}
|
||||
|
||||
setDurationType(d);
|
||||
Chord* other = tr->chord1() == this ? tr->chord2() : tr->chord1();
|
||||
_tremolo = tr;
|
||||
if (other)
|
||||
other->setTremolo(tr);
|
||||
}
|
||||
else
|
||||
_tremolo = tr;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// add
|
||||
//---------------------------------------------------------
|
||||
|
@ -459,24 +517,7 @@ void Chord::add(Element* e)
|
|||
_arpeggio = toArpeggio(e);
|
||||
break;
|
||||
case ElementType::TREMOLO:
|
||||
{
|
||||
Tremolo* tr = toTremolo(e);
|
||||
if (tr->twoNotes()) {
|
||||
if (!(_tremolo && _tremolo->twoNotes())) {
|
||||
TDuration d = durationType();
|
||||
int dots = d.dots();
|
||||
d = d.shift(-1);
|
||||
d.setDots(dots);
|
||||
if (tr->chord1())
|
||||
tr->chord1()->setDurationType(d);
|
||||
if (tr->chord2())
|
||||
tr->chord2()->setDurationType(d);
|
||||
}
|
||||
if (tr->chord2())
|
||||
tr->chord2()->setTremolo(tr);
|
||||
}
|
||||
_tremolo = tr;
|
||||
}
|
||||
setTremolo(toTremolo(e));
|
||||
break;
|
||||
case ElementType::GLISSANDO:
|
||||
_endsGlissando = true;
|
||||
|
@ -559,25 +600,7 @@ void Chord::remove(Element* e)
|
|||
_arpeggio = 0;
|
||||
break;
|
||||
case ElementType::TREMOLO:
|
||||
{
|
||||
Tremolo* tremolo = toTremolo(e);
|
||||
if (tremolo->twoNotes()) {
|
||||
TDuration d = durationType();
|
||||
int dots = d.dots();
|
||||
d = d.shift(1);
|
||||
d.setDots(dots);
|
||||
Fraction f = duration();
|
||||
if (f.numerator() > 0)
|
||||
d = TDuration(f);
|
||||
if (tremolo->chord1())
|
||||
tremolo->chord1()->setDurationType(d);
|
||||
if (tremolo->chord2()) {
|
||||
tremolo->chord2()->setDurationType(d);
|
||||
tremolo->chord2()->setTremolo(0);
|
||||
}
|
||||
}
|
||||
_tremolo = 0;
|
||||
}
|
||||
setTremolo(nullptr);
|
||||
break;
|
||||
case ElementType::GLISSANDO:
|
||||
_endsGlissando = false;
|
||||
|
@ -1075,6 +1098,7 @@ bool Chord::readProperties(XmlReader& e)
|
|||
_tremolo->setTrack(track());
|
||||
_tremolo->read(e);
|
||||
_tremolo->setParent(this);
|
||||
_tremolo->setDurationType(durationType());
|
||||
}
|
||||
else if (tag == "tickOffset") // obsolete
|
||||
;
|
||||
|
|
|
@ -138,7 +138,7 @@ class Chord final : public ChordRest {
|
|||
Stem* stem() const { return _stem; }
|
||||
Arpeggio* arpeggio() const { return _arpeggio; }
|
||||
Tremolo* tremolo() const { return _tremolo; }
|
||||
void setTremolo(Tremolo* t) { _tremolo = t; }
|
||||
void setTremolo(Tremolo* t);
|
||||
bool endsGlissando() const { return _endsGlissando; }
|
||||
void setEndsGlissando (bool val) { _endsGlissando = val; }
|
||||
void updateEndsGlissando();
|
||||
|
|
|
@ -2333,6 +2333,50 @@ void layoutDrumsetChord(Chord* c, const Drumset* drumset, const StaffType* st, q
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// connectTremolo
|
||||
// Connect two-notes tremolo and update duration types
|
||||
// for the involved chords.
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void connectTremolo(Measure* m)
|
||||
{
|
||||
const int ntracks = m->score()->ntracks();
|
||||
constexpr SegmentType st = SegmentType::ChordRest;
|
||||
for (Segment* s = m->first(st); s; s = s->next(st)) {
|
||||
for (int i = 0; i < ntracks; ++i) {
|
||||
Element* e = s->element(i);
|
||||
if (!e || !e->isChord())
|
||||
continue;
|
||||
|
||||
Chord* c = toChord(e);
|
||||
Tremolo* tremolo = c->tremolo();
|
||||
if (tremolo && tremolo->twoNotes()) {
|
||||
// Ensure correct duration type for chord
|
||||
c->setDurationType(tremolo->durationType());
|
||||
|
||||
// If it is the first tremolo's chord, find the second
|
||||
// chord for tremolo, if needed.
|
||||
if (!tremolo->chord1())
|
||||
tremolo->setChords(c, tremolo->chord2());
|
||||
else if (tremolo->chord1() != c || tremolo->chord2())
|
||||
continue;
|
||||
|
||||
for (Segment* ls = s->next(st); ls; ls = ls->next(st)) {
|
||||
if (Element* element = ls->element(i)) {
|
||||
if (!element->isChord())
|
||||
qDebug("cannot connect tremolo");
|
||||
Chord* nc = toChord(element);
|
||||
tremolo->setChords(c, nc);
|
||||
nc->setTremolo(tremolo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// getNextMeasure
|
||||
//---------------------------------------------------------
|
||||
|
@ -2407,6 +2451,8 @@ void Score::getNextMeasure(LayoutContext& lc)
|
|||
if (measure->sectionBreak() && measure->pause() != 0.0)
|
||||
setPause(measure->endTick(), measure->pause());
|
||||
|
||||
connectTremolo(measure);
|
||||
|
||||
//
|
||||
// calculate accidentals and note lines,
|
||||
// create stem and set stem direction
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "score.h"
|
||||
#include "page.h"
|
||||
#include "system.h"
|
||||
#include "tremolo.h"
|
||||
#include "measure.h"
|
||||
#include "layout.h"
|
||||
#include "bracket.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "noteevent.h"
|
||||
#include "pitchspelling.h"
|
||||
#include "shape.h"
|
||||
#include "tremolo.h"
|
||||
#include "key.h"
|
||||
|
||||
namespace Ms {
|
||||
|
|
|
@ -1065,6 +1065,7 @@ static void readChord(Measure* m, Chord* chord, XmlReader& e)
|
|||
}
|
||||
else if (tag == "Tremolo") {
|
||||
Tremolo* tremolo = new Tremolo(chord->score());
|
||||
tremolo->setDurationType(chord->durationType());
|
||||
chord->setTremolo(tremolo);
|
||||
tremolo->setTrack(chord->track());
|
||||
readTremolo(tremolo, e);
|
||||
|
|
|
@ -1991,6 +1991,7 @@ bool readChordProperties206(XmlReader& e, Chord* ch)
|
|||
tremolo->setTrack(ch->track());
|
||||
tremolo->read(e);
|
||||
tremolo->setParent(ch);
|
||||
tremolo->setDurationType(ch->durationType());
|
||||
ch->setTremolo(tremolo);
|
||||
}
|
||||
else if (tag == "tickOffset") // obsolete
|
||||
|
|
|
@ -53,6 +53,7 @@ Tremolo::Tremolo(const Tremolo& t)
|
|||
setTremoloType(t.tremoloType());
|
||||
_chord1 = t.chord1();
|
||||
_chord2 = t.chord2();
|
||||
_durationType = t._durationType;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -243,6 +244,8 @@ void Tremolo::layout()
|
|||
//
|
||||
// two chord tremolo
|
||||
//
|
||||
|
||||
#if 0 // Needs to be done earlier, see connectTremolo in layout.cpp
|
||||
Segment* s = _chord1->segment()->next();
|
||||
while (s) {
|
||||
if (s->element(track()) && (s->element(track())->isChord()))
|
||||
|
@ -256,6 +259,7 @@ void Tremolo::layout()
|
|||
|
||||
_chord2 = toChord(s->element(track()));
|
||||
_chord2->setTremolo(this);
|
||||
#endif
|
||||
|
||||
Stem* stem1 = _chord1->stem();
|
||||
Stem* stem2 = _chord2->stem();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef __TREMOLO_H__
|
||||
#define __TREMOLO_H__
|
||||
|
||||
#include "durationtype.h"
|
||||
#include "symbol.h"
|
||||
|
||||
namespace Ms {
|
||||
|
@ -34,6 +35,7 @@ class Tremolo final : public Element {
|
|||
TremoloType _tremoloType;
|
||||
Chord* _chord1;
|
||||
Chord* _chord2;
|
||||
TDuration _durationType;
|
||||
QPainterPath path;
|
||||
|
||||
int _lines; // derived from _subtype
|
||||
|
@ -67,6 +69,9 @@ class Tremolo final : public Element {
|
|||
Chord* chord1() const { return _chord1; }
|
||||
Chord* chord2() const { return _chord2; }
|
||||
|
||||
TDuration durationType() const { return _durationType; }
|
||||
void setDurationType(TDuration d) { _durationType = d; }
|
||||
|
||||
void setChords(Chord* c1, Chord* c2) {
|
||||
_chord1 = c1;
|
||||
_chord2 = c2;
|
||||
|
|
Loading…
Reference in a new issue