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 #if defined(SCORE_HAS_GPU_JS)
10 #include <Gfx/TexturePort.hpp>
11 
12 #include <QQuickItem>
13 #endif
14 
15 #include <score/tools/Debug.hpp>
16 
17 #include <ossia/detail/math.hpp>
18 #include <ossia/detail/ssize.hpp>
19 #include <ossia/network/domain/domain.hpp>
20 
21 #include <QJSValue>
22 #include <QObject>
23 #include <QQmlListProperty>
24 #include <QVariant>
25 #include <QVector>
26 
27 #include <libremidi/message.hpp>
28 
29 #include <score_plugin_js_export.h>
30 #include <wobjectimpl.h>
31 
32 #include <verdigris>
33 
34 class QQuickItem;
35 W_REGISTER_ARGTYPE(QJSValue)
36 namespace JS
37 {
38 class SCORE_PLUGIN_JS_EXPORT Inlet : public QObject
39 {
40  W_OBJECT(Inlet)
41 
42 public:
43  using QObject::QObject;
44  virtual ~Inlet() override;
45  virtual Process::Inlet* make(Id<Process::Port>&& id, QObject*) = 0;
46  virtual bool isEvent() const { return false; }
47 
48  W_INLINE_PROPERTY_CREF(QString, address, {}, address, setAddress, addressChanged)
49 };
50 
51 class SCORE_PLUGIN_JS_EXPORT Outlet : public QObject
52 {
53  W_OBJECT(Outlet)
54 
55 public:
56  using QObject::QObject;
57  virtual ~Outlet() override;
58  virtual Process::Outlet* make(Id<Process::Port>&& id, QObject*) = 0;
59 
60  W_INLINE_PROPERTY_CREF(QString, address, {}, address, setAddress, addressChanged)
61 };
62 
63 struct SCORE_PLUGIN_JS_EXPORT InValueMessage
64 {
65  W_GADGET(InValueMessage)
66 
67 public:
68  qreal timestamp;
69  QVariant value;
70  W_PROPERTY(qreal, timestamp MEMBER timestamp)
71  W_PROPERTY(QVariant, value MEMBER value)
72 };
73 
74 struct SCORE_PLUGIN_JS_EXPORT OutValueMessage
75 {
76  W_GADGET(OutValueMessage)
77 
78 public:
79  qreal timestamp;
80  QJSValue value;
81  W_PROPERTY(qreal, timestamp MEMBER timestamp)
82  W_PROPERTY(QJSValue, value MEMBER value)
83 };
84 
85 class SCORE_PLUGIN_JS_EXPORT ValueInlet : public Inlet
86 {
87  W_OBJECT(ValueInlet)
88 
89  QVariant m_value;
90  QVariantList m_values;
91 
92 public:
93  explicit ValueInlet(QObject* parent = nullptr);
94  virtual ~ValueInlet() override;
95  QVariant value() const;
96  QVariantList values() const { return m_values; }
97 
98  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
99  {
100  return new Process::ValueInlet(id, parent);
101  }
102 
103  int length() const noexcept;
104  W_SLOT(length)
105 
106  QVariant at(int index) const noexcept;
107  W_SLOT(at)
108 
109  void clear() { m_values.clear(); }
110  void setValue(QVariant value);
111  void addValue(QVariant&& val) { m_values.append(std::move(val)); }
112  void valueChanged(QVariant value) W_SIGNAL(valueChanged, value);
113 
114  W_PROPERTY(QVariantList, values READ values)
115  W_PROPERTY(QVariant, value READ value NOTIFY valueChanged)
116 };
117 
118 class SCORE_PLUGIN_JS_EXPORT ControlInlet : public Inlet
119 {
120  W_OBJECT(ControlInlet)
121 
122  QVariant m_value;
123 
124 public:
125  explicit ControlInlet(QObject* parent = nullptr);
126  virtual ~ControlInlet() override;
127  QVariant value() const noexcept;
128 
129  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
130  {
131  return new Process::ControlInlet(id, parent);
132  }
133 
134  void clear() { m_value = QVariant{}; }
135  virtual void setValue(QVariant value);
136  void valueChanged(QVariant value) W_SIGNAL(valueChanged, value);
137 
138  W_PROPERTY(QVariant, value READ value NOTIFY valueChanged)
139 };
140 
141 template <typename Impl, typename ValueType>
142 class SCORE_PLUGIN_JS_EXPORT GenericControlInlet : public ControlInlet
143 {
144  W_OBJECT(GenericControlInlet)
145 
146 public:
147  using ControlInlet::ControlInlet;
148  virtual ~GenericControlInlet() override = default;
149  bool isEvent() const override { return true; }
150  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
151  {
152  return new Impl(id, parent);
153  }
154 
155  void clear() { m_value = {}; }
156  ValueType value() const noexcept { return m_value; }
157  void setValue(QVariant value) override
158  {
159  auto conv = value.value<ValueType>();
160  if(m_value == conv)
161  return;
162 
163  m_value = std::move(conv);
164  valueChanged(m_value);
165  }
166  void setValue(ValueType value)
167  {
168  if(m_value == value)
169  return;
170 
171  m_value = value;
172  valueChanged(m_value);
173  }
174  void valueChanged(ValueType value) W_SIGNAL(valueChanged, value);
175 
176  W_PROPERTY(ValueType, value READ value NOTIFY valueChanged)
177 
178 private:
179  ValueType m_value{};
180 };
181 W_OBJECT_IMPL((GenericControlInlet<A, B>), template <typename A, typename B>)
182 struct SCORE_PLUGIN_JS_EXPORT FloatRangeSpinBox
183  : JS::GenericControlInlet<Process::FloatRangeSpinBox, QVector2D>
184 {
185  W_OBJECT(FloatRangeSpinBox);
186  using GenericControlInlet::GenericControlInlet;
187 };
188 struct SCORE_PLUGIN_JS_EXPORT IntRangeSlider
189  : JS::GenericControlInlet<Process::IntRangeSlider, QVector2D>
190 {
191  W_OBJECT(IntRangeSlider);
192  using GenericControlInlet::GenericControlInlet;
193 };
194 struct SCORE_PLUGIN_JS_EXPORT IntRangeSpinBox
195  : JS::GenericControlInlet<Process::IntRangeSpinBox, QVector2D>
196 {
197  W_OBJECT(IntRangeSpinBox);
198  using GenericControlInlet::GenericControlInlet;
199 };
200 struct SCORE_PLUGIN_JS_EXPORT HSVSlider
201  : JS::GenericControlInlet<Process::HSVSlider, QVector4D>
202 {
203  W_OBJECT(HSVSlider);
204  using GenericControlInlet::GenericControlInlet;
205 };
206 struct SCORE_PLUGIN_JS_EXPORT XYSlider
207  : JS::GenericControlInlet<Process::XYSlider, QVector2D>
208 {
209  W_OBJECT(XYSlider);
210  using GenericControlInlet::GenericControlInlet;
211 };
212 struct SCORE_PLUGIN_JS_EXPORT XYZSlider
213  : JS::GenericControlInlet<Process::XYZSlider, QVector3D>
214 {
215  W_OBJECT(XYZSlider);
216  using GenericControlInlet::GenericControlInlet;
217 };
218 struct SCORE_PLUGIN_JS_EXPORT XYSpinboxes
219  : JS::GenericControlInlet<Process::XYSpinboxes, QVector2D>
220 {
221  W_OBJECT(XYSpinboxes);
222  using GenericControlInlet::GenericControlInlet;
223 };
224 struct SCORE_PLUGIN_JS_EXPORT XYZSpinboxes
225  : JS::GenericControlInlet<Process::XYZSpinboxes, QVector3D>
226 {
227  W_OBJECT(XYZSpinboxes);
228  using GenericControlInlet::GenericControlInlet;
229 };
230 struct SCORE_PLUGIN_JS_EXPORT MultiSlider
231  : JS::GenericControlInlet<Process::MultiSlider, QVector<qreal>>
232 {
233  W_OBJECT(MultiSlider);
234  using GenericControlInlet::GenericControlInlet;
235 };
236 struct SCORE_PLUGIN_JS_EXPORT FileChooser
237  : JS::GenericControlInlet<Process::FileChooser, QString>
238 {
239  W_OBJECT(FileChooser);
240  using GenericControlInlet::GenericControlInlet;
241 };
242 struct SCORE_PLUGIN_JS_EXPORT AudioFileChooser
243  : JS::GenericControlInlet<Process::AudioFileChooser, QString>
244 {
245  W_OBJECT(AudioFileChooser);
246  using GenericControlInlet::GenericControlInlet;
247 };
248 struct SCORE_PLUGIN_JS_EXPORT VideoFileChooser
249  : JS::GenericControlInlet<Process::VideoFileChooser, QString>
250 {
251  W_OBJECT(VideoFileChooser);
252  using GenericControlInlet::GenericControlInlet;
253 };
254 
255 template <typename Impl = Process::FloatSlider>
256 class SCORE_PLUGIN_JS_EXPORT FloatSlider : public GenericControlInlet<Impl, float>
257 {
258  W_OBJECT(FloatSlider)
259 
260 public:
262  virtual ~FloatSlider() override = default;
263  bool isEvent() const override { return true; }
264 
265  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
266  {
267  return new Impl{(float)m_min, (float)m_max, (float)m_init,
268  this->objectName(), id, parent};
269  }
270 
271  W_INLINE_PROPERTY_VALUE(qreal, init, {0.5}, init, setInit, initChanged)
272  W_INLINE_PROPERTY_VALUE(qreal, min, {0.}, getMin, setMin, minChanged)
273  W_INLINE_PROPERTY_VALUE(qreal, max, {1.}, getMax, setMax, maxChanged)
274 };
275 W_OBJECT_IMPL(JS::FloatSlider<Impl>, template <typename Impl>)
276 
277 template <typename Impl = Process::IntSlider>
278 class SCORE_PLUGIN_JS_EXPORT IntSlider : public GenericControlInlet<Impl, int>
279 {
280  W_OBJECT(IntSlider)
281 
282 public:
284  virtual ~IntSlider() override = default;
285  bool isEvent() const override { return true; }
286 
287  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
288  {
289  return new Impl{m_min, m_max, m_init, this->objectName(), id, parent};
290  }
291 
292  W_INLINE_PROPERTY_VALUE(int, init, {0}, init, setInit, initChanged)
293  W_INLINE_PROPERTY_VALUE(int, min, {0}, getMin, setMin, minChanged)
294  W_INLINE_PROPERTY_VALUE(int, max, {127}, getMax, setMax, maxChanged)
295 };
296 W_OBJECT_IMPL(JS::IntSlider<Impl>, template <typename Impl>)
297 
298 class SCORE_PLUGIN_JS_EXPORT Enum : public ControlInlet
299 {
300  W_OBJECT(Enum)
301 
302 public:
303  using ControlInlet::ControlInlet;
304  virtual ~Enum() override;
305  bool isEvent() const override { return true; }
306 
307  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
308  {
309  return new Process::Enum{m_choices, {}, current(), objectName(), id, parent};
310  }
311 
312  auto getValues() const { return choices(); }
313 
314  std::string current() const
315  {
316  if(!m_choices.isEmpty() && ossia::valid_index(m_index, m_choices))
317  {
318  return m_choices[m_index].toStdString();
319  }
320  return {};
321  }
322 
323  W_INLINE_PROPERTY_VALUE(int, index, {}, index, setIndex, indexChanged)
324  W_INLINE_PROPERTY_CREF(QStringList, choices, {}, choices, setChoices, choicesChanged)
325 };
326 
327 class SCORE_PLUGIN_JS_EXPORT Toggle : public ControlInlet
328 {
329  W_OBJECT(Toggle)
330 
331 public:
332  using ControlInlet::ControlInlet;
333  virtual ~Toggle() override;
334  bool isEvent() const override { return true; }
335  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
336  {
337  return new Process::Toggle{m_checked, objectName(), id, parent};
338  }
339 
340  W_INLINE_PROPERTY_VALUE(bool, checked, {}, checked, setChecked, checkedChanged)
341 };
342 
343 class SCORE_PLUGIN_JS_EXPORT Button : public ControlInlet
344 {
345  W_OBJECT(Button)
346 
347 public:
348  using ControlInlet::ControlInlet;
349  virtual ~Button() override;
350  bool isEvent() const override { return true; }
351  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
352  {
353  return new Process::Button{objectName(), id, parent};
354  }
355 
356  W_INLINE_PROPERTY_VALUE(bool, checked, {}, checked, setChecked, checkedChanged)
357 };
358 
359 class SCORE_PLUGIN_JS_EXPORT Impulse : public ControlInlet
360 {
361  W_OBJECT(Impulse)
362 
363 public:
364  using ControlInlet::ControlInlet;
365  virtual ~Impulse() override;
366  bool isEvent() const override { return false; }
367  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
368  {
369  return new Process::ImpulseButton{objectName(), id, parent};
370  }
371 
372  void impulse() W_SIGNAL(impulse);
373 };
374 
375 class SCORE_PLUGIN_JS_EXPORT LineEdit : public ControlInlet
376 {
377  W_OBJECT(LineEdit)
378 
379 public:
380  using ControlInlet::ControlInlet;
381  virtual ~LineEdit() override;
382  bool isEvent() const override { return true; }
383  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
384  {
385  return new Process::LineEdit{m_text, objectName(), id, parent};
386  }
387 
388  W_INLINE_PROPERTY_CREF(QString, text, {}, text, setText, textChanged)
389 };
390 
391 class SCORE_PLUGIN_JS_EXPORT ValueOutlet : public Outlet
392 {
393  W_OBJECT(ValueOutlet)
394 
395  QJSValue m_value;
396 
397 public:
398  std::vector<OutValueMessage> values;
399 
400  explicit ValueOutlet(QObject* parent = nullptr);
401  virtual ~ValueOutlet() override;
402  const QJSValue& value() const;
403  void clear()
404  {
405  m_value = QJSValue{};
406  values.clear();
407  }
408  Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
409  {
410  return new Process::ValueOutlet(id, parent);
411  }
412 
413 public:
414  void setValue(const QJSValue& value);
415  W_SLOT(setValue);
416  void addValue(qreal timestamp, QJSValue t);
417  W_SLOT(addValue);
418 
419  W_PROPERTY(QJSValue, value READ value WRITE setValue)
420 };
421 
422 class SCORE_PLUGIN_JS_EXPORT AudioInlet : public Inlet
423 {
424  W_OBJECT(AudioInlet)
425 
426 public:
427  explicit AudioInlet(QObject* parent = nullptr);
428  virtual ~AudioInlet() override;
429  const QVector<QVector<double>>& audio() const;
430  void setAudio(const QVector<QVector<double>>& audio);
431 
432  QVector<double> channel(int i) const
433  {
434  if(m_audio.size() > i)
435  return m_audio[i];
436  return {};
437  }
438  W_INVOKABLE(channel);
439 
440  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
441  {
442  return new Process::AudioInlet(id, parent);
443  }
444 
445 private:
446  QVector<QVector<double>> m_audio;
447 };
448 
449 class SCORE_PLUGIN_JS_EXPORT AudioOutlet : public Outlet
450 {
451  W_OBJECT(AudioOutlet)
452 
453 public:
454  explicit AudioOutlet(QObject* parent = nullptr);
455  virtual ~AudioOutlet() override;
456  Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
457  {
458  auto p = new Process::AudioOutlet(id, parent);
459  if(id.val() == 0)
460  p->setPropagate(true);
461  return p;
462  }
463 
464  const QVector<QVector<double>>& audio() const;
465 
466  void setChannel(int i, const QJSValue& v);
467  W_INVOKABLE(setChannel)
468 private:
469  QVector<QVector<double>> m_audio;
470 };
471 
472 class SCORE_PLUGIN_JS_EXPORT MidiMessage
473 {
474  W_GADGET(MidiMessage)
475 
476 public:
477  QByteArray bytes;
478 
479  W_PROPERTY(QByteArray, bytes MEMBER bytes)
480 };
481 
482 class SCORE_PLUGIN_JS_EXPORT MidiInlet : public Inlet
483 {
484  W_OBJECT(MidiInlet)
485 
486 public:
487  explicit MidiInlet(QObject* parent = nullptr);
488  virtual ~MidiInlet() override;
489  template <typename T>
490  void setMidi(const T& arr)
491  {
492  m_midi.clear();
493  for(const libremidi::message& mess : arr)
494  {
495  const auto N = mess.size();
496  QVector<int> m;
497  m.resize(N);
498 
499  for(std::size_t i = 0; i < N; i++)
500  m[i] = mess.bytes[i];
501 
502  m_midi.push_back(QVariant::fromValue(m));
503  }
504  }
505 
506  QVariantList messages() const { return m_midi; }
507  W_INVOKABLE(messages);
508 
509  Process::Inlet* make(Id<Process::Port>&& id, QObject* parent) override
510  {
511  return new Process::MidiInlet(id, parent);
512  }
513 
514 private:
515  QVariantList m_midi;
516 };
517 
518 class SCORE_PLUGIN_JS_EXPORT MidiOutlet : public Outlet
519 {
520  W_OBJECT(MidiOutlet)
521 
522 public:
523  explicit MidiOutlet(QObject* parent = nullptr);
524  virtual ~MidiOutlet() override;
525  Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
526  {
527  return new Process::MidiOutlet(id, parent);
528  }
529 
530  void clear();
531  const QVector<QVector<int>>& midi() const;
532 
533  void setMessages(const QVariantList m)
534  {
535  m_midi.clear();
536  for(auto& v : m)
537  {
538  if(v.canConvert<QVector<int>>())
539  m_midi.push_back(v.value<QVector<int>>());
540  }
541  }
542  W_INVOKABLE(setMessages);
543 
544  void add(QVector<int> m) { m_midi.push_back(std::move(m)); }
545  W_INVOKABLE(add);
546 
547 private:
548  QVector<QVector<int>> m_midi;
549 };
550 
551 #if defined(SCORE_HAS_GPU_JS)
552 class TextureOutlet : public Outlet
553 {
554  W_OBJECT(TextureOutlet)
555 
556 public:
557  explicit TextureOutlet(QObject* parent = nullptr);
558  virtual ~TextureOutlet() override;
559  Process::Outlet* make(Id<Process::Port>&& id, QObject* parent) override
560  {
561  auto p = new Gfx::TextureOutlet(id, parent);
562  return p;
563  }
564 
565  QQuickItem* item() /*Qt6: const*/ noexcept { return m_item; }
566  void setItem(QQuickItem* v) { m_item = v; }
567 
568  W_PROPERTY(QQuickItem*, item READ item WRITE setItem CONSTANT)
569 private:
570  QQuickItem* m_item{};
571 };
572 #endif
573 
574 class Script : public QObject
575 {
576  W_OBJECT(Script)
577  W_CLASSINFO("DefaultProperty", "data")
578  W_CLASSINFO(
579  "qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
580 
581 public:
582  QQmlListProperty<QObject> data() noexcept { return {this, &m_data}; }
583 
584  QJSValue& tick() /*Qt6: const*/ noexcept { return m_tick; }
585  void setTick(const QJSValue& v) { m_tick = v; }
586  QJSValue& start() /*Qt6: const*/ noexcept { return m_start; }
587  void setStart(const QJSValue& v) { m_start = v; }
588  QJSValue& stop() /*Qt6: const*/ noexcept { return m_stop; }
589  void setStop(const QJSValue& v) { m_stop = v; }
590  QJSValue& pause() /*Qt6: const*/ noexcept { return m_pause; }
591  void setPause(const QJSValue& v) { m_pause = v; }
592  QJSValue& resume() /*Qt6: const*/ noexcept { return m_resume; }
593  void setResume(const QJSValue& v) { m_resume = v; }
594  W_PROPERTY(QJSValue, tick READ tick WRITE setTick CONSTANT)
595  W_PROPERTY(QJSValue, start READ start WRITE setStart CONSTANT)
596  W_PROPERTY(QJSValue, stop READ stop WRITE setStop CONSTANT)
597  W_PROPERTY(QJSValue, pause READ pause WRITE setPause CONSTANT)
598  W_PROPERTY(QJSValue, resume READ resume WRITE setResume CONSTANT)
599  W_PROPERTY(QQmlListProperty<QObject>, data READ data)
600 
601 private:
602  QList<QObject*> m_data;
603  QJSValue m_tick;
604  QJSValue m_start;
605  QJSValue m_stop;
606  QJSValue m_pause;
607  QJSValue m_resume;
608 };
609 }
610 
611 inline QDataStream& operator<<(QDataStream& i, const JS::MidiMessage& sel)
612 {
613  SCORE_ABORT;
614  return i;
615 }
616 inline QDataStream& operator>>(QDataStream& i, JS::MidiMessage& sel)
617 {
618  SCORE_ABORT;
619  return i;
620 }
621 inline QDataStream& operator<<(QDataStream& i, const JS::InValueMessage& sel)
622 {
623  SCORE_ABORT;
624  return i;
625 }
626 inline QDataStream& operator>>(QDataStream& i, JS::InValueMessage& sel)
627 {
628  SCORE_ABORT;
629  return i;
630 }
631 inline QDataStream& operator<<(QDataStream& i, const JS::OutValueMessage& sel)
632 {
633  SCORE_ABORT;
634  return i;
635 }
636 inline QDataStream& operator>>(QDataStream& i, JS::OutValueMessage& sel)
637 {
638  SCORE_ABORT;
639  return i;
640 }
641 Q_DECLARE_METATYPE(JS::ValueInlet*)
642 Q_DECLARE_METATYPE(JS::ValueOutlet*)
643 Q_DECLARE_METATYPE(JS::AudioInlet*)
644 Q_DECLARE_METATYPE(JS::AudioOutlet*)
645 Q_DECLARE_METATYPE(JS::MidiMessage)
646 Q_DECLARE_METATYPE(JS::MidiInlet*)
647 Q_DECLARE_METATYPE(JS::MidiOutlet*)
648 
649 W_REGISTER_ARGTYPE(JS::ValueInlet*)
650 W_REGISTER_ARGTYPE(JS::ValueOutlet*)
651 W_REGISTER_ARGTYPE(JS::AudioInlet*)
652 W_REGISTER_ARGTYPE(JS::AudioOutlet*)
653 W_REGISTER_ARGTYPE(JS::MidiMessage)
654 W_REGISTER_ARGTYPE(JS::MidiInlet*)
655 W_REGISTER_ARGTYPE(JS::MidiOutlet*)
Definition: QmlObjects.hpp:406
Definition: QmlObjects.hpp:433
Definition: QmlObjects.hpp:330
Definition: QmlObjects.hpp:114
Definition: QmlObjects.hpp:287
Definition: QmlObjects.hpp:249
Definition: QmlObjects.hpp:137
Definition: QmlObjects.hpp:345
Definition: QmlObjects.hpp:269
Definition: QmlObjects.hpp:39
Definition: QmlObjects.hpp:361
Definition: QmlObjects.hpp:464
Definition: QmlObjects.hpp:455
Definition: QmlObjects.hpp:500
Definition: QmlObjects.hpp:51
Definition: Port.hpp:300
Definition: Port.hpp:323
Definition: Port.hpp:203
Definition: Port.hpp:177
Definition: Port.hpp:379
Definition: Port.hpp:402
Definition: Port.hpp:273
Definition: Port.hpp:492
Definition: Port.hpp:515
Definition: QmlObjects.hpp:556
Definition: QmlObjects.hpp:315
Definition: QmlObjects.hpp:82
Definition: QmlObjects.hpp:376
The id_base_t class.
Definition: Identifier.hpp:57
Base classes and tools to implement processes and layers.
Definition: JSONVisitor.hpp:1324
Definition: QmlObjects.hpp:236
Definition: QmlObjects.hpp:230
Definition: QmlObjects.hpp:176
Definition: QmlObjects.hpp:194
Definition: QmlObjects.hpp:62
Definition: QmlObjects.hpp:182
Definition: QmlObjects.hpp:188
Definition: QmlObjects.hpp:224
Definition: QmlObjects.hpp:72
Definition: QmlObjects.hpp:242
Definition: QmlObjects.hpp:200
Definition: QmlObjects.hpp:212
Definition: QmlObjects.hpp:206
Definition: QmlObjects.hpp:218