Loading...
Searching...
No Matches
QmlObjects.hpp
1#pragma once
2#include <State/Domain.hpp>
3
4#include <Process/Dataflow/Port.hpp>
5#include <Process/Dataflow/WidgetInlets.hpp>
6
7#include <JS/Qml/QtMetatypes.hpp>
8
9#include <libremidi/detail/conversion.hpp>
10
11#if defined(SCORE_HAS_GPU_JS)
12#include <Gfx/TexturePort.hpp>
13
14#include <QQuickItem>
15#endif
16
17#include <score/tools/Debug.hpp>
18
19#include <ossia/detail/math.hpp>
20#include <ossia/detail/ssize.hpp>
21#include <ossia/network/domain/domain.hpp>
22
23#include <ossia-qt/js_utilities.hpp>
24
25#include <QJSValue>
26#include <QObject>
27#include <QQmlListProperty>
28#include <QVariant>
29#include <QVector>
30
31#include <libremidi/message.hpp>
32#include <libremidi/ump.hpp>
33
34#include <score_plugin_js_export.h>
35#include <wobjectimpl.h>
36
37#include <verdigris>
38
39class QQuickItem;
40namespace JS
41{
42class SCORE_PLUGIN_JS_EXPORT Inlet : public QObject
43{
44 W_OBJECT(Inlet)
45
46public:
47 using QObject::QObject;
48 virtual ~Inlet() override;
49 virtual Process::Inlet* make(Id<Process::Port>&& id, QObject*) = 0;
50 virtual bool isEvent() const { return false; }
51
52 W_INLINE_PROPERTY_CREF(QString, address, {}, address, setAddress, addressChanged)
53};
54
55class SCORE_PLUGIN_JS_EXPORT Outlet : public QObject
56{
57 W_OBJECT(Outlet)
58
59public:
60 using QObject::QObject;
61 virtual ~Outlet() override;
62 virtual Process::Outlet* make(Id<Process::Port>&& id, QObject*) = 0;
63
64 W_INLINE_PROPERTY_CREF(QString, address, {}, address, setAddress, addressChanged)
65};
66
67struct SCORE_PLUGIN_JS_EXPORT InValueMessage
68{
69 W_GADGET(InValueMessage)
70
71public:
72 qreal timestamp;
73 QVariant value;
74 W_PROPERTY(qreal, timestamp MEMBER timestamp)
75 W_PROPERTY(QVariant, value MEMBER value)
76};
77
78struct SCORE_PLUGIN_JS_EXPORT OutValueMessage
79{
80 W_GADGET(OutValueMessage)
81
82public:
83 qreal timestamp;
84 QJSValue value;
85 W_PROPERTY(qreal, timestamp MEMBER timestamp)
86 W_PROPERTY(QJSValue, value MEMBER value)
87};
88
89class SCORE_PLUGIN_JS_EXPORT ValueInlet : public Inlet
90{
91 W_OBJECT(ValueInlet)
92
93 QVariant m_value;
94 QVariantList m_values;
95
96public:
97 explicit ValueInlet(QObject* parent = nullptr);
98 virtual ~ValueInlet() override;
99 QVariant value() const;
100 QVariantList values() const { return m_values; }
101
102 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
103 {
104 return new Process::ValueInlet(objectName(), id, parent);
105 }
106
107 int length() const noexcept;
108 W_SLOT(length)
109
110 QVariant at(int index) const noexcept;
111 W_SLOT(at)
112
113 void clear() { m_values.clear(); }
114 void setValue(QVariant value);
115 void addValue(QVariant&& val) { m_values.append(std::move(val)); }
116 void valueChanged(QVariant value) W_SIGNAL(valueChanged, value);
117
118 W_PROPERTY(QVariantList, values READ values)
119 W_PROPERTY(QVariant, value READ value NOTIFY valueChanged)
120};
121
122class SCORE_PLUGIN_JS_EXPORT ControlInlet : public Inlet
123{
124 W_OBJECT(ControlInlet)
125
126 QVariant m_value;
127
128public:
129 explicit ControlInlet(QObject* parent = nullptr);
130 virtual ~ControlInlet() override;
131 QVariant value() const noexcept;
132
133 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
134 {
135 return new Process::ControlInlet(objectName(), id, parent);
136 }
137
138 void clear() { m_value = QVariant{}; }
139 virtual void setValue(QVariant value);
140 void valueChanged(QVariant value) W_SIGNAL(valueChanged, value);
141
142 W_PROPERTY(QVariant, value READ value NOTIFY valueChanged)
143};
144
145template <typename Impl, typename ValueType, typename OssiaType>
146class SCORE_PLUGIN_JS_EXPORT GenericControlInlet : public ControlInlet
147{
148 W_OBJECT(GenericControlInlet)
149
150public:
151 using ControlInlet::ControlInlet;
152 virtual ~GenericControlInlet() override = default;
153 bool isEvent() const override { return true; }
154 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
155 {
156 return new Impl(objectName(), id, parent);
157 }
158
159 void clear() { m_value = {}; }
160 ValueType value() const noexcept { return m_value; }
161 void setValue(QVariant value) override
162 {
163 auto conv = value.value<ValueType>();
164 if(m_value == conv)
165 return;
166
167 m_value = std::move(conv);
168 valueChanged(m_value);
169 }
170 void setValue(ValueType value)
171 {
172 if(m_value == value)
173 return;
174
175 m_value = value;
176 valueChanged(m_value);
177 }
178 void valueChanged(ValueType value) W_SIGNAL(valueChanged, value);
179
180 W_PROPERTY(ValueType, value READ value NOTIFY valueChanged)
181
182protected:
183 ValueType m_value{};
184};
185W_OBJECT_IMPL(
186 (GenericControlInlet<A, B, C>), template <typename A, typename B, typename C>)
187struct SCORE_PLUGIN_JS_EXPORT MultiSlider
189 Process::MultiSlider, QVector<qreal>, std::vector<ossia::value>>
190{
191 W_OBJECT(MultiSlider);
192 using GenericControlInlet::GenericControlInlet;
193};
194struct SCORE_PLUGIN_JS_EXPORT FileChooser
195 : JS::GenericControlInlet<Process::FileChooser, QString, std::string>
196{
197 W_OBJECT(FileChooser);
198 using GenericControlInlet::GenericControlInlet;
199};
200struct SCORE_PLUGIN_JS_EXPORT AudioFileChooser
201 : JS::GenericControlInlet<Process::AudioFileChooser, QString, std::string>
202{
203 W_OBJECT(AudioFileChooser);
204 using GenericControlInlet::GenericControlInlet;
205};
206struct SCORE_PLUGIN_JS_EXPORT VideoFileChooser
207 : JS::GenericControlInlet<Process::VideoFileChooser, QString, std::string>
208{
209 W_OBJECT(VideoFileChooser);
210 using GenericControlInlet::GenericControlInlet;
211};
212
213template <typename Impl = Process::FloatSlider>
214class SCORE_PLUGIN_JS_EXPORT FloatSlider : public GenericControlInlet<Impl, float, float>
215{
216 W_OBJECT(FloatSlider)
217
218public:
219 using GenericControlInlet<Impl, float, float>::GenericControlInlet;
220 virtual ~FloatSlider() override = default;
221 bool isEvent() const override { return true; }
222
223 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
224 {
225 return new Impl{(float)m_min, (float)m_max, (float)m_init,
226 this->objectName(), id, parent};
227 }
228
229 W_INLINE_PROPERTY_VALUE(qreal, init, {0.5}, init, setInit, initChanged)
230 W_INLINE_PROPERTY_VALUE(qreal, min, {0.}, getMin, setMin, minChanged)
231 W_INLINE_PROPERTY_VALUE(qreal, max, {1.}, getMax, setMax, maxChanged)
232};
233W_OBJECT_IMPL(JS::FloatSlider<Impl>, template <typename Impl>)
234
235template <typename Impl = Process::IntSlider>
236class SCORE_PLUGIN_JS_EXPORT IntSlider : public GenericControlInlet<Impl, int, int>
237{
238 W_OBJECT(IntSlider)
239
240public:
241 using GenericControlInlet<Impl, int, int>::GenericControlInlet;
242 virtual ~IntSlider() override = default;
243 bool isEvent() const override { return true; }
244
245 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
246 {
247 return new Impl{m_min, m_max, m_init, this->objectName(), id, parent};
248 }
249
250 W_INLINE_PROPERTY_VALUE(int, init, {0}, init, setInit, initChanged)
251 W_INLINE_PROPERTY_VALUE(int, min, {0}, getMin, setMin, minChanged)
252 W_INLINE_PROPERTY_VALUE(int, max, {127}, getMax, setMax, maxChanged)
253};
254W_OBJECT_IMPL(JS::IntSlider<Impl>, template <typename Impl>)
255
256static constexpr auto vec2(double v)
257{
258 return QVector2D{(float)v, (float)v};
259}
260static constexpr auto vec3(double v)
261{
262 return QVector3D{(float)v, (float)v, (float)v};
263}
264static constexpr auto vec4(double v)
265{
266 return QVector4D{(float)v, (float)v, (float)v, (float)v};
267}
268static constexpr auto vec_to_ossia(QVector2D v)
269{
270 return ossia::vec2f{(float)v[0], (float)v[1]};
271}
272static constexpr auto vec_to_ossia(QVector3D v)
273{
274 return ossia::vec3f{(float)v[0], (float)v[1], (float)v[2]};
275}
276static constexpr auto vec_to_ossia(QVector4D v)
277{
278 return ossia::vec4f{(float)v[0], (float)v[1], (float)v[2], (float)v[3]};
279}
280
281template <typename Impl>
282class SCORE_PLUGIN_JS_EXPORT FloatControl2D
283 : public GenericControlInlet<Impl, QVector2D, ossia::vec2f>
284{
285 W_OBJECT(FloatControl2D)
286
287public:
288 using GenericControlInlet<Impl, QVector2D, ossia::vec2f>::GenericControlInlet;
289 virtual ~FloatControl2D() override = default;
290 bool isEvent() const override { return true; }
291
292 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
293 {
294 if constexpr(std::is_constructible_v<
295 Impl, ossia::vec2f, ossia::vec2f, ossia::vec2f, bool, QString,
296 Id<Process::Port>, QObject*>)
297 return new Impl{
298 vec_to_ossia(m_min),
299 vec_to_ossia(m_max),
300 vec_to_ossia(m_init),
301 false,
302 this->objectName(),
303 id,
304 parent};
305 else if constexpr(std::is_constructible_v<
306 Impl, ossia::vec2f, ossia::vec2f, ossia::vec2f, QString,
307 Id<Process::Port>, QObject*>)
308 return new Impl{
309 vec_to_ossia(m_min),
310 vec_to_ossia(m_max),
311 vec_to_ossia(m_init),
312 this->objectName(),
313 id,
314 parent};
315 else
316 return new Impl{vec_to_ossia(m_init), this->objectName(), id, parent};
317 }
318
319 W_INLINE_PROPERTY_VALUE(QVector2D, init, {vec2(0.)}, init, setInit, initChanged);
320 W_INLINE_PROPERTY_VALUE(QVector2D, min, {vec2(0.)}, getMin, setMin, minChanged);
321 W_INLINE_PROPERTY_VALUE(QVector2D, max, {vec2(1.)}, getMax, setMax, maxChanged);
322};
323W_OBJECT_IMPL(JS::FloatControl2D<Impl>, template <typename Impl>)
324
325template <typename Impl>
326class SCORE_PLUGIN_JS_EXPORT IntControl2D
327 : public GenericControlInlet<Impl, QVector2D, ossia::vec2f>
328{
329 W_OBJECT(IntControl2D)
330
331public:
332 using GenericControlInlet<Impl, QVector2D, ossia::vec2f>::GenericControlInlet;
333 virtual ~IntControl2D() override = default;
334 bool isEvent() const override { return true; }
335
336 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
337 {
338 return new Impl{
339 vec_to_ossia(m_min),
340 vec_to_ossia(m_max),
341 vec_to_ossia(m_init),
342 true,
343 this->objectName(),
344 id,
345 parent};
346 }
347
348 W_INLINE_PROPERTY_VALUE(QVector2D, init, {vec2(0.)}, init, setInit, initChanged);
349 W_INLINE_PROPERTY_VALUE(QVector2D, min, {vec2(0.)}, getMin, setMin, minChanged);
350 W_INLINE_PROPERTY_VALUE(QVector2D, max, {vec2(1.)}, getMax, setMax, maxChanged);
351};
352W_OBJECT_IMPL(JS::IntControl2D<Impl>, template <typename Impl>)
353
354template <typename Impl>
355class SCORE_PLUGIN_JS_EXPORT FloatControl1D_2D
356 : public GenericControlInlet<Impl, QVector2D, ossia::vec2f>
357{
358 W_OBJECT(FloatControl1D_2D)
359
360public:
361 using GenericControlInlet<Impl, QVector2D, ossia::vec2f>::GenericControlInlet;
362 virtual ~FloatControl1D_2D() override = default;
363 bool isEvent() const override { return true; }
364
365 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
366 {
367 return new Impl(m_min, m_max, vec_to_ossia(m_init), this->objectName(), id, parent);
368 }
369
370 W_INLINE_PROPERTY_VALUE(QVector2D, init, {vec2(0.)}, init, setInit, initChanged);
371 W_INLINE_PROPERTY_VALUE(float, min, {0.}, getMin, setMin, minChanged);
372 W_INLINE_PROPERTY_VALUE(float, max, {1.}, getMax, setMax, maxChanged);
373};
374W_OBJECT_IMPL(JS::FloatControl1D_2D<Impl>, template <typename Impl>)
375
376template <typename Impl>
377class SCORE_PLUGIN_JS_EXPORT FloatControl3D
378 : public GenericControlInlet<Impl, QVector3D, ossia::vec3f>
379{
380 W_OBJECT(FloatControl3D)
381
382public:
383 using GenericControlInlet<Impl, QVector3D, ossia::vec3f>::GenericControlInlet;
384 virtual ~FloatControl3D() override = default;
385 bool isEvent() const override { return true; }
386
387 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
388 {
389 if constexpr(std::is_constructible_v<
390 Impl, ossia::vec3f, ossia::vec3f, ossia::vec3f, bool, QString,
391 Id<Process::Port>, QObject*>)
392 return new Impl{
393 vec_to_ossia(m_min),
394 vec_to_ossia(m_max),
395 vec_to_ossia(m_init),
396 false,
397 this->objectName(),
398 id,
399 parent};
400 else if constexpr(std::is_constructible_v<
401 Impl, ossia::vec3f, ossia::vec3f, ossia::vec3f, QString,
402 Id<Process::Port>, QObject*>)
403 return new Impl{
404 vec_to_ossia(m_min),
405 vec_to_ossia(m_max),
406 vec_to_ossia(m_init),
407 this->objectName(),
408 id,
409 parent};
410 else
411 return new Impl{vec_to_ossia(m_init), this->objectName(), id, parent};
412 }
413
414 W_INLINE_PROPERTY_VALUE(QVector3D, init, {vec3(0.)}, init, setInit, initChanged);
415 W_INLINE_PROPERTY_VALUE(QVector3D, min, {vec3(0.)}, getMin, setMin, minChanged);
416 W_INLINE_PROPERTY_VALUE(QVector3D, max, {vec3(1.)}, getMax, setMax, maxChanged);
417};
418W_OBJECT_IMPL(JS::FloatControl3D<Impl>, template <typename Impl>)
419
420template <typename Impl>
421class SCORE_PLUGIN_JS_EXPORT IntControl3D
422 : public GenericControlInlet<Impl, QVector3D, ossia::vec3f>
423{
424 W_OBJECT(IntControl3D)
425
426public:
427 using GenericControlInlet<Impl, QVector3D, ossia::vec3f>::GenericControlInlet;
428 virtual ~IntControl3D() override = default;
429 bool isEvent() const override { return true; }
430
431 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
432 {
433 return new Impl{
434 vec_to_ossia(m_min),
435 vec_to_ossia(m_max),
436 vec_to_ossia(m_init),
437 true,
438 this->objectName(),
439 id,
440 parent};
441 }
442
443 W_INLINE_PROPERTY_VALUE(QVector3D, init, {vec3(0.)}, init, setInit, initChanged);
444 W_INLINE_PROPERTY_VALUE(QVector3D, min, {vec3(0.)}, getMin, setMin, minChanged);
445 W_INLINE_PROPERTY_VALUE(QVector3D, max, {vec3(1.)}, getMax, setMax, maxChanged);
446};
447W_OBJECT_IMPL(JS::IntControl3D<Impl>, template <typename Impl>)
448
449template <typename Impl>
450class SCORE_PLUGIN_JS_EXPORT FloatControl4D
451 : public GenericControlInlet<Impl, QVector4D, ossia::vec4f>
452{
453 W_OBJECT(FloatControl4D)
454
455public:
456 using GenericControlInlet<Impl, QVector4D, ossia::vec4f>::GenericControlInlet;
457 virtual ~FloatControl4D() override = default;
458 bool isEvent() const override { return true; }
459
460 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
461 {
462 if constexpr(std::is_constructible_v<
463 Impl, ossia::vec4f, ossia::vec4f, ossia::vec4f, QString,
464 Id<Process::Port>, QObject*>)
465 return new Impl{
466 vec_to_ossia(m_min),
467 vec_to_ossia(m_max),
468 vec_to_ossia(m_init),
469 this->objectName(),
470 id,
471 parent};
472 else
473 return new Impl{vec_to_ossia(m_init), this->objectName(), id, parent};
474 }
475
476 W_INLINE_PROPERTY_VALUE(QVector4D, init, {vec4(0.)}, init, setInit, initChanged);
477 W_INLINE_PROPERTY_VALUE(QVector4D, min, {vec4(0.)}, getMin, setMin, minChanged);
478 W_INLINE_PROPERTY_VALUE(QVector4D, max, {vec4(1.)}, getMax, setMax, maxChanged);
479};
480W_OBJECT_IMPL(JS::FloatControl4D<Impl>, template <typename Impl>)
481
482class SCORE_PLUGIN_JS_EXPORT Enum : public ControlInlet
483{
484 W_OBJECT(Enum)
485
486public:
487 using ControlInlet::ControlInlet;
488 virtual ~Enum() override;
489 bool isEvent() const override { return true; }
490
491 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
492 {
493 return new Process::Enum{m_choices, {}, current(), objectName(), id, parent};
494 }
495
496 auto getValues() const { return choices(); }
497
498 std::string current() const
499 {
500 if(!m_choices.isEmpty() && ossia::valid_index(m_index, m_choices))
501 {
502 return m_choices[m_index].toStdString();
503 }
504 return {};
505 }
506
507 W_INLINE_PROPERTY_VALUE(int, index, {}, index, setIndex, indexChanged)
508 W_INLINE_PROPERTY_CREF(QStringList, choices, {}, choices, setChoices, choicesChanged)
509};
510
511class SCORE_PLUGIN_JS_EXPORT ComboBox : public ControlInlet
512{
513 W_OBJECT(ComboBox)
514
515public:
516 using ControlInlet::ControlInlet;
517 virtual ~ComboBox() override;
518 bool isEvent() const override { return true; }
519
520 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
521 {
522 std::vector<std::pair<QString, ossia::value>> choices;
523 choices.reserve(m_choices.size());
524 for(auto& c : m_choices)
525 choices.emplace_back(c, c.toStdString());
526 return new Process::ComboBox{choices, current(), objectName(), id, parent};
527 }
528
529 auto getValues() const { return choices(); }
530
531 std::string current() const
532 {
533 if(!m_choices.isEmpty() && ossia::valid_index(m_index, m_choices))
534 {
535 return m_choices[m_index].toStdString();
536 }
537 return {};
538 }
539
540 W_INLINE_PROPERTY_VALUE(int, index, {}, index, setIndex, indexChanged)
541 W_INLINE_PROPERTY_CREF(QStringList, choices, {}, choices, setChoices, choicesChanged)
542};
543
544class SCORE_PLUGIN_JS_EXPORT Toggle : public ControlInlet
545{
546 W_OBJECT(Toggle)
547
548public:
549 using ControlInlet::ControlInlet;
550 virtual ~Toggle() override;
551 bool isEvent() const override { return true; }
552 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
553 {
554 return new Process::Toggle{m_checked, objectName(), id, parent};
555 }
556
557 W_INLINE_PROPERTY_VALUE(bool, checked, {}, checked, setChecked, checkedChanged)
558};
559
560class SCORE_PLUGIN_JS_EXPORT Button : public ControlInlet
561{
562 W_OBJECT(Button)
563
564public:
565 using ControlInlet::ControlInlet;
566 virtual ~Button() override;
567 bool isEvent() const override { return true; }
568 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
569 {
570 return new Process::Button{objectName(), id, parent};
571 }
572
573 W_INLINE_PROPERTY_VALUE(bool, checked, {}, checked, setChecked, checkedChanged)
574};
575
576class SCORE_PLUGIN_JS_EXPORT Impulse : public ControlInlet
577{
578 W_OBJECT(Impulse)
579
580public:
581 using ControlInlet::ControlInlet;
582 virtual ~Impulse() override;
583 bool isEvent() const override { return false; }
584 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
585 {
586 return new Process::ImpulseButton{objectName(), id, parent};
587 }
588
589 void impulse() W_SIGNAL(impulse);
590};
591
592class SCORE_PLUGIN_JS_EXPORT LineEdit : public ControlInlet
593{
594 W_OBJECT(LineEdit)
595
596public:
597 using ControlInlet::ControlInlet;
598 virtual ~LineEdit() override;
599 bool isEvent() const override { return true; }
600 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
601 {
602 return new Process::LineEdit{m_text, objectName(), id, parent};
603 }
604
605 W_INLINE_PROPERTY_CREF(QString, text, {}, text, setText, textChanged)
606};
607
608class SCORE_PLUGIN_JS_EXPORT HSVSlider
609 : public GenericControlInlet<Process::HSVSlider, QColor, ossia::vec4f>
610{
611 W_OBJECT(HSVSlider)
612
613public:
615 Process::HSVSlider, QColor, ossia::vec4f>::GenericControlInlet;
616 virtual ~HSVSlider() override;
617 bool isEvent() const override { return true; }
618 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
619 {
620 auto col = init().toRgb();
621 ossia::vec4f v{
622 (float)col.redF(), (float)col.greenF(), (float)col.blueF(), (float)col.alphaF()};
623 return new Process::HSVSlider{v, objectName(), id, parent};
624 }
625
626 void setValue(QVariant value) override
627 {
628 auto vec = value.value<QVector4D>();
629 auto conv = QColor::fromRgbF(vec[0], vec[1], vec[2], vec[3]);
630 if(m_value == conv)
631 return;
632
633 m_value = std::move(conv);
634 valueChanged(m_value);
635 }
636 W_INLINE_PROPERTY_CREF(QColor, init, {}, init, setInit, initChanged)
637};
638class SCORE_PLUGIN_JS_EXPORT ValueOutlet : public Outlet
639{
640 W_OBJECT(ValueOutlet)
641
642 QJSValue m_value;
643
644public:
645 std::vector<OutValueMessage> values;
646
647 explicit ValueOutlet(QObject* parent = nullptr);
648 virtual ~ValueOutlet() override;
649 const QJSValue& value() const;
650 void clear()
651 {
652 m_value = QJSValue{};
653 values.clear();
654 }
655 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
656 {
657 return new Process::ValueOutlet(objectName(), id, parent);
658 }
659
660public:
661 void setValue(const QJSValue& value);
662 W_SLOT(setValue);
663 void addValue(qreal timestamp, QJSValue t);
664 W_SLOT(addValue);
665
666 W_PROPERTY(QJSValue, value READ value WRITE setValue)
667};
668
669class SCORE_PLUGIN_JS_EXPORT AudioInlet : public Inlet
670{
671 W_OBJECT(AudioInlet)
672
673public:
674 explicit AudioInlet(QObject* parent = nullptr);
675 virtual ~AudioInlet() override;
676 const QVector<QVector<double>>& audio() const;
677 void setAudio(const QVector<QVector<double>>& audio);
678
679 QVector<double> channel(int i) const
680 {
681 if(m_audio.size() > i)
682 return m_audio[i];
683 return {};
684 }
685 W_INVOKABLE(channel);
686
687 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
688 {
689 return new Process::AudioInlet(objectName(), id, parent);
690 }
691
692private:
693 QVector<QVector<double>> m_audio;
694};
695
696class SCORE_PLUGIN_JS_EXPORT AudioOutlet : public Outlet
697{
698 W_OBJECT(AudioOutlet)
699
700public:
701 explicit AudioOutlet(QObject* parent = nullptr);
702 virtual ~AudioOutlet() override;
703 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
704 {
705 auto p = new Process::AudioOutlet(objectName(), id, parent);
706 if(id.val() == 0)
707 p->setPropagate(true);
708 return p;
709 }
710
711 const QVector<QVector<double>>& audio() const;
712
713 void setChannel(int i, const QJSValue& v);
714 W_INVOKABLE(setChannel)
715private:
716 QVector<QVector<double>> m_audio;
717};
718
719class SCORE_PLUGIN_JS_EXPORT MidiMessage
720{
721 W_GADGET(MidiMessage)
722
723public:
724 QByteArray bytes;
725
726 W_PROPERTY(QByteArray, bytes MEMBER bytes)
727};
728
729class SCORE_PLUGIN_JS_EXPORT MidiInlet : public Inlet
730{
731 W_OBJECT(MidiInlet)
732
733public:
734 explicit MidiInlet(QObject* parent = nullptr);
735 virtual ~MidiInlet() override;
736 template <typename T>
737 void setMidi(const T& arr)
738 {
739 m_midi.clear();
740 for(const libremidi::ump& mess : arr)
741 {
742 auto m1 = libremidi::midi1_from_ump(mess);
743 const auto N = mess.size();
744 QVector<int> m;
745 m.resize(N);
746
747 for(std::size_t i = 0; i < N; i++)
748 m[i] = m1.bytes[i];
749
750 m_midi.push_back(QVariant::fromValue(m));
751 }
752 }
753
754 QVariantList messages() const { return m_midi; }
755 W_INVOKABLE(messages);
756
757 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
758 {
759 return new Process::MidiInlet(objectName(), id, parent);
760 }
761
762private:
763 QVariantList m_midi;
764};
765
766class SCORE_PLUGIN_JS_EXPORT MidiOutlet : public Outlet
767{
768 W_OBJECT(MidiOutlet)
769
770public:
771 explicit MidiOutlet(QObject* parent = nullptr);
772 virtual ~MidiOutlet() override;
773 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
774 {
775 return new Process::MidiOutlet(objectName(), id, parent);
776 }
777
778 void clear();
779 const QVector<QVector<int>>& midi() const;
780
781 void setMessages(const QVariantList m)
782 {
783 m_midi.clear();
784 for(auto& v : m)
785 {
786 if(v.canConvert<QVector<int>>())
787 m_midi.push_back(v.value<QVector<int>>());
788 }
789 }
790 W_INVOKABLE(setMessages);
791
792 void add(QVector<int> m) { m_midi.push_back(std::move(m)); }
793 W_INVOKABLE(add);
794
795private:
796 QVector<QVector<int>> m_midi;
797};
798
799#if defined(SCORE_HAS_GPU_JS)
800class TextureInlet : public Inlet
801{
802 W_OBJECT(TextureInlet)
803
804public:
805 explicit TextureInlet(QObject* parent = nullptr);
806 virtual ~TextureInlet() override;
807 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
808 {
809 auto p = new Gfx::TextureInlet(objectName(), id, parent);
810 return p;
811 }
812
813 QQuickItem* item() const noexcept { return m_item; }
814
815 W_PROPERTY(QQuickItem*, item READ item CONSTANT)
816private:
817 QQuickItem* m_item{};
818};
819
820class TextureOutlet : public Outlet
821{
822 W_OBJECT(TextureOutlet)
823
824public:
825 explicit TextureOutlet(QObject* parent = nullptr);
826 virtual ~TextureOutlet() override;
827 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
828 {
829 auto p = new Gfx::TextureOutlet(objectName(), id, parent);
830 return p;
831 }
832
833 QQuickItem* item() const noexcept { return m_item; }
834 void setItem(QQuickItem* v) { m_item = v; }
835
836 W_PROPERTY(QQuickItem*, item READ item WRITE setItem CONSTANT)
837private:
838 QQuickItem* m_item{};
839};
840#endif
841
842class Script : public QObject
843{
844 W_OBJECT(Script)
845 W_CLASSINFO("DefaultProperty", "data")
846 W_CLASSINFO(
847 "qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
848
849public:
850 QQmlListProperty<QObject> data() noexcept { return {this, &m_data}; }
851
852 QJSValue& tick() /*Qt6: const*/ noexcept { return m_tick; }
853 void setTick(const QJSValue& v) { m_tick = v; }
854 QJSValue& start() /*Qt6: const*/ noexcept { return m_start; }
855 void setStart(const QJSValue& v) { m_start = v; }
856 QJSValue& stop() /*Qt6: const*/ noexcept { return m_stop; }
857 void setStop(const QJSValue& v) { m_stop = v; }
858 QJSValue& pause() /*Qt6: const*/ noexcept { return m_pause; }
859 void setPause(const QJSValue& v) { m_pause = v; }
860 QJSValue& resume() /*Qt6: const*/ noexcept { return m_resume; }
861 void setResume(const QJSValue& v) { m_resume = v; }
862 W_PROPERTY(QJSValue, tick READ tick WRITE setTick CONSTANT)
863 W_PROPERTY(QJSValue, start READ start WRITE setStart CONSTANT)
864 W_PROPERTY(QJSValue, stop READ stop WRITE setStop CONSTANT)
865 W_PROPERTY(QJSValue, pause READ pause WRITE setPause CONSTANT)
866 W_PROPERTY(QJSValue, resume READ resume WRITE setResume CONSTANT)
867 W_PROPERTY(QQmlListProperty<QObject>, data READ data)
868
869private:
870 QList<QObject*> m_data;
871 QJSValue m_tick;
872 QJSValue m_start;
873 QJSValue m_stop;
874 QJSValue m_pause;
875 QJSValue m_resume;
876};
877}
878
879inline QDataStream& operator<<(QDataStream& i, const JS::MidiMessage& sel)
880{
881 SCORE_ABORT;
882 return i;
883}
884inline QDataStream& operator>>(QDataStream& i, JS::MidiMessage& sel)
885{
886 SCORE_ABORT;
887 return i;
888}
889inline QDataStream& operator<<(QDataStream& i, const JS::InValueMessage& sel)
890{
891 SCORE_ABORT;
892 return i;
893}
894inline QDataStream& operator>>(QDataStream& i, JS::InValueMessage& sel)
895{
896 SCORE_ABORT;
897 return i;
898}
899inline QDataStream& operator<<(QDataStream& i, const JS::OutValueMessage& sel)
900{
901 SCORE_ABORT;
902 return i;
903}
904inline QDataStream& operator>>(QDataStream& i, JS::OutValueMessage& sel)
905{
906 SCORE_ABORT;
907 return i;
908}
909Q_DECLARE_METATYPE(JS::ValueInlet*)
910Q_DECLARE_METATYPE(JS::ValueOutlet*)
911Q_DECLARE_METATYPE(JS::AudioInlet*)
912Q_DECLARE_METATYPE(JS::AudioOutlet*)
913Q_DECLARE_METATYPE(JS::MidiMessage)
914Q_DECLARE_METATYPE(JS::MidiInlet*)
915Q_DECLARE_METATYPE(JS::MidiOutlet*)
916
917W_REGISTER_ARGTYPE(JS::ValueInlet*)
918W_REGISTER_ARGTYPE(JS::ValueOutlet*)
919W_REGISTER_ARGTYPE(JS::AudioInlet*)
920W_REGISTER_ARGTYPE(JS::AudioOutlet*)
921W_REGISTER_ARGTYPE(JS::MidiMessage)
922W_REGISTER_ARGTYPE(JS::MidiInlet*)
923W_REGISTER_ARGTYPE(JS::MidiOutlet*)
Definition QmlObjects.hpp:670
Definition QmlObjects.hpp:697
Definition QmlObjects.hpp:561
Definition QmlObjects.hpp:512
Definition QmlObjects.hpp:123
Definition QmlObjects.hpp:483
Definition QmlObjects.hpp:357
Definition QmlObjects.hpp:284
Definition QmlObjects.hpp:379
Definition QmlObjects.hpp:452
Definition QmlObjects.hpp:215
Definition QmlObjects.hpp:147
Definition QmlObjects.hpp:610
Definition QmlObjects.hpp:577
Definition QmlObjects.hpp:43
Definition QmlObjects.hpp:328
Definition QmlObjects.hpp:423
Definition QmlObjects.hpp:237
Definition QmlObjects.hpp:593
Definition QmlObjects.hpp:730
Definition QmlObjects.hpp:720
Definition QmlObjects.hpp:767
Definition QmlObjects.hpp:56
Definition QmlObjects.hpp:843
Definition QmlObjects.hpp:545
Definition QmlObjects.hpp:90
Definition QmlObjects.hpp:639
Definition Port.hpp:301
Definition Port.hpp:324
Definition Port.hpp:205
Definition Port.hpp:179
Definition Port.hpp:380
Definition Port.hpp:403
Definition Port.hpp:274
Definition Port.hpp:492
Definition Port.hpp:515
The id_base_t class.
Definition Identifier.hpp:59
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
STL namespace.
Definition QmlObjects.hpp:202
Definition QmlObjects.hpp:196
Definition QmlObjects.hpp:68
Definition QmlObjects.hpp:190
Definition QmlObjects.hpp:79
Definition QmlObjects.hpp:208