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 : #include "bend.h"
24 :
25 : #include "note.h"
26 :
27 : #include "log.h"
28 :
29 : using namespace mu;
30 : using namespace muse::draw;
31 : using namespace mu::engraving;
32 :
33 : //---------------------------------------------------------
34 : // label
35 : //---------------------------------------------------------
36 :
37 : const char* Bend::label[13] = {
38 : "", "1/4", "1/2", "3/4", "full",
39 : "1 1/4", "1 1/2", "1 3/4", "2",
40 : "2 1/4", "2 1/2", "2 3/4", "3"
41 : };
42 :
43 : static const ElementStyle bendStyle {
44 : { Sid::bendFontFace, Pid::FONT_FACE },
45 : { Sid::bendFontSize, Pid::FONT_SIZE },
46 : { Sid::bendFontStyle, Pid::FONT_STYLE },
47 : { Sid::bendLineWidth, Pid::LINE_WIDTH },
48 : };
49 :
50 : static const PitchValues BEND_CURVE = { PitchValue(0, 0),
51 : PitchValue(15, 100),
52 : PitchValue(60, 100) };
53 :
54 : static const PitchValues BEND_RELEASE_CURVE = { PitchValue(0, 0),
55 : PitchValue(10, 100),
56 : PitchValue(20, 100),
57 : PitchValue(30, 0),
58 : PitchValue(60, 0) };
59 :
60 : static const PitchValues BEND_RELEASE_BEND_CURVE = { PitchValue(0, 0),
61 : PitchValue(10, 100),
62 : PitchValue(20, 100),
63 : PitchValue(30, 0),
64 : PitchValue(40, 0),
65 : PitchValue(50, 100),
66 : PitchValue(60, 100) };
67 :
68 : static const PitchValues PREBEND_CURVE = { PitchValue(0, 100),
69 : PitchValue(60, 100) };
70 :
71 : static const PitchValues PREBEND_RELEASE_CURVE = { PitchValue(0, 100),
72 : PitchValue(15, 100),
73 : PitchValue(30, 0),
74 : PitchValue(60, 0) };
75 :
76 : //---------------------------------------------------------
77 : // Bend
78 : //---------------------------------------------------------
79 :
80 4 : Bend::Bend(DummyParentOr<Note> parent)
81 4 : : EngravingItem(ElementType::BEND, parent, ElementFlag::MOVABLE)
82 : {
83 4 : initElementStyle(&bendStyle);
84 4 : }
85 :
86 : //---------------------------------------------------------
87 : // font
88 : //---------------------------------------------------------
89 :
90 4 : Font Bend::font(double sp) const
91 : {
92 4 : Font f(m_fontFace, Font::Type::Unknown);
93 4 : f.setBold(m_fontStyle & FontStyle::Bold);
94 4 : f.setItalic(m_fontStyle & FontStyle::Italic);
95 4 : f.setUnderline(m_fontStyle & FontStyle::Underline);
96 4 : f.setStrike(m_fontStyle & FontStyle::Strike);
97 4 : double m = m_fontSize;
98 4 : m *= sp / defaultSpatium();
99 :
100 4 : f.setPointSizeF(m);
101 4 : return f;
102 0 : }
103 :
104 0 : BendType Bend::parseBendTypeFromCurve() const
105 : {
106 0 : if (m_points == BEND_CURVE) {
107 0 : return BendType::BEND;
108 0 : } else if (m_points == BEND_RELEASE_CURVE) {
109 0 : return BendType::BEND_RELEASE;
110 0 : } else if (m_points == BEND_RELEASE_BEND_CURVE) {
111 0 : return BendType::BEND_RELEASE_BEND;
112 0 : } else if (m_points == PREBEND_CURVE) {
113 0 : return BendType::PREBEND;
114 0 : } else if (m_points == PREBEND_RELEASE_CURVE) {
115 0 : return BendType::PREBEND_RELEASE;
116 : } else {
117 0 : return BendType::CUSTOM;
118 : }
119 : }
120 :
121 0 : void Bend::updatePointsByBendType(const BendType bendType)
122 : {
123 0 : switch (bendType) {
124 0 : case BendType::BEND:
125 0 : m_points = BEND_CURVE;
126 0 : break;
127 0 : case BendType::BEND_RELEASE:
128 0 : m_points = BEND_RELEASE_CURVE;
129 0 : break;
130 0 : case BendType::BEND_RELEASE_BEND:
131 0 : m_points = BEND_RELEASE_BEND_CURVE;
132 0 : break;
133 0 : case BendType::PREBEND:
134 0 : m_points = PREBEND_CURVE;
135 0 : break;
136 0 : case BendType::PREBEND_RELEASE:
137 0 : m_points = PREBEND_RELEASE_CURVE;
138 0 : break;
139 0 : default:
140 0 : break;
141 : }
142 0 : }
143 :
144 : //---------------------------------------------------------
145 : // getProperty
146 : //---------------------------------------------------------
147 :
148 40 : PropertyValue Bend::getProperty(Pid id) const
149 : {
150 40 : switch (id) {
151 0 : case Pid::FONT_FACE:
152 0 : return m_fontFace;
153 0 : case Pid::FONT_SIZE:
154 0 : return m_fontSize;
155 0 : case Pid::FONT_STYLE:
156 0 : return int(m_fontStyle);
157 4 : case Pid::PLAY:
158 4 : return playBend();
159 0 : case Pid::LINE_WIDTH:
160 0 : return m_lineWidth;
161 0 : case Pid::BEND_TYPE:
162 0 : return static_cast<int>(parseBendTypeFromCurve());
163 0 : case Pid::BEND_CURVE:
164 0 : return m_points;
165 36 : default:
166 36 : return EngravingItem::getProperty(id);
167 : }
168 : }
169 :
170 : //---------------------------------------------------------
171 : // setProperty
172 : //---------------------------------------------------------
173 :
174 16 : bool Bend::setProperty(Pid id, const PropertyValue& v)
175 : {
176 16 : switch (id) {
177 4 : case Pid::FONT_FACE:
178 4 : m_fontFace = v.value<String>();
179 4 : break;
180 4 : case Pid::FONT_SIZE:
181 4 : m_fontSize = v.toReal();
182 4 : break;
183 4 : case Pid::FONT_STYLE:
184 4 : m_fontStyle = FontStyle(v.toInt());
185 4 : break;
186 0 : case Pid::PLAY:
187 0 : setPlayBend(v.toBool());
188 0 : break;
189 4 : case Pid::LINE_WIDTH:
190 4 : m_lineWidth = v.value<Spatium>();
191 4 : break;
192 0 : case Pid::BEND_TYPE:
193 0 : updatePointsByBendType(static_cast<BendType>(v.toInt()));
194 0 : break;
195 0 : case Pid::BEND_CURVE:
196 0 : setPoints(v.value<PitchValues>());
197 0 : break;
198 0 : default:
199 0 : return EngravingItem::setProperty(id, v);
200 : }
201 16 : triggerLayout();
202 16 : return true;
203 : }
204 :
205 : //---------------------------------------------------------
206 : // propertyDefault
207 : //---------------------------------------------------------
208 :
209 40 : PropertyValue Bend::propertyDefault(Pid id) const
210 : {
211 40 : switch (id) {
212 4 : case Pid::PLAY:
213 4 : return true;
214 0 : case Pid::BEND_TYPE:
215 0 : return static_cast<int>(BendType::BEND);
216 0 : case Pid::BEND_CURVE:
217 0 : return BEND_CURVE;
218 36 : default:
219 36 : return EngravingItem::propertyDefault(id);
220 : }
221 : }
|