1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2002-2017 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 __ELEMENT_H__ 14 #define __ELEMENT_H__ 15 16 #include "elementgroup.h" 17 #include "spatium.h" 18 #include "fraction.h" 19 #include "scoreElement.h" 20 #include "shape.h" 21 #include "sig.h" 22 #include "sym.h" 23 24 namespace Ms { 25 26 #ifdef Q_OS_MAC 27 #define CONTROL_MODIFIER Qt::AltModifier 28 #else 29 #define CONTROL_MODIFIER Qt::ControlModifier 30 #endif 31 32 #ifndef VOICES 33 #define VOICES 4 34 #endif 35 36 class XmlReader; 37 class XmlWriter; 38 enum class Pid; 39 class StaffType; 40 41 //--------------------------------------------------------- 42 // Grip 43 //--------------------------------------------------------- 44 45 enum class Grip { 46 NO_GRIP = -1, 47 START = 0, END = 1, // arpeggio etc. 48 MIDDLE = 2, APERTURE = 3, // Line 49 /*START, END , */ 50 BEZIER1 = 2, SHOULDER = 3, BEZIER2 = 4, DRAG = 5, // Slur 51 GRIPS = 6 // number of grips for slur 52 }; 53 54 //--------------------------------------------------------- 55 // OffsetChange 56 //--------------------------------------------------------- 57 58 enum class OffsetChange { 59 RELATIVE_OFFSET = -1, 60 NONE = 0, 61 ABSOLUTE_OFFSET = 1 62 }; 63 64 //--------------------------------------------------------- 65 // ElementFlag 66 //--------------------------------------------------------- 67 68 enum class ElementFlag { 69 NOTHING = 0x00000000, 70 DROP_TARGET = 0x00000001, 71 NOT_SELECTABLE = 0x00000002, 72 MOVABLE = 0x00000004, 73 COMPOSITION = 0x00000008, // true if element is part of another element 74 HAS_TAG = 0x00000010, // true if this is a layered element 75 ON_STAFF = 0x00000020, 76 SELECTED = 0x00000040, 77 GENERATED = 0x00000080, 78 INVISIBLE = 0x00000100, 79 NO_AUTOPLACE = 0x00000200, 80 SYSTEM = 0x00000400, 81 PLACE_ABOVE = 0x00000800, 82 SIZE_SPATIUM_DEPENDENT = 0x00001000, 83 84 // measure flags 85 REPEAT_END = 0x00002000, 86 REPEAT_START = 0x00004000, 87 REPEAT_JUMP = 0x00008000, 88 IRREGULAR = 0x00010000, 89 LINE_BREAK = 0x00020000, 90 PAGE_BREAK = 0x00040000, 91 SECTION_BREAK = 0x00080000, 92 NO_BREAK = 0x00100000, 93 HEADER = 0x00200000, 94 TRAILER = 0x00400000, // also used in segment 95 KEYSIG = 0x00800000, 96 97 // segment flags 98 ENABLED = 0x01000000, // used for segments 99 EMPTY = 0x02000000, 100 WRITTEN = 0x04000000, 101 }; 102 103 typedef QFlags<ElementFlag> ElementFlags; 104 Q_DECLARE_OPERATORS_FOR_FLAGS(ElementFlags); 105 106 class ElementEditData; 107 108 //--------------------------------------------------------- 109 // EditData 110 // used in editDrag 111 //--------------------------------------------------------- 112 113 class EditData { 114 QList<ElementEditData*> data; 115 116 public: 117 MuseScoreView* view { 0 }; 118 119 QVector<QRectF> grip; 120 int grips { 0 }; // number of grips 121 Grip curGrip { Grip(0) }; 122 123 QPointF pos; 124 QPointF startMove; 125 QPointF normalizedStartMove; ///< Introduced for transition of drag logic. Don't use in new code. 126 QPoint startMovePixel; 127 QPointF lastPos; 128 QPointF delta; ///< This property is deprecated, use evtDelta or moveDelta instead. In normal drag equals to moveDelta, in edit drag - to evtDelta 129 QPointF evtDelta; ///< Mouse offset for the last mouse move event 130 QPointF moveDelta; ///< Mouse offset from the start of mouse move 131 bool hRaster { false }; 132 bool vRaster { false }; 133 134 int key { 0 }; 135 Qt::KeyboardModifiers modifiers { /*0*/ }; // '0' initialized via default constructor, doing it here too results in compiler warning with Qt 5.15 136 QString s; 137 138 Qt::MouseButtons buttons { Qt::NoButton }; 139 140 // drop data: 141 QPointF dragOffset; 142 Element* element { 0 }; 143 Element* dropElement { 0 }; 144 view(v)145 EditData(MuseScoreView* v = nullptr) : view(v) {} 146 void clearData(); 147 148 ElementEditData* getData(const Element*) const; 149 void addData(ElementEditData*); 150 bool control(bool textEditing = false) const; shift()151 bool shift() const { return modifiers & Qt::ShiftModifier; } isStartEndGrip()152 bool isStartEndGrip() { return curGrip == Grip::START || curGrip == Grip::END; } 153 }; 154 155 //------------------------------------------------------------------- 156 // @@ Element 157 /// \brief Base class of score layout elements 158 /// 159 /// The Element class is the virtual base class of all 160 /// score layout elements. 161 //------------------------------------------------------------------- 162 163 class Element : public ScoreElement { 164 Element* _parent { 0 }; 165 mutable QRectF _bbox; ///< Bounding box relative to _pos + _offset 166 qreal _mag; ///< standard magnification (derived value) 167 QPointF _pos; ///< Reference position, relative to _parent, set by autoplace 168 QPointF _offset; ///< offset from reference position, set by autoplace or user 169 OffsetChange _offsetChanged; ///< set by user actions that change offset, used by autoplace 170 QPointF _changedPos; ///< position set when changing offset 171 Spatium _minDistance; ///< autoplace min distance 172 int _track; ///< staffIdx * VOICES + voice 173 mutable ElementFlags _flags; 174 ///< valid after call to layout() 175 uint _tag; ///< tag bitmask 176 177 public: 178 enum class EditBehavior { 179 SelectOnly, 180 Edit, 181 }; 182 183 protected: 184 mutable int _z; 185 QColor _color; ///< element color attribute 186 187 public: 188 Element(Score* = 0, ElementFlags = ElementFlag::NOTHING); 189 Element(const Element&); 190 virtual ~Element(); 191 192 Element &operator=(const Element&) = delete; 193 //@ create a copy of the element 194 Q_INVOKABLE virtual Ms::Element* clone() const = 0; 195 virtual Element* linkedClone(); 196 197 void deleteLater(); 198 parent()199 Element* parent() const { return _parent; } setParent(Element * e)200 void setParent(Element* e) { _parent = e; } 201 202 Element* findAncestor(ElementType t); 203 const Element* findAncestor(ElementType t) const; 204 205 Measure* findMeasure(); 206 const Measure* findMeasure() const; 207 MeasureBase* findMeasureBase(); 208 const MeasureBase* findMeasureBase() const; 209 isElement()210 virtual bool isElement() const override { return true; } 211 212 qreal spatium() const; 213 setFlag(ElementFlag f,bool v)214 inline void setFlag(ElementFlag f, bool v) { if (v) _flags |= f; else _flags &= ~ElementFlags(f); } setFlag(ElementFlag f,bool v)215 inline void setFlag(ElementFlag f, bool v) const { if (v) _flags |= f; else _flags &= ~ElementFlags(f); } flag(ElementFlag f)216 inline bool flag(ElementFlag f) const { return _flags & f; } 217 selected()218 bool selected() const { return flag(ElementFlag::SELECTED); } setSelected(bool f)219 virtual void setSelected(bool f) { setFlag(ElementFlag::SELECTED, f); } 220 visible()221 bool visible() const { return !flag(ElementFlag::INVISIBLE); } setVisible(bool f)222 virtual void setVisible(bool f) { setFlag(ElementFlag::INVISIBLE, !f); } 223 sizeIsSpatiumDependent()224 virtual bool sizeIsSpatiumDependent() const override { return !flag(ElementFlag::SIZE_SPATIUM_DEPENDENT); } setSizeIsSpatiumDependent(bool v)225 void setSizeIsSpatiumDependent(bool v) { setFlag(ElementFlag::SIZE_SPATIUM_DEPENDENT, !v); } 226 virtual bool offsetIsSpatiumDependent() const override; 227 placement()228 Placement placement() const { return Placement(!flag(ElementFlag::PLACE_ABOVE)); } setPlacement(Placement val)229 void setPlacement(Placement val) { setFlag(ElementFlag::PLACE_ABOVE, !bool(val)); } placeAbove()230 bool placeAbove() const { return placement() == Placement::ABOVE; } placeBelow()231 bool placeBelow() const { return placement() == Placement::BELOW; } placeMultiple()232 virtual bool placeMultiple() const { return true; } 233 generated()234 bool generated() const { return flag(ElementFlag::GENERATED); } setGenerated(bool val)235 void setGenerated(bool val) { setFlag(ElementFlag::GENERATED, val); } 236 minDistance()237 Spatium minDistance() const { return _minDistance; } setMinDistance(Spatium v)238 void setMinDistance(Spatium v) { _minDistance = v; } offsetChanged()239 OffsetChange offsetChanged() const { return _offsetChanged; } 240 void setOffsetChanged(bool v, bool absolute = true, const QPointF& diff = QPointF()); 241 ipos()242 const QPointF& ipos() const { return _pos; } pos()243 virtual const QPointF pos() const { return _pos + _offset; } x()244 virtual qreal x() const { return _pos.x() + _offset.x(); } y()245 virtual qreal y() const { return _pos.y() + _offset.y(); } setPos(qreal x,qreal y)246 void setPos(qreal x, qreal y) { _pos.rx() = x, _pos.ry() = y; } setPos(const QPointF & p)247 void setPos(const QPointF& p) { _pos = p; } rpos()248 QPointF& rpos() { return _pos; } rxpos()249 qreal& rxpos() { return _pos.rx(); } rypos()250 qreal& rypos() { return _pos.ry(); } move(const QPointF & s)251 virtual void move(const QPointF& s) { _pos += s; } 252 253 virtual QPointF pagePos() const; ///< position in page coordinates 254 virtual QPointF canvasPos() const; ///< position in canvas coordinates 255 qreal pageX() const; 256 qreal canvasX() const; 257 mapFromCanvas(const QPointF & p)258 QPointF mapFromCanvas(const QPointF& p) const { return p - canvasPos(); } mapToCanvas(const QPointF & p)259 QPointF mapToCanvas(const QPointF& p) const { return p + canvasPos(); } 260 offset()261 const QPointF& offset() const { return _offset; } setOffset(const QPointF & o)262 virtual void setOffset(const QPointF& o) { _offset = o; } setOffset(qreal x,qreal y)263 void setOffset(qreal x, qreal y) { _offset.rx() = x, _offset.ry() = y; } roffset()264 QPointF& roffset() { return _offset; } rxoffset()265 qreal& rxoffset() { return _offset.rx(); } ryoffset()266 qreal& ryoffset() { return _offset.ry(); } 267 268 virtual Fraction tick() const; 269 virtual Fraction rtick() const; 270 virtual Fraction playTick() const; ///< Returns the tick at which playback should begin when this element is selected. Defaults to the element's own tick position. 271 272 Fraction beat() const; 273 isNudged()274 bool isNudged() const { return !_offset.isNull(); } 275 bbox()276 virtual const QRectF& bbox() const { return _bbox; } bbox()277 virtual QRectF& bbox() { return _bbox; } height()278 virtual qreal height() const { return bbox().height(); } setHeight(qreal v)279 virtual void setHeight(qreal v) { _bbox.setHeight(v); } width()280 virtual qreal width() const { return bbox().width(); } setWidth(qreal v)281 virtual void setWidth(qreal v) { _bbox.setWidth(v); } abbox()282 QRectF abbox() const { return bbox().translated(pagePos()); } pageBoundingRect()283 QRectF pageBoundingRect() const { return bbox().translated(pagePos()); } canvasBoundingRect()284 QRectF canvasBoundingRect() const { return bbox().translated(canvasPos()); } setbbox(const QRectF & r)285 virtual void setbbox(const QRectF& r) const { _bbox = r; } addbbox(const QRectF & r)286 virtual void addbbox(const QRectF& r) const { _bbox |= r; } 287 bool contains(const QPointF& p) const; 288 bool intersects(const QRectF& r) const; 289 #ifndef NDEBUG shape()290 virtual Shape shape() const { return Shape(bbox(), name()); } 291 #else shape()292 virtual Shape shape() const { return Shape(bbox()); } 293 #endif baseLine()294 virtual qreal baseLine() const { return -height(); } 295 subtype()296 virtual int subtype() const { return -1; } // for select gui 297 draw(QPainter *)298 virtual void draw(QPainter*) const {} drawAt(QPainter * p,const QPointF & pt)299 void drawAt(QPainter*p, const QPointF& pt) const { p->translate(pt); draw(p); p->translate(-pt);} 300 301 virtual void writeProperties(XmlWriter& xml) const; 302 virtual bool readProperties(XmlReader&); 303 304 virtual void write(XmlWriter&) const; 305 virtual void read(XmlReader&); 306 307 // virtual ElementGroup getElementGroup() { return SingleElementGroup(this); } getDragGroup(std::function<bool (const Element *)> isDragged)308 virtual std::unique_ptr<ElementGroup> getDragGroup(std::function<bool(const Element*)> isDragged) { Q_UNUSED(isDragged); return std::unique_ptr<ElementGroup>(new SingleElementGroup(this)); } 309 310 virtual void startDrag(EditData&); 311 virtual QRectF drag(EditData&); 312 virtual void endDrag(EditData&); 313 /** Returns anchor lines displayed while dragging element in canvas coordinates. */ dragAnchorLines()314 virtual QVector<QLineF> dragAnchorLines() const { return QVector<QLineF>(); } 315 /** 316 * A generic \ref dragAnchorLines() implementation which can be used in 317 * dragAnchorLines() overrides in descendants. It is not made its default 318 * implementation in Element class since showing anchor lines is not 319 * desirable for most element types. 320 * TODO: maybe Annotation class could be extracted which would be a base 321 * class of various annotation types and which would have this 322 * dragAnchorLines() implementation by default. 323 */ 324 QVector<QLineF> genericDragAnchorLines() const; 325 isEditable()326 virtual bool isEditable() const { return !flag(ElementFlag::GENERATED); } 327 328 virtual void startEdit(EditData&); 329 virtual bool edit(EditData&); 330 virtual void startEditDrag(EditData&); 331 virtual void editDrag(EditData&); 332 virtual void endEditDrag(EditData&); 333 virtual void endEdit(EditData&); 334 editCut(EditData &)335 virtual void editCut(EditData&) {} editCopy(EditData &)336 virtual void editCopy(EditData&) {} 337 338 void updateGrips(EditData&) const; 339 virtual bool nextGrip(EditData&) const; 340 virtual bool prevGrip(EditData&) const; 341 /** Returns anchor lines displayed while dragging element's grip in canvas coordinates. */ gripAnchorLines(Grip)342 virtual QVector<QLineF> gripAnchorLines(Grip) const { return QVector<QLineF>(); } 343 normalModeEditBehavior()344 virtual EditBehavior normalModeEditBehavior() const { return EditBehavior::SelectOnly; } gripsCount()345 virtual int gripsCount() const { return 0; } initialEditModeGrip()346 virtual Grip initialEditModeGrip() const { return Grip::NO_GRIP; } defaultGrip()347 virtual Grip defaultGrip() const { return Grip::NO_GRIP; } 348 /** Returns grips positions in page coordinates. */ 349 virtual std::vector<QPointF> gripsPositions(const EditData& = EditData()) const { return std::vector<QPointF>(); } 350 track()351 int track() const { return _track; } setTrack(int val)352 virtual void setTrack(int val) { _track = val; } 353 354 int z() const; setZ(int val)355 void setZ(int val) { _z = val; } 356 staffIdx()357 int staffIdx() const { return _track >> 2; } vStaffIdx()358 virtual int vStaffIdx() const { return staffIdx(); } voice()359 int voice() const { return _track & 3; } setVoice(int v)360 void setVoice(int v) { _track = (_track / VOICES) * VOICES + v; } 361 Staff* staff() const; 362 const StaffType* staffType() const; 363 bool onTabStaff() const; 364 Part* part() const; 365 366 virtual void add(Element*); 367 virtual void remove(Element*); 368 virtual void change(Element* o, Element* n); 369 layout()370 virtual void layout() {} 371 virtual void spatiumChanged(qreal /*oldValue*/, qreal /*newValue*/); 372 virtual void localSpatiumChanged(qreal /*oldValue*/, qreal /*newValue*/); 373 374 // debug functions 375 virtual void dump() const; 376 virtual Q_INVOKABLE QString subtypeName() const; 377 //@ Returns the human-readable name of the element type 378 //@ Returns the name of the element type _name()379 virtual Q_INVOKABLE QString _name() const { return QString(name()); } 380 color()381 virtual QColor color() const { return _color; } 382 QColor curColor() const; 383 QColor curColor(bool isVisible) const; 384 QColor curColor(bool isVisible, QColor normalColor) const; setColor(const QColor & c)385 virtual void setColor(const QColor& c) { _color = c; } 386 void undoSetColor(const QColor& c); 387 void undoSetVisible(bool v); 388 389 static ElementType readType(XmlReader& node, QPointF*, Fraction*); 390 static Element* readMimeData(Score* score, const QByteArray& data, QPointF*, Fraction*); 391 392 virtual QByteArray mimeData(const QPointF&) const; 393 /** 394 Return true if this element accepts a drop at canvas relative \a pos 395 of given element \a type and \a subtype. 396 397 Reimplemented by elements that accept drops. Used to change cursor shape while 398 dragging to indicate drop targets. 399 */ acceptDrop(EditData &)400 virtual bool acceptDrop(EditData&) const { return false; } 401 402 /** 403 Handle a dropped element at canvas relative \a pos of given element 404 \a type and \a subtype. Returns dropped element if any. 405 The ownership of element in DropData is transferred to the called 406 element (if not used, element has to be deleted). 407 The returned element will be selected if not in note edit mode. 408 409 Reimplemented by elements that accept drops. 410 */ drop(EditData &)411 virtual Element* drop(EditData&) { return 0;} 412 413 /** 414 delivers mouseEvent to element in edit mode 415 returns true if mouse event is accepted by element 416 */ mousePress(EditData &)417 virtual bool mousePress(EditData&) { return false; } 418 419 mutable bool itemDiscovered { false }; ///< helper flag for bsp 420 421 virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true); 422 423 virtual void reset() override; // reset all properties & position to default 424 mag()425 virtual qreal mag() const { return _mag; } setMag(qreal val)426 void setMag(qreal val) { _mag = val; } 427 qreal magS() const; 428 429 bool isPrintable() const; point(const Spatium sp)430 qreal point(const Spatium sp) const { return sp.val() * spatium(); } 431 432 static Ms::Element* create(Ms::ElementType type, Score*); 433 static Element* name2Element(const QStringRef&, Score*); 434 systemFlag()435 bool systemFlag() const { return flag(ElementFlag::SYSTEM); } setSystemFlag(bool v)436 void setSystemFlag(bool v) const { setFlag(ElementFlag::SYSTEM, v); } 437 header()438 bool header() const { return flag(ElementFlag::HEADER); } setHeader(bool v)439 void setHeader(bool v) { setFlag(ElementFlag::HEADER, v); } 440 trailer()441 bool trailer() const { return flag(ElementFlag::TRAILER); } setTrailer(bool val)442 void setTrailer(bool val) { setFlag(ElementFlag::TRAILER, val); } 443 selectable()444 bool selectable() const { return !flag(ElementFlag::NOT_SELECTABLE); } setSelectable(bool val)445 void setSelectable(bool val) { setFlag(ElementFlag::NOT_SELECTABLE, !val); } 446 dropTarget()447 bool dropTarget() const { return flag(ElementFlag::DROP_TARGET); } setDropTarget(bool v)448 void setDropTarget(bool v) const { setFlag(ElementFlag::DROP_TARGET, v); } 449 composition()450 bool composition() const { return flag(ElementFlag::COMPOSITION); } setComposition(bool v)451 void setComposition(bool v) const { setFlag(ElementFlag::COMPOSITION, v); } 452 isMovable()453 virtual bool isMovable() const { return flag(ElementFlag::MOVABLE); } 454 enabled()455 bool enabled() const { return flag(ElementFlag::ENABLED); } setEnabled(bool val)456 void setEnabled(bool val) { setFlag(ElementFlag::ENABLED, val); } 457 tag()458 uint tag() const { return _tag; } setTag(uint val)459 void setTag(uint val) { _tag = val; } 460 461 bool autoplace() const; setAutoplace(bool v)462 virtual void setAutoplace(bool v) { setFlag(ElementFlag::NO_AUTOPLACE, !v); } addToSkyline()463 bool addToSkyline() const { return !(_flags & (ElementFlag::INVISIBLE|ElementFlag::NO_AUTOPLACE)); } 464 465 virtual QVariant getProperty(Pid) const override; 466 virtual bool setProperty(Pid, const QVariant&) override; 467 virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps) override; 468 using ScoreElement::undoChangeProperty; 469 virtual QVariant propertyDefault(Pid) const override; 470 virtual Pid propertyId(const QStringRef& xmlName) const override; propertyUserValue(Pid)471 virtual QString propertyUserValue(Pid) const override; 472 virtual Element* propertyDelegate(Pid) { return 0; } // return Spanner for SpannerSegment for some properties 473 474 bool custom(Pid) const; 475 virtual bool isUserModified() const; 476 477 void drawSymbol(SymId id, QPainter* p, const QPointF& o = QPointF(), qreal scale = 1.0) const; 478 void drawSymbol(SymId id, QPainter* p, const QPointF& o, int n) const; 479 void drawSymbols(const std::vector<SymId>&, QPainter* p, const QPointF& o = QPointF(), qreal scale = 1.0) const; 480 void drawSymbols(const std::vector<SymId>&, QPainter* p, const QPointF& o, const QSizeF& scale) const; 481 qreal symHeight(SymId id) const; 482 qreal symWidth(SymId id) const; 483 qreal symWidth(const std::vector<SymId>&) const; 484 QRectF symBbox(SymId id) const; 485 QRectF symBbox(const std::vector<SymId>&) const; 486 QPointF symStemDownNW(SymId id) const; 487 QPointF symStemUpSE(SymId id) const; 488 QPointF symStemDownSW(SymId id) const; 489 QPointF symStemUpNW(SymId id) const; 490 QPointF symCutOutNE(SymId id) const; 491 QPointF symCutOutNW(SymId id) const; 492 QPointF symCutOutSE(SymId id) const; 493 QPointF symCutOutSW(SymId id) const; 494 qreal symAdvance(SymId id) const; 495 bool symIsValid(SymId id) const; 496 497 bool concertPitch() const; 498 virtual Element* nextElement(); // selects the next score element, (notes, rests etc. as well as articulation etc.) 499 virtual Element* prevElement(); // selects the next score element, (notes, rests etc. as well as articulation etc.) 500 virtual Element* nextSegmentElement(); //< Used for navigation 501 virtual Element* prevSegmentElement(); //< next-element and prev-element command 502 503 virtual QString accessibleInfo() const; //< used to populate the status bar screenReaderInfo()504 virtual QString screenReaderInfo() const { //< by default returns accessibleInfo, but can be overridden 505 return accessibleInfo(); 506 } 507 // if the screen-reader needs a special string (see note for example) accessibleExtraInfo()508 virtual QString accessibleExtraInfo() const { // used to return info that will be appended to accessibleInfo 509 return QString(); // and passed only to the screen-reader 510 } 511 512 virtual void triggerLayout() const; 513 virtual void triggerLayoutAll() const; 514 virtual void drawEditMode(QPainter*, EditData&); 515 516 void autoplaceSegmentElement(bool above, bool add); // helper functions 517 void autoplaceMeasureElement(bool above, bool add); 518 void autoplaceSegmentElement(bool add = true) { autoplaceSegmentElement(placeAbove(), add); } 519 void autoplaceMeasureElement(bool add = true) { autoplaceMeasureElement(placeAbove(), add); } 520 void autoplaceCalculateOffset(QRectF& r, qreal minDistance); 521 qreal rebaseOffset(bool nox = true); 522 bool rebaseMinDistance(qreal& md, qreal& yd, qreal sp, qreal rebase, bool above, bool fix); 523 524 qreal styleP(Sid idx) const; 525 }; 526 527 //----------------------------------------------------------------------------- 528 // ElementEditData 529 // holds element specific data during element editing: 530 // 531 // startEditDrag(EditData&) creates data and attaches it to EditData 532 // editDrag(EditData&) 533 // endEditDrag(EditData&) use data to create undo records 534 //----------------------------------------------------------------------------- 535 536 enum class EditDataType : signed char { 537 ElementEditData, 538 TextEditData, 539 BarLineEditData, 540 BeamEditData, 541 NoteEditData, 542 }; 543 544 struct PropertyData { 545 Pid id; 546 QVariant data; 547 PropertyFlags f; 548 }; 549 550 class ElementEditData { 551 public: 552 Element* e; 553 QList<PropertyData> propertyData; 554 QPointF initOffset; ///< for dragging: difference between actual offset and editData.moveDelta 555 556 virtual ~ElementEditData() = default; pushProperty(Pid pid)557 void pushProperty(Pid pid) { propertyData.push_back(PropertyData({ pid, e->getProperty(pid), e->propertyFlags(pid) })); } type()558 virtual EditDataType type() { return EditDataType::ElementEditData; } 559 }; 560 561 //--------------------------------------------------------- 562 // ElementList 563 //--------------------------------------------------------- 564 565 class ElementList : public std::vector<Element*> { 566 public: ElementList()567 ElementList() {} 568 bool remove(Element*); 569 void replace(Element* old, Element* n); 570 void write(XmlWriter&) const; 571 void write(XmlWriter&, const char* name) const; 572 }; 573 574 //--------------------------------------------------------- 575 // @@ Compound 576 //--------------------------------------------------------- 577 578 class Compound : public Element { 579 QList<Element*> elements; 580 581 protected: getElements()582 const QList<Element*>& getElements() const { return elements; } 583 584 public: 585 Compound(Score*); 586 Compound(const Compound&); 587 virtual ElementType type() const = 0; 588 589 virtual void draw(QPainter*) const; 590 virtual void addElement(Element*, qreal x, qreal y); 591 void clear(); 592 virtual void setSelected(bool f); 593 virtual void setVisible(bool); 594 virtual void layout(); 595 }; 596 597 extern bool elementLessThan(const Element* const, const Element* const); 598 extern void collectElements(void* data, Element* e); 599 600 601 } // namespace Ms 602 603 Q_DECLARE_METATYPE(Ms::ElementType); 604 605 #endif 606 607