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 :
23 : #ifndef MU_ENGRAVING_MEASUREBASE_H
24 : #define MU_ENGRAVING_MEASUREBASE_H
25 :
26 : /**
27 : \file
28 : Definition of MeasureBase class.
29 : */
30 :
31 : #include "engravingitem.h"
32 :
33 : namespace mu::engraving {
34 : class Box;
35 : class LayoutBreak;
36 : class Measure;
37 : class Score;
38 : class System;
39 : class RangeLock;
40 :
41 : //---------------------------------------------------------
42 : // Repeat
43 : //---------------------------------------------------------
44 :
45 : enum class Repeat : char {
46 : NONE = 0,
47 : END = 1,
48 : START = 2,
49 : MEASURE = 4,
50 : JUMP = 8
51 : };
52 :
53 218 : constexpr Repeat operator|(Repeat t1, Repeat t2)
54 : {
55 218 : return static_cast<Repeat>(static_cast<int>(t1) | static_cast<int>(t2));
56 : }
57 :
58 : constexpr bool operator&(Repeat t1, Repeat t2)
59 : {
60 : return static_cast<int>(t1) & static_cast<int>(t2);
61 : }
62 :
63 : //---------------------------------------------------------
64 : // @@ MeasureBase
65 : /// Virtual base class for Measure, HBox and VBox
66 : //
67 : // @P lineBreak bool true if a system break is positioned on this measure
68 : // @P nextMeasure Measure the next Measure (read-only)
69 : // @P nextMeasureMM Measure the next multi-measure rest Measure (read-only)
70 : // @P pageBreak bool true if a page break is positioned on this measure
71 : // @P prevMeasure Measure the previous Measure (read-only)
72 : // @P prevMeasureMM Measure the previous multi-measure rest Measure (read-only)
73 : //---------------------------------------------------------
74 :
75 : class MeasureBase : public EngravingItem
76 : {
77 0 : OBJECT_ALLOCATOR(engraving, MeasureBase)
78 :
79 : public:
80 :
81 : ~MeasureBase();
82 :
83 : //! The system this measure is currently laid out on; null if not placed.
84 4227316 : System* system() const { return m_system; }
85 118298 : void setSystem(System* s) { m_system = s; }
86 : EngravingItem* layoutParent() const override;
87 :
88 : //! A measure or frame is owned by its score, or by the frame it is nested in.
89 : //! A system merely places it; see setSystem(). These overloads hide
90 : //! EngravingItem::setOwnershipParent, so that no other parent can be set by accident.
91 : void setOwnershipParent(Score* score);
92 : void setOwnershipParent(Box* box);
93 :
94 : System* prevNonVBoxSystem() const;
95 : System* nextNonVBoxSystem() const;
96 : Page* page() const;
97 : Page* prevPage() const;
98 : Page* nextPage() const;
99 :
100 : virtual void scanElements(std::function<void(EngravingItem*)> func) override;
101 :
102 : virtual void setScore(Score* s) override;
103 :
104 770325 : MeasureBase* next() const { return m_next; }
105 : MeasureBase* nextMM() const;
106 34985 : void setNext(MeasureBase* e) { m_next = e; }
107 1131875 : MeasureBase* prev() const { return m_prev; }
108 : MeasureBase* prevMM() const;
109 18947 : void setPrev(MeasureBase* e) { m_prev = e; }
110 : MeasureBase* top() const;
111 :
112 : MeasureBase* getInScore(Score* score, bool useNextMeasureFallback = false) const;
113 :
114 : Measure* nextMeasure() const;
115 : Measure* prevMeasure() const;
116 : Measure* nextMeasureMM() const;
117 : Measure* prevMeasureMM() const;
118 :
119 65627 : ElementList& el() { return m_el; }
120 100322 : const ElementList& el() const { return m_el; }
121 :
122 : const MeasureBase* mbWithPrecedingSectionBreak() const;
123 : LayoutBreak* sectionBreakElement() const;
124 :
125 : void undoSetBreak(bool v, LayoutBreakType type);
126 : void undoSetLineBreak(bool v) { undoSetBreak(v, LayoutBreakType::LINE); }
127 : void undoSetPageBreak(bool v) { undoSetBreak(v, LayoutBreakType::PAGE); }
128 : void undoSetSectionBreak(bool v) { undoSetBreak(v, LayoutBreakType::SECTION); }
129 12 : void undoSetNoBreak(bool v) { undoSetBreak(v, LayoutBreakType::NOBREAK); }
130 :
131 : void cleanupLayoutBreaks(bool undo);
132 :
133 0 : virtual void moveTicks(const Fraction& diff) { setTick(tick() + diff); }
134 :
135 : bool acceptDrop(EditData&) const override;
136 : EngravingItem* drop(Transaction& tx, EditData&) override;
137 :
138 : void add(EngravingItem*) override;
139 : void remove(EngravingItem*) override;
140 :
141 : Fraction tick() const override;
142 : void setTick(const Fraction& f);
143 :
144 2405899 : Fraction ticks() const { return m_len; }
145 36974 : void setTicks(const Fraction& f) { m_len = f; }
146 :
147 702454 : Fraction endTick() const { return m_tick + m_len; }
148 :
149 : void triggerLayout() const override;
150 :
151 : double pause() const;
152 :
153 : void clearElements();
154 : ElementList takeElements();
155 :
156 97183 : bool lineBreak() const { return flag(ElementFlag::LINE_BREAK); }
157 2321 : void setLineBreak(bool v) { setFlag(ElementFlag::LINE_BREAK, v); }
158 :
159 89961 : bool pageBreak() const { return flag(ElementFlag::PAGE_BREAK); }
160 937 : void setPageBreak(bool v) { setFlag(ElementFlag::PAGE_BREAK, v); }
161 :
162 454368 : bool sectionBreak() const { return flag(ElementFlag::SECTION_BREAK); }
163 948 : void setSectionBreak(bool v) { setFlag(ElementFlag::SECTION_BREAK, v); }
164 :
165 88869 : bool noBreak() const { return flag(ElementFlag::NO_BREAK); }
166 981 : void setNoBreak(bool v) { setFlag(ElementFlag::NO_BREAK, v); }
167 :
168 0 : virtual void computeMinWidth() { }
169 :
170 : int index() const;
171 : int measureIndex() const;
172 :
173 : bool isBefore(const EngravingItem* other) const override;
174 : bool isBefore(const MeasureBase* other) const;
175 3127 : bool isBeforeOrEqual(const MeasureBase* other) const { return other == this || isBefore(other); }
176 34 : bool isAfter(const MeasureBase* other) const { return !isBeforeOrEqual(other); }
177 0 : bool isAfterOrEqual(const MeasureBase* other) const { return !isBefore(other); }
178 :
179 : const RangeLock* systemLock() const;
180 : bool isStartOfSystemLock() const;
181 : bool isEndOfSystemLock() const;
182 :
183 : const RangeLock* pageLock() const;
184 : bool isStartOfPageLock() const;
185 : bool isEndOfPageLock() const;
186 :
187 : protected:
188 : MeasureBase(const ElementType& type, Score* parent);
189 : MeasureBase(const MeasureBase&);
190 :
191 : Fraction m_len { Fraction(0, 1) }; // actual length of measure
192 :
193 : ElementList m_el; // Measure(/tick) relative -elements: with defined start time
194 : // but outside the staff
195 : private:
196 : MeasureBase* m_next = nullptr;
197 : MeasureBase* m_prev = nullptr;
198 :
199 : System* m_system = nullptr; // current layout placement; not owned, not copied
200 :
201 : Fraction m_tick = Fraction(0, 1);
202 : };
203 :
204 : //---------------------------------------------------------
205 : // MeasureBaseList
206 : //---------------------------------------------------------
207 :
208 : class MeasureBaseList
209 : {
210 : public:
211 : MeasureBaseList();
212 104519 : MeasureBase* first() const { return m_first; }
213 102270 : MeasureBase* last() const { return m_last; }
214 : void clear();
215 : void add(MeasureBase*);
216 : void remove(MeasureBase*);
217 : void insert(MeasureBase*, MeasureBase*);
218 : void remove(MeasureBase*, MeasureBase*);
219 : void change(MeasureBase* o, MeasureBase* n);
220 98 : int size() const { return m_size; }
221 130020 : bool empty() const { return m_size == 0; }
222 :
223 : void append(MeasureBase*);
224 :
225 : void updateTickIndex();
226 :
227 : Measure* measureByTick(int tick) const;
228 : MeasureBase* firstMeasureBaseAtTick(int tick) const;
229 : std::vector<MeasureBase*> measureBasesAtTick(int tick) const;
230 :
231 : private:
232 : void push_back(MeasureBase* m);
233 : void push_front(MeasureBase* m);
234 :
235 : int m_size = 0;
236 : MeasureBase* m_first = nullptr;
237 : MeasureBase* m_last = nullptr;
238 :
239 : // At a tick there can be any number of MeasureBases
240 : // There can only be one Measure
241 : // There can be any number of Boxes
242 : std::multimap<int, MeasureBase*> m_tickIndex;
243 : };
244 : } // namespace mu::engraving
245 : #endif
|