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::range_slider)
298 static constexpr auto c = avnd::get_range<T>();
299 if constexpr(std::is_integral_v<value_type>)
301 auto [start, end] = c.init;
307 auto [start, end] = c.init;
312 else if constexpr(widg.widget == avnd::widget_type::range_spinbox)
314 static constexpr auto c = avnd::get_range<T>();
315 if constexpr(std::is_integral_v<value_type>)
317 auto [start, end] = c.init;
323 auto [start, end] = c.init;
328 else if constexpr(widg.widget == avnd::widget_type::string_list)
331 =
new CustomGenericControl<Process::MultiSlider, Node, T, avnd::field_index<N>>{
332 oscr::to_ossia_value(T{}.value), qname,
id, parent};
336 else if constexpr(widg.widget == avnd::widget_type::multi_slider)
338 std::vector<ossia::value> init;
341 else if constexpr(widg.widget == avnd::widget_type::multi_slider_xy)
343 std::vector<ossia::value> init;
346 else if constexpr(widg.widget == avnd::widget_type::path_generator_xy)
348 std::vector<ossia::value> init;
351 else if constexpr(widg.widget == avnd::widget_type::spinbox)
353 static constexpr auto c = avnd::get_range<T>();
354 if constexpr(std::is_integral_v<value_type>)
356 return new ControlTypeToUse<Process::IntSpinBox, Node, T, avnd::field_index<N>>{
357 c.min, c.max, c.init, qname, id, parent};
364 else if constexpr(widg.widget == avnd::widget_type::knob)
366 static constexpr auto c = avnd::get_range<T>();
367 if constexpr(std::is_integral_v<value_type>)
374 if constexpr(avnd::has_mapper<T>)
376 return new CustomFloatControl<Node, avnd::field_index<N>>{c.min, c.max, c.init,
385 else if constexpr(widg.widget == avnd::widget_type::lineedit)
387 if constexpr(avnd::has_range<T>)
389 static constexpr auto c = avnd::get_range<T>();
390 if constexpr(avnd::program_parameter<T>)
393 p->language = T::language();
397 return new ControlTypeToUse<Process::LineEdit, Node, T, avnd::field_index<N>>{
398 c.init.data(), qname, id, parent};
402 if constexpr(avnd::program_parameter<T>)
405 p->language = T::language();
409 return new ControlTypeToUse<Process::LineEdit, Node, T, avnd::field_index<N>>{
410 "", qname, id, parent};
413 else if constexpr(avnd::folder_items_parameter<T>)
418 static constexpr auto c = avnd::get_range<T>();
419 const std::string initv{c.init};
420 std::vector<std::pair<QString, ossia::value>> initAlts;
421 initAlts.emplace_back(QString::fromStdString(initv), initv);
423 std::move(initAlts), ossia::value{initv}, qname, id, parent};
424 combo->folderPortName
425 = QString::fromUtf8(T::folder_port().data(), T::folder_port().size());
427 const std::string_view ex = T::extensions();
429 while(pos < ex.size())
431 auto sp = ex.find(
' ', pos);
432 if(sp == std::string_view::npos)
436 auto suffix = QString::fromUtf8(ex.data() + pos,
int(sp - pos));
439 while(suffix.startsWith(
'.'))
441 if(!suffix.isEmpty())
442 combo->fileExtensions.push_back(
"*." + suffix);
448 else if constexpr(widg.widget == avnd::widget_type::combobox)
450 static constexpr auto c = avnd::get_range<T>();
451 using init_type = std::decay_t<
decltype(c.init)>;
453 if constexpr(std::is_integral_v<init_type> || std::is_enum_v<init_type>)
454 init =
static_cast<int>(c.init);
458 to_combobox_range(c.values), std::move(init), qname, id, parent};
460 else if constexpr(widg.widget == avnd::widget_type::choices)
462 static constexpr auto c = avnd::get_range<T>();
463 auto enums = avnd::to_enum_range(c.values);
465 std::is_integral_v<
decltype(c.init)> || std::is_enum_v<
decltype(c.init)>);
466 auto init = enums[
static_cast<int>(c.init)];
467 std::vector<QString> pixmaps;
468 if constexpr(avnd::has_pixmaps<T>)
470 for(std::string_view pix : avnd::get_pixmaps<T>())
472 pixmaps.push_back(QString::fromLatin1(pix.data(), pix.size()));
476 std::move(enums), pixmaps, std::move(init), qname, id, parent};
478 else if constexpr(widg.widget == avnd::widget_type::xy)
480 static constexpr auto c = avnd::get_range<T>();
481 if constexpr(
requires {
488 {c.min, c.min}, {c.max, c.max}, {c.init, c.init}, qname, id, parent};
492 auto [mx, my] = c.min;
493 auto [Mx, My] = c.max;
494 auto [ix, iy] = c.init;
498 else if constexpr(widg.widget == avnd::widget_type::xyz)
500 static constexpr auto c = avnd::get_range<T>();
501 if constexpr(
requires {
508 {c.min, c.min, c.min},
509 {c.max, c.max, c.max},
510 {c.init, c.init, c.init},
517 auto [mx, my, mz] = c.min;
518 auto [Mx, My, Mz] = c.max;
519 auto [ix, iy, iz] = c.init;
524 else if constexpr(widg.widget == avnd::widget_type::xy_spinbox)
526 using data_type = std::decay_t<
decltype(value_type{}.x)>;
527 static constexpr auto c = avnd::get_range<T>();
528 if constexpr(
requires {
538 std::is_integral_v<data_type>,
545 auto [mx, my] = c.min;
546 auto [Mx, My] = c.max;
547 auto [ix, iy] = c.init;
549 {mx, my}, {Mx, My}, {ix, iy}, std::is_integral_v<data_type>,
553 else if constexpr(widg.widget == avnd::widget_type::xyz_spinbox)
555 static constexpr auto c = avnd::get_range<T>();
556 if constexpr(
requires {
563 {c.min, c.min, c.min},
564 {c.max, c.max, c.max},
565 {c.init, c.init, c.init},
573 auto [mx, my, mz] = c.min;
574 auto [Mx, My, Mz] = c.max;
575 auto [ix, iy, iz] = c.init;
580 else if constexpr(widg.widget == avnd::widget_type::color)
582 static constexpr auto c = avnd::get_range<T>();
583 static constexpr auto i = c.init;
586 else if constexpr(widg.widget == avnd::widget_type::control)
590 else if constexpr(widg.widget == avnd::widget_type::no_control)
596 static_assert(T::is_not_a_valid_control);
600template <
typename T, std::
size_t N>
604 constexpr auto name = avnd::get_name<T>();
605 constexpr auto widg = avnd::get_widget<T>();
606 QString qname = QString::fromUtf8(name.data(), name.size());
610 if constexpr(widg.widget == avnd::widget_type::bargraph)
612 static constexpr auto c = avnd::get_range<T>();
615 else if constexpr(widg.widget == avnd::widget_type::control)
619 else if constexpr(widg.widget == avnd::widget_type::no_control)
623 else if constexpr(avnd::fp_ish<
decltype(T::value)>)
625 static constexpr auto c = avnd::get_range<T>();
635static inline constexpr auto make_control_out(
const T& t)
637 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:674
Definition WidgetInlets.hpp:337
Definition WidgetInlets.hpp:446
Definition WidgetInlets.hpp:491
Definition WidgetInlets.hpp:174
Definition WidgetInlets.hpp:235
Definition WidgetInlets.hpp:267
Definition WidgetInlets.hpp:160
Definition WidgetInlets.hpp:298
Definition WidgetInlets.hpp:395
Definition WidgetInlets.hpp:539
Definition WidgetInlets.hpp:219
Definition WidgetInlets.hpp:251
Definition WidgetInlets.hpp:204
Definition WidgetInlets.hpp:189
Definition WidgetInlets.hpp:629
Definition WidgetInlets.hpp:644
Definition WidgetInlets.hpp:658
Definition WidgetInlets.hpp:433
Definition WidgetInlets.hpp:312
Definition WidgetInlets.hpp:326
Definition WidgetInlets.hpp:553
Definition WidgetInlets.hpp:587
Definition WidgetInlets.hpp:570
Definition WidgetInlets.hpp:611
Definition VisitorInterface.hpp:13
The VisitorVariant struct.
Definition VisitorInterface.hpp:26
Definition Concepts.hpp:74
Definition Concepts.hpp:101
Definition Concepts.hpp:120