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 : #include "containers.h"
26 :
27 : #include "chordrest.h"
28 : #include "notedot.h"
29 :
30 : namespace mu::engraving {
31 : class TDuration;
32 : class Transaction;
33 :
34 : struct RestVerticalClearance {
35 : public:
36 11095 : void reset()
37 : {
38 11095 : m_above = 1000; // arbitrary high value
39 11095 : m_below = 1000; // arbitrary high value
40 11095 : m_locked = false;
41 11095 : }
42 :
43 1116 : int above() const { return m_above; }
44 1292 : int below() const { return m_below; }
45 1277 : void setAbove(int v) { m_above = std::max(std::min(m_above, v), 0); }
46 1078 : void setBelow(int v) { m_below = std::max(std::min(m_below, v), 0); }
47 :
48 9 : bool locked() const { return m_locked; }
49 388 : void setLocked(bool v) { m_locked = v; }
50 :
51 : private:
52 : int m_above = 0.0; // In space units
53 : int m_below = 0.0; // In space units
54 : bool m_locked = false;
55 : };
56 :
57 : //---------------------------------------------------------
58 : // @@ Rest
59 : /// This class implements a rest.
60 : //---------------------------------------------------------
61 :
62 : class Rest : public ChordRest
63 : {
64 43741 : OBJECT_ALLOCATOR(engraving, Rest)
65 1350 : DECLARE_CLASSOF(ElementType::REST)
66 :
67 : public:
68 :
69 41761 : ~Rest() { muse::DeleteAll(m_dots); }
70 :
71 : void hack_toRestType();
72 :
73 : Rest& operator=(const Rest&) = delete;
74 :
75 565 : Rest* clone() const override { return new Rest(*this, false); }
76 941 : EngravingItem* linkedClone() override { return new Rest(*this, true); }
77 1767266 : Measure* measure() const override { return ownershipParent() ? toMeasure(ownershipParent()->ownershipParent()) : 0; }
78 : double mag() const override;
79 : double intrinsicMag() const override;
80 :
81 : void scanElements(std::function<void(EngravingItem*)> func) override;
82 : void setTrack(track_idx_t val) override;
83 :
84 : bool acceptDrop(EditData&) const override;
85 : EngravingItem* drop(Transaction& tx, EditData&) override;
86 :
87 569319 : bool isGap() const { return m_gap; }
88 2384 : virtual void setGap(bool v) { m_gap = v; }
89 :
90 : virtual void add(EngravingItem*) override;
91 : virtual void remove(EngravingItem*) override;
92 :
93 : void checkDots();
94 :
95 : NoteDot* dot(int n);
96 : const std::vector<NoteDot*>& dotList() const;
97 66608 : int dotLine() const { return m_dotline; }
98 66608 : void setDotLine(int l) { m_dotline = l; }
99 :
100 : static int getDotline(DurationType durationType);
101 : bool accent();
102 : void setAccent(bool flag);
103 :
104 : bool isWholeRest() const;
105 : bool isBreveRest() const;
106 :
107 66608 : DeadSlapped* deadSlapped() const { return m_deadSlapped; }
108 :
109 : double rightEdge() const override;
110 : double centerX() const;
111 :
112 16940 : bool alignWithOtherRests() const { return m_alignWithOtherRests; }
113 0 : void setAlignWithOtherRests(bool v) { m_alignWithOtherRests = v; }
114 :
115 : void localSpatiumChanged(double oldValue, double newValue) override;
116 : PropertyValue propertyDefault(Pid) const override;
117 : void resetProperty(Pid id) override;
118 : bool setProperty(Pid propertyId, const PropertyValue& v) override;
119 : PropertyValue getProperty(Pid propertyId) const override;
120 : void undoChangeDotsVisible(bool v);
121 :
122 : EngravingItem* nextElement() override;
123 : EngravingItem* prevElement() override;
124 : String accessibleInfo() const override;
125 : String screenReaderInfo() const override;
126 :
127 : bool shouldNotBeDrawn() const;
128 : bool debugDrawGap() const;
129 :
130 14826 : RestVerticalClearance& verticalClearance() { return m_verticalClearance; }
131 :
132 : struct LayoutData : public ChordRest::LayoutData {
133 : std::vector<Rest*> mergedRests; // Rests from other voices that may be merged with this
134 : ld_field<SymId> sym = { "[Rest] sym", SymId::restQuarter };
135 : };
136 373665 : DECLARE_LAYOUTDATA_METHODS(Rest)
137 :
138 : SymId getSymbol(DurationType type, int line, int lines) const;
139 : double symWidthNoLedgerLines(LayoutData* ldata) const;
140 :
141 : protected:
142 : Rest(const ElementType& type, DummyParentOr<Segment> parent);
143 : Rest(const ElementType& type, DummyParentOr<Segment> parent, const TDuration&);
144 : Rest(const Rest&, bool link = false);
145 :
146 : Sid getPropertyStyle(Pid pid) const override;
147 0 : virtual RectF numberRect() const { return RectF(); } // TODO: add style to show number over 1-measure rests
148 :
149 : private:
150 :
151 : friend class Factory;
152 : Rest(DummyParentOr<Segment> parent);
153 : Rest(DummyParentOr<Segment> parent, const TDuration&);
154 :
155 : RectF drag(EditData&) override;
156 : double upPos() const override;
157 : double downPos() const override;
158 : void setOffset(const PointF& o) override;
159 :
160 : // values calculated by layout:
161 :
162 : int m_dotline = -1; // depends on rest symbol
163 : bool m_gap = false; // invisible and not selectable for user
164 : std::vector<NoteDot*> m_dots;
165 : DeadSlapped* m_deadSlapped = nullptr;
166 :
167 : RestVerticalClearance m_verticalClearance;
168 :
169 : bool m_alignWithOtherRests = true;
170 : };
171 : }
|