1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2011 Werner Schweer
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License version 2
9 //  as published by the Free Software Foundation and appearing in
10 //  the file LICENCE.GPL
11 //=============================================================================
12 
13 #ifndef __CHORD_H__
14 #define __CHORD_H__
15 
16 /**
17  \file
18  Definition of classes Chord, HelpLine and NoteList.
19 */
20 
21 #include <functional>
22 #include "chordrest.h"
23 
24 namespace Ms {
25 
26 class Note;
27 class Hook;
28 class Arpeggio;
29 class Tremolo;
30 class Chord;
31 //class Glissando;
32 class Stem;
33 class Chord;
34 class StemSlash;
35 class LedgerLine;
36 class AccidentalState;
37 
38 enum class TremoloChordType : char { TremoloSingle, TremoloFirstNote, TremoloSecondNote };
39 
40 //---------------------------------------------------------
41 //   @@ Chord
42 ///    Graphic representation of a chord.
43 ///    Single notes are handled as degenerated chords.
44 //
45 //   @P beam          Beam          the beam of the chord, if any (read only)
46 //   @P graceNotes    array[Chord]  the list of grace note chords (read only)
47 //   @P hook          Hook          the hook of the chord, if any (read only)
48 //   @P lyrics        array[Lyrics] the list of lyrics (read only)
49 //   @P notes         array[Note]   the list of notes (read only)
50 //   @P stem          Stem          the stem of the chord, if any (read only)
51 //   @P stemSlash     StemSlash     the stem slash of the chord (acciaccatura), if any (read only)
52 //   @P stemDirection Direction     the stem direction of the chord: AUTO, UP, DOWN (read only)
53 //---------------------------------------------------------
54 
55 class Chord final : public ChordRest {
56       std::vector<Note*>   _notes;       // sorted to decreasing line step
57       LedgerLine*          _ledgerLines; // single linked list
58 
59       Stem*               _stem;
60       Hook*               _hook;
61       StemSlash*          _stemSlash;    // for acciacatura
62 
63       Arpeggio*           _arpeggio;
64       Tremolo*            _tremolo;
65       bool                _endsGlissando;///< true if this chord is the ending point of a glissando (needed for layout)
66       QVector<Chord*>     _graceNotes;
67       int                 _graceIndex;   ///< if this is a grace note, index in parent list
68 
69       Direction          _stemDirection;
70       NoteType           _noteType;      ///< mark grace notes: acciaccatura and appoggiatura
71       bool               _noStem;
72       PlayEventType      _playEventType; ///< play events were modified by user
73 
74       qreal _spaceLw;
75       qreal _spaceRw;
76 
77       QVector<Articulation*> _articulations;
78 
79       qreal upPos()   const override;
80       qreal downPos() const override;
81       qreal centerX() const;
82       void addLedgerLines();
83       void processSiblings(std::function<void(Element*)> func) const;
84 
85       void layoutPitched();
86       void layoutTablature();
87       qreal noteHeadWidth() const;
88 
89    public:
90       Chord(Score* s = 0);
91       Chord(const Chord&, bool link = false);
92       ~Chord();
93       Chord &operator=(const Chord&) = delete;
94 
clone()95       Chord* clone() const override       { return new Chord(*this, false); }
linkedClone()96       Element* linkedClone() override     { return new Chord(*this, true); }
97       void undoUnlink() override;
98 
99       void setScore(Score* s) override;
type()100       ElementType type() const override   { return ElementType::CHORD; }
101       qreal chordMag() const;
102       qreal mag() const override;
103 
104       void write(XmlWriter& xml) const override;
105       void read(XmlReader&) override;
106       bool readProperties(XmlReader&) override;
107       Element* drop(EditData&) override;
108 
setStemDirection(Direction d)109       void setStemDirection(Direction d) { _stemDirection = d; }
stemDirection()110       Direction stemDirection() const    { return _stemDirection; }
111 
ledgerLines()112       LedgerLine* ledgerLines()                  { return _ledgerLines; }
113 
114       qreal defaultStemLength() const;
115       qreal minAbsStemLength() const;
116 
117       void layoutStem1() override;
118       void layoutStem();
119       void layoutArpeggio2();
120       void layoutSpanners();
121       void layoutSpanners(System* system, const Fraction& stick);
122 
notes()123       std::vector<Note*>& notes()                 { return _notes; }
notes()124       const std::vector<Note*>& notes() const     { return _notes; }
125 
126       // Chord has at least one Note
127       Note* upNote() const;
128       Note* downNote() const;
129       int upString() const;
130       int downString() const;
131 
132       qreal maxHeadWidth() const;
133 
134       Note* findNote(int pitch, int skip = 0) const;
135 
stem()136       Stem* stem() const                     { return _stem; }
arpeggio()137       Arpeggio* arpeggio() const             { return _arpeggio;  }
tremolo()138       Tremolo* tremolo() const               { return _tremolo;   }
139       void setTremolo(Tremolo* t);
endsGlissando()140       bool endsGlissando() const             { return _endsGlissando; }
setEndsGlissando(bool val)141       void setEndsGlissando (bool val)       { _endsGlissando = val; }
142       void updateEndsGlissando();
stemSlash()143       StemSlash* stemSlash() const           { return _stemSlash; }
144       bool slash();
145       void setSlash(bool flag, bool stemless);
146       void removeMarkings(bool keepTremolo = false) override;
147 
graceNotes()148       const QVector<Chord*>& graceNotes() const { return _graceNotes; }
graceNotes()149       QVector<Chord*>& graceNotes()             { return _graceNotes; }
150 
151       QVector<Chord*> graceNotesBefore() const;
152       QVector<Chord*> graceNotesAfter() const;
153 
graceIndex()154       int graceIndex() const                        { return _graceIndex; }
setGraceIndex(int val)155       void setGraceIndex(int val)                   { _graceIndex = val;  }
156 
157       int upLine() const override;
158       int downLine() const override;
159       QPointF stemPos() const override;          ///< page coordinates
160       QPointF stemPosBeam() const override;      ///< page coordinates
161       qreal stemPosX() const override;
162       qreal rightEdge() const override;
163 
164       bool underBeam() const;
hook()165       Hook* hook() const                     { return _hook; }
166 
167       //@ add an element to the Chord
168       Q_INVOKABLE void add(Ms::Element*) override;
169       //@ remove the element from the Chord
170       Q_INVOKABLE void remove(Ms::Element*) override;
171 
172       Note* selectedNote() const;
173       void layout() override;
174       QPointF pagePos() const override;      ///< position in page coordinates
175       void layout2();
176       void cmdUpdateNotes(AccidentalState*);
177 
noteType()178       NoteType noteType() const       { return _noteType; }
setNoteType(NoteType t)179       void setNoteType(NoteType t)    { _noteType = t; }
isGrace()180       bool isGrace() const            { return _noteType != NoteType::NORMAL; }
181       void toGraceAfter();
182       void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;
183 
184       void setTrack(int val) override;
185 
186       void computeUp() override;
187 
188       qreal dotPosX() const;
189 
noStem()190       bool noStem() const                           { return _noStem;  }
setNoStem(bool val)191       void setNoStem(bool val)                      { _noStem = val;   }
192 
playEventType()193       PlayEventType playEventType() const           { return _playEventType; }
setPlayEventType(PlayEventType v)194       void setPlayEventType(PlayEventType v)        { _playEventType = v;    }
195       QList<NoteEventList> getNoteEventLists();
196       void setNoteEventLists(QList<NoteEventList>& nel);
197 
198       TremoloChordType tremoloChordType() const;
199 
200       void layoutArticulations();
201       void layoutArticulations2();
202       void layoutArticulations3(Slur* s);
203 
articulations()204       QVector<Articulation*>& articulations()             { return _articulations; }
articulations()205       const QVector<Articulation*>& articulations() const { return _articulations; }
206       Articulation* hasArticulation(const Articulation*);
hasSingleArticulation()207       bool hasSingleArticulation() const                  { return _articulations.size() == 1; }
208 
209       void crossMeasureSetup(bool on) override;
210 
211       void localSpatiumChanged(qreal oldValue, qreal newValue) override;
212       QVariant getProperty(Pid propertyId) const override;
213       bool setProperty(Pid propertyId, const QVariant&) override;
214       QVariant propertyDefault(Pid) const override;
215 
216       void reset() override;
217 
218       Segment* segment() const override;
219       Measure* measure() const override;
220 
221       void sortNotes();
222 
223       Chord* nextTiedChord(bool backwards = false, bool sameSize = true);
224 
225       Element* nextElement() override;
226       Element* prevElement() override;
227       Element* nextSegmentElement() override;
228       Element* lastElementBeforeSegment();
229       Element* prevSegmentElement() override;
230       QString accessibleExtraInfo() const override;
231 
232       Shape shape() const override;
233       };
234 
235 
236 }     // namespace Ms
237 #endif
238 
239