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