Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #ifndef MU_ENGRAVING_BEAMBASE_H
23 : #define MU_ENGRAVING_BEAMBASE_H
24 :
25 : #include "engravingitem.h"
26 :
27 : namespace mu::engraving {
28 : class Beam;
29 : class TremoloTwoChord;
30 :
31 : enum class BeamType : unsigned char {
32 : INVALID,
33 : BEAM,
34 : TREMOLO
35 : };
36 :
37 : //---------------------------------------------------------
38 : // BeamFragment
39 : // position of primary beam
40 : // idx 0 - DirectionV::AUTO or DirectionV::DOWN
41 : // 1 - DirectionV::UP
42 : //---------------------------------------------------------
43 :
44 : struct BeamFragment {
45 : double py1[2] = { 0.0, 0.0 };
46 : double py2[2] = { 0.0, 0.0 };
47 : };
48 :
49 : enum class ChordBeamAnchorType : unsigned char {
50 : Start, End, Middle
51 : };
52 :
53 : class BeamSegment
54 : {
55 26055 : OBJECT_ALLOCATOR(engraving, BeamSegment)
56 : public:
57 : LineF line;
58 : int level = 0;
59 : bool above = false; // above level 0 or below? (meaningless for level 0)
60 : Fraction startTick;
61 : Fraction endTick;
62 : bool isBeamlet = false;
63 : bool isBefore = false;
64 :
65 : Shape shape() const;
66 : EngravingItem* parentElement = nullptr;
67 :
68 : BeamSegment(EngravingItem* b);
69 : };
70 :
71 : class BeamBase : public EngravingItem
72 : {
73 0 : OBJECT_ALLOCATOR(engraving, BeamBase)
74 : DECLARE_CLASSOF(ElementType::INVALID) // dummy
75 :
76 4492 : M_PROPERTY2(int, crossStaffMove, setCrossStaffMove, 0)
77 :
78 : public:
79 :
80 : virtual int maxCRMove() const = 0;
81 : virtual int minCRMove() const = 0;
82 :
83 : virtual PropertyValue getProperty(Pid propertyId) const override;
84 : virtual bool setProperty(Pid propertyId, const PropertyValue&) override;
85 : virtual PropertyValue propertyDefault(Pid propertyId) const override;
86 :
87 : int crossStaffIdx() const;
88 : int defaultCrossStaffIdx() const;
89 : bool acceptCrossStaffMove(int move) const;
90 :
91 82909 : bool up() const { return m_up; }
92 5928 : void setUp(bool v) { m_up = v; }
93 :
94 : bool userModified() const;
95 : void setUserModified(bool val);
96 :
97 8237 : DirectionV direction() const { return m_direction; }
98 809 : void doSetDirection(DirectionV val) { m_direction = val; }
99 : virtual void setDirection(DirectionV v) = 0;
100 :
101 98490 : inline int directionIdx() const { return (m_direction == DirectionV::AUTO || m_direction == DirectionV::DOWN) ? 0 : 1; }
102 :
103 90 : const std::vector<BeamSegment*>& beamSegments() const { return m_beamSegments; }
104 25636 : std::vector<BeamSegment*>& beamSegments() { return m_beamSegments; }
105 : virtual void clearBeamSegments();
106 :
107 225 : const PointF& startAnchor() const { return m_startAnchor; }
108 58157 : PointF& startAnchor() { return m_startAnchor; }
109 18323 : void setStartAnchor(const PointF& p) { m_startAnchor = p; }
110 225 : const PointF& endAnchor() const { return m_endAnchor; }
111 9395 : PointF& endAnchor() { return m_endAnchor; }
112 18323 : void setEndAnchor(const PointF& p) { m_endAnchor = p; }
113 :
114 : void undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps = PropertyFlags::NOSTYLE) override;
115 :
116 : struct NotePosition {
117 : int line;
118 : staff_idx_t staff;
119 53292 : NotePosition(int note, staff_idx_t staff)
120 53292 : : line(note), staff(staff) {}
121 : NotePosition()
122 : : line(0), staff(0) {}
123 :
124 92148 : inline bool operator<(const NotePosition& other) const
125 : {
126 92148 : return staff < other.staff || (staff == other.staff && line < other.line);
127 : }
128 :
129 30598 : inline bool operator>(const NotePosition& other) const
130 : {
131 30598 : return other < *this;
132 : }
133 :
134 1996 : inline bool operator<=(const NotePosition& other) const
135 : {
136 1996 : return !(other < *this);
137 : }
138 :
139 2609 : inline bool operator >=(const NotePosition& other) const
140 : {
141 2609 : return !(*this < other);
142 : }
143 :
144 22686 : inline bool operator==(const NotePosition& other) const
145 : {
146 22686 : return line == other.line && staff == other.staff;
147 : }
148 :
149 : inline bool operator!=(const NotePosition& other) const
150 : {
151 : return line != other.line || staff != other.staff;
152 : }
153 : };
154 :
155 : enum class CrossStaffBeamPosition : signed char {
156 : INVALID,
157 : BETWEEN,
158 : ABOVE,
159 : BELOW
160 : };
161 :
162 : struct LayoutData : public EngravingItem::LayoutData {
163 : BeamType beamType = BeamType::INVALID;
164 : const Beam* beam = nullptr;
165 : const TremoloTwoChord* trem = nullptr;
166 : bool up = false;
167 : Fraction tick = Fraction(0, 1);
168 : double spatium = 0.;
169 : PointF startAnchor;
170 : PointF endAnchor;
171 : double slope = 0.;
172 : bool isGrace = false;
173 : int beamSpacing = 0;
174 : double beamDist = 0.0;
175 : double beamWidth = 0.0;
176 : std::vector<ChordRest*> elements;
177 : std::vector<NotePosition> notePositions;
178 : const StaffType* tab = nullptr;
179 : bool isBesideTabStaff = false;
180 : CrossStaffBeamPosition crossStaffBeamPos = CrossStaffBeamPosition::INVALID;
181 : const Chord* limitingChordAbove = nullptr; // <-
182 : const Chord* limitingChordBelow = nullptr; // <- For cross-staff spacing and centering
183 :
184 23 : void setAnchors(PointF startA, PointF endA) { startAnchor = startA; endAnchor = endA; }
185 0 : bool isValid() const override { return !(beamType == BeamType::INVALID); }
186 : };
187 146106 : DECLARE_LAYOUTDATA_METHODS(BeamBase)
188 :
189 : protected:
190 2872 : BeamBase(const ElementType& type, EngravingObject* parent, ElementFlags flags = ElementFlag::ON_STAFF);
191 : BeamBase(const BeamBase&);
192 : std::vector<BeamSegment*> m_beamSegments;
193 : PointF m_startAnchor;
194 : PointF m_endAnchor;
195 :
196 : private:
197 : bool m_up = true;
198 : bool m_userModified[2]{ false }; // 0: auto/down 1: up
199 : DirectionV m_direction = DirectionV::AUTO;
200 : };
201 : }
202 :
203 : #endif // MU_ENGRAVING_BEAMBASE_H
|