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 __STAFF_H__
14 #define __STAFF_H__
15 
16 /**
17  \file
18  Definition of class Staff.
19 */
20 
21 #include "mscore.h"
22 #include "changeMap.h"
23 #include "pitch.h"
24 #include "cleflist.h"
25 #include "keylist.h"
26 #include "stafftypelist.h"
27 #include "groups.h"
28 #include "scoreElement.h"
29 
30 namespace Ms {
31 
32 class InstrumentTemplate;
33 class XmlWriter;
34 class Part;
35 class Score;
36 class KeyList;
37 class StaffType;
38 class Staff;
39 struct ClefTypeList;
40 class Segment;
41 class Clef;
42 class TimeSig;
43 class Ottava;
44 class BracketItem;
45 class Note;
46 
47 enum class Key;
48 
49 //---------------------------------------------------------
50 //   SwingParameters
51 //---------------------------------------------------------
52 
53 struct SwingParameters {
54       int swingUnit;
55       int swingRatio;
56       };
57 
58 //---------------------------------------------------------
59 //    Staff
60 ///    Global staff data not directly related to drawing.
61 //---------------------------------------------------------
62 
63 class Staff final : public ScoreElement {
64    public:
65       enum class HideMode { AUTO, ALWAYS, NEVER, INSTRUMENT };
66 
67    private:
68       Part* _part       { 0 };
69 
70       ClefList clefs;
71       ClefTypeList _defaultClefType;
72 
73       KeyList _keys;
74       std::map<int,TimeSig*> timesigs;
75 
76       QList <BracketItem*> _brackets;
77       int  _barLineSpan        { false };    ///< true - span barline to next staff
78       int _barLineFrom         { 0     };    ///< line of start staff to draw the barline from (0 = staff top line, ...)
79       int _barLineTo           { 0     };    ///< line of end staff to draw the bar line to (0= staff bottom line, ...)
80 
81       bool _invisible          { false };
82       bool _cutaway            { false };
83       bool _showIfEmpty        { false };       ///< show this staff if system is empty and hideEmptyStaves is true
84       bool _hideSystemBarLine  { false };       // no system barline if not preceded by staff with barline
85       bool _mergeMatchingRests { false };       // merge matching rests in multiple voices
86       HideMode _hideWhenEmpty  { HideMode::AUTO };    // hide empty staves
87 
88       QColor _color            { MScore::defaultColor };
89       qreal _userDist          { 0.0   };       ///< user edited extra distance
90 
91       StaffTypeList _staffTypeList;
92 
93       QMap<int,int> _channelList[VOICES];
94       QMap<int,SwingParameters> _swingList;
95       QMap<int,int> _capoList;
96       bool _playbackVoice[VOICES] { true, true, true, true };
97 
98       ChangeMap _velocities;         ///< cached value
99       ChangeMap _velocityMultiplications;         ///< cached value
100       PitchList _pitchOffsets;      ///< cached value
101 
102       void fillBrackets(int);
103       void cleanBrackets();
104 
105       qreal mag(const StaffType*) const;
106 
107    public:
108       Staff(Score* score = 0);
109       void init(const InstrumentTemplate*, const StaffType *staffType, int);
110       void initFromStaffType(const StaffType* staffType);
111       void init(const Staff*);
112 
type()113       ElementType type() const override { return ElementType::STAFF; }
114 
115       bool isTop() const;
116       QString partName() const;
117       int rstaff() const;
118       int idx() const;
119       void read(XmlReader&);
120       bool readProperties(XmlReader&);
121       void write(XmlWriter& xml) const;
part()122       Part* part() const             { return _part;        }
setPart(Part * p)123       void setPart(Part* p)          { _part = p;           }
124 
125       BracketType bracketType(int idx) const;
126       int bracketSpan(int idx) const;
127       void setBracketType(int idx, BracketType val);
128       void setBracketSpan(int idx, int val);
129       void swapBracket(int oldIdx, int newIdx);
130       void changeBracketColumn(int oldColumn, int newColumn);
131       void addBracket(BracketItem*);
brackets()132       const QList<BracketItem*>& brackets() const { return _brackets; }
brackets()133       QList<BracketItem*>& brackets()             { return _brackets; }
134       void cleanupBrackets();
135       int bracketLevels() const;
136 
clefList()137       ClefList& clefList()                           { return clefs;  }
138       ClefTypeList clefType(const Fraction&) const;
defaultClefType()139       ClefTypeList defaultClefType() const           { return _defaultClefType; }
setDefaultClefType(const ClefTypeList & l)140       void setDefaultClefType(const ClefTypeList& l) { _defaultClefType = l; }
141       ClefType clef(const Fraction&) const;
142       Fraction nextClefTick(const Fraction&) const;
143       Fraction currentClefTick(const Fraction&) const;
144 
145       void setClef(Clef*);
146       void removeClef(const Clef*);
147 
148       void addTimeSig(TimeSig*);
149       void removeTimeSig(TimeSig*);
150       void clearTimeSig();
151       Fraction timeStretch(const Fraction&) const;
152       TimeSig* timeSig(const Fraction&) const;
153       TimeSig* nextTimeSig(const Fraction&) const;
154       Fraction currentTimeSigTick(const Fraction&) const;
155 
isLocalTimeSignature(const Fraction & tick)156       bool isLocalTimeSignature(const Fraction& tick) { return timeStretch(tick) != Fraction(1, 1); }
157 
158       const Groups& group(const Fraction&) const;
159 
keyList()160       KeyList* keyList()                      { return &_keys;                  }
key(const Fraction & tick)161       Key key(const Fraction& tick) const     { return keySigEvent(tick).key(); }
162       KeySigEvent keySigEvent(const Fraction&) const;
163       Fraction nextKeyTick(const Fraction&) const;
164       Fraction currentKeyTick(const Fraction&) const;
165       KeySigEvent prevKey(const Fraction&) const;
166       void setKey(const Fraction&, KeySigEvent);
167       void removeKey(const Fraction&);
168 
169       bool show() const;
170       bool stemless(const Fraction&) const;
cutaway()171       bool cutaway() const           { return _cutaway;     }
setCutaway(bool val)172       void setCutaway(bool val)      { _cutaway = val;      }
showIfEmpty()173       bool showIfEmpty() const       { return _showIfEmpty; }
setShowIfEmpty(bool val)174       void setShowIfEmpty(bool val)  { _showIfEmpty = val;  }
175 
hideSystemBarLine()176       bool hideSystemBarLine() const      { return _hideSystemBarLine; }
setHideSystemBarLine(bool val)177       void setHideSystemBarLine(bool val) { _hideSystemBarLine = val;  }
hideWhenEmpty()178       HideMode hideWhenEmpty() const      { return _hideWhenEmpty;     }
setHideWhenEmpty(HideMode v)179       void setHideWhenEmpty(HideMode v)   { _hideWhenEmpty = v;        }
mergeMatchingRests()180       bool mergeMatchingRests() const     { return _mergeMatchingRests;}
setMergeMatchingRests(bool val)181       void setMergeMatchingRests(bool val){ _mergeMatchingRests = val; }
182 
barLineSpan()183       int barLineSpan() const        { return _barLineSpan; }
barLineFrom()184       int barLineFrom() const        { return _barLineFrom; }
barLineTo()185       int barLineTo() const          { return _barLineTo;   }
setBarLineSpan(int val)186       void setBarLineSpan(int val)   { _barLineSpan = val;  }
setBarLineFrom(int val)187       void setBarLineFrom(int val)   { _barLineFrom = val;  }
setBarLineTo(int val)188       void setBarLineTo(int val)     { _barLineTo = val;    }
189       qreal height() const;
190 
191       int channel(const Fraction&, int voice) const;
192 
193       QList<Note*> getNotes() const;
194       void addChord(QList<Note*>& list, Chord* chord, int voice) const;
195 
clearChannelList(int voice)196       void clearChannelList(int voice)                               { _channelList[voice].clear(); }
insertIntoChannelList(int voice,const Fraction & tick,int channelId)197       void insertIntoChannelList(int voice, const Fraction& tick, int channelId) { _channelList[voice].insert(tick.ticks(), channelId); }
198 
199       SwingParameters swing(const Fraction&)  const;
clearSwingList()200       void clearSwingList()                                  { _swingList.clear(); }
insertIntoSwingList(const Fraction & tick,SwingParameters sp)201       void insertIntoSwingList(const Fraction& tick, SwingParameters sp) { _swingList.insert(tick.ticks(), sp); }
202 
203       int capo(const Fraction&) const;
clearCapoList()204       void clearCapoList()                             { _capoList.clear(); }
insertIntoCapoList(const Fraction & tick,int fretId)205       void insertIntoCapoList(const Fraction& tick, int fretId)    { _capoList.insert(tick.ticks(), fretId); }
206 
207       //==== staff type helper function
208       const StaffType* staffType(const Fraction&) const;
209       const StaffType* constStaffType(const Fraction&) const;
210       const StaffType* staffTypeForElement(const Element*) const;
211       StaffType* staffType(const Fraction&);
212       StaffType* setStaffType(const Fraction&, const StaffType&);
213       void removeStaffType(const Fraction&);
214       void staffTypeListChanged(const Fraction&);
215 
216       bool isPitchedStaff(const Fraction&) const;
217       bool isTabStaff(const Fraction&) const;
218       bool isDrumStaff(const Fraction&) const;
219 
220       int lines(const Fraction&) const;
221       void setLines(const Fraction&, int lines);
222       qreal lineDistance(const Fraction&) const;
223 
224       bool invisible(const Fraction&) const;
225       void setInvisible(const Fraction&, bool val);
226 
227       void setSlashStyle(const Fraction&, bool val);
228       int middleLine(const Fraction&) const;
229       int bottomLine(const Fraction&) const;
230 
231       qreal mag(const Fraction&) const;
232       qreal mag(const Element*) const;
233       qreal spatium(const Fraction&) const;
234       qreal spatium(const Element*) const;
235       //===========
236 
velocities()237       ChangeMap& velocities()           { return _velocities;     }
velocityMultiplications()238       ChangeMap& velocityMultiplications()      { return _velocityMultiplications;     }
pitchOffsets()239       PitchList& pitchOffsets()        { return _pitchOffsets;   }
240 
pitchOffset(const Fraction & tick)241       int pitchOffset(const Fraction& tick) { return _pitchOffsets.pitchOffset(tick.ticks());   }
242       void updateOttava();
243 
244       QList<Staff*> staffList() const;
245       bool primaryStaff() const;
246 
userDist()247       qreal userDist() const        { return _userDist;  }
setUserDist(qreal val)248       void setUserDist(qreal val)   { _userDist = val;   }
249 
250       void spatiumChanged(qreal /*oldValue*/, qreal /*newValue*/);
251       void localSpatiumChanged(double oldVal, double newVal, Fraction tick);
252       bool genKeySig();
253       bool showLedgerLines(const Fraction&) const;
254 
255       QColor color(const Fraction&) const;
256       void setColor(const Fraction&, const QColor& val);
257       void undoSetColor(const QColor& val);
258       void insertTime(const Fraction&, const Fraction& len);
259 
260       QVariant getProperty(Pid) const override;
261       bool setProperty(Pid, const QVariant&) override;
262       QVariant propertyDefault(Pid) const override;
263 
264       BracketType innerBracket() const;
265 
playbackVoice(int voice)266       bool playbackVoice(int voice) const        { return _playbackVoice[voice]; }
setPlaybackVoice(int voice,bool val)267       void setPlaybackVoice(int voice, bool val) { _playbackVoice[voice] = val; }
268 
269 #ifndef NDEBUG
270       void dumpClefs(const char* title) const;
271       void dumpKeys(const char* title) const;
272       void dumpTimeSigs(const char*) const;
273 #else
dumpClefs(const char *)274       void dumpClefs(const char*) const {}
dumpKeys(const char *)275       void dumpKeys(const char*) const {}
dumpTimeSigs(const char *)276       void dumpTimeSigs(const char*) const {}
277 #endif
278 
279       void triggerLayout();
280       void triggerLayout(const Fraction& tick);
281       };
282 
283 }     // namespace Ms
284 #endif
285 
286