1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2010-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 __SPANNER_H__
14 #define __SPANNER_H__
15 
16 #include "element.h"
17 
18 namespace Ms {
19 
20 class Spanner;
21 
22 //---------------------------------------------------------
23 //   SpannerSegmentType
24 //---------------------------------------------------------
25 
26 enum class SpannerSegmentType {
27       SINGLE, BEGIN, MIDDLE, END
28       };
29 
30 //---------------------------------------------------------
31 //   @@ SpannerSegment
32 //!    parent: System
33 //---------------------------------------------------------
34 
35 class SpannerSegment : public Element {
36       Spanner* _spanner;
37       SpannerSegmentType _spannerSegmentType;
38 
39    protected:
40       QPointF _p2;
41       QPointF _offset2;
42 
43    public:
44       SpannerSegment(Spanner*, Score*, ElementFlags f = ElementFlag::ON_STAFF | ElementFlag::MOVABLE);
45       SpannerSegment(Score* s, ElementFlags f = ElementFlag::ON_STAFF | ElementFlag::MOVABLE);
46       SpannerSegment(const SpannerSegment&);
47       virtual SpannerSegment* clone() const = 0;
48 
49       virtual qreal mag() const override;
50       virtual Fraction tick() const override;
51 
spanner()52       Spanner* spanner() const              { return _spanner;            }
setSpanner(Spanner * val)53       Spanner* setSpanner(Spanner* val)     { return _spanner = val;      }
54 
setSpannerSegmentType(SpannerSegmentType s)55       void setSpannerSegmentType(SpannerSegmentType s) { _spannerSegmentType = s;               }
spannerSegmentType()56       SpannerSegmentType spannerSegmentType() const    { return _spannerSegmentType;            }
isSingleType()57       bool isSingleType() const                        { return spannerSegmentType() == SpannerSegmentType::SINGLE; }
isBeginType()58       bool isBeginType() const                         { return spannerSegmentType() == SpannerSegmentType::BEGIN;  }
isSingleBeginType()59       bool isSingleBeginType() const                   { return isSingleType() || isBeginType(); }
isSingleEndType()60       bool isSingleEndType() const                     { return isSingleType() || isEndType(); }
isMiddleType()61       bool isMiddleType() const                        { return spannerSegmentType() == SpannerSegmentType::MIDDLE; }
isEndType()62       bool isEndType() const                           { return spannerSegmentType() == SpannerSegmentType::END;    }
63 
64       void setSystem(System* s);
system()65       System* system() const                { return toSystem(parent()); }
66 
userOff2()67       const QPointF& userOff2() const       { return _offset2;       }
setUserOff2(const QPointF & o)68       void setUserOff2(const QPointF& o)    { _offset2 = o;          }
setUserXoffset2(qreal x)69       void setUserXoffset2(qreal x)         { _offset2.setX(x);      }
rUserXoffset2()70       qreal& rUserXoffset2()                { return _offset2.rx();  }
rUserYoffset2()71       qreal& rUserYoffset2()                { return _offset2.ry();  }
72 
setPos2(const QPointF & p)73       void setPos2(const QPointF& p)        { _p2 = p;                }
74       //TODO: rename to spanSegPosWithUserOffset()
pos2()75       QPointF pos2() const                  { return _p2 + _offset2; }
76       //TODO: rename to spanSegPos()
ipos2()77       const QPointF& ipos2() const          { return _p2;             }
rpos2()78       QPointF& rpos2()                      { return _p2;             }
rxpos2()79       qreal& rxpos2()                       { return _p2.rx();        }
rypos2()80       qreal& rypos2()                       { return _p2.ry();        }
81 
isEditable()82       virtual bool isEditable() const override { return true; }
83 
84       QByteArray mimeData(const QPointF& dragOffset) const override;
85 
86       virtual void spatiumChanged(qreal ov, qreal nv) override;
87 
88       virtual QVariant getProperty(Pid id) const override;
89       virtual bool setProperty(Pid id, const QVariant& v) override;
90       virtual QVariant propertyDefault(Pid id) const override;
91       virtual Element* propertyDelegate(Pid) override;
92       virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps) override;
93       using ScoreElement::undoChangeProperty;
94 
95       virtual Sid getPropertyStyle(Pid id) const override;
96       virtual PropertyFlags propertyFlags(Pid id) const override;
97       virtual void resetProperty(Pid id) override;
98       virtual void styleChanged() override;
99       void reset() override;
100 
101       virtual void setSelected(bool f) override;
102       virtual void setVisible(bool f) override;
103       virtual void setColor(const QColor& col) override;
104 
105       virtual Element* nextSegmentElement() override;
106       virtual Element* prevSegmentElement() override;
107       virtual QString accessibleInfo() const override;
108       virtual void triggerLayout() const override;
109       void autoplaceSpannerSegment();
110       };
111 
112 //----------------------------------------------------------------------------------
113 //   @@ Spanner
114 ///   Virtual base class for slurs, ties, lines etc.
115 //
116 //    @P anchor         enum (Spanner.CHORD, Spanner.MEASURE, Spanner.NOTE, Spanner.SEGMENT)
117 //    @P endElement     Element           the element the spanner end is anchored to (read-only)
118 //    @P startElement   Element           the element the spanner start is anchored to (read-only)
119 //    @P tick           int               tick start position
120 //    @P tick2          int               tick end position
121 //----------------------------------------------------------------------------------
122 
123 class Spanner : public Element {
124       Q_GADGET
125    public:
126       enum class Anchor {
127             SEGMENT, MEASURE, CHORD, NOTE
128             };
129       Q_ENUM(Anchor);
130    private:
131 
132       Element* _startElement { 0  };
133       Element* _endElement   { 0  };
134 
135       Anchor _anchor         { Anchor::SEGMENT };
136       Fraction _tick         { Fraction(-1, 1) };
137       Fraction _ticks        { Fraction(0, 1) };
138       int _track2            { -1 };
139       bool _broken           { false };
140 
141       std::vector<SpannerSegment*> segments;
142       std::deque<SpannerSegment*> unusedSegments; // Currently unused segments which can be reused later.
143                                                   // We cannot just delete them as they can be referenced
144                                                   // in undo stack or other places already.
145 
146    protected:
147       void pushUnusedSegment(SpannerSegment* seg);
148       SpannerSegment* popUnusedSegment();
149       void reuse(SpannerSegment* seg);            // called when segment from unusedSegments
150                                                   // is added back to the spanner.
151       int reuseSegments(int number);
152       SpannerSegment* getNextLayoutSystemSegment(System* system, std::function<SpannerSegment*()> createSegment);
153       void fixupSegments(unsigned int targetNumber, std::function<SpannerSegment*()> createSegment);
154 
spannerSegments()155       const std::vector<SpannerSegment*> spannerSegments() const { return segments; }
156 
157    public:
158       Spanner(Score* s, ElementFlags = ElementFlag::NOTHING);
159       Spanner(const Spanner&);
160       ~Spanner();
161 
162       virtual qreal mag() const override;
163 
164       virtual ElementType type() const = 0;
165       virtual void setScore(Score* s) override;
166 
167       bool readProperties(XmlReader&) override;
168       void writeProperties(XmlWriter&) const override;
169 
170       void writeSpannerStart(XmlWriter& xml, const Element* current, int track, Fraction frac = { -1, 1 }) const;
171       void writeSpannerEnd(XmlWriter& xml,   const Element* current, int track, Fraction frac = { -1, 1 }) const;
172       static void readSpanner(XmlReader& e, Element* current, int track);
173       static void readSpanner(XmlReader& e, Score* current, int track);
174 
tick()175       virtual Fraction tick() const override { return _tick;          }
tick2()176       Fraction tick2() const                 { return _tick + _ticks; }
ticks()177       Fraction ticks() const                 { return _ticks;         }
178 
179       void setTick(const Fraction&);
180       void setTick2(const Fraction&);
181       void setTicks(const Fraction&);
182 
track2()183       int track2() const       { return _track2;   }
setTrack2(int v)184       void setTrack2(int v)    { _track2 = v;      }
effectiveTrack2()185       int effectiveTrack2() const { return _track2 == -1 ? track() : _track2; }
186 
broken()187       bool broken() const      { return _broken;   }
setBroken(bool v)188       void setBroken(bool v)   { _broken = v;      }
189 
anchor()190       Anchor anchor() const    { return _anchor;   }
setAnchor(Anchor a)191       void setAnchor(Anchor a) { _anchor = a;      }
192 
spannerSegments()193       const std::vector<SpannerSegment*>& spannerSegments() { return segments; }
frontSegment()194       SpannerSegment* frontSegment()               { return segments.front(); }
frontSegment()195       const SpannerSegment* frontSegment() const   { return segments.front(); }
backSegment()196       SpannerSegment* backSegment()                { return segments.back();  }
backSegment()197       const SpannerSegment* backSegment() const    { return segments.back();  }
segmentAt(int n)198       SpannerSegment* segmentAt(int n)             { return segments[n];      }
segmentAt(int n)199       const SpannerSegment* segmentAt(int n) const { return segments[n];      }
nsegments()200       size_t nsegments() const                     { return segments.size();  }
segmentsEmpty()201       bool segmentsEmpty() const                   { return segments.empty(); }
202       void eraseSpannerSegments();
203 
204       virtual SpannerSegment* layoutSystem(System*);
205       virtual void layoutSystemsDone();
206 
207       virtual void triggerLayout() const override;
208       virtual void triggerLayoutAll() const override;
209       virtual void add(Element*) override;
210       virtual void remove(Element*) override;
211       virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;
212       bool removeSpannerBack();
213       virtual void removeUnmanaged();
214       virtual void insertTimeUnmanaged(const Fraction& tick, const Fraction& len);
215 
216       QVariant getProperty(Pid propertyId) const;
217       bool setProperty(Pid propertyId, const QVariant& v);
218       QVariant propertyDefault(Pid propertyId) const;
219       virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps) override;
220 
221       void computeStartElement();
222       void computeEndElement();
223       static Note* endElementFromSpanner(Spanner* sp, Element* newStart);
224       static Note* startElementFromSpanner(Spanner* sp, Element* newEnd);
225       void setNoteSpan(Note* startNote, Note* endNote);
226 
startElement()227       Element* startElement() const    { return _startElement; }
endElement()228       Element* endElement() const      { return _endElement;   }
229 
230       Measure* startMeasure() const;
231       Measure* endMeasure() const;
232 
233       void setStartElement(Element* e);
234       void setEndElement(Element* e);
235 
236       ChordRest* startCR();
237       ChordRest* endCR();
238 
239       Chord* startChord();
240       Chord* endChord();
241 
242       Segment* startSegment() const;
243       Segment* endSegment() const;
244 
245       virtual void setSelected(bool f) override;
246       virtual void setVisible(bool f) override;
247       virtual void setAutoplace(bool f) override;
248       virtual void setColor(const QColor& col) override;
249       Spanner* nextSpanner(Element* e, int activeStaff);
250       Spanner* prevSpanner(Element* e, int activeStaff);
251       virtual Element* nextSegmentElement() override;
252       virtual Element* prevSegmentElement() override;
253 
254       friend class SpannerSegment;
255       using ScoreElement::undoChangeProperty;
256       };
257 
258 }     // namespace Ms
259 #endif
260