2#include <Process/Dataflow/WidgetInlets.hpp>
3#include <Process/ProcessFlags.hpp>
4#include <Process/ProcessMetadata.hpp>
6#include <Dataflow/CurveInlet.hpp>
7#include <Engine/Node/CommonWidgets.hpp>
9#include <score/plugins/UuidKey.hpp>
11#include <ossia/dataflow/audio_port.hpp>
12#include <ossia/dataflow/port.hpp>
13#include <ossia/dataflow/safe_nodes/tick_policies.hpp>
15#include <boost/container/vector.hpp>
17#include <avnd/binding/ossia/dynamic_ports.hpp>
18#include <avnd/binding/ossia/qt.hpp>
19#include <avnd/binding/ossia/to_value.hpp>
20#include <avnd/binding/ossia/uuid.hpp>
21#include <avnd/common/concepts_polyfill.hpp>
22#include <avnd/common/struct_reflection.hpp>
23#include <avnd/concepts/audio_port.hpp>
24#include <avnd/concepts/channels.hpp>
25#include <avnd/concepts/curve.hpp>
26#include <avnd/concepts/folder_items.hpp>
27#include <avnd/concepts/gfx.hpp>
28#include <avnd/concepts/midi_port.hpp>
29#include <avnd/concepts/parameter.hpp>
30#include <avnd/introspection/input.hpp>
31#include <avnd/wrappers/metadatas.hpp>
32#include <avnd/wrappers/widgets.hpp>
39#define make_uuid(text) score::uuids::string_generator::compute((text))
49 = oscr::has_controller_ports<T> || oscr::has_dynamic_ports<T>
50 || (avnd::controller_setup_port_input_introspection<T>::size > 0);
52template <
typename Node,
typename FieldIndex>
53struct CustomFloatControl;
55template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
56struct CustomGenericControl;
59template <
typename Node,
typename FieldIndex>
64template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
65struct is_custom_serialized<
66 oscr::CustomGenericControl<BaseInletType, Node, T, FieldIndex>> : std::true_type
75 using Process::ControlInlet::ControlInlet;
80 : ControlInlet{name, id, parent}
82 displayHandledExplicitly =
true;
85 setDomain(ossia::make_domain(min, max));
88 auto getMin()
const noexcept {
return domain().get().template convert_min<float>(); }
89 auto getMax()
const noexcept {
return domain().get().template convert_max<float>(); }
91 void setupExecution(ossia::inlet& inl, QObject* exec_context)
const noexcept override
93 auto& port = **safe_cast<ossia::value_inlet*>(&inl);
94 port.type = ossia::val_type::FLOAT;
95 port.domain = domain().get();
99template <
typename Node,
typename FieldIndex>
102 using CustomFloatControlBase::CustomFloatControlBase;
104 static key_type static_concreteKey()
noexcept
106 return make_field_uuid<Node>(
true, FieldIndex{});
108 key_type concreteKey()
const noexcept override {
return static_concreteKey(); }
110 void serialize_impl(
const VisitorVariant& vis)
const noexcept override
112 score::serialize_dyn(vis, *
this);
118template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
121 using BaseInletType::BaseInletType;
122 void setValue(
const ossia::value& value)
override
124 if constexpr(
requires { T::migrate_value(value); })
125 BaseInletType::setValue(T::migrate_value(value));
127 BaseInletType::setValue(value);
130 static BaseInletType::key_type static_concreteKey()
noexcept
132 return make_field_uuid<Node>(
true, FieldIndex{});
134 BaseInletType::key_type concreteKey()
const noexcept override
136 return static_concreteKey();
139 void serialize_impl(
const VisitorVariant& vis)
const noexcept override
141 score::serialize_dyn(vis, *
this);
147template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
148using ControlTypeToUse = std::conditional_t<
149 avnd::controller_interaction_port<T>,
152template <
typename Node,
typename FieldIndex>
164template <
typename Node,
typename FieldIndex>
176template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
178 DataStream,
oscr::CustomGenericControl<BaseInletType, Node, T, FieldIndex>>
183 s.read((
const BaseInletType&)p);
189template <
typename BaseInletType,
typename Node,
typename T,
typename FieldIndex>
191 JSONObject,
oscr::CustomGenericControl<BaseInletType, Node, T, FieldIndex>>
196 s.read((
const BaseInletType&)p);
205template <
typename Node,
typename T, std::
size_t N>
209 using value_type = as_type(T::value);
210 constexpr auto name = avnd::get_name<T>();
211 QString qname = QString::fromUtf8(name.data(), name.size());
213 constexpr auto widg = avnd::get_widget<T>();
217 if constexpr(avnd::curve_port<T>)
221 else if constexpr(widg.widget == avnd::widget_type::bang)
225 else if constexpr(widg.widget == avnd::widget_type::button)
229 else if constexpr(widg.widget == avnd::widget_type::toggle)
231 static constexpr auto c = avnd::get_range<T>();
232 if constexpr(
requires { c.values(); })
235 {c.values[0], c.values[1]}, c.init, qname, id, parent};
242 else if constexpr(widg.widget == avnd::widget_type::slider)
244 static constexpr auto c = avnd::get_range<T>();
245 if constexpr(std::is_integral_v<value_type>)
251 if constexpr(avnd::has_mapper<T>)
253 return new CustomFloatControl<Node, avnd::field_index<N>>{c.min, c.max, c.init,
262 else if constexpr(widg.widget == avnd::widget_type::log_slider)
264 static constexpr auto c = avnd::get_range<T>();
267 else if constexpr(widg.widget == avnd::widget_type::log_knob)
270 static constexpr auto c = avnd::get_range<T>();
273 else if constexpr(widg.widget == avnd::widget_type::time_chooser)
275 static constexpr auto c = avnd::get_range<T>();
278 else if constexpr(widg.widget == avnd::widget_type::folder)
280 if constexpr(avnd::has_range<T>) {
281 static constexpr auto c = avnd::get_range<T>();
283 auto init = std::begin(c.init);
284 if constexpr(std::is_same_v<std::decay_t<
decltype(init)>,
const char*>)
290 QString::fromUtf8(&*std::begin(c.init), std::size(c.init)), qname, id, parent};
296 else if constexpr(widg.widget == avnd::widget_type::file)
299 if constexpr(
requires { T::filters(); })
301 constexpr std::string_view f = T::filters();
302 filters = QString::fromUtf8(f.data(), f.size());
306 else if constexpr(widg.widget == avnd::widget_type::range_slider)
308 static constexpr auto c = avnd::get_range<T>();
309 if constexpr(std::is_integral_v<value_type>)
311 auto [start, end] = c.init;
317 auto [start, end] = c.init;
322 else if constexpr(widg.widget == avnd::widget_type::range_spinbox)
324 static constexpr auto c = avnd::get_range<T>();
325 if constexpr(std::is_integral_v<value_type>)
327 auto [start, end] = c.init;
333 auto [start, end] = c.init;
338 else if constexpr(widg.widget == avnd::widget_type::string_list)
341 =
new CustomGenericControl<Process::MultiSlider, Node, T, avnd::field_index<N>>{
342 oscr::to_ossia_value(T{}.value), qname,
id, parent};
346 else if constexpr(widg.widget == avnd::widget_type::multi_slider)
348 std::vector<ossia::value> init;
351 else if constexpr(widg.widget == avnd::widget_type::multi_slider_xy)
353 std::vector<ossia::value> init;
356 else if constexpr(widg.widget == avnd::widget_type::path_generator_xy)
358 std::vector<ossia::value> init;
361 else if constexpr(widg.widget == avnd::widget_type::spinbox)
363 static constexpr auto c = avnd::get_range<T>();
364 if constexpr(std::is_integral_v<value_type>)
366 return new ControlTypeToUse<Process::IntSpinBox, Node, T, avnd::field_index<N>>{
367 c.min, c.max, c.init, qname, id, parent};
374 else if constexpr(widg.widget == avnd::widget_type::knob)
376 static constexpr auto c = avnd::get_range<T>();
377 if constexpr(std::is_integral_v<value_type>)
384 if constexpr(avnd::has_mapper<T>)
386 return new CustomFloatControl<Node, avnd::field_index<N>>{c.min, c.max, c.init,
395 else if constexpr(widg.widget == avnd::widget_type::lineedit)
397 if constexpr(avnd::has_range<T>)
399 static constexpr auto c = avnd::get_range<T>();
400 if constexpr(avnd::program_parameter<T>)
403 p->language = T::language();
407 return new ControlTypeToUse<Process::LineEdit, Node, T, avnd::field_index<N>>{
408 c.init.data(), qname, id, parent};
412 if constexpr(avnd::program_parameter<T>)
415 p->language = T::language();
419 return new ControlTypeToUse<Process::LineEdit, Node, T, avnd::field_index<N>>{
420 "", qname, id, parent};
423 else if constexpr(avnd::folder_items_parameter<T>)
428 static constexpr auto c = avnd::get_range<T>();
429 const std::string initv{c.init};
430 std::vector<std::pair<QString, ossia::value>> initAlts;
431 initAlts.emplace_back(QString::fromStdString(initv), initv);
433 std::move(initAlts), ossia::value{initv}, qname, id, parent};
434 combo->folderPortName
435 = QString::fromUtf8(T::folder_port().data(), T::folder_port().size());
437 const std::string_view ex = T::extensions();
439 while(pos < ex.size())
441 auto sp = ex.find(
' ', pos);
442 if(sp == std::string_view::npos)
446 auto suffix = QString::fromUtf8(ex.data() + pos,
int(sp - pos));
449 while(suffix.startsWith(
'.'))
451 if(!suffix.isEmpty())
452 combo->fileExtensions.push_back(
"*." + suffix);
458 else if constexpr(widg.widget == avnd::widget_type::combobox)
460 static constexpr auto c = avnd::get_range<T>();
461 using init_type = std::decay_t<
decltype(c.init)>;
463 if constexpr(std::is_integral_v<init_type> || std::is_enum_v<init_type>)
464 init =
static_cast<int>(c.init);
468 to_combobox_range(c.values), std::move(init), qname, id, parent};
470 else if constexpr(widg.widget == avnd::widget_type::choices)
472 static constexpr auto c = avnd::get_range<T>();
473 auto enums = avnd::to_enum_range(c.values);
475 std::is_integral_v<
decltype(c.init)> || std::is_enum_v<
decltype(c.init)>);
476 auto init = enums[
static_cast<int>(c.init)];
477 std::vector<QString> pixmaps;
478 if constexpr(avnd::has_pixmaps<T>)
480 for(std::string_view pix : avnd::get_pixmaps<T>())
482 pixmaps.push_back(QString::fromLatin1(pix.data(), pix.size()));
486 std::move(enums), pixmaps, std::move(init), qname, id, parent};
488 else if constexpr(widg.widget == avnd::widget_type::xy)
490 static constexpr auto c = avnd::get_range<T>();
491 if constexpr(
requires {
498 {c.min, c.min}, {c.max, c.max}, {c.init, c.init}, qname, id, parent};
502 auto [mx, my] = c.min;
503 auto [Mx, My] = c.max;
504 auto [ix, iy] = c.init;
508 else if constexpr(widg.widget == avnd::widget_type::xyz)
510 static constexpr auto c = avnd::get_range<T>();
511 if constexpr(
requires {
518 {c.min, c.min, c.min},
519 {c.max, c.max, c.max},
520 {c.init, c.init, c.init},
527 auto [mx, my, mz] = c.min;
528 auto [Mx, My, Mz] = c.max;
529 auto [ix, iy, iz] = c.init;
534 else if constexpr(widg.widget == avnd::widget_type::xy_spinbox)
536 using data_type = std::decay_t<
decltype(value_type{}.x)>;
537 static constexpr auto c = avnd::get_range<T>();
538 if constexpr(
requires {
548 std::is_integral_v<data_type>,
555 auto [mx, my] = c.min;
556 auto [Mx, My] = c.max;
557 auto [ix, iy] = c.init;
559 {mx, my}, {Mx, My}, {ix, iy}, std::is_integral_v<data_type>,
563 else if constexpr(widg.widget == avnd::widget_type::xyz_spinbox)
565 static constexpr auto c = avnd::get_range<T>();
566 if constexpr(
requires {
574 std::array<float, 3> init{c.init, c.init, c.init};
575 if constexpr(std::is_default_constructible_v<T>)
577 const auto [ix, iy, iz] = T{}.value;
578 init = {float(ix), float(iy), float(iz)};
581 {c.min, c.min, c.min},
582 {c.max, c.max, c.max},
583 {init[0], init[1], init[2]},
591 auto [mx, my, mz] = c.min;
592 auto [Mx, My, Mz] = c.max;
593 auto [ix, iy, iz] = c.init;
595 false, qname, id, parent};
598 else if constexpr(widg.widget == avnd::widget_type::xyzw_spinbox)
600 static constexpr auto c = avnd::get_range<T>();
601 if constexpr(
requires {
608 {c.min, c.min, c.min},
609 {c.max, c.max, c.max},
610 {c.init, c.init, c.init},
618 auto [mx, my, mz, mw] = c.min;
619 auto [Mx, My, Mz, Mw] = c.max;
620 auto [ix, iy, iz, iw] = c.init;
623 false, qname, id, parent};
626 else if constexpr(widg.widget == avnd::widget_type::color)
628 static constexpr auto c = avnd::get_range<T>();
629 static constexpr auto i = c.init;
632 else if constexpr(widg.widget == avnd::widget_type::control)
636 else if constexpr(widg.widget == avnd::widget_type::no_control)
642 static_assert(T::is_not_a_valid_control);
646template <
typename T, std::
size_t N>
650 constexpr auto name = avnd::get_name<T>();
651 constexpr auto widg = avnd::get_widget<T>();
652 QString qname = QString::fromUtf8(name.data(), name.size());
656 if constexpr(widg.widget == avnd::widget_type::bargraph)
658 static constexpr auto c = avnd::get_range<T>();
661 else if constexpr(widg.widget == avnd::widget_type::control)
665 else if constexpr(widg.widget == avnd::widget_type::no_control)
669 else if constexpr(avnd::fp_ish<
decltype(T::value)>)
671 static constexpr auto c = avnd::get_range<T>();
681static inline constexpr auto make_control_out(
const T& t)
683 return make_control_out<T>();
Definition VisitorInterface.hpp:53
Definition DataStreamVisitor.hpp:27
Definition DataStreamVisitor.hpp:202
Definition VisitorInterface.hpp:61
Definition JSONVisitor.hpp:52
Definition JSONVisitor.hpp:423
Definition UuidKey.hpp:345
The id_base_t class.
Definition Identifier.hpp:59
Definition Concepts.hpp:49
Definition Controls.hpp:27
Definition CurveInlet.hpp:47
Definition WidgetInlets.hpp:781
Definition WidgetInlets.hpp:373
Definition WidgetInlets.hpp:517
Definition WidgetInlets.hpp:568
Definition WidgetInlets.hpp:423
Definition WidgetInlets.hpp:178
Definition WidgetInlets.hpp:247
Definition WidgetInlets.hpp:283
Definition WidgetInlets.hpp:162
Definition WidgetInlets.hpp:318
Definition WidgetInlets.hpp:444
Definition WidgetInlets.hpp:629
Definition WidgetInlets.hpp:229
Definition WidgetInlets.hpp:265
Definition WidgetInlets.hpp:212
Definition WidgetInlets.hpp:195
Definition WidgetInlets.hpp:730
Definition WidgetInlets.hpp:747
Definition WidgetInlets.hpp:763
Definition WidgetInlets.hpp:494
Definition WidgetInlets.hpp:334
Definition WidgetInlets.hpp:360
Definition WidgetInlets.hpp:646
Definition WidgetInlets.hpp:684
Definition WidgetInlets.hpp:665
Definition WidgetInlets.hpp:710
Definition VisitorInterface.hpp:13
The VisitorVariant struct.
Definition VisitorInterface.hpp:26
Definition Concepts.hpp:74
Definition Concepts.hpp:101
Definition Concepts.hpp:120