1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2016 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 __SLURTIE_H__
14 #define __SLURTIE_H__
15 
16 #include "spanner.h"
17 #include "mscore.h"
18 
19 namespace Ms {
20 
21 //---------------------------------------------------------
22 //   SlurPos
23 //---------------------------------------------------------
24 
25 struct SlurPos {
26       QPointF p1;             // start point of slur
27       System* system1;        // start system of slur
28       QPointF p2;             // end point of slur
29       System* system2;        // end system of slur
30       };
31 
32 struct SlurOffsets {
33       QPointF o[4];
34       };
35 
36 //---------------------------------------------------------
37 //   UP
38 //---------------------------------------------------------
39 
40 struct UP {
41       QPointF p;            // layout position relative to pos()
42       QPointF off;          // user offset in point units
43 
posUP44       QPointF pos() const { return p + off; }
45       bool operator!=(const UP& up) const { return p != up.p || off != up.off; }
46       };
47 
48 //---------------------------------------------------------
49 //   CubicBezier
50 //    Helper class to optimize cubic Bezier curve points
51 //    calculation.
52 //---------------------------------------------------------
53 
54 class CubicBezier {
55       QPointF p1;
56       QPointF p2;
57       QPointF p3;
58       QPointF p4;
59 
60    public:
CubicBezier(QPointF _p1,QPointF _p2,QPointF _p3,QPointF _p4)61       CubicBezier(QPointF _p1, QPointF _p2, QPointF _p3, QPointF _p4)
62          : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
63 
pointAtPercent(qreal t)64       QPointF pointAtPercent(qreal t) const
65             {
66             Q_ASSERT(t >= 0.0 && t <= 1.0);
67             const qreal r = 1.0 - t;
68             const QPointF B123 = r * (r*p1 + t*p2) + t * (r*p2 + t*p3);
69             const QPointF B234 = r * (r*p2 + t*p3) + t * (r*p3 + t*p4);
70             return r*B123 + t*B234;
71             }
72       };
73 
74 class SlurTie;
75 
76 //---------------------------------------------------------
77 //   SlurTieSegment
78 //---------------------------------------------------------
79 
80 class SlurTieSegment : public SpannerSegment {
81    protected:
82       struct UP _ups[int(Grip::GRIPS)];
83 
84       QPainterPath path;
85       QPainterPath shapePath;
86       Shape _shape;
87 
88       virtual void changeAnchor(EditData&, Element*) = 0;
89       QVector<QLineF> gripAnchorLines(Grip grip) const override;
90 
91    public:
92       SlurTieSegment(Score*);
93       SlurTieSegment(const SlurTieSegment&);
94       virtual void spatiumChanged(qreal, qreal) override;
slurTie()95       SlurTie* slurTie() const { return (SlurTie*)spanner(); }
96 
97       virtual void startEditDrag(EditData& ed) override;
98       virtual void endEditDrag(EditData& ed) override;
99       virtual void editDrag(EditData&) override;
100 
101       virtual QVariant getProperty(Pid propertyId) const override;
102       virtual bool setProperty(Pid propertyId, const QVariant&) override;
103       virtual QVariant propertyDefault(Pid id) const override;
104       virtual void reset() override;
105       virtual void undoChangeProperty(Pid id, const QVariant&, PropertyFlags ps) override;
106       virtual void move(const QPointF& s) override;
isEditable()107       virtual bool isEditable() const override { return true; }
108 
setSlurOffset(Grip i,const QPointF & val)109       void setSlurOffset(Grip i, const QPointF& val) { _ups[int(i)].off = val;  }
ups(Grip i)110       const struct UP& ups(Grip i) const             { return _ups[int(i)]; }
ups(Grip i)111       struct UP& ups(Grip i)                         { return _ups[int(i)]; }
shape()112       virtual Shape shape() const override           { return _shape; }
113 
normalModeEditBehavior()114       Element::EditBehavior normalModeEditBehavior() const override { return Element::EditBehavior::Edit; }
gripsCount()115       int gripsCount() const override { return int(Grip::GRIPS); }
initialEditModeGrip()116       Grip initialEditModeGrip() const override{ return Grip::END; }
defaultGrip()117       Grip defaultGrip() const override { return Grip::DRAG; }
118       std::vector<QPointF> gripsPositions(const EditData& = EditData()) const override;
119 
120       void writeSlur(XmlWriter& xml, int no) const;
121       void read(XmlReader&);
122       virtual void drawEditMode(QPainter*, EditData&) override;
123       virtual void computeBezier(QPointF so = QPointF()) = 0;
124       };
125 
126 //-------------------------------------------------------------------
127 //   @@ SlurTie
128 //   @P lineType       int  (0 - solid, 1 - dotted, 2 - dashed, 3 - wide dashed)
129 //   @P slurDirection  enum (Direction.AUTO, Direction.DOWN, Direction.UP)
130 //-------------------------------------------------------------------
131 
132 class SlurTie : public Spanner {
133       int _lineType;    // 0 = solid, 1 = dotted, 2 = dashed, 3 = wide dashed
134 
135    protected:
136       bool _up;               // actual direction
137 
138       Direction _slurDirection;
139       void fixupSegments(unsigned nsegs);
140 
141    public:
142       SlurTie(Score*);
143       SlurTie(const SlurTie&);
144       ~SlurTie();
145 
146       virtual ElementType type() const = 0;
up()147       bool up() const                             { return _up; }
148 
149       virtual void reset() override;
150 
slurDirection()151       Direction slurDirection() const     { return _slurDirection; }
setSlurDirection(Direction d)152       void setSlurDirection(Direction d)  { _slurDirection = d; }
153       void undoSetSlurDirection(Direction d);
154 
layout2(const QPointF,int,struct UP &)155       virtual void layout2(const QPointF, int, struct UP&)  {}
contains(const QPointF &)156       virtual bool contains(const QPointF&) const { return false; }  // not selectable
157 
158       virtual void read(XmlReader&) override;
159 
160       void writeProperties(XmlWriter& xml) const;
161       bool readProperties(XmlReader&);
162 
lineType()163       int lineType() const                { return _lineType; }
setLineType(int val)164       void setLineType(int val)           { _lineType = val;  }
165       void undoSetLineType(int);
166 
167       virtual void slurPos(SlurPos*) = 0;
168       virtual SlurTieSegment* newSlurTieSegment() = 0;
169 
170 
171       virtual QVariant getProperty(Pid propertyId) const override;
172       virtual bool setProperty(Pid propertyId, const QVariant&) override;
173       virtual QVariant propertyDefault(Pid id) const override;
174       };
175 
176 }
177 
178 #endif
179 
180