//============================================================================= // MuseScore // Music Composition & Notation // // Copyright (C) 2016 Werner Schweer // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 // as published by the Free Software Foundation and appearing in // the file LICENCE.GPL //============================================================================= #ifndef __SLURTIE_H__ #define __SLURTIE_H__ #include "spanner.h" #include "mscore.h" namespace Ms { //--------------------------------------------------------- // SlurPos //--------------------------------------------------------- struct SlurPos { QPointF p1; // start point of slur System* system1; // start system of slur QPointF p2; // end point of slur System* system2; // end system of slur }; struct SlurOffsets { QPointF o[4]; }; //--------------------------------------------------------- // UP //--------------------------------------------------------- struct UP { QPointF p; // layout position relative to pos() QPointF off; // user offset in point units QPointF pos() const { return p + off; } bool operator!=(const UP& up) const { return p != up.p || off != up.off; } }; //--------------------------------------------------------- // CubicBezier // Helper class to optimize cubic Bezier curve points // calculation. //--------------------------------------------------------- class CubicBezier { QPointF p1; QPointF p2; QPointF p3; QPointF p4; public: CubicBezier(QPointF _p1, QPointF _p2, QPointF _p3, QPointF _p4) : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {} QPointF pointAtPercent(qreal t) const { Q_ASSERT(t >= 0.0 && t <= 1.0); const qreal r = 1.0 - t; const QPointF B123 = r * (r*p1 + t*p2) + t * (r*p2 + t*p3); const QPointF B234 = r * (r*p2 + t*p3) + t * (r*p3 + t*p4); return r*B123 + t*B234; } }; class SlurTie; //--------------------------------------------------------- // SlurTieSegment //--------------------------------------------------------- class SlurTieSegment : public SpannerSegment { protected: struct UP _ups[int(Grip::GRIPS)]; QPainterPath path; QPainterPath shapePath; Shape _shape; virtual void changeAnchor(EditData&, Element*) = 0; virtual QPointF gripAnchor(Grip grip) const override; public: SlurTieSegment(Score*); SlurTieSegment(const SlurTieSegment&); virtual void spatiumChanged(qreal, qreal) override; SlurTie* slurTie() const { return (SlurTie*)spanner(); } virtual void startEdit(EditData&) override; virtual void endEdit(EditData&) override; virtual void startEditDrag(EditData& ed) override; virtual void endEditDrag(EditData& ed) override; virtual void editDrag(EditData&) override; virtual QVariant getProperty(Pid propertyId) const override; virtual bool setProperty(Pid propertyId, const QVariant&) override; virtual QVariant propertyDefault(Pid id) const override; virtual void reset() override; virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps) override; virtual void move(const QPointF& s) override; virtual bool isEditable() const override { return true; } void setSlurOffset(Grip i, const QPointF& val) { _ups[int(i)].off = val; } const struct UP& ups(Grip i) const { return _ups[int(i)]; } struct UP& ups(Grip i) { return _ups[int(i)]; } virtual Shape shape() const override { return _shape; } void writeSlur(XmlWriter& xml, int no) const; void read(XmlReader&); virtual void drawEditMode(QPainter*, EditData&) override; virtual void computeBezier(QPointF so = QPointF()) = 0; }; //------------------------------------------------------------------- // @@ SlurTie // @P lineType int (0 - solid, 1 - dotted, 2 - dashed, 3 - wide dashed) // @P slurDirection enum (Direction.AUTO, Direction.DOWN, Direction.UP) //------------------------------------------------------------------- class SlurTie : public Spanner { int _lineType; // 0 = solid, 1 = dotted, 2 = dashed, 3 = wide dashed static Element* editStartElement; static Element* editEndElement; static QList editUps; protected: bool _up; // actual direction Direction _slurDirection; qreal firstNoteRestSegmentX(System* system); void fixupSegments(unsigned nsegs); public: SlurTie(Score*); SlurTie(const SlurTie&); ~SlurTie(); virtual ElementType type() const = 0; bool up() const { return _up; } virtual void reset() override; Direction slurDirection() const { return _slurDirection; } void setSlurDirection(Direction d) { _slurDirection = d; } void undoSetSlurDirection(Direction d); virtual void layout2(const QPointF, int, struct UP&) {} virtual bool contains(const QPointF&) const { return false; } // not selectable virtual void read(XmlReader&) override; void writeProperties(XmlWriter& xml) const; bool readProperties(XmlReader&); int lineType() const { return _lineType; } void setLineType(int val) { _lineType = val; } void undoSetLineType(int); virtual void slurPos(SlurPos*) = 0; virtual SlurTieSegment* newSlurTieSegment() = 0; virtual QVariant getProperty(Pid propertyId) const override; virtual bool setProperty(Pid propertyId, const QVariant&) override; virtual QVariant propertyDefault(Pid id) const override; }; } #endif