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 : #include "vibrato.h"
23 :
24 : #include <cmath>
25 :
26 : #include "types/typesconv.h"
27 :
28 : #include "iengravingfont.h"
29 :
30 : #include "score.h"
31 : #include "system.h"
32 : #include "trill.h"
33 :
34 : #include "log.h"
35 :
36 : using namespace mu;
37 : using namespace mu::engraving;
38 :
39 : namespace mu::engraving {
40 28 : VibratoSegment::VibratoSegment(Vibrato* sp)
41 28 : : LineSegment(ElementType::VIBRATO_SEGMENT, sp, ElementFlag::MOVABLE | ElementFlag::ON_STAFF)
42 : {
43 28 : }
44 :
45 : //---------------------------------------------------------
46 : // symbolLine
47 : //---------------------------------------------------------
48 :
49 28 : void VibratoSegment::symbolLine(SymId start, SymId fill)
50 : {
51 28 : double x1 = 0;
52 28 : double x2 = pos2().x();
53 28 : double w = x2 - x1;
54 28 : double mag = magS();
55 28 : IEngravingFontPtr f = score()->engravingFont();
56 :
57 28 : m_symbols.clear();
58 28 : m_symbols.push_back(start);
59 28 : double w1 = f->advance(start, mag);
60 28 : double w2 = f->advance(fill, mag);
61 28 : int n = lrint((w - w1) / w2);
62 274 : for (int i = 0; i < n; ++i) {
63 246 : m_symbols.push_back(fill);
64 : }
65 28 : RectF r(f->bbox(m_symbols, mag));
66 28 : setbbox(r);
67 28 : }
68 :
69 0 : void VibratoSegment::symbolLine(SymId start, SymId fill, SymId end)
70 : {
71 0 : double x1 = 0;
72 0 : double x2 = pos2().x();
73 0 : double w = x2 - x1;
74 0 : double mag = magS();
75 0 : IEngravingFontPtr f = score()->engravingFont();
76 :
77 0 : m_symbols.clear();
78 0 : m_symbols.push_back(start);
79 0 : double w1 = f->bbox(start, mag).width();
80 0 : double w2 = f->width(fill, mag);
81 0 : double w3 = f->width(end, mag);
82 0 : int n = lrint((w - w1 - w3) / w2);
83 0 : for (int i = 0; i < n; ++i) {
84 0 : m_symbols.push_back(fill);
85 : }
86 0 : m_symbols.push_back(end);
87 0 : RectF r(f->bbox(m_symbols, mag));
88 0 : setbbox(r);
89 0 : }
90 :
91 : //---------------------------------------------------------
92 : // propertyDelegate
93 : //---------------------------------------------------------
94 :
95 156 : EngravingObject* VibratoSegment::propertyDelegate(Pid pid) const
96 : {
97 156 : if (pid == Pid::VIBRATO_TYPE || pid == Pid::PLACEMENT) {
98 0 : return spanner();
99 : }
100 156 : return LineSegment::propertyDelegate(pid);
101 : }
102 :
103 : //---------------------------------------------------------
104 : // vibratoStyle
105 : //---------------------------------------------------------
106 :
107 : static const ElementStyle vibratoStyle {
108 : { Sid::vibratoPlacement, Pid::PLACEMENT },
109 : };
110 :
111 : //---------------------------------------------------------
112 : // Vibrato
113 : //---------------------------------------------------------
114 :
115 32 : Vibrato::Vibrato(DummyParentOr<EngravingItem> parent)
116 32 : : SLine(ElementType::VIBRATO, parent)
117 : {
118 32 : initElementStyle(&vibratoStyle);
119 32 : m_vibratoType = VibratoType::GUITAR_VIBRATO;
120 32 : }
121 :
122 56 : Vibrato::~Vibrato()
123 : {
124 56 : }
125 :
126 : static const ElementStyle vibratoSegmentStyle {
127 : { Sid::vibratoMinDistance, Pid::MIN_DISTANCE },
128 : };
129 :
130 : //---------------------------------------------------------
131 : // createLineSegment
132 : //---------------------------------------------------------
133 :
134 28 : LineSegment* Vibrato::createLineSegment()
135 : {
136 28 : VibratoSegment* seg = new VibratoSegment(this);
137 28 : seg->setTrack(track());
138 28 : seg->setColor(lineColor());
139 28 : seg->initElementStyle(&vibratoSegmentStyle);
140 28 : return seg;
141 : }
142 :
143 56 : PointF Vibrato::linePos(Grip grip, System** system) const
144 : {
145 56 : return Trill::trillLinePos(this, grip, system);
146 : }
147 :
148 : //---------------------------------------------------------
149 : // vibratoTypeName
150 : //---------------------------------------------------------
151 :
152 0 : String Vibrato::vibratoTypeUserName() const
153 : {
154 0 : return TConv::translatedUserName(vibratoType());
155 : }
156 :
157 : //---------------------------------------------------------
158 : // subtypeUserName
159 : //---------------------------------------------------------
160 :
161 0 : muse::TranslatableString Vibrato::subtypeUserName() const
162 : {
163 0 : return TConv::userName(vibratoType());
164 : }
165 :
166 30 : Sid Vibrato::defaultPosSid() const
167 : {
168 30 : return placeAbove() ? Sid::vibratoPosAbove : Sid::vibratoPosBelow;
169 : }
170 :
171 : //---------------------------------------------------------
172 : // getProperty
173 : //---------------------------------------------------------
174 :
175 344 : PropertyValue Vibrato::getProperty(Pid propertyId) const
176 : {
177 344 : switch (propertyId) {
178 0 : case Pid::VIBRATO_TYPE:
179 0 : return int(vibratoType());
180 344 : default:
181 344 : break;
182 : }
183 344 : return SLine::getProperty(propertyId);
184 : }
185 :
186 : //---------------------------------------------------------
187 : // setProperty
188 : //---------------------------------------------------------
189 :
190 35 : bool Vibrato::setProperty(Pid propertyId, const PropertyValue& val)
191 : {
192 35 : switch (propertyId) {
193 0 : case Pid::VIBRATO_TYPE:
194 0 : setVibratoType(VibratoType(val.toInt()));
195 0 : break;
196 0 : case Pid::COLOR:
197 0 : setColor(val.value<Color>());
198 0 : setLineColor(val.value<Color>());
199 0 : break;
200 35 : default:
201 35 : return SLine::setProperty(propertyId, val);
202 : }
203 0 : triggerLayout();
204 0 : return true;
205 : }
206 :
207 : //---------------------------------------------------------
208 : // propertyDefault
209 : //---------------------------------------------------------
210 :
211 340 : PropertyValue Vibrato::propertyDefault(Pid propertyId) const
212 : {
213 340 : switch (propertyId) {
214 0 : case Pid::VIBRATO_TYPE:
215 0 : return static_cast<int>(VibratoType::GUITAR_VIBRATO);
216 2 : case Pid::PLACEMENT:
217 2 : return style().styleV(Sid::vibratoPlacement);
218 338 : default:
219 338 : return SLine::propertyDefault(propertyId);
220 : }
221 : }
222 :
223 : //---------------------------------------------------------
224 : // accessibleInfo
225 : //---------------------------------------------------------
226 :
227 0 : String Vibrato::accessibleInfo() const
228 : {
229 0 : return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), vibratoTypeUserName());
230 : }
231 : }
|