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_ARTICULATION_H
24 : #define MU_ENGRAVING_ARTICULATION_H
25 :
26 : #include <set>
27 :
28 : #include "chordrest.h"
29 : #include "engravingitem.h"
30 :
31 : namespace mu::engraving {
32 : class Factory;
33 :
34 : class ChordRest;
35 : class Measure;
36 : class Page;
37 : class Segment;
38 : class System;
39 :
40 : //---------------------------------------------------------
41 : // ArticulationInfo
42 : // gives infos about note attributes
43 : //---------------------------------------------------------
44 :
45 : enum class ArticulationCategory : unsigned char {
46 : NONE = 0x0,
47 : DOUBLE = 0x1,
48 : TENUTO = 0x2,
49 : STACCATO = 0x4,
50 : ACCENT = 0x8,
51 : MARCATO = 0x10,
52 : LUTE_FINGERING = 0x20,
53 : LAISSEZ_VIB = 0x40,
54 : HANDBELLS = 0x80,
55 : };
56 : DECLARE_FLAGS(ArticulationCategories, ArticulationCategory)
57 : DECLARE_OPERATORS_FOR_FLAGS(ArticulationCategories)
58 :
59 : enum class ArticulationAnchor : char {
60 : TOP, // attribute is always placed at top
61 : BOTTOM, // attribute is placed at bottom
62 : AUTO, // anchor depends on chord direction, away from stem
63 : };
64 :
65 : enum class ArticulationStemSideAlign : char
66 : {
67 : // horizontal align for stem-side articulation layout
68 : STEM, // attribute is placed directly over the stem
69 : NOTEHEAD, // attribute is centered on the notehead
70 : AVERAGE, // attribute is placed at the average of stem pos and notehead center
71 : };
72 :
73 : // flags:
74 : enum class ArticulationShowIn : char {
75 : PITCHED_STAFF = 1, TABLATURE = 2
76 : };
77 :
78 : constexpr ArticulationShowIn operator|(ArticulationShowIn a1, ArticulationShowIn a2)
79 : {
80 : return static_cast<ArticulationShowIn>(static_cast<unsigned char>(a1) | static_cast<unsigned char>(a2));
81 : }
82 :
83 : constexpr bool operator&(ArticulationShowIn a1, ArticulationShowIn a2)
84 : {
85 : return static_cast<unsigned char>(a1) & static_cast<unsigned char>(a2);
86 : }
87 :
88 : enum class ArticulationsUpdateMode : unsigned char {
89 : Insert,
90 : Remove
91 : };
92 :
93 : std::set<SymId> updateArticulations(const std::set<SymId>& articulationSymbolIds, SymId articulationSymbolId,
94 : ArticulationsUpdateMode updateMode = ArticulationsUpdateMode::Insert);
95 : std::set<SymId> splitArticulations(const std::set<SymId>& articulationSymbolIds);
96 : std::set<SymId> joinArticulations(const std::set<SymId>& articulationSymbolIds);
97 : std::set<SymId> flipArticulations(const std::set<SymId>& articulationSymbolIds, PlacementV placement);
98 :
99 : //---------------------------------------------------------
100 : // @@ Articulation
101 : /// articulation marks
102 : //---------------------------------------------------------
103 :
104 : class Articulation : public EngravingItem
105 : {
106 2178 : OBJECT_ALLOCATOR(engraving, Articulation)
107 2376 : DECLARE_CLASSOF(ElementType::ARTICULATION)
108 :
109 : public:
110 :
111 92 : Articulation(const Articulation&) = default;
112 : Articulation& operator=(const Articulation&) = delete;
113 :
114 88 : virtual Articulation* clone() const override { return new Articulation(*this); }
115 :
116 : virtual double mag() const override;
117 :
118 13015 : SymId symId() const { return m_symId; }
119 : void setSymId(SymId id);
120 : virtual int subtype() const override;
121 :
122 : void setTextType(ArticulationTextType textType);
123 7561 : ArticulationTextType textType() const { return m_textType; }
124 340 : Text* text() const { return m_text; }
125 28 : void setText(Text* t) { m_text = t; }
126 :
127 : void setSelected(bool f) override;
128 : void setVisible(bool f) override;
129 :
130 : TranslatableString typeUserName() const override;
131 : TranslatableString subtypeUserName() const override;
132 : String articulationName() const; // type-name of articulation; used for midi rendering
133 : static String symId2ArticulationName(SymId symId);
134 :
135 : bool layoutCloseToNote() const;
136 :
137 : bool isHiddenOnTabStaff() const;
138 :
139 : std::vector<LineF> dragAnchorLines() const override;
140 :
141 : PropertyValue getProperty(Pid propertyId) const override;
142 : bool setProperty(Pid propertyId, const PropertyValue&) override;
143 : PropertyValue propertyDefault(Pid) const override;
144 : void resetProperty(Pid id) override;
145 : Sid getPropertyStyle(Pid id) const override;
146 :
147 386 : void setDirection(DirectionV d) { m_direction = d; }
148 1132 : DirectionV direction() const { return m_direction; }
149 :
150 : ChordRest* chordRest() const;
151 : Segment* segment() const;
152 : Measure* measure() const;
153 : System* system() const;
154 : Page* page() const;
155 :
156 8227 : ArticulationAnchor anchor() const { return m_anchor; }
157 1709 : void setAnchor(ArticulationAnchor v) { m_anchor = v; }
158 :
159 951 : OrnamentStyle ornamentStyle() const { return m_ornamentStyle; }
160 180 : void setOrnamentStyle(OrnamentStyle val) { m_ornamentStyle = val; }
161 :
162 953 : bool playArticulation() const { return m_playArticulation; }
163 179 : void setPlayArticulation(bool val) { m_playArticulation = val; }
164 :
165 761 : String channelName() const { return m_channelName; }
166 0 : void setChannelName(const String& s) { m_channelName = s; }
167 :
168 : virtual String accessibleInfo() const override;
169 :
170 9013 : bool isDouble() const { return m_categories & ArticulationCategory::DOUBLE; }
171 15992 : bool isTenuto() const { return m_categories & ArticulationCategory::TENUTO; }
172 29372 : bool isStaccato() const { return m_categories & ArticulationCategory::STACCATO; }
173 3019 : bool isAccent() const { return m_categories & ArticulationCategory::ACCENT; }
174 2626 : bool isMarcato() const { return m_categories & ArticulationCategory::MARCATO; }
175 : bool isLuteFingering() const { return m_categories & ArticulationCategory::LUTE_FINGERING; }
176 14199 : bool isLaissezVib() const { return m_categories & ArticulationCategory::LAISSEZ_VIB; }
177 2490 : bool isHandbellsArticulation() const { return m_categories & ArticulationCategory::HANDBELLS; }
178 :
179 : bool isBasicArticulation() const;
180 :
181 : void styleChanged() override;
182 :
183 : bool isOnCrossBeamSide() const;
184 :
185 : staff_idx_t vStaffIdx() const override;
186 :
187 : struct LayoutData : public EngravingItem::LayoutData
188 : {
189 : ld_field<bool> up = { "[Articulation] up", true };
190 : ld_field<SymId> symId = { "[Articulation] symId", SymId::noSym };
191 :
192 1861 : void reset() override
193 : {
194 1861 : EngravingItem::LayoutData::reset();
195 1861 : up.reset();
196 1861 : symId.reset();
197 1861 : }
198 :
199 : double opticalCenter() const;
200 : };
201 42864 : DECLARE_LAYOUTDATA_METHODS(Articulation)
202 :
203 : void setUp(bool val);
204 :
205 : //! --- DEPRECATED ---
206 28878 : bool up() const { return ldata()->up; }
207 : //! ------------------
208 :
209 : protected:
210 : friend class mu::engraving::Factory;
211 : Articulation(DummyParentOr<ChordRest> parent, ElementType type = ElementType::ARTICULATION);
212 :
213 : private:
214 :
215 : void setupShowOnTabStyles();
216 :
217 : enum class AnchorGroup : unsigned char {
218 : ARTICULATION,
219 : LUTE_FINGERING,
220 : OTHER
221 : };
222 : static AnchorGroup anchorGroup(SymId);
223 :
224 : void computeCategories();
225 :
226 : ArticulationCategories m_categories = ArticulationCategory::NONE;
227 :
228 : SymId m_symId = SymId::noSym;
229 : DirectionV m_direction = DirectionV::AUTO;
230 : String m_channelName;
231 :
232 : ArticulationTextType m_textType = ArticulationTextType::NO_TEXT;
233 : Text* m_text = nullptr;
234 :
235 : ArticulationAnchor m_anchor = ArticulationAnchor::AUTO;
236 :
237 : OrnamentStyle m_ornamentStyle = OrnamentStyle::DEFAULT; // for use in ornaments such as trill
238 : bool m_playArticulation = true;
239 :
240 : std::pair<Sid, Sid> m_showOnTabStyles = { Sid::NOSTYLE, Sid::NOSTYLE };
241 : };
242 : } // namespace mu::engraving
243 :
244 : #endif
|