2 #include <Process/Dataflow/Port.hpp>
4 #include <score/tools/Debug.hpp>
6 #include <ossia/detail/math.hpp>
7 #include <ossia/network/domain/domain.hpp>
9 #include <QDoubleSpinBox>
12 #include <type_traits>
14 namespace WidgetFactory
18 static constexpr
auto getMin(
auto& slider) noexcept
20 if constexpr(requires { slider.getMin(); })
21 return slider.getMin();
23 return slider.domain().get().template convert_min<T>();
27 static constexpr
auto getMax(
auto& slider) noexcept
29 if constexpr(requires { slider.getMax(); })
30 return slider.getMax();
32 return slider.domain().get().template convert_max<T>();
36 static constexpr
auto getInit(
auto& slider) noexcept
38 if constexpr(requires { slider.getInit(); })
39 return slider.getInit();
40 else if constexpr(requires { slider.init(); })
41 return ossia::convert<T>(slider.init());
43 return getMin<T>(slider);
48 static constexpr
double to01(
double min,
double range,
double val) noexcept
50 return (val - min) /
range;
53 static constexpr
double from01(
double min,
double range,
double val) noexcept
55 return min + val *
range;
59 static double to01(
const T& slider,
double val) noexcept
61 auto min = getMin<double>(slider);
62 auto max = getMax<double>(slider);
65 return to01(min, max - min, val);
69 static double from01(
const T& slider,
double val) noexcept
71 auto min = getMin<double>(slider);
72 auto max = getMax<double>(slider);
75 return from01(min, max - min, val);
79 static ossia::vec2f to01(
const T& slider, ossia::vec2f val) noexcept
82 const auto min = getMin<ossia::vec2f>(slider);
83 const auto max = getMax<ossia::vec2f>(slider);
84 res[0] = to01(min[0], max[0] - min[0], val[0]);
85 res[1] = to01(min[1], max[1] - min[1], val[1]);
90 static ossia::vec2f from01(
const T& slider, ossia::vec2f val) noexcept
93 const auto min = getMin<ossia::vec2f>(slider);
94 const auto max = getMax<ossia::vec2f>(slider);
95 res[0] = from01(min[0], max[0] - min[0], val[0]);
96 res[1] = from01(min[1], max[1] - min[1], val[1]);
100 template <
typename T>
101 static ossia::vec3f to01(
const T& slider, ossia::vec3f val) noexcept
104 const auto min = getMin<ossia::vec3f>(slider);
105 const auto max = getMax<ossia::vec3f>(slider);
106 res[0] = to01(min[0], max[0] - min[0], val[0]);
107 res[1] = to01(min[1], max[1] - min[1], val[1]);
108 res[2] = to01(min[2], max[2] - min[2], val[2]);
112 template <
typename T>
113 static ossia::vec3f from01(
const T& slider, ossia::vec3f val) noexcept
116 const auto min = getMin<ossia::vec3f>(slider);
117 const auto max = getMax<ossia::vec3f>(slider);
118 res[0] = from01(min[0], max[0] - min[0], val[0]);
119 res[1] = from01(min[1], max[1] - min[1], val[1]);
120 res[2] = from01(min[2], max[2] - min[2], val[2]);
124 template <
typename T>
125 static ossia::vec4f to01(
const T& slider, ossia::vec4f val) noexcept
128 const auto min = getMin<ossia::vec4f>(slider);
129 const auto max = getMax<ossia::vec4f>(slider);
130 res[0] = to01(min[0], max[0] - min[0], val[0]);
131 res[1] = to01(min[1], max[1] - min[1], val[1]);
132 res[2] = to01(min[2], max[2] - min[2], val[2]);
133 res[3] = to01(min[3], max[3] - min[3], val[3]);
137 template <
typename T>
138 static ossia::vec4f from01(
const T& slider, ossia::vec4f val) noexcept
141 const auto min = getMin<ossia::vec4f>(slider);
142 const auto max = getMax<ossia::vec4f>(slider);
143 res[0] = from01(min[0], max[0] - min[0], val[0]);
144 res[1] = from01(min[1], max[1] - min[1], val[1]);
145 res[2] = from01(min[2], max[2] - min[2], val[2]);
146 res[3] = from01(min[3], max[3] - min[3], val[3]);
149 template <
typename T, std::
size_t N>
150 static std::array<float, N> from01(
const T& slider, std::array<double, N> val) noexcept
152 std::array<float, N> res;
153 const auto min = getMin<std::array<double, N>>(slider);
154 const auto max = getMax<std::array<double, N>>(slider);
155 for(
int i = 0; i < N; i++)
156 res[i] = from01(min[i], max[i] - min[i], val[i]);
163 static double to01(
double min,
double range,
double val) noexcept
165 return ossia::log_to_normalized(min,
range, val);
168 static double from01(
double min,
double range,
double val) noexcept
170 return ossia::normalized_to_log(min,
range, val);
173 template <
typename T>
174 static double to01(
const T& slider,
double val) noexcept
176 auto min = getMin<double>(slider);
177 auto max = getMax<double>(slider);
180 return to01(min, max - min, val);
183 template <
typename T>
184 static double from01(
const T& slider,
double val) noexcept
186 auto min = getMin<double>(slider);
187 auto max = getMax<double>(slider);
190 return from01(min, max - min, val);
194 template <
typename Norm_T>
199 template <
typename T>
202 min = getMin<double>(slider);
203 max = getMax<double>(slider);
208 constexpr
double to01(
double val)
const noexcept
210 return Norm_T::to01(min, max - min, val);
213 constexpr
double from01(
double val)
const noexcept
215 return Norm_T::from01(min, max - min, val);
219 template <
typename Norm_T,
typename Sl
ider_T>
222 const Slider_T& slider;
229 constexpr
double to01(
double val)
const noexcept {
return Norm_T::to01(slider, val); }
231 constexpr
double from01(
double val)
const noexcept
233 return Norm_T::from01(slider, val);
237 template <
typename Control_T,
typename W
idget_T>
238 static void initWidgetProperties(Control_T& inlet, Widget_T& widget)
240 if constexpr(requires { widget.setNoValueChangeOnMove(
true); })
241 widget.setNoValueChangeOnMove(inlet.noValueChangeOnMove);
244 template <
typename W
idget_T>
245 static void setRange(Widget_T& widget,
auto&& min,
auto&& max,
auto&& init)
247 widget.setRange(min, max, init);
250 static inline void setRange(QSpinBox& widget,
auto&& min,
auto&& max,
auto&& init)
252 widget.setRange(min, max);
255 static inline void setRange(QDoubleSpinBox& widget,
auto&& min,
auto&& max,
auto&& init)
257 widget.setRange(min, max);
260 template <
typename T,
typename Control_T,
typename W
idget_T>
261 static void bindFloatDomain(
const T& slider, Control_T& inlet, Widget_T& widget)
263 auto min = getMin<float>(slider);
264 auto max = getMax<float>(slider);
268 setRange(widget, min, max, getInit<float>(slider));
270 if constexpr(std::is_base_of_v<Process::ControlInlet, T>)
272 SCORE_ASSERT(&slider == &inlet);
273 QObject::connect(&inlet, &Control_T::domainChanged, &widget, [&slider, &widget] {
274 auto min = getMin<float>(slider);
275 auto max = getMax<float>(slider);
279 setRange(widget, min, max, getInit<float>(slider));
284 template <
typename T,
typename Control_T,
typename W
idget_T>
285 static void bindIntDomain(
const T& slider, Control_T& inlet, Widget_T& widget)
287 auto min = getMin<int>(slider);
288 auto max = getMax<int>(slider);
292 setRange(widget, min, max, getInit<int>(slider));
294 if constexpr(std::is_base_of_v<Process::ControlInlet, T>)
296 SCORE_ASSERT(&slider == &inlet);
297 QObject::connect(&inlet, &Control_T::domainChanged, &widget, [&slider, &widget] {
298 auto min = getMin<int>(slider);
299 auto max = getMax<int>(slider);
303 setRange(widget, min, max, getInit<int>(slider));
308 template <
typename T,
typename Control_T,
typename W
idget_T>
309 static void bindVec2Domain(
const T& slider, Control_T& inlet, Widget_T& widget)
311 auto update_range = [&widget, &inlet, &slider] {
312 auto min = ossia::get_min(inlet.domain());
313 auto max = ossia::get_max(inlet.domain());
314 auto min_float = min.template target<float>();
315 auto max_float = max.template target<float>();
316 if(min_float && max_float)
318 if(*max_float - *min_float == 0)
319 *max_float = *min_float + 1;
321 {*min_float, *min_float}, {*max_float, *max_float}, {*min_float, *min_float});
325 auto min_vec2 = min.template target<ossia::vec2f>();
326 auto max_vec2 = max.template target<ossia::vec2f>();
327 if(min_vec2 && max_vec2)
329 auto& min = *min_vec2;
330 auto& max = *max_vec2;
331 for(std::size_t i = 0; i < min.size(); i++)
333 if(max[i] - min[i] == 0)
337 auto init_vec2 = getInit<ossia::vec2f>(slider);
338 widget.setRange(min, max, init_vec2);
345 if constexpr(std::is_base_of_v<Process::ControlInlet, T>)
347 SCORE_ASSERT(&slider == &inlet);
348 QObject::connect(&inlet, &Control_T::domainChanged, &widget, update_range);
352 template <
typename T,
typename Control_T,
typename W
idget_T>
353 static void bindVec3Domain(
const T& slider, Control_T& inlet, Widget_T& widget)
355 auto update_range = [&widget, &inlet, &slider] {
356 auto min = ossia::get_min(inlet.domain());
357 auto max = ossia::get_max(inlet.domain());
358 auto min_float = min.template target<float>();
359 auto max_float = max.template target<float>();
360 if(min_float && max_float)
362 if(*max_float - *min_float == 0)
363 *max_float = *min_float + 1;
365 {*min_float, *min_float, *min_float}, {*max_float, *max_float, *max_float});
369 auto min_vec3 = min.template target<ossia::vec3f>();
370 auto max_vec3 = max.template target<ossia::vec3f>();
371 if(min_vec3 && max_vec3)
373 auto& min = *min_vec3;
374 auto& max = *max_vec3;
375 for(std::size_t i = 0; i < min.size(); i++)
377 if(max[i] - min[i] == 0)
381 auto init_vec3 = getInit<ossia::vec3f>(slider);
382 widget.setRange(min, max, init_vec3);
389 if constexpr(std::is_base_of_v<Process::ControlInlet, T>)
391 SCORE_ASSERT(&slider == &inlet);
392 QObject::connect(&inlet, &Control_T::domainChanged, &widget, update_range);
Definition: LFO_v2.hpp:68