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 : #pragma once
24 :
25 : /**
26 : \file
27 : Definition of classes SysStaff and System
28 : */
29 :
30 : #include "engravingitem.h"
31 : #include "instrumentname.h"
32 :
33 : namespace mu::engraving {
34 : class Box;
35 : class Bracket;
36 : class InstrumentName;
37 : class MeasureBase;
38 : class Page;
39 : class SpannerSegment;
40 : class StaffVisibilityIndicator;
41 : class RangeLock;
42 :
43 : //---------------------------------------------------------
44 : // SysStaff
45 : /// One staff in a System.
46 : //---------------------------------------------------------
47 :
48 : class SysStaff
49 : {
50 : public:
51 9951 : SysStaff() {}
52 : ~SysStaff();
53 :
54 661 : const std::unordered_map<InstrumentNameRole, InstrumentName*>& instrumentNames() const { return m_instrumentNames; }
55 : InstrumentName* name(InstrumentNameRole role) const;
56 : void addInstrumentName(InstrumentName* n);
57 : void removeInstrumentName(InstrumentNameRole role);
58 :
59 7375 : const RectF& bbox() const { return m_bbox; }
60 132483 : RectF& bbox() { return m_bbox; }
61 535 : void setbbox(const RectF& r) { m_bbox = r; }
62 32084 : void setbbox(double x, double y, double w, double h) { m_bbox.setRect(x, y, w, h); }
63 611365 : double y() const { return m_bbox.y() + m_yOff; }
64 10686 : void setYOff(double offset) { m_yOff = offset; }
65 0 : double yOffset() const { return m_yOff; }
66 : double yBottom() const;
67 :
68 : void saveLayout();
69 : void restoreLayout();
70 :
71 0 : double continuousDist() const { return m_continuousDist; }
72 0 : void setContinuousDist(double val) { m_continuousDist = val; }
73 :
74 2269585 : bool show() const { return m_show; }
75 21893 : void setShow(bool v) { m_show = v; }
76 :
77 7735 : const Skyline& skyline() const { return m_skyline; }
78 182985 : Skyline& skyline() { return m_skyline; }
79 :
80 : private:
81 : std::unordered_map<InstrumentNameRole, InstrumentName*> m_instrumentNames;
82 :
83 : RectF m_bbox; // Bbox of StaffLines.
84 : Skyline m_skyline;
85 : double m_yOff = 0.0; // offset of top staff line within bbox
86 : double m_yPos = 0.0; // y position of bbox after System::layout2
87 : double m_height = 0.0; // height of bbox after System::layout2
88 : double m_continuousDist = -1.0; // distance for continuous mode
89 : bool m_show = true; // derived from Staff or false if empty
90 : // staff is hidden
91 : };
92 :
93 : //---------------------------------------------------------
94 : // System
95 : /// One row of measures for all instruments;
96 : /// a complete piece of the timeline.
97 : //---------------------------------------------------------
98 :
99 : class System final : public EngravingItem
100 : {
101 16257 : OBJECT_ALLOCATOR(engraving, System)
102 1106 : DECLARE_CLASSOF(ElementType::SYSTEM)
103 :
104 : public:
105 : ~System();
106 :
107 0 : System* clone() const override { return new System(*this); }
108 :
109 : void add(EngravingItem*) override;
110 : void remove(EngravingItem*) override;
111 : void change(EngravingItem* o, EngravingItem* n) override;
112 :
113 : void scanElements(std::function<void(EngravingItem*)> func) override;
114 : EngravingItemList accessibleChildren() const override;
115 :
116 : void appendMeasure(MeasureBase*);
117 : void removeMeasure(MeasureBase*);
118 : void removeLastMeasure();
119 :
120 : //! The page this system is currently laid out on; null if not placed.
121 58572 : Page* page() const { return m_page; }
122 10080 : void setPage(Page* p) { m_page = p; }
123 : EngravingItem* layoutParent() const override;
124 :
125 : //! A system is owned by its score; a page merely places it, see setPage().
126 : //! This overload hides EngravingItem::setOwnershipParent, so that no other
127 : //! parent can be set by accident.
128 : void setOwnershipParent(Score* score);
129 :
130 : void clear(); ///< Clear measure list.
131 :
132 865455 : std::vector<SysStaff*>& staves() { return m_staves; }
133 1194559 : const std::vector<SysStaff*>& staves() const { return m_staves; }
134 : double staffYpage(staff_idx_t staffIdx) const;
135 : double staffCanvasYpage(staff_idx_t staffIdx) const;
136 : SysStaff* staff(size_t staffIdx) const;
137 :
138 : bool pageBreak() const;
139 :
140 : SysStaff* insertStaff(int);
141 : void removeStaff(int);
142 : void adjustStavesNumber(size_t nstaves);
143 :
144 : staff_idx_t searchStaff(double y, staff_idx_t preferredStaff = muse::nidx, double spacingFactor = 0.5) const;
145 : Fraction snap(const Fraction& tick, const PointF p) const;
146 : Fraction snapNote(const Fraction& tick, const PointF p, int staff) const;
147 :
148 119582 : const std::vector<MeasureBase*>& measures() const { return m_ml; }
149 429869 : std::vector<MeasureBase*>& measures() { return m_ml; }
150 :
151 9 : MeasureBase* measure(int idx) { return m_ml[idx]; }
152 48244 : MeasureBase* first() const { return m_ml.front(); }
153 78048 : MeasureBase* last() const { return m_ml.back(); }
154 : Measure* firstMeasure() const;
155 : Measure* lastMeasure() const;
156 : Fraction endTick() const;
157 :
158 : MeasureBase* nextMeasure(const MeasureBase*) const;
159 :
160 284928 : double leftMargin() const { return m_leftMargin; }
161 14371 : void setLeftMargin(double val) { m_leftMargin = val; }
162 :
163 30032 : double systemHeight() const { return m_systemHeight; }
164 7192 : void setSystemHeight(double h) { m_systemHeight = h; }
165 :
166 : Box* vbox() const;
167 :
168 : const std::vector<Bracket*>& brackets() const { return m_brackets; }
169 114057 : std::vector<Bracket*>& brackets() { return m_brackets; }
170 :
171 34090 : std::list<SpannerSegment*>& spannerSegments() { return m_spannerSegments; }
172 22746 : const std::list<SpannerSegment*>& spannerSegments() const { return m_spannerSegments; }
173 :
174 11035 : SystemDivider* systemDividerLeft() const { return m_systemDividerLeft; }
175 11033 : SystemDivider* systemDividerRight() const { return m_systemDividerRight; }
176 :
177 : EngravingItem* nextSegmentElement() override;
178 : EngravingItem* prevSegmentElement() override;
179 :
180 : double topDistance(staff_idx_t staffIdx, const SkylineLine&) const;
181 : double bottomDistance(staff_idx_t staffIdx, const SkylineLine&) const;
182 : double minTop() const;
183 : double minBottom() const;
184 : double spacerDistance(bool up) const;
185 : Spacer* upSpacer(staff_idx_t staffIdx, Spacer* prevDownSpacer) const;
186 : Spacer* downSpacer(staff_idx_t staffIdx) const;
187 :
188 : double firstNoteRestSegmentX(bool leading = false) const;
189 : double endingXForOpenEndedLines() const;
190 : ChordRest* lastChordRest(track_idx_t track) const;
191 : ChordRest* firstChordRest(track_idx_t track) const;
192 :
193 16908 : bool hasFixedDownDistance() const { return m_fixedDownDistance; }
194 7379 : void setFixedDownDistance(bool val) const { m_fixedDownDistance = val; }
195 :
196 : staff_idx_t firstVisibleStaff() const;
197 : staff_idx_t nextVisibleStaff(staff_idx_t) const;
198 : staff_idx_t prevVisibleStaff(staff_idx_t) const;
199 : staff_idx_t lastVisibleStaff() const;
200 :
201 10949 : double distance() const { return m_distance; }
202 12340 : void setDistance(double d) { m_distance = d; }
203 :
204 : staff_idx_t firstSysStaffOfPart(const Part* part) const;
205 : staff_idx_t firstVisibleSysStaffOfPart(const Part* part) const;
206 : staff_idx_t firstVisibleSysStaffWithInstrument(const String& instrumentId, staff_idx_t startFrom);
207 : staff_idx_t lastSysStaffOfPart(const Part* part) const;
208 : staff_idx_t lastVisibleSysStaffOfPart(const Part* part) const;
209 : std::vector<staff_idx_t> visibleStavesOfPart(const Part* part) const;
210 : std::vector<Part*> visiblePartsOfGroup(staff_idx_t start, staff_idx_t end) const;
211 :
212 : #ifndef ENGRAVING_NO_ACCESSIBILITY
213 : AccessibleItemPtr createAccessible() override;
214 : #endif
215 :
216 : size_t getBracketsColumnsCount() const;
217 :
218 : void resetShortestLongestChordRest();
219 :
220 10195 : StaffVisibilityIndicator* staffVisibilityIndicator() const { return m_staffVisibilityIndicator; }
221 : void setHasStaffVisibilityIndicator(bool has);
222 :
223 : bool isLocked() const;
224 : const RangeLock* systemLock() const;
225 :
226 10195 : const std::vector<SystemLockIndicator*> systemLockIndicators() const { return m_systemLockIndicators; }
227 : void addSystemLockIndicator(SystemLockIndicator* sli);
228 : void deleteSystemLockIndicators();
229 :
230 0 : PageLockIndicator* pageLockIndicator() const { return m_pageLockIndicator; }
231 : void setPageLockIndicator(PageLockIndicator* pli);
232 : void deletePageLockIndicator();
233 :
234 : struct LayoutData : public EngravingItem::LayoutData {
235 : public:
236 63458 : bool useLongNames() const { return m_useLongNames; }
237 14363 : void setUseLongNames(bool v) { m_useLongNames = v; }
238 14568 : double instrumentNameOffset() const { return m_instrumentNameOffset; }
239 14371 : void setInstrumentNameOffset(double v) { m_instrumentNameOffset = v; }
240 :
241 14655 : double firstColumnWidth() const { return m_firstColumnWidth; }
242 14667 : void setFirstColumnWidth(double v) { m_firstColumnWidth = v; }
243 7674 : double secondColumnWidth() const { return m_secondColumnWidth; }
244 22045 : void setSecondColumnWidth(double v) { m_secondColumnWidth = v; }
245 36847 : double totalNamesWidth() const { return m_totalNamesWidth; }
246 22488 : void setTotalNamesWidth(double v) { m_totalNamesWidth = v; }
247 :
248 0 : const std::unordered_map<staff_idx_t, double>& groupBracketsWidth() const { return m_groupBracketsWidth; }
249 0 : void setGroupBracketsWidthAtStaffIdx(staff_idx_t i, double w) { m_groupBracketsWidth[i] = w; }
250 23438 : double groupBracketsWidthAtStaffIdx(staff_idx_t i) const
251 : {
252 23438 : return m_groupBracketsWidth.count(i) ? m_groupBracketsWidth.at(i) : 0.0;
253 : }
254 :
255 14371 : void clearGroupBracketsWidth() { m_groupBracketsWidth.clear(); }
256 :
257 8748 : const std::unordered_map<Part*, InstrumentName*>& partsWithGroupName() const { return m_partsWithGroupName; }
258 290 : void addPartWithGroupNames(Part* p, InstrumentName* n) { m_partsWithGroupName.emplace(p, n); }
259 14363 : void clearPartsWithGroupNames() { m_partsWithGroupName.clear(); }
260 :
261 : private:
262 : bool m_useLongNames = false;
263 : double m_instrumentNameOffset = 0.0;
264 :
265 : double m_firstColumnWidth = 0.0;
266 : double m_secondColumnWidth = 0.0;
267 : double m_totalNamesWidth = 0.0;
268 :
269 : std::unordered_map<staff_idx_t, double> m_groupBracketsWidth;
270 :
271 : std::unordered_map<Part*, InstrumentName*> m_partsWithGroupName;
272 : };
273 211401 : DECLARE_LAYOUTDATA_METHODS(System)
274 :
275 : private:
276 : friend class Factory;
277 :
278 : System(Score* parent);
279 :
280 : staff_idx_t firstVisibleSysStaff() const;
281 : staff_idx_t lastVisibleSysStaff() const;
282 :
283 : staff_idx_t firstVisibleStaffFrom(staff_idx_t startStaffIdx) const;
284 :
285 : Page* m_page = nullptr; // current layout placement; not owned, not copied
286 :
287 : SystemDivider* m_systemDividerLeft = nullptr; // to the next system
288 : SystemDivider* m_systemDividerRight = nullptr;
289 :
290 : std::vector<MeasureBase*> m_ml;
291 : std::vector<SysStaff*> m_staves;
292 : std::vector<Bracket*> m_brackets;
293 : std::list<SpannerSegment*> m_spannerSegments;
294 : std::vector<SystemLockIndicator*> m_systemLockIndicators;
295 : PageLockIndicator* m_pageLockIndicator = nullptr;
296 :
297 : StaffVisibilityIndicator* m_staffVisibilityIndicator = nullptr;
298 :
299 : double m_leftMargin = 0.0; // left margin for instrument name, brackets etc.
300 : mutable bool m_fixedDownDistance = false;
301 : double m_distance = 0.0; // temp. variable used during layout
302 : double m_systemHeight = 0.0;
303 : };
304 :
305 : typedef std::vector<System*>::iterator iSystem;
306 : typedef std::vector<System*>::const_iterator ciSystem;
307 : } // namespace mu::engraving
|