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