Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include <map>
26 : #include <vector>
27 :
28 : #include "engravingitem.h"
29 :
30 : #include "draw/types/color.h"
31 :
32 : #include "cleflist.h"
33 : #include "groups.h"
34 : #include "keylist.h"
35 : #include "mscore.h"
36 : #include "stafftypelist.h"
37 :
38 : #include "../types/types.h"
39 :
40 : namespace mu::engraving {
41 : class BracketItem;
42 : class Clef;
43 : class Factory;
44 : class InstrumentTemplate;
45 : class KeyList;
46 : class Note;
47 : class Part;
48 : class Score;
49 : class StaffType;
50 : class TimeSig;
51 :
52 : enum class Key : signed char;
53 :
54 : //---------------------------------------------------------
55 : // Staff
56 : /// Global staff data not directly related to drawing.
57 : //---------------------------------------------------------
58 :
59 : class Staff final : public EngravingItem
60 : {
61 6764 : OBJECT_ALLOCATOR(engraving, Staff)
62 :
63 : public:
64 : Staff* clone() const override;
65 :
66 : void init(const InstrumentTemplate*, const StaffType* staffType, staff_idx_t templateStaffIdx);
67 : void initFromStaffType(const StaffType* staffType);
68 : void init(const Staff*);
69 :
70 : const ID& id() const;
71 : void setId(const ID& id);
72 :
73 : bool isTop() const;
74 : String partName() const;
75 : staff_idx_t rstaff() const;
76 : staff_idx_t idx() const;
77 :
78 987664 : Part* part() const { return m_part; }
79 3937 : void setPart(Part* p) { m_part = p; }
80 :
81 : Part* originPart(const Fraction& tick) const;
82 :
83 155 : ClefList& clefList() { return m_clefs; }
84 : ClefTypeList clefType(const Fraction&) const;
85 55248 : ClefTypeList defaultClefType() const { return m_defaultClefType; }
86 1224 : void setDefaultClefType(const ClefTypeList& l) { m_defaultClefType = l; }
87 : ClefType clef(const Fraction&) const;
88 : Fraction nextClefTick(const Fraction&) const;
89 : Fraction currentClefTick(const Fraction&) const;
90 :
91 : String staffName() const;
92 :
93 : void setClef(Clef*);
94 : void removeClef(const Clef*);
95 :
96 : void addTimeSig(TimeSig*);
97 : void removeTimeSig(TimeSig*);
98 : void clearTimeSig();
99 : Fraction timeStretch(const Fraction&) const;
100 : TimeSig* timeSig(const Fraction&) const;
101 : TimeSig* nextTimeSig(const Fraction&) const;
102 : Fraction currentTimeSigTick(const Fraction&) const;
103 :
104 : const Groups& group(const Fraction&) const;
105 :
106 : Interval transpose(const Fraction& tick) const;
107 :
108 1861 : KeyList* keyList() { return &m_keys; }
109 1492909 : Key key(const Fraction& tick) const { return keySigEvent(tick).key(); }
110 11198 : Key concertKey(const Fraction& tick) const { return keySigEvent(tick).concertKey(); }
111 : KeySigEvent keySigEvent(const Fraction&) const;
112 : Fraction nextKeyTick(const Fraction&) const;
113 : Fraction currentKeyTick(const Fraction&) const;
114 : KeySigEvent prevKey(const Fraction&) const;
115 : void setKey(const Fraction&, KeySigEvent);
116 : void removeKey(const Fraction&);
117 :
118 : bool show() const;
119 : bool stemless(const Fraction&) const;
120 143357 : bool cutaway() const { return m_cutaway; }
121 6 : void setCutaway(bool val) { m_cutaway = val; }
122 1975 : bool showIfEntireSystemEmpty() const { return m_showIfEntireSystemEmpty; }
123 0 : void setShowIfEntireSystemEmpty(bool val) { m_showIfEntireSystemEmpty = val; }
124 :
125 114626 : bool hideSystemBarLine() const { return m_hideSystemBarLine; }
126 6 : void setHideSystemBarLine(bool val) { m_hideSystemBarLine = val; }
127 7654 : AutoOnOff hideWhenEmpty() const { return m_hideWhenEmpty; }
128 9 : void setHideWhenEmpty(AutoOnOff v) { m_hideWhenEmpty = v; }
129 7410 : AutoOnOff mergeMatchingRests() const { return m_mergeMatchingRests; }
130 12 : void setMergeMatchingRests(AutoOnOff val) { m_mergeMatchingRests = val; }
131 : bool shouldMergeMatchingRests() const;
132 :
133 89237 : bool barLineSpan() const { return m_barLineSpan; }
134 87643 : int barLineFrom() const { return m_barLineFrom; }
135 87643 : int barLineTo() const { return m_barLineTo; }
136 820 : void setBarLineSpan(const bool val) { m_barLineSpan = val; }
137 77 : void setBarLineFrom(int val) { m_barLineFrom = val; }
138 637 : void setBarLineTo(int val) { m_barLineTo = val; }
139 : double staffHeight() const;
140 : double staffHeight(const Fraction& tick) const;
141 :
142 : int channel(const Fraction&, voice_idx_t voice) const;
143 :
144 9560 : void clearChannelList(voice_idx_t voice) { m_channelList[voice].clear(); }
145 632 : void insertIntoChannelList(voice_idx_t voice, const Fraction& tick, int channelId)
146 : {
147 632 : m_channelList[voice].insert({ tick.ticks(), channelId });
148 632 : }
149 :
150 : SwingParameters swing(const Fraction&) const;
151 269 : void clearSwingMap() { m_swingMap.clear(); }
152 10 : void insertIntoSwingMap(const Fraction& tick, SwingParameters sp) { m_swingMap.insert({ tick.ticks(), sp }); }
153 :
154 : const CapoParams& capo(const Fraction&) const;
155 : void insertCapoParams(const Fraction& tick, const CapoParams& params, bool ignoreNotationUpdate);
156 : void removeCapoParams(const Fraction& tick);
157 :
158 : //==== staff type helper function
159 : const StaffType* staffType(const Fraction& = Fraction(0, 1)) const;
160 : const StaffType* constStaffType(const Fraction&) const;
161 : const StaffType* staffTypeForElement(const EngravingItem*) const;
162 : bool isStaffTypeStartFrom(const Fraction& = Fraction(0, 1)) const;
163 : void moveStaffType(const Fraction& from, const Fraction& to);
164 : StaffType* staffType(const Fraction&);
165 : StaffType* setStaffType(const Fraction&, const StaffType&);
166 : void removeStaffType(const Fraction&);
167 : void staffTypeListChanged(const Fraction&);
168 :
169 : std::pair<int, int> staffTypeRange(const Fraction&) const;
170 :
171 : bool isPitchedStaff(const Fraction&) const;
172 : bool isTabStaff(const Fraction&) const;
173 : bool isDrumStaff(const Fraction&) const;
174 :
175 : int lines(const Fraction&) const;
176 : void setLines(const Fraction&, int lines);
177 : double lineDistance(const Fraction&) const;
178 :
179 : bool isLinesInvisible(const Fraction&) const;
180 : void setIsLinesInvisible(const Fraction&, bool val);
181 :
182 : void setSlashStyle(const Fraction&, bool val);
183 : int middleLine(const Fraction&) const;
184 : int bottomLine(const Fraction&) const;
185 :
186 : double staffMag(const Fraction&) const;
187 : double staffMag(const EngravingItem* element) const;
188 : double spatium(const Fraction&) const;
189 : double spatium(const EngravingItem*) const;
190 : //===========
191 :
192 : int pitchOffset(const Fraction& tick) const;
193 : void updateOttava();
194 :
195 : std::vector<Staff*> staffList() const;
196 : Staff* primaryStaff() const;
197 : bool isPrimaryStaff() const;
198 :
199 12843 : Spatium userDist() const { return m_userDist; }
200 3 : void setUserDist(Spatium val) { m_userDist = val; }
201 :
202 : void setLocalSpatium(double oldVal, double newVal, Fraction tick);
203 : bool genKeySig();
204 : bool showLedgerLines(const Fraction&) const;
205 :
206 : using EngravingItem::color;
207 : using EngravingItem::setColor;
208 : Color color(const Fraction&) const;
209 : void setColor(const Fraction&, const Color& val);
210 : void insertTime(const Fraction&, const Fraction& len);
211 :
212 : PropertyValue getProperty(Pid) const override;
213 : bool setProperty(Pid, const PropertyValue&) override;
214 : PropertyValue propertyDefault(Pid) const override;
215 :
216 : bool playbackVoice(int voice) const;
217 : void setPlaybackVoice(int voice, bool val);
218 :
219 : const std::array<bool, VOICES>& visibilityVoices() const;
220 : bool isVoiceVisible(voice_idx_t voice) const;
221 : bool canDisableVoice() const;
222 :
223 : bool reflectTranspositionInLinkedTab() const;
224 : void setReflectTranspositionInLinkedTab(bool reflect);
225 :
226 : #ifndef NDEBUG
227 : void dumpClefs(const char* title) const;
228 : void dumpKeys(const char* title) const;
229 : void dumpTimeSigs(const char*) const;
230 : #else
231 : void dumpClefs(const char*) const {}
232 : void dumpKeys(const char*) const {}
233 : void dumpTimeSigs(const char*) const {}
234 : #endif
235 :
236 : void triggerLayout() const override;
237 : void triggerLayout(const Fraction& tick);
238 :
239 : Staff* findLinkedInScore(const Score* score) const override;
240 :
241 : track_idx_t getLinkedTrackInStaff(const Staff* linkedStaff, const track_idx_t strack) const;
242 : bool trackHasLinksInVoiceZero(track_idx_t track);
243 :
244 : void undoSetShowMeasureNumbers(bool show);
245 : bool shouldShowMeasureNumbers() const;
246 :
247 : bool isLastOfScore() const;
248 : bool isSystemObjectStaff() const;
249 : bool hasSystemObjectsBelowBottomStaff() const;
250 :
251 : String individualStaffNameLong(const Fraction& tick) const;
252 : String individualStaffNameShort(const Fraction& tick) const;
253 :
254 : private:
255 :
256 : friend class Factory;
257 : Staff(Part* parent);
258 : Staff(const Staff& staff);
259 :
260 : double staffMag(const StaffType*) const;
261 :
262 : friend class Excerpt;
263 : void setVoiceVisible(voice_idx_t voice, bool visible);
264 : void updateVisibilityVoices(const Staff* masterStaff, const TracksMap& tracks);
265 :
266 : ID m_id = INVALID_ID;
267 : Part* m_part = nullptr;
268 :
269 : ClefList m_clefs;
270 : ClefTypeList m_defaultClefType;
271 :
272 : KeyList m_keys;
273 : std::map<int, TimeSig*> m_timesigs;
274 :
275 : bool m_barLineSpan = false; // true - span barline to next staff
276 : int m_barLineFrom = 0; // line of start staff to draw the barline from (0 = staff top line, ...)
277 : int m_barLineTo = 0; // line of end staff to draw the bar line to (0= staff bottom line, ...)
278 :
279 : bool m_cutaway = false;
280 : bool m_showIfEntireSystemEmpty = false; // show this staff if system is empty and hideEmptyStaves is true
281 : bool m_hideSystemBarLine = false; // no system barline if not preceded by staff with barline
282 : AutoOnOff m_mergeMatchingRests = AutoOnOff::AUTO; // merge matching rests in multiple voices
283 : AutoOnOff m_hideWhenEmpty = AutoOnOff::AUTO; // hide empty staves
284 :
285 : Color m_color;
286 : Spatium m_userDist { 0.0_sp }; ///< user edited extra distance
287 :
288 : StaffTypeList m_staffTypeList;
289 :
290 : std::map<int, int> m_channelList[VOICES];
291 : std::map<int, SwingParameters> m_swingMap;
292 : std::map<int, CapoParams> m_capoMap;
293 : std::map<int, int> m_pitchOffsetMap;
294 : bool m_playbackVoice[VOICES] { true, true, true, true };
295 : std::array<bool, VOICES> m_visibilityVoices { true, true, true, true };
296 :
297 : bool m_reflectTranspositionInLinkedTab = true;
298 :
299 : AutoOnOff m_showMeasureNumbers = AutoOnOff::AUTO;
300 : };
301 : }
|