1 /* This file is part of the KDE project
2  * Copyright (C) 2007 Marijn Kruisselbrink <mkruisselbrink@kde.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #ifndef MUSIC_CORE_CHORD_H
20 #define MUSIC_CORE_CHORD_H
21 
22 #include "VoiceElement.h"
23 #include "Global.h"
24 
25 #include <QString>
26 
27 namespace MusicCore {
28 
29 class Note;
30 
31 /**
32  * A Chord is used to represent one or more notes that have the same duration and starting time and are in the same
33  * voice. A Chord is also used to represent rests, when it has no notes. When a chord does not have any notes its
34  * staff should be set to know on which staff to display the rest. When the chord contains notes the notes can have
35  * their own staff, so you could have one chord spreading multiple staves (with all staves in the same part).
36  */
37 class Chord : public VoiceElement
38 {
39     Q_OBJECT
40 public:
41     /**
42      * Creates a new Chord instance, not specifying the staff on which the chord should be placed. Add this note to
43      * a VoiceBar instance using the addElement method.
44      *
45      * @param duration the duration of the chord
46      * @param dots the number of dots of the chord, each dot multiplies the length of the chord by 1.5
47      */
48     explicit Chord(Duration duration, int dots = 0);
49 
50     /**
51      * This constructor is overloaded for convenience, to avoid having to call the setStaff method to set the staff
52      * when creating rests.
53      *
54      * @param staff the staff on which the chord should be placed
55      * @param duration the duration of the chord
56      * @param dots the number of dots of the chord, each dot multiplies the length of the chord by 1.5
57      */
58     Chord(Staff* staff, Duration duration, int dots = 0);
59 
60     /**
61      * Destructor.
62      */
63     ~Chord() override;
64 
65     /**
66      * Returns the duration of the chord.
67      */
68     Duration duration() const;
69 
70     /**
71      * Returns the number of dots of this chord. Each dot multiplies the duration by a factor 1.5.
72      */
73     int dots() const;
74 
75     /**
76      * Returns the number of notes in this chord.
77      */
78     int noteCount() const;
79 
80     /**
81      * Returns the note at the given index in this chord.
82      *
83      * @param index the index of the note to return
84      */
85     Note* note(int index) const;
86 
87     /**
88      * Adds a new note to this chord. The note will be drawn on the given staff and will have the given pitch and
89      * accidentals.
90      *
91      * @param staff the staff the note should be drawn on
92      * @param pitch the pitch of the new note
93      * @param accidentals the number of accidentals of the note
94      */
95     Note* addNote(Staff* staff, int pitch, int accidentals = 0);
96 
97     /**
98      * Adds an existing note to this chord. This will transfer ownership of the note to the chord. When the chord is
99      * deleted, all notes in it are also deleted.
100      *
101      * @param note the note to add
102      */
103     void addNote(Note* note);
104 
105     /**
106      * Removes a note from this chord. If deleteNote is true the note is not only removed, but also deleted.
107      *
108      * @param index the index of the note to remove
109      * @param deleteNote should the note not only be removed, but also deleted
110      */
111     void removeNote(int index, bool deleteNote = true);
112 
113     /**
114      * Removes a note from this chord. if deleteNote is true, the note is not only removed but also deleted.
115      *
116      * @param note the note to remove
117      * @param deleteNote should the note also be deleted
118      */
119     void removeNote(Note* note, bool deleteNote = true);
120 
121     /**
122      * This overrides the method in the VoiceElement class to return the correct y position based on pitch
123      * of the notes this chord contains.
124      */
125     qreal y() const override;
126 
127     /**
128      * This overrides the method in the VoiceElement class to return the correct height based on the pitch of
129      * the notes in this chord.
130      */
131     qreal height() const override;
132     qreal width() const override;
133     qreal beatline() const override;
134 
135     qreal stemX() const;
136     qreal centerX() const;
137     qreal topNoteY() const;
138     qreal bottomNoteY() const;
139     qreal stemEndY(bool interpolateBeams = true) const;
140     qreal beamDirection() const;
141 
142     StemDirection stemDirection() const;
143     StemDirection desiredStemDirection() const;
144     void setStemDirection(StemDirection direction);
145 
146     /**
147      * Length of the stem as it extends beyond the top-most or bottom-most note, measured in number of lines.
148      */
149     qreal stemLength() const;
150     void setStemLength(qreal stemLength);
151     qreal desiredStemLength() const;
152 
153     int beamCount() const;
154     const Chord* beamStart(int index) const;
155     const Chord* beamEnd(int index) const;
156     Chord* beamStart(int index);
157     Chord* beamEnd(int index);
158     BeamType beamType(int index) const;
159     void setBeam(int index, Chord* beamStart, Chord* beamEnd, BeamType type = BeamFlag);
160 public Q_SLOTS:
161     /**
162      * Changes the duration of the chord.
163      *
164      * @param duration the new duration
165      */
166     void setDuration(Duration duration);
167 
168     /**
169      * Changes the number of dots of the chord.
170      *
171      * @param dots the new number of dots
172      */
173     void setDots(int dots);
174 Q_SIGNALS:
175     /**
176      * This signal is emitted when the duration of this chord changes.
177      */
178     void durationChanged(Duration duration);
179 
180     /**
181      * This signal is emitted when the number of dots of this chord changes.
182      */
183     void dotsChanged(int dots);
184 private:
185     class Private;
186     Private * const d;
187 };
188 
189 } // namespace MusicCore
190 
191 #endif // MUSIC_CORE_CHORD_H
192 
193