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 <QQmlEngine>
26 :
27 : #include "engraving/dom/interval.h"
28 : #include "engraving/types/fraction.h"
29 : #include "engraving/types/types.h"
30 :
31 : namespace mu::engraving::apiv1 {
32 : //---------------------------------------------------------
33 : // FractionWrapper
34 : /// Fraction object available to QML plugins.
35 : /// Use PluginAPI::PluginAPI::fraction to create a
36 : /// fraction for usage within your plugin:
37 : /// \code
38 : /// var ts = newElement(EngravingItem.TIMESIG);
39 : /// ts.timesig = fraction(3, 4);
40 : /// \endcode
41 : //---------------------------------------------------------
42 :
43 : class Fraction : public QObject
44 : {
45 : Q_OBJECT
46 : /// Fraction numerator
47 : Q_PROPERTY(int numerator READ numerator)
48 : /// Fraction denominator
49 : Q_PROPERTY(int denominator READ denominator)
50 : /// MIDI ticks number equal to the number of the whole
51 : /// notes represented by this fraction.
52 : Q_PROPERTY(int ticks READ ticks)
53 : /// String representation of this fraction
54 : Q_PROPERTY(QString str READ toString)
55 : /// Real computed value of this fraction,
56 : /// e.g. 0.25 for a fraction of 1/4.
57 : /// \since MuseScore 4.6
58 : Q_PROPERTY(qreal real READ toDouble)
59 : /// Returns a reduced (simplified) fraction equal in value to this fraction.
60 : /// E.g. a fraction of 6/8 returns a fraction of 3/4.
61 : /// \since MuseScore 4.6
62 : Q_PROPERTY(apiv1::Fraction * reduced READ reduced)
63 : /// Returns the inverse (reciprocal) fraction of this fraction.
64 : /// E.g. a fraction of 2/16 returns a fraction of 16/2.
65 : /// \since MuseScore 4.6
66 : Q_PROPERTY(apiv1::Fraction * inverse READ inverse)
67 : /// Returns the absolute value of this fraction.
68 : /// E.g. a fraction of -3/2 returns a fraction of 3/2.
69 : /// \since MuseScore 4.6
70 : Q_PROPERTY(apiv1::Fraction * absValue READ absValue)
71 :
72 : mu::engraving::Fraction f;
73 :
74 : /// \cond MS_INTERNAL
75 : // public slots:
76 : // void setFraction(engraving::Fraction m_f) { f = m_f; }
77 :
78 : public:
79 0 : Fraction() = default;
80 14 : Fraction(const mu::engraving::Fraction& m_f)
81 14 : : f(m_f) {}
82 :
83 14 : mu::engraving::Fraction fraction() const { return f; }
84 0 : int numerator() const { return f.numerator(); }
85 0 : int denominator() const { return f.denominator(); }
86 0 : int ticks() const { return f.ticks(); }
87 0 : QString toString() const { return f.toString(); }
88 0 : qreal toDouble() const { return f.toDouble(); }
89 : Fraction* reduced() const;
90 : Fraction* inverse() const;
91 : Fraction* absValue() const;
92 : /// \endcond
93 :
94 : // Arithmetic
95 : /// Returns the sum of two fractions.
96 : /// \since MuseScore 4.6
97 : Q_INVOKABLE apiv1::Fraction* plus(apiv1::Fraction* other);
98 : /// Returns the difference between two fractions.
99 : /// \since MuseScore 4.6
100 : Q_INVOKABLE apiv1::Fraction* minus(apiv1::Fraction* other);
101 : /// Returns the product of two fractions.
102 : /// \since MuseScore 4.6
103 : Q_INVOKABLE apiv1::Fraction* times(apiv1::Fraction* other);
104 : /// Returns the product of a fraction with an integer.
105 : /// \since MuseScore 4.6
106 : Q_INVOKABLE apiv1::Fraction* times(int v);
107 : /// Returns the quotient of two fractions.
108 : /// \since MuseScore 4.6
109 : Q_INVOKABLE apiv1::Fraction* dividedBy(apiv1::Fraction* other);
110 : /// Returns the quotient of a fraction and an integer.
111 : /// \since MuseScore 4.6
112 : Q_INVOKABLE apiv1::Fraction* dividedBy(int v);
113 :
114 : // Comparators
115 : /// Returns whether the first fraction is larger than the second.
116 : /// \since MuseScore 4.6
117 : Q_INVOKABLE bool greaterThan(apiv1::Fraction* other);
118 : /// Returns whether the first fraction is smaller than the second.
119 : /// \since MuseScore 4.6
120 : Q_INVOKABLE bool lessThan(apiv1::Fraction* other);
121 : /// Returns whether the first fraction is equivalent in value second.
122 : /// Comparing e.g. 2/4 to 1/2 returns true.
123 : /// \since MuseScore 4.6
124 : Q_INVOKABLE bool equals(apiv1::Fraction* other);
125 : /// Returns whether the numerators and denominators of two fractions match.
126 : /// Comparing e.g. 2/4 to 1/2 returns false.
127 : /// \since MuseScore 4.6
128 : Q_INVOKABLE bool identical(apiv1::Fraction* other);
129 : };
130 :
131 : //---------------------------------------------------------
132 : // wrap
133 : /// \cond PLUGIN_API \private \endcond
134 : /// \relates FractionWrapper
135 : //---------------------------------------------------------
136 :
137 0 : inline apiv1::Fraction* wrap(mu::engraving::Fraction f)
138 : {
139 0 : apiv1::Fraction* w = new apiv1::Fraction(f);
140 : // All wrapper objects should belong to JavaScript code.
141 0 : QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
142 0 : return w;
143 : }
144 :
145 : //---------------------------------------------------------
146 : // OrnamentIntervalWrapper
147 : /// Ornament interval wrapper object available to QML plugins.
148 : /// Use PluginAPI::PluginAPI::ornamentInterval to create an
149 : /// ornament interval for usage within your plugin:
150 : /// \code
151 : /// var interval = ornamentInterval(IntervalStep.SECOND, IntervalType.MAJOR);
152 : /// \endcode
153 : //---------------------------------------------------------
154 :
155 : class OrnamentIntervalWrapper : public QObject
156 : {
157 : Q_OBJECT
158 : /// Interval step
159 : Q_PROPERTY(IntervalStep step READ step)
160 : /// Interval type
161 : Q_PROPERTY(IntervalType type READ type)
162 : /// Whether this interval is perfect
163 : Q_PROPERTY(bool isPerfect READ isPerfect)
164 :
165 : mu::engraving::OrnamentInterval o;
166 :
167 : /// \cond MS_INTERNAL
168 : public slots:
169 0 : void setOrnamentInterval(engraving::OrnamentInterval m_o) { o = m_o; }
170 :
171 : public:
172 0 : OrnamentIntervalWrapper() = default;
173 0 : OrnamentIntervalWrapper(const mu::engraving::OrnamentInterval& m_o)
174 0 : : o(m_o) {}
175 :
176 0 : mu::engraving::OrnamentInterval ornamentInterval() const { return o; }
177 0 : IntervalStep step() const { return IntervalStep(o.step); }
178 0 : IntervalType type() const { return IntervalType(o.type); }
179 0 : bool isPerfect() const { return o.isPerfect(); }
180 : /// \endcond
181 : };
182 :
183 : //---------------------------------------------------------
184 : // wrap
185 : /// \cond PLUGIN_API \private \endcond
186 : /// \relates OrnamentIntervalWrapper
187 : //---------------------------------------------------------
188 :
189 0 : inline OrnamentIntervalWrapper* wrap(mu::engraving::OrnamentInterval o)
190 : {
191 0 : OrnamentIntervalWrapper* w = new OrnamentIntervalWrapper(o);
192 : // All wrapper objects should belong to JavaScript code.
193 0 : QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
194 0 : return w;
195 : }
196 :
197 : //---------------------------------------------------------
198 : // IntervalWrapper
199 : /// Interval wrapper object available to QML plugins.
200 : /// Use PluginAPI::PluginAPI::interval to create an
201 : /// interval for usage within your plugin:
202 : /// \code
203 : /// var interval = interval(5, 9); // Major 6th
204 : /// \endcode
205 : //---------------------------------------------------------
206 :
207 : class IntervalWrapper : public QObject
208 : {
209 : Q_OBJECT
210 : /// Diatonic steps
211 : Q_PROPERTY(int diatonic READ diatonic)
212 : /// Chromatic steps
213 : Q_PROPERTY(int chromatic READ chromatic)
214 : /// Whether this interval is perfect
215 : Q_PROPERTY(bool isZero READ isZero)
216 :
217 : mu::engraving::Interval i;
218 :
219 : /// \cond MS_INTERNAL
220 : public slots:
221 0 : void setInterval(engraving::Interval m_i) { i = m_i; }
222 :
223 : public:
224 0 : IntervalWrapper() = default;
225 0 : IntervalWrapper(const mu::engraving::Interval& m_i)
226 0 : : i(m_i) {}
227 :
228 : mu::engraving::Interval interval() const { return i; }
229 0 : int diatonic() const { return i.diatonic; }
230 0 : int chromatic() const { return i.chromatic; }
231 0 : bool isZero() const { return i.isZero(); }
232 : /// \endcond
233 :
234 : /// Flip (invert) the interval.
235 0 : Q_INVOKABLE void flip() { i.flip(); }
236 : };
237 :
238 : //---------------------------------------------------------
239 : // wrap
240 : /// \cond PLUGIN_API \private \endcond
241 : /// \relates IntervalWrapper
242 : //---------------------------------------------------------
243 :
244 0 : inline IntervalWrapper* wrap(mu::engraving::Interval i)
245 : {
246 0 : IntervalWrapper* w = new IntervalWrapper(i);
247 : // All wrapper objects should belong to JavaScript code.
248 0 : QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
249 0 : return w;
250 : }
251 : }
|