1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2012 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 __BEAM_H__
14 #define __BEAM_H__
15 
16 #include "element.h"
17 #include "durationtype.h"
18 #include "property.h"
19 
20 namespace Ms {
21 
22 class ChordRest;
23 class MuseScoreView;
24 class Chord;
25 class System;
26 class Skyline;
27 
28 enum class IconType : signed char;
29 enum class SpannerSegmentType;
30 
31 struct BeamFragment;
32 
33 //---------------------------------------------------------
34 //   @@ Beam
35 //---------------------------------------------------------
36 
37 class Beam final : public Element {
38       Q_GADGET
39       QVector<ChordRest*> _elements;        // must be sorted by tick
40       QVector<QLineF*> beamSegments;
41       Direction _direction;
42 
43       bool _up;
44       bool _distribute;                   // equal spacing of elements
45       bool _noSlope;
46 
47       bool _userModified[2];              // 0: auto/down  1: up
48       bool _isGrace;
49       bool _cross;
50 
51       qreal _grow1;                       // define "feather" beams
52       qreal _grow2;
53       qreal _beamDist;
54 
55       QVector<BeamFragment*> fragments;     // beam splits across systems
56 
57       mutable int _id;          // used in read()/write()
58 
59       int minMove;              // set in layout1()
60       int maxMove;
61       TDuration maxDuration;
62       qreal slope { 0.0 };
63 
64       void layout2(std::vector<ChordRest*>, SpannerSegmentType, int frag);
65       bool twoBeamedNotes();
66       void computeStemLen(const std::vector<ChordRest*>& crl, qreal& py1, int beamLevels);
67       bool slopeZero(const std::vector<ChordRest*>& crl);
68       bool hasNoSlope();
69       void addChordRest(ChordRest* a);
70       void removeChordRest(ChordRest* a);
71 
72    public:
73       enum class Mode : signed char {
74             ///.\{
75             AUTO, BEGIN, MID, END, NONE, BEGIN32, BEGIN64, INVALID = -1
76             ///\}
77             };
78       Q_ENUM(Mode);
79 
80       Beam(Score* = 0);
81       Beam(const Beam&);
82       ~Beam();
clone()83       Beam* clone() const override         { return new Beam(*this); }
type()84       ElementType type() const override    { return ElementType::BEAM; }
85       QPointF pagePos() const override;    ///< position in page coordinates
86       QPointF canvasPos() const override;  ///< position in page coordinates
87 
isEditable()88       bool isEditable() const override { return true; }
89       void startEdit(EditData&) override;
90       void endEdit(EditData&) override;
91       void editDrag(EditData&) override;
92 
93       Fraction tick() const override;
94       Fraction rtick() const override;
95       Fraction ticks() const;
96 
97       void write(XmlWriter& xml) const override;
98       void read(XmlReader&) override;
99       void spatiumChanged(qreal /*oldValue*/, qreal /*newValue*/) override;
100 
101       void reset() override;
102 
system()103       System* system() const { return toSystem(parent()); }
104 
105       void layout1();
106       void layoutGraceNotes();
107       void layout();
108 
elements()109       const QVector<ChordRest*>& elements() { return _elements;  }
clear()110       void clear()                        { _elements.clear(); }
empty()111       bool empty() const                { return _elements.empty(); }
contains(const ChordRest * cr)112       bool contains(const ChordRest* cr) const { return std::find(_elements.begin(), _elements.end(), cr) != _elements.end(); }
113 
114       void add(Element*) override;
115       void remove(Element*) override;
116 
117       void move(const QPointF&) override;
118       void draw(QPainter*) const override;
119 
up()120       bool up() const                     { return _up; }
setUp(bool v)121       void setUp(bool v)                  { _up = v;    }
setId(int i)122       void setId(int i) const             { _id = i;    }
id()123       int id() const                      { return _id; }
noSlope()124       bool noSlope() const                { return _noSlope; }
setNoSlope(bool val)125       void setNoSlope(bool val)           { _noSlope = val; }
126 
127       void setBeamDirection(Direction d);
beamDirection()128       Direction beamDirection() const     { return _direction; }
129 
130       bool acceptDrop(EditData&) const override;
131       Element* drop(EditData&) override;
132 
growLeft()133       qreal growLeft() const              { return _grow1; }
growRight()134       qreal growRight() const             { return _grow2; }
setGrowLeft(qreal val)135       void setGrowLeft(qreal val)         { _grow1 = val;  }
setGrowRight(qreal val)136       void setGrowRight(qreal val)        { _grow2 = val;  }
137 
distribute()138       bool distribute() const             { return _distribute; }
setDistribute(bool val)139       void setDistribute(bool val)        { _distribute = val;  }
140 
141       bool userModified() const;
142       void setUserModified(bool val);
143 
144       QPointF beamPos() const;
145       void setBeamPos(const QPointF& bp);
146 
beamDist()147       qreal beamDist() const              { return _beamDist; }
148 
149       QVariant getProperty(Pid propertyId) const override;
150       bool setProperty(Pid propertyId, const QVariant&) override;
151       QVariant propertyDefault(Pid id) const override;
152 
isGrace()153       bool isGrace() const { return _isGrace; }  // for debugger
cross()154       bool cross() const   { return _cross; }
155 
156       void addSkyline(Skyline&);
157 
158       void triggerLayout() const override;
159 
normalModeEditBehavior()160       EditBehavior normalModeEditBehavior() const override { return EditBehavior::Edit; }
gripsCount()161       int gripsCount() const override { return 3; }
initialEditModeGrip()162       Grip initialEditModeGrip() const override { return Grip::END; }
defaultGrip()163       Grip defaultGrip() const override { return Grip::MIDDLE; }
164       std::vector<QPointF> gripsPositions(const EditData&) const override;
165 
166       static IconType iconType(Mode);
167 
168       QRectF drag(EditData &) override;
169       bool isMovable() const override;
170       void startDrag(EditData &) override;
171 
172     private:
173       void initBeamEditData(EditData &ed);
174       };
175 
176 
177 }     // namespace Ms
178 #endif
179