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#endif
15
16#include <score/tools/Debug.hpp>
17
18#include <ossia/detail/math.hpp>
19#include <ossia/detail/ssize.hpp>
20#include <ossia/network/domain/domain.hpp>
21
22#include <ossia-qt/js_utilities.hpp>
23
24#include <QJSValue>
25#include <QObject>
26#include <QQuickItem>
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 QVector<QVector<double>>& audio();
677 const QVector<QVector<double>>& audio() const;
678 void setAudio(const QVector<QVector<double>>& audio);
679 void setAudio(QVector<QVector<double>>&& audio);
680
681 QVector<double> channel(int i) const
682 {
683 if(m_audio.size() > i)
684 return m_audio[i];
685 return {};
686 }
687 W_INVOKABLE(channel);
688
689 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
690 {
691 return new Process::AudioInlet(objectName(), id, parent);
692 }
693
694private:
695 QVector<QVector<double>> m_audio;
696};
697
698class SCORE_PLUGIN_JS_EXPORT AudioOutlet : public Outlet
699{
700 W_OBJECT(AudioOutlet)
701
702public:
703 explicit AudioOutlet(QObject* parent = nullptr);
704 virtual ~AudioOutlet() override;
705 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
706 {
707 auto p = new Process::AudioOutlet(objectName(), id, parent);
708 if(id.val() == 0)
709 p->setPropagate(true);
710 return p;
711 }
712
713 const QVector<QVector<double>>& audio() const;
714
715 void setChannel(int i, const QJSValue& v);
716 W_INVOKABLE(setChannel)
717private:
718 QVector<QVector<double>> m_audio;
719};
720
721class SCORE_PLUGIN_JS_EXPORT MidiMessage
722{
723 W_GADGET(MidiMessage)
724
725public:
726 QByteArray bytes;
727
728 W_PROPERTY(QByteArray, bytes MEMBER bytes)
729};
730
731class SCORE_PLUGIN_JS_EXPORT MidiInlet : public Inlet
732{
733 W_OBJECT(MidiInlet)
734
735public:
736 explicit MidiInlet(QObject* parent = nullptr);
737 virtual ~MidiInlet() override;
738 template <typename T>
739 void setMidi(const T& arr)
740 {
741 m_midi.clear();
742 for(const libremidi::ump& mess : arr)
743 {
744 auto m1 = libremidi::midi1_from_ump(mess);
745 const auto N = mess.size();
746 QVector<int> m;
747 m.resize(N);
748
749 for(std::size_t i = 0; i < N; i++)
750 m[i] = m1.bytes[i];
751
752 m_midi.push_back(QVariant::fromValue(m));
753 }
754 }
755
756 QVariantList messages() const { return m_midi; }
757 W_INVOKABLE(messages);
758
759 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
760 {
761 return new Process::MidiInlet(objectName(), id, parent);
762 }
763
764private:
765 QVariantList m_midi;
766};
767
768class SCORE_PLUGIN_JS_EXPORT MidiOutlet : public Outlet
769{
770 W_OBJECT(MidiOutlet)
771
772public:
773 explicit MidiOutlet(QObject* parent = nullptr);
774 virtual ~MidiOutlet() override;
775 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
776 {
777 return new Process::MidiOutlet(objectName(), id, parent);
778 }
779
780 void clear();
781 const QVector<QVector<int>>& midi() const;
782
783 void setMessages(const QVariantList m)
784 {
785 m_midi.clear();
786 for(auto& v : m)
787 {
788 if(v.canConvert<QVector<int>>())
789 m_midi.push_back(v.value<QVector<int>>());
790 }
791 }
792 W_INVOKABLE(setMessages);
793
794 void add(QVector<int> m) { m_midi.push_back(std::move(m)); }
795 W_INVOKABLE(add);
796
797private:
798 QVector<QVector<int>> m_midi;
799};
800
801#if defined(SCORE_HAS_GPU_JS)
802class TextureInlet : public Inlet
803{
804 W_OBJECT(TextureInlet)
805
806public:
807 explicit TextureInlet(QObject* parent = nullptr);
808 virtual ~TextureInlet() override;
809 Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
810 {
811 auto p = new Gfx::TextureInlet(objectName(), id, parent);
812 return p;
813 }
814
815 QQuickItem* item() const noexcept { return m_item; }
816
817 W_PROPERTY(QQuickItem*, item READ item CONSTANT)
818private:
819 QQuickItem* m_item{};
820};
821
822class TextureOutlet : public Outlet
823{
824 W_OBJECT(TextureOutlet)
825
826public:
827 explicit TextureOutlet(QObject* parent = nullptr);
828 virtual ~TextureOutlet() override;
829 Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
830 {
831 auto p = new Gfx::TextureOutlet(objectName(), id, parent);
832 return p;
833 }
834
835 QQuickItem* item() const noexcept { return m_item; }
836 void setItem(QQuickItem* v) { m_item = v; }
837
838 W_PROPERTY(QQuickItem*, item READ item WRITE setItem CONSTANT)
839private:
840 QQuickItem* m_item{};
841};
842#endif
843
844class Script : public QObject
845{
846 W_OBJECT(Script)
847 W_CLASSINFO("DefaultProperty", "data")
848
849public:
850 QQmlListProperty<QObject> data() noexcept { return {this, &m_data}; }
851 W_PROPERTY(QQmlListProperty<QObject>, data READ data)
852
853 const QJSValue& tick() const noexcept { return m_tick; }
854 void setTick(const QJSValue& v) { m_tick = v; }
855 W_PROPERTY(QJSValue, tick READ tick WRITE setTick CONSTANT)
856
857 const QJSValue& start() const noexcept { return m_start; }
858 void setStart(const QJSValue& v) { m_start = v; }
859 W_PROPERTY(QJSValue, start READ start WRITE setStart CONSTANT)
860
861 const QJSValue& stop() const noexcept { return m_stop; }
862 void setStop(const QJSValue& v) { m_stop = v; }
863 W_PROPERTY(QJSValue, stop READ stop WRITE setStop CONSTANT)
864
865 const QJSValue& pause() const noexcept { return m_pause; }
866 void setPause(const QJSValue& v) { m_pause = v; }
867 W_PROPERTY(QJSValue, pause READ pause WRITE setPause CONSTANT)
868
869 const QJSValue& resume() const noexcept { return m_resume; }
870 void setResume(const QJSValue& v) { m_resume = v; }
871 W_PROPERTY(QJSValue, resume READ resume WRITE setResume CONSTANT)
872
873 const QJSValue& uiEvent() const noexcept { return m_uiEvent; }
874 void setUiEvent(const QJSValue& v) { m_uiEvent = v; }
875 W_PROPERTY(QJSValue, uiEvent READ uiEvent WRITE setUiEvent CONSTANT)
876
877 void uiSend(const QJSValue& v) W_SIGNAL(uiSend, v);
878
879 const QJSValue& loadState() const noexcept { return m_loadState; }
880 void setLoadState(const QJSValue& v) { m_loadState = v; }
881 W_PROPERTY(QJSValue, loadState READ loadState WRITE setLoadState CONSTANT)
882
883 const QJSValue& stateUpdated() const noexcept { return m_stateUpdated; }
884 void setStateUpdated(const QJSValue& v) { m_stateUpdated = v; }
885 W_PROPERTY(QJSValue, stateUpdated READ stateUpdated WRITE setStateUpdated CONSTANT)
886
887private:
888 QList<QObject*> m_data;
889 QJSValue m_tick;
890 QJSValue m_start;
891 QJSValue m_stop;
892 QJSValue m_pause;
893 QJSValue m_resume;
894 QJSValue m_uiEvent;
895 QJSValue m_loadState;
896 QJSValue m_stateUpdated;
897};
898
899class ScriptUI : public QQuickItem
900{
901 W_OBJECT(ScriptUI)
902
903public:
904 const QJSValue& executionEvent() const noexcept { return m_executionEvent; }
905 void setExecutionEvent(const QJSValue& v) { m_executionEvent = v; }
906 W_PROPERTY(QJSValue, executionEvent READ executionEvent WRITE setExecutionEvent CONSTANT)
907
908 const QJSValue& loadState() const noexcept { return m_loadState; }
909 void setLoadState(const QJSValue& v) { m_loadState = v; }
910 W_PROPERTY(QJSValue, loadState READ loadState WRITE setLoadState CONSTANT)
911
912 const QJSValue& stateUpdated() const noexcept { return m_stateUpdated; }
913 void setStateUpdated(const QJSValue& v) { m_stateUpdated = v; }
914 W_PROPERTY(QJSValue, stateUpdated READ stateUpdated WRITE setStateUpdated CONSTANT)
915
916 void executionSend(const QJSValue& v)
917 W_SIGNAL(executionSend, v);
918
919 void beginUpdateState(const QString& name)
920 W_SIGNAL(beginUpdateState, name);
921 void updateState(const QString& k, const QJSValue& v)
922 W_SIGNAL(updateState, k, v);
923 void endUpdateState()
924 W_SIGNAL(endUpdateState);
925 void cancelUpdateState()
926 W_SIGNAL(cancelUpdateState);
927 void clearState()
928 W_SIGNAL(clearState);
929 void replaceState(const QJSValue& v)
930 W_SIGNAL(replaceState, v);
931
932 Process::Inlet* inlet(int i) const noexcept;
933 W_INVOKABLE(inlet, (int));
934 Process::Outlet* outlet(int i) const noexcept;
935 W_INVOKABLE(outlet, (int));
936 Process::Inlet* inlet(const QString& i) const noexcept;
937 W_INVOKABLE(inlet, (const QString&));
938 Process::Outlet* outlet(const QString& i) const noexcept;
939 W_INVOKABLE(outlet, (const QString&));
940
941 Process::ProcessModel* process() const noexcept { return m_process; }
942 void setProcess(Process::ProcessModel* v) { m_process = v; }
943
944private:
945 QJSValue m_executionEvent;
946 QJSValue m_loadState;
947 QJSValue m_stateUpdated;
948 Process::ProcessModel* m_process{};
949};
950}
951
952inline QDataStream& operator<<(QDataStream& i, const JS::MidiMessage& sel)
953{
954 SCORE_ABORT;
955 return i;
956}
957inline QDataStream& operator>>(QDataStream& i, JS::MidiMessage& sel)
958{
959 SCORE_ABORT;
960 return i;
961}
962inline QDataStream& operator<<(QDataStream& i, const JS::InValueMessage& sel)
963{
964 SCORE_ABORT;
965 return i;
966}
967inline QDataStream& operator>>(QDataStream& i, JS::InValueMessage& sel)
968{
969 SCORE_ABORT;
970 return i;
971}
972inline QDataStream& operator<<(QDataStream& i, const JS::OutValueMessage& sel)
973{
974 SCORE_ABORT;
975 return i;
976}
977inline QDataStream& operator>>(QDataStream& i, JS::OutValueMessage& sel)
978{
979 SCORE_ABORT;
980 return i;
981}
982Q_DECLARE_METATYPE(JS::ValueInlet*)
983Q_DECLARE_METATYPE(JS::ValueOutlet*)
984Q_DECLARE_METATYPE(JS::AudioInlet*)
985Q_DECLARE_METATYPE(JS::AudioOutlet*)
986Q_DECLARE_METATYPE(JS::MidiMessage)
987Q_DECLARE_METATYPE(JS::MidiInlet*)
988Q_DECLARE_METATYPE(JS::MidiOutlet*)
989
990W_REGISTER_ARGTYPE(JS::ValueInlet*)
991W_REGISTER_ARGTYPE(JS::ValueOutlet*)
992W_REGISTER_ARGTYPE(JS::AudioInlet*)
993W_REGISTER_ARGTYPE(JS::AudioOutlet*)
994W_REGISTER_ARGTYPE(JS::MidiMessage)
995W_REGISTER_ARGTYPE(JS::MidiInlet*)
996W_REGISTER_ARGTYPE(JS::MidiOutlet*)
Definition QmlObjects.hpp:670
Definition QmlObjects.hpp:699
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:732
Definition QmlObjects.hpp:722
Definition QmlObjects.hpp:769
Definition QmlObjects.hpp:56
Definition QmlObjects.hpp:845
Definition QmlObjects.hpp:900
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
The Process class.
Definition score-lib-process/Process/Process.hpp:62
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
Definition WidgetInlets.hpp:488
Definition WidgetInlets.hpp:444
Definition WidgetInlets.hpp:464
Definition WidgetInlets.hpp:512
Definition WidgetInlets.hpp:499
Definition WidgetInlets.hpp:349
Definition WidgetInlets.hpp:324