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 __SEGMENT_H__
14 #define __SEGMENT_H__
15
16 #include "element.h"
17 #include "shape.h"
18 #include "mscore.h"
19
20 namespace Ms {
21
22 class Measure;
23 class Segment;
24 class ChordRest;
25 class Spanner;
26 class System;
27
28 //------------------------------------------------------------------------
29 // @@ Segment
30 // A segment holds all vertical aligned staff elements.
31 // Segments are typed and contain only Elements of the same type.
32 //
33 // All Elements in a segment start at the same tick. The Segment can store one Element for
34 // each voice in each staff in the score.
35 // Some elements (Clef, KeySig, TimeSig etc.) are assumed to always have voice zero
36 // and can be found in _elist[staffIdx * VOICES];
37
38 // Segments are children of Measures and store Clefs, KeySigs, TimeSigs,
39 // BarLines and ChordRests.
40 //
41 // @P annotations array[Element] the list of annotations (read only)
42 // @P next Segment the next segment in the whole score; null at last score segment (read-only)
43 // @P nextInMeasure Segment the next segment in measure; null at last measure segment (read-only)
44 // @P prev Segment the previous segment in the whole score; null at first score segment (read-only)
45 // @P prevInMeasure Segment the previous segment in measure; null at first measure segment (read-only)
46 // @P segmentType enum (Segment.All, .Ambitus, .BarLine, .Breath, .ChordRest, .Clef, .EndBarLine, .Invalid, .KeySig, .KeySigAnnounce, .StartRepeatBarLine, .TimeSig, .TimeSigAnnounce)
47 // @P tick int midi tick position (read only)
48 //------------------------------------------------------------------------
49
50 class Segment final : public Element {
51 SegmentType _segmentType { SegmentType::Invalid };
52 Fraction _tick; // { Fraction(0, 1) };
53 Fraction _ticks; // { Fraction(0, 1) };
54 Spatium _extraLeadingSpace;
55 qreal _stretch;
56
57 Segment* _next = nullptr; // linked list of segments inside a measure
58 Segment* _prev = nullptr;
59
60 std::vector<Element*> _annotations;
61 std::vector<Element*> _elist; // Element storage, size = staves * VOICES.
62 std::vector<Shape> _shapes; // size = staves
63 std::vector<qreal> _dotPosX; // size = staves
64
65
66 void init();
67 void checkEmpty() const;
68 void checkElement(Element*, int track);
setEmpty(bool val)69 void setEmpty(bool val) const { setFlag(ElementFlag::EMPTY, val); }
70
71 protected:
72 Element* getElement(int staff); //??
73
74 public:
75 Segment(Measure* m = 0);
76 Segment(Measure*, SegmentType, const Fraction&);
77 Segment(const Segment&);
78 ~Segment();
79
clone()80 Segment* clone() const override { return new Segment(*this); }
type()81 ElementType type() const override { return ElementType::SEGMENT; }
82
83 void setScore(Score*) override;
84
next()85 Segment* next() const { return _next; }
86 Segment* next(SegmentType) const;
87 Segment* nextActive() const;
88 Segment* nextEnabled() const;
89 Segment* nextInStaff(int staffIdx, SegmentType t = SegmentType::ChordRest) const;
setNext(Segment * e)90 void setNext(Segment* e) { _next = e; }
91
prev()92 Segment* prev() const { return _prev; }
93 Segment* prev(SegmentType) const;
94 Segment* prevActive() const;
95 Segment* prevEnabled() const;
setPrev(Segment * e)96 void setPrev(Segment* e) { _prev = e; }
97
98 // don’t stop at measure boundary:
99 Segment* next1() const;
100 Segment* next1enabled() const;
101 Segment* next1MM() const;
102 Segment* next1MMenabled() const;
103 Segment* next1(SegmentType) const;
104 Segment* next1MM(SegmentType) const;
105
106 Segment* prev1() const;
107 Segment* prev1enabled() const;
108 Segment* prev1MM() const;
109 Segment* prev1MMenabled() const;
110 Segment* prev1(SegmentType) const;
111 Segment* prev1MM(SegmentType) const;
112
113 Segment* nextCR(int track = -1, bool sameStaff = false) const;
114
115 ChordRest* nextChordRest(int track, bool backwards = false) const;
116
117 Element* element(int track) const;
118
119 // a variant of the above function, specifically designed to be called from QML
120 //@ returns the element at track 'track' (null if none)
121 Ms::Element* elementAt(int track) const;
122
elist()123 const std::vector<Element*>& elist() const { return _elist; }
elist()124 std::vector<Element*>& elist() { return _elist; }
125
126 void removeElement(int track);
127 void setElement(int track, Element* el);
128 void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;
129
measure()130 Measure* measure() const { return toMeasure(parent()); }
system()131 System* system() const { return toSystem(parent()->parent()); }
x()132 qreal x() const override { return ipos().x(); }
setX(qreal v)133 void setX(qreal v) { rxpos() = v; }
134
135 void insertStaff(int staff);
136 void removeStaff(int staff);
137
138 void add(Element*) override;
139 void remove(Element*) override;
140 void swapElements(int i1, int i2);
141
142 void sortStaves(QList<int>& dst);
143 const char* subTypeName() const;
144
145 static const char* subTypeName(SegmentType);
146 static SegmentType segmentType(ElementType type);
147
segmentType()148 SegmentType segmentType() const { return _segmentType; }
149 void setSegmentType(SegmentType t);
150
empty()151 bool empty() const { return flag(ElementFlag::EMPTY); }
written()152 bool written() const { return flag(ElementFlag::WRITTEN); }
setWritten(bool val)153 void setWritten(bool val) const { setFlag(ElementFlag::WRITTEN, val); }
154
155 void fixStaffIdx();
156
stretch()157 qreal stretch() const { return _stretch; }
setStretch(qreal v)158 void setStretch(qreal v) { _stretch = v; }
159
rtick()160 Fraction rtick() const override { return _tick; }
setRtick(const Fraction & v)161 void setRtick(const Fraction& v) { Q_ASSERT(v >= Fraction(0,1)); _tick = v; }
162 Fraction tick() const override;
163
ticks()164 Fraction ticks() const { return _ticks; }
setTicks(const Fraction & v)165 void setTicks(const Fraction& v) { _ticks = v; }
166
167 qreal widthInStaff(int staffIdx, SegmentType t = SegmentType::ChordRest) const;
168 Fraction ticksInStaff(int staffIdx) const;
169
170 bool splitsTuplet() const;
171
annotations()172 const std::vector<Element*>& annotations() const { return _annotations; }
173 void clearAnnotations();
174 void removeAnnotation(Element* e);
175 bool hasAnnotationOrElement(ElementType type, int minTrack, int maxTrack) const;
176 Element* findAnnotation(ElementType type, int minTrack, int maxTrack);
177 std::vector<Element*> findAnnotations(ElementType type, int minTrack, int maxTrack);
178 bool hasElements() const;
179 bool hasElements(int minTrack, int maxTrack) const;
180 bool allElementsInvisible() const;
181
dotPosX(int staffIdx)182 qreal dotPosX(int staffIdx) const { return _dotPosX[staffIdx]; }
setDotPosX(int staffIdx,qreal val)183 void setDotPosX(int staffIdx, qreal val) { _dotPosX[staffIdx] = val; }
184
extraLeadingSpace()185 Spatium extraLeadingSpace() const { return _extraLeadingSpace; }
setExtraLeadingSpace(Spatium v)186 void setExtraLeadingSpace(Spatium v) { _extraLeadingSpace = v; }
187
188 void write(XmlWriter&) const override;
189 void read(XmlReader&) override;
190
191 QVariant getProperty(Pid propertyId) const override;
192 bool setProperty(Pid propertyId, const QVariant&) override;
193 QVariant propertyDefault(Pid) const override;
194
195 bool operator<(const Segment&) const;
196 bool operator>(const Segment&) const;
197
198 virtual QString accessibleExtraInfo() const override;
199
200 Element* firstInNextSegments(int activeStaff); //<
201 Element* lastInPrevSegments(int activeStaff); //<
202 Element* firstElement(int staff); //< These methods are used for navigation
203 Element* lastElement(int staff); //< for next-element and prev-element
204 Element* firstElementOfSegment(Segment* s, int activeStaff);
205 Element* nextElementOfSegment(Segment* s, Element* e, int activeStaff);
206 Element* prevElementOfSegment(Segment* s, Element* e, int activeStaff);
207 Element* lastElementOfSegment(Segment* s, int activeStaff);
208 Element* nextAnnotation(Element* e);
209 Element* prevAnnotation(Element* e);
210 Element* firstAnnotation(Segment* s, int activeStaff);
211 Element* lastAnnotation(Segment* s, int activeStaff);
212 Spanner* firstSpanner(int activeStaff);
213 Spanner* lastSpanner(int activeStaff);
214 bool notChordRestType(Segment* s);
215 using Element::nextElement;
216 Element* nextElement(int activeStaff);
217 using Element::prevElement;
218 Element* prevElement(int activeStaff);
219
shapes()220 std::vector<Shape> shapes() { return _shapes; }
shapes()221 const std::vector<Shape>& shapes() const { return _shapes; }
staffShape(int staffIdx)222 const Shape& staffShape(int staffIdx) const { return _shapes[staffIdx]; }
staffShape(int staffIdx)223 Shape& staffShape(int staffIdx) { return _shapes[staffIdx]; }
224 void createShapes();
225 void createShape(int staffIdx);
226 qreal minRight() const;
227 qreal minLeft(const Shape&) const;
228 qreal minLeft() const;
229 qreal minHorizontalDistance(Segment*, bool isSystemGap) const;
230 qreal minHorizontalCollidingDistance(Segment* ns) const;
231
232 // some helper function
cr(int track)233 ChordRest* cr(int track) const { return toChordRest(_elist[track]); }
isType(const SegmentType t)234 bool isType(const SegmentType t) const{ return int(_segmentType) & int(t); }
isBeginBarLineType()235 bool isBeginBarLineType() const { return _segmentType == SegmentType::BeginBarLine; }
isClefType()236 bool isClefType() const { return _segmentType == SegmentType::Clef; }
isHeaderClefType()237 bool isHeaderClefType() const { return _segmentType == SegmentType::HeaderClef; }
isKeySigType()238 bool isKeySigType() const { return _segmentType == SegmentType::KeySig; }
isAmbitusType()239 bool isAmbitusType() const { return _segmentType == SegmentType::Ambitus; }
isTimeSigType()240 bool isTimeSigType() const { return _segmentType == SegmentType::TimeSig; }
isStartRepeatBarLineType()241 bool isStartRepeatBarLineType() const { return _segmentType == SegmentType::StartRepeatBarLine; }
isBarLineType()242 bool isBarLineType() const { return _segmentType == SegmentType::BarLine; }
isBreathType()243 bool isBreathType() const { return _segmentType == SegmentType::Breath; }
isChordRestType()244 bool isChordRestType() const { return _segmentType == SegmentType::ChordRest; }
isEndBarLineType()245 bool isEndBarLineType() const { return _segmentType == SegmentType::EndBarLine; }
isKeySigAnnounceType()246 bool isKeySigAnnounceType() const { return _segmentType == SegmentType::KeySigAnnounce; }
isTimeSigAnnounceType()247 bool isTimeSigAnnounceType() const { return _segmentType == SegmentType::TimeSigAnnounce; }
248
249 static constexpr SegmentType durationSegmentsMask = SegmentType::ChordRest; // segment types which may have non-zero tick length
250 };
251
252 //---------------------------------------------------------
253 // nextActive
254 //---------------------------------------------------------
255
nextActive()256 inline Segment* Segment::nextActive() const
257 {
258 Segment* ns = next();
259 while (ns && !(ns->enabled() && ns->visible()))
260 ns = ns->next();
261 return ns;
262 }
263
264 //---------------------------------------------------------
265 // nextEnabled
266 //---------------------------------------------------------
267
nextEnabled()268 inline Segment* Segment::nextEnabled() const
269 {
270 Segment* ns = next();
271 while (ns && !ns->enabled())
272 ns = ns->next();
273 return ns;
274 }
275
276 //---------------------------------------------------------
277 // prevActive
278 //---------------------------------------------------------
279
prevActive()280 inline Segment* Segment::prevActive() const
281 {
282 Segment* ps = prev();
283 while (ps && !(ps->enabled() && ps->visible()))
284 ps = ps->prev();
285 return ps;
286 }
287
288 //---------------------------------------------------------
289 // prevEnabled
290 //---------------------------------------------------------
291
prevEnabled()292 inline Segment* Segment::prevEnabled() const
293 {
294 Segment* ps = prev();
295 while (ps && !ps->enabled())
296 ps = ps->prev();
297 return ps;
298 }
299
300 } // namespace Ms
301
302 Q_DECLARE_METATYPE(Ms::SegmentType);
303
304 #endif
305
306