Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-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 "articulationpatternsegmentitem.h"
24 :
25 : using namespace muse::mpe;
26 :
27 0 : ArticulationPatternSegmentItem::ArticulationPatternSegmentItem(QObject* parent, const ArticulationPatternSegment& segment,
28 0 : const int scopePositionFrom, const int scopePositionTo)
29 0 : : QObject(parent)
30 : {
31 0 : load(segment, scopePositionFrom, scopePositionTo);
32 0 : }
33 :
34 0 : ArticulationPatternSegment ArticulationPatternSegmentItem::patternSegmentData() const
35 : {
36 0 : ArticulationPatternSegment result;
37 :
38 0 : result.arrangementPattern.durationFactor = durationFactor();
39 0 : result.arrangementPattern.timestampOffset = timestampShiftFactor();
40 :
41 0 : result.pitchPattern.pitchOffsetMap = pitchOffsetsMap();
42 :
43 0 : result.expressionPattern.dynamicOffsetMap = dynamicOffsetsMap();
44 :
45 0 : return result;
46 0 : }
47 :
48 0 : void ArticulationPatternSegmentItem::load(const ArticulationPatternSegment& segment,
49 : const int scopePositionFrom,
50 : const int scopePositionTo)
51 : {
52 0 : auto pointsFromMap = [](const SharedMap<duration_percentage_t, percentage_t>& map) -> QList<QPoint> {
53 0 : QList<QPoint> result;
54 0 : for (const auto& pair : map) {
55 0 : result << QPoint(pair.first, pair.second);
56 : }
57 :
58 0 : return result;
59 0 : };
60 :
61 0 : setPositionFrom(scopePositionFrom);
62 0 : setPositionTo(scopePositionTo);
63 :
64 0 : setDurationFactor(segment.arrangementPattern.durationFactor);
65 0 : setTimestampShiftFactor(segment.arrangementPattern.timestampOffset);
66 :
67 0 : setPitchOffsets(pointsFromMap(segment.pitchPattern.pitchOffsetMap));
68 :
69 0 : setDynamicOffsets(pointsFromMap(segment.expressionPattern.dynamicOffsetMap));
70 0 : }
71 :
72 0 : int ArticulationPatternSegmentItem::durationFactor() const
73 : {
74 0 : return m_durationFactor;
75 : }
76 :
77 0 : void ArticulationPatternSegmentItem::setDurationFactor(int newDurationFactor)
78 : {
79 0 : if (m_durationFactor == newDurationFactor) {
80 0 : return;
81 : }
82 0 : m_durationFactor = newDurationFactor;
83 0 : emit durationFactorChanged();
84 : }
85 :
86 0 : int ArticulationPatternSegmentItem::timestampShiftFactor() const
87 : {
88 0 : return m_timestampShiftFactor;
89 : }
90 :
91 0 : void ArticulationPatternSegmentItem::setTimestampShiftFactor(int newTimestampShiftFactor)
92 : {
93 0 : if (m_timestampShiftFactor == newTimestampShiftFactor) {
94 0 : return;
95 : }
96 0 : m_timestampShiftFactor = newTimestampShiftFactor;
97 0 : emit timestampShiftFactorChanged();
98 : }
99 :
100 0 : const QList<QPoint>& ArticulationPatternSegmentItem::pitchOffsets() const
101 : {
102 0 : return m_pitchOffsets;
103 : }
104 :
105 0 : const QList<QPoint>& ArticulationPatternSegmentItem::dynamicOffsets() const
106 : {
107 0 : return m_dynamicOffsets;
108 : }
109 :
110 0 : int ArticulationPatternSegmentItem::positionFrom() const
111 : {
112 0 : return m_scopePositionFrom;
113 : }
114 :
115 0 : void ArticulationPatternSegmentItem::setPositionFrom(int newScopePositionFrom)
116 : {
117 0 : if (m_scopePositionFrom == newScopePositionFrom) {
118 0 : return;
119 : }
120 0 : m_scopePositionFrom = newScopePositionFrom;
121 0 : emit positionFromChanged();
122 : }
123 :
124 0 : int ArticulationPatternSegmentItem::positionTo() const
125 : {
126 0 : return m_scopePositionTo;
127 : }
128 :
129 0 : void ArticulationPatternSegmentItem::setPositionTo(int newScopePositionTo)
130 : {
131 0 : if (m_scopePositionTo == newScopePositionTo) {
132 0 : return;
133 : }
134 0 : m_scopePositionTo = newScopePositionTo;
135 0 : emit positionToChanged();
136 : }
137 :
138 0 : int ArticulationPatternSegmentItem::selectedDynamicOffsetIndex() const
139 : {
140 0 : return m_selectedDynamicOffsetIndex;
141 : }
142 :
143 0 : void ArticulationPatternSegmentItem::setSelectedDynamicOffsetIndex(int newSelectedDynamicOffsetIndex)
144 : {
145 0 : if (m_selectedDynamicOffsetIndex == newSelectedDynamicOffsetIndex) {
146 0 : return;
147 : }
148 0 : m_selectedDynamicOffsetIndex = newSelectedDynamicOffsetIndex;
149 0 : emit selectedDynamicOffsetIndexChanged();
150 : }
151 :
152 0 : int ArticulationPatternSegmentItem::dynamicOffsetValueAt(const int index)
153 : {
154 0 : if (index >= m_dynamicOffsets.size()) {
155 0 : return 0;
156 : }
157 :
158 0 : return m_dynamicOffsets.at(index).y();
159 : }
160 :
161 0 : void ArticulationPatternSegmentItem::updateDynamicOffsetValue(const int index, const int value)
162 : {
163 0 : if (index >= m_dynamicOffsets.size()) {
164 0 : return;
165 : }
166 :
167 0 : m_dynamicOffsets[index].setY(value);
168 0 : emit dynamicOffsetsChanged();
169 : }
170 :
171 0 : int ArticulationPatternSegmentItem::selectedPitchOffsetIndex() const
172 : {
173 0 : return m_selectedPitchOffsetIndex;
174 : }
175 :
176 0 : void ArticulationPatternSegmentItem::setSelectedPitchOffsetIndex(int newSelectedPitchOffsetIndex)
177 : {
178 0 : if (m_selectedPitchOffsetIndex == newSelectedPitchOffsetIndex) {
179 0 : return;
180 : }
181 0 : m_selectedPitchOffsetIndex = newSelectedPitchOffsetIndex;
182 0 : emit selectedPitchOffsetIndexChanged();
183 : }
184 :
185 0 : int ArticulationPatternSegmentItem::pitchOffsetValueAt(const int index)
186 : {
187 0 : if (index >= m_pitchOffsets.size()) {
188 0 : return 0;
189 : }
190 :
191 0 : return m_pitchOffsets.at(index).y();
192 : }
193 :
194 0 : void ArticulationPatternSegmentItem::updatePitchOffsetValue(const int index, const int value)
195 : {
196 0 : if (index >= m_pitchOffsets.size()) {
197 0 : return;
198 : }
199 :
200 0 : m_pitchOffsets[index].setY(value);
201 0 : emit pitchOffsetsChanged();
202 : }
203 :
204 0 : void ArticulationPatternSegmentItem::setPitchOffsets(const QList<QPoint>& offsets)
205 : {
206 0 : if (m_pitchOffsets == offsets) {
207 0 : return;
208 : }
209 :
210 0 : m_pitchOffsets = offsets;
211 0 : emit pitchOffsetsChanged();
212 : }
213 :
214 0 : void ArticulationPatternSegmentItem::setDynamicOffsets(const QList<QPoint>& offsets)
215 : {
216 0 : if (m_dynamicOffsets == offsets) {
217 0 : return;
218 : }
219 :
220 0 : m_dynamicOffsets = offsets;
221 0 : emit dynamicOffsetsChanged();
222 : }
223 :
224 0 : int ArticulationPatternSegmentItem::singlePercentValue() const
225 : {
226 0 : return ONE_PERCENT;
227 : }
228 :
229 0 : PitchPattern::PitchOffsetMap ArticulationPatternSegmentItem::pitchOffsetsMap() const
230 : {
231 0 : PitchPattern::PitchOffsetMap result;
232 0 : for (const QPoint& point : m_pitchOffsets) {
233 0 : result.emplace(point.x(), point.y());
234 : }
235 :
236 0 : return result;
237 0 : }
238 :
239 0 : ExpressionPattern::DynamicOffsetMap ArticulationPatternSegmentItem::dynamicOffsetsMap() const
240 : {
241 0 : ExpressionPattern::DynamicOffsetMap result;
242 0 : for (const QPoint& point : m_dynamicOffsets) {
243 0 : result.emplace(point.x(), point.y());
244 : }
245 :
246 0 : return result;
247 0 : }
|