2#include <Process/Commands/SetControlValue.hpp>
3#include <Process/Dataflow/ControlWidgetDomains.hpp>
4#include <Process/Dataflow/Port.hpp>
5#include <Process/Dataflow/TimeSignature.hpp>
6#include <Process/Dataflow/WidgetInlets.hpp>
7#include <Process/Script/ScriptEditor.hpp>
9#include <score/command/Dispatchers/CommandDispatcher.hpp>
10#include <score/document/DocumentContext.hpp>
11#include <score/graphics/GraphicWidgets.hpp>
12#include <score/graphics/GraphicsItem.hpp>
13#include <score/graphics/RectItem.hpp>
14#include <score/graphics/TextItem.hpp>
15#include <score/tools/Unused.hpp>
16#include <score/widgets/ComboBox.hpp>
17#include <score/widgets/ControlWidgets.hpp>
18#include <score/widgets/HelpInteraction.hpp>
19#include <score/widgets/SignalUtils.hpp>
21#include <ossia/detail/algorithms.hpp>
22#include <ossia/network/domain/domain_functions.hpp>
23#include <ossia/network/value/value_conversion.hpp>
25#include <ossia-qt/invoke.hpp>
28#include <QApplication>
31#include <QGraphicsItem>
32#include <QGraphicsSceneDragDropEvent>
35#include <QTextDocument>
37#include <score_lib_process_export.h>
59namespace WidgetFactory
61static_assert(std::numeric_limits<float>::is_iec559,
"IEEE 754 required");
63using SetControlValue =
typename std::conditional_t<
67template <
typename Normalizer,
typename T>
68using ConcreteNormalizer = std::conditional_t<
69 std::is_base_of_v<Process::ControlInlet, T>
70 || std::is_base_of_v<Process::ControlOutlet, T>,
71 UpdatingNormalizer<Normalizer, T>, FixedNormalizer<Normalizer>>;
72template <
typename ControlUI,
typename Normalizer,
bool Control>
79 std::is_same_v<score::QGraphicsKnob, ControlUI>
80 || std::is_same_v<score::QGraphicsLogKnob, ControlUI>)
82 return DefaultControlLayouts::knob();
86 return DefaultControlLayouts::slider();
91 static auto make_widget(
94 ConcreteNormalizer<Normalizer, T> norm{inlet};
97 sl->setOrientation(Qt::Horizontal);
98 sl->setContentsMargins(0, 0, 0, 0);
99 bindFloatDomain(inlet, inlet, *sl);
100 sl->setValue(norm.to01(ossia::convert<double>(inlet.value())));
102 if constexpr(Control)
105 sl, &score::DoubleSlider::sliderMoved, context,
106 [sl, norm, &inlet, &ctx](
double v) {
108 ctx.dispatcher.
submit<SetControlValue<T>>(inlet, norm.from01(sl->value()));
111 sl, &score::DoubleSlider::sliderReleased, context, [sl, norm, &inlet, &ctx]() {
112 ctx.dispatcher.
submit<SetControlValue<T>>(inlet, norm.from01(sl->value()));
118 QObject::connect(&inlet, &T::valueChanged, sl, [sl, norm](
const ossia::value& val) {
119 if constexpr(Control)
122 sl->setValue(norm.to01(ossia::convert<double>(val)));
126 sl->setValue(norm.to01(ossia::convert<double>(val)));
133 template <
typename T,
typename Control_T>
134 static auto make_item(
136 QGraphicsItem* parent, QObject* context)
138 ConcreteNormalizer<Normalizer, T> norm{slider};
140 auto sl =
new ControlUI{
nullptr};
141 initWidgetProperties(inlet, *sl);
142 bindFloatDomain(slider, inlet, *sl);
143 sl->setValue(norm.to01(ossia::convert<double>(inlet.value())));
145 if constexpr(Control)
147 QObject::connect(sl, &ControlUI::sliderMoved, context, [sl, norm, &inlet, &ctx] {
149 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
150 inlet, norm.from01(sl->value()));
153 sl, &ControlUI::sliderReleased, context, [sl, norm, &inlet, &ctx] {
154 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
155 inlet, norm.from01(sl->value()));
162 &inlet, &Control_T::valueChanged, sl, [sl, norm](
const ossia::value& val) {
163 if constexpr(Control)
166 sl->setValue(norm.to01(ossia::convert<double>(val)));
170 sl->setValue(norm.to01(ossia::convert<double>(val)));
174 &inlet, &Control_T::executionValueChanged, sl,
175 [sl, norm](
const ossia::value& val) {
176 sl->setExecutionValue(norm.to01(ossia::convert<double>(val)));
178 QObject::connect(&inlet, &Control_T::executionReset, sl, &ControlUI::resetExecution);
195 return Process::DefaultControlLayouts::slider();
198 template <
typename T>
199 static auto make_widget(
203 sl->setOrientation(Qt::Horizontal);
204 bindIntDomain(inlet, inlet, *sl);
205 sl->setValue(ossia::convert<int>(inlet.value()));
206 sl->setContentsMargins(0, 0, 0, 0);
209 sl, &score::IntSlider::sliderMoved, context, [sl, &inlet, &ctx](
int p) {
211 ctx.dispatcher.
submit<SetControlValue<T>>(inlet, p);
213 QObject::connect(sl, &score::IntSlider::sliderReleased, context, [sl, &inlet, &ctx] {
214 ctx.dispatcher.
submit<SetControlValue<T>>(inlet, sl->value());
219 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
221 sl->setValue(ossia::convert<int>(val));
227 template <
typename T,
typename Control_T>
228 static QGraphicsItem* make_item(
230 QGraphicsItem* parent, QObject* context)
233 initWidgetProperties(inlet, *sl);
234 bindIntDomain(slider, inlet, *sl);
235 sl->setValue(ossia::convert<int>(inlet.value()));
238 sl, &score::QGraphicsIntSlider::sliderMoved, context, [=, &inlet, &ctx] {
240 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
243 sl, &score::QGraphicsIntSlider::sliderReleased, context, [&ctx, sl]() {
248 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
250 sl->setValue(ossia::convert<int>(val));
253 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
254 sl->setExecutionValue(ossia::convert<int>(val));
257 &inlet, &Control_T::executionReset, sl,
258 &score::QGraphicsIntSlider::resetExecution);
268 return Process::DefaultControlLayouts::slider();
271 template <
typename T>
272 static auto make_widget(
279 template <
typename T,
typename Control_T>
280 static QGraphicsItem* make_item(
282 QGraphicsItem* parent, QObject* context)
285 initWidgetProperties(inlet, *sl);
286 bindIntDomain(slider, inlet, *sl);
287 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
290 sl, &score::QGraphicsRangeSlider::sliderMoved, context, [=, &inlet, &ctx] {
292 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
295 sl, &score::QGraphicsRangeSlider::sliderReleased, context, [&ctx, sl]() {
300 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
302 sl->setValue(ossia::convert<ossia::vec2f>(val));
305 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
310 &inlet, &Control_T::executionReset, sl,
311 &score::QGraphicsRangeSlider::resetExecution);
320 return Process::DefaultControlLayouts::slider();
323 template <
typename T>
324 static auto make_widget(
331 template <
typename T,
typename Control_T>
332 static QGraphicsItem* make_item(
334 QGraphicsItem* parent, QObject* context)
337 initWidgetProperties(inlet, *sl);
338 bindFloatDomain(slider, inlet, *sl);
339 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
342 sl, &score::QGraphicsRangeSlider::sliderMoved, context, [=, &inlet, &ctx] {
344 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
347 sl, &score::QGraphicsRangeSlider::sliderReleased, context, [&ctx, sl]() {
352 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
354 sl->setValue(ossia::convert<ossia::vec2f>(val));
357 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
362 &inlet, &Control_T::executionReset, sl,
363 &score::QGraphicsRangeSlider::resetExecution);
372 return Process::DefaultControlLayouts::pad();
375 template <
typename T>
376 static auto make_widget(
383 template <
typename T,
typename Control_T>
384 static QGraphicsItem* make_item(
386 QGraphicsItem* parent, QObject* context)
389 initWidgetProperties(inlet, *sl);
390 bindVec2Domain(slider, inlet, *sl);
392 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(inlet.value())));
395 sl, &score::QGraphicsXYSpinboxChooser::sliderMoved, context, [=, &inlet, &ctx] {
397 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
398 inlet, LinearNormalizer::from01(*sl, sl->value()));
401 sl, &score::QGraphicsXYSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
406 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
408 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(val)));
419 return Process::DefaultControlLayouts::spinbox();
422 template <
typename T>
423 static auto make_widget(
426 auto sl =
new QSpinBox{parent};
427 bindIntDomain(inlet, inlet, *sl);
428 sl->setValue(ossia::convert<int>(inlet.value()));
429 sl->setContentsMargins(0, 0, 0, 0);
432 sl, SignalUtils::QSpinBox_valueChanged_int(), context, [&inlet, &ctx](
int val) {
436 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
437 sl->setValue(ossia::convert<int>(val));
443 template <
typename T,
typename Control_T>
444 static QGraphicsItem* make_item(
446 QGraphicsItem* parent, QObject* context)
449 initWidgetProperties(inlet, *sl);
450 bindIntDomain(slider, inlet, *sl);
451 sl->setValue(ossia::convert<int>(inlet.value()));
454 sl, &score::QGraphicsIntSpinbox::sliderMoved, context, [=, &inlet, &ctx] {
456 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
459 sl, &score::QGraphicsIntSpinbox::sliderReleased, context, [&ctx, sl]() {
464 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
466 sl->setValue(ossia::convert<int>(val));
470 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
472 sl->setExecutionValue(ossia::convert<int>(val));
475 &inlet, &Control_T::executionReset, sl,
476 &score::QGraphicsIntSpinbox::resetExecution);
486 return Process::DefaultControlLayouts::spinbox();
489 template <
typename T>
490 static auto make_widget(
493 auto sl =
new QDoubleSpinBox{parent};
494 bindFloatDomain(inlet, inlet, *sl);
495 sl->setValue(ossia::convert<float>(inlet.value()));
496 sl->setContentsMargins(0, 0, 0, 0);
499 sl, SignalUtils::QDoubleSpinBox_valueChanged_double(), context,
500 [&inlet, &ctx](
double val) {
504 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
505 sl->setValue(ossia::convert<float>(val));
511 template <
typename T,
typename Control_T>
512 static QGraphicsItem* make_item(
514 QGraphicsItem* parent, QObject* context)
516 ConcreteNormalizer<LinearNormalizer, T> norm{slider};
519 initWidgetProperties(inlet, *sl);
520 bindFloatDomain(slider, inlet, *sl);
521 sl->setValue(norm.to01(ossia::convert<float>(inlet.value())));
524 sl, &score::QGraphicsSpinbox::sliderMoved, context,
527 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, norm.from01(sl->value()));
530 sl, &score::QGraphicsSpinbox::sliderReleased, context, [&ctx, sl]() {
535 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
537 sl->setValue(norm.to01(ossia::convert<float>(val)));
541 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
543 sl->setExecutionValue(norm.to01(ossia::convert<float>(val)));
546 &inlet, &Control_T::executionReset, sl,
547 &score::QGraphicsSpinbox::resetExecution);
558 return DefaultControlLayouts::knob();
561 template <
typename T>
562 static auto make_widget(
569 template <
typename T,
typename Control_T>
570 static auto make_item(
572 QGraphicsItem* parent, QObject* context)
575 initWidgetProperties(inlet, *sl);
577 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
580 sl, &score::QGraphicsTimeChooser::sliderMoved, context, [sl, &inlet, &ctx] {
581 sl->knob.moving =
true;
582 sl->combo.moving =
true;
583 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
586 sl, &score::QGraphicsTimeChooser::sliderReleased, context, [sl, &inlet, &ctx] {
587 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
589 sl->knob.moving =
false;
590 sl->combo.moving =
false;
594 &inlet, &Control_T::valueChanged, sl, [sl](
const ossia::value& val) {
595 if(!sl->knob.moving && !sl->combo.moving)
597 sl->setValue(ossia::convert<ossia::vec2f>(val));
601 &inlet, &Control_T::executionValueChanged, sl, [sl](
const ossia::value& val) {
602 sl->setExecutionValue(ossia::convert<ossia::vec2f>(val));
605 &inlet, &Control_T::executionReset, sl,
606 &score::QGraphicsTimeChooser::resetExecution);
616 return Process::DefaultControlLayouts::toggle();
619 template <
typename T>
620 static auto make_widget(
623 auto sl =
new QCheckBox{parent};
624 sl->setChecked(ossia::convert<bool>(inlet.value()));
625 QObject::connect(sl, &QCheckBox::toggled, context, [&inlet, &ctx](
bool val) {
629 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
630 sl->setChecked(ossia::convert<bool>(val));
636 template <
typename T,
typename Control_T>
637 static QGraphicsItem* make_item(
639 QGraphicsItem* parent, QObject* context)
642 initWidgetProperties(inlet, *cb);
643 cb->setState(ossia::convert<bool>(inlet.value()));
646 cb, &score::QGraphicsCheckBox::toggled, context,
647 [=, &inlet, &ctx](
bool toggled) {
648 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toggled);
653 &inlet, &Control_T::valueChanged, cb,
654 [cb](
const ossia::value& val) { cb->setState(ossia::convert<bool>(val)); });
664 return Process::DefaultControlLayouts::bang();
667 template <
typename T>
668 static auto make_widget(
671 auto sl =
new QPushButton{parent};
672 const auto& name = inlet.visualName();
673 sl->setText(name.isEmpty() ? QObject::tr(
"Bang") : name);
674 sl->setContentsMargins(0, 0, 0, 0);
676 auto& cinlet =
const_cast<T&
>(inlet);
677 QObject::connect(sl, &QPushButton::pressed, context, [&cinlet] {
678 cinlet.valueChanged(ossia::impulse{});
684 template <
typename T,
typename Control_T>
685 static QGraphicsItem* make_item(
687 QGraphicsItem* parent, QObject* context)
690 initWidgetProperties(inlet, *toggle);
693 toggle, &score::QGraphicsButton::pressed, context, [=, &inlet](
bool pressed) {
696 inlet.valueChanged(ossia::impulse{});
708 return Process::DefaultControlLayouts::bang();
711 template <
typename T>
712 static auto make_widget(
715 auto sl =
new QPushButton{parent};
716 const auto& name = inlet.visualName();
717 sl->setText(name.isEmpty() ? QObject::tr(
"Bang") : name);
718 sl->setContentsMargins(0, 0, 0, 0);
721 auto& cinlet =
const_cast<T&
>(inlet);
723 sl, &QPushButton::pressed, context, [&cinlet] { cinlet.setValue(
true); });
725 sl, &QPushButton::released, context, [&cinlet] { cinlet.setValue(
false); });
730 template <
typename T,
typename Control_T>
731 static QGraphicsItem* make_item(
733 QGraphicsItem* parent, QObject* context)
736 initWidgetProperties(inlet, *toggle);
739 toggle, &score::QGraphicsButton::pressed, context,
740 [=, &inlet, &ctx](
bool pressed) {
741 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, pressed);
753 return Process::DefaultControlLayouts::chooser_toggle();
756 template <
typename T>
757 static constexpr auto getAlternatives(
const T& t) ->
decltype(
auto)
759 if constexpr(std::is_member_function_pointer_v<
decltype(&T::alternatives)>)
761 return t.alternatives();
765 return t.alternatives;
769 template <
typename T>
770 static auto make_widget(
774 const auto& alts = getAlternatives(inlet);
775 SCORE_ASSERT(alts.size() == 2);
777 toggleBtn->setCheckable(
true);
778 bool b = ossia::convert<bool>(inlet.value());
779 if(b && !toggleBtn->isChecked())
781 else if(!b && toggleBtn->isChecked())
785 toggleBtn, &score::ToggleButton::toggled, context, [&inlet, &ctx](
bool val) {
790 &inlet, &T::valueChanged, toggleBtn, [toggleBtn](
const ossia::value& val) {
791 bool b = ossia::convert<bool>(val);
792 if(b && !toggleBtn->isChecked())
794 else if(!b && toggleBtn->isChecked())
801 template <
typename T,
typename Control_T>
802 static QGraphicsItem* make_item(
804 QGraphicsItem* parent, QObject* context)
806 const auto& alts = getAlternatives(control);
807 SCORE_ASSERT(alts.size() == 2);
809 initWidgetProperties(inlet, *toggle);
810 toggle->setState(ossia::convert<bool>(inlet.value()));
813 toggle, &score::QGraphicsToggle::toggled, context,
814 [=, &inlet, &ctx](
bool toggled) {
815 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toggled);
820 &inlet, &Control_T::valueChanged, toggle, [toggle](
const ossia::value& val) {
821 toggle->setState(ossia::convert<bool>(val));
832 return Process::DefaultControlLayouts::lineedit();
835 template <
typename T>
836 static auto make_widget(
839 auto sl =
new QLineEdit{parent};
840 sl->setText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
841 sl->setContentsMargins(0, 0, 0, 0);
842 sl->setMaximumWidth(70);
843 QObject::connect(sl, &QLineEdit::editingFinished, context, [sl, &inlet, &ctx]() {
845 inlet, sl->text().toStdString());
848 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
849 sl->setText(QString::fromStdString(ossia::convert<std::string>(val)));
855 template <
typename T,
typename Control_T>
858 QGraphicsItem* parent, QObject* context)
861 initWidgetProperties(inlet, *sl);
862 sl->setTextWidth(180.);
863 sl->setDefaultTextColor(QColor{
"#E0B01E"});
864 sl->setCursor(Qt::IBeamCursor);
866 sl->setPlainText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
868 auto doc = sl->document();
869 auto on_edit = [=, &inlet, &ctx] {
870 auto cur_str = ossia::convert<std::string>(inlet.value());
871 if(cur_str != doc->toPlainText().toStdString())
874 inlet, doc->toPlainText().toStdString());
878 if(!inlet.noValueChangeOnMove)
880 QObject::connect(doc, &QTextDocument::contentsChanged, context, on_edit);
884 QObject::connect(sl, &score::QGraphicsLineEdit::editingFinished, context, on_edit);
890 sl, &score::QGraphicsLineEdit::sizeChanged, obj,
891 &score::ResizeableItem::childrenSizeChanged);
894 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
895 auto str = QString::fromStdString(ossia::convert<std::string>(val));
896 if(str != doc->toPlainText())
897 doc->setPlainText(str);
912 this->setText(QString::fromStdString(ossia::convert<std::string>(port.value())));
914 &QWidget::deleteLater);
917 void on_accepted()
override
919 this->setError(0, QString{});
920 auto cur = ossia::convert<std::string>(m_port.value());
921 auto next = this->text().toStdString();
924 ossia::qt::run_async(
925 qApp, [&ctx = m_context.commandStack, port = QPointer{&m_port}, next] {
928 CommandDispatcher<>{ctx}.submit(new Process::SetControlValue{*port, next});
941 return Process::DefaultControlLayouts::lineedit();
944 template <
typename T>
945 static auto make_widget(
948 auto toggle =
new QPushButton{QObject::tr(
"Edit..."), parent};
949 QObject::connect(toggle, &QPushButton::clicked, context, [=, &inlet, &ctx] {
950 createDialog(inlet, ctx);
955 template <
typename T,
typename Control_T>
956 static auto make_item(
958 QGraphicsItem* parent, QObject* context)
961 initWidgetProperties(inlet, *toggle);
964 toggle, &score::QGraphicsTextButton::pressed, context,
965 [=, &inlet, &ctx] { createDialog(inlet, ctx); }, Qt::QueuedConnection);
982 return Process::DefaultControlLayouts::lineedit();
984 template <
typename T>
985 static auto make_widget(
988 auto sl =
new QLineEdit{parent};
989 auto act =
new QAction{sl};
991 score::setHelp(act, QObject::tr(
"Opening a File"));
992 act->setIcon(QIcon(
":/icons/search.png"));
993 sl->setPlaceholderText(QObject::tr(
"Open File"));
994 auto on_open = [=, &inlet] {
996 = QFileDialog::getOpenFileName(
nullptr,
"Open File", {}, inlet.filters());
997 if(filename.isEmpty())
999 sl->setText(filename);
1002 QObject::connect(sl, &QLineEdit::returnPressed, on_open);
1003 QObject::connect(act, &QAction::triggered, on_open);
1004 sl->addAction(act, QLineEdit::TrailingPosition);
1006 sl->setText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
1007 sl->setContentsMargins(0, 0, 0, 0);
1010 QObject::connect(sl, &QLineEdit::editingFinished, context, [sl, &inlet, &ctx]() {
1012 inlet, sl->text().toStdString());
1014 QObject::connect(&inlet, &T::valueChanged, sl, [sl](
const ossia::value& val) {
1015 sl->setText(QString::fromStdString(ossia::convert<std::string>(val)));
1020 template <
typename T,
typename Control_T>
1023 QGraphicsItem* parent, QObject* context)
1026 initWidgetProperties(inlet, *bt);
1027 auto on_open = [&inlet, &ctx] {
1029 = QFileDialog::getOpenFileName(
nullptr,
"Open File", {}, inlet.filters());
1030 if(filename.isEmpty())
1034 inlet, filename.toStdString());
1036 auto on_set = [&inlet, &ctx](
const QString& filename) {
1037 if(filename.isEmpty())
1041 inlet, filename.toStdString());
1044 bt, &score::QGraphicsTextButton::pressed, &inlet, on_open, Qt::QueuedConnection);
1046 bt, &score::QGraphicsTextButton::dropped, &inlet, on_set, Qt::QueuedConnection);
1047 auto set = [=](
const ossia::value& val) {
1048 auto str = QString::fromStdString(ossia::convert<std::string>(val));
1049 if(str != bt->text())
1052 bt->setText(str.split(
"/").back());
1054 bt->setText(
"Choose a file...");
1058 set(slider.value());
1059 QObject::connect(&inlet, &Control_T::valueChanged, bt, set);
1069 return Process::DefaultControlLayouts::list();
1072 static const auto& toStd(
const char*
const& s) {
return s; }
1073 static const auto& toStd(
const std::string& s) {
return s; }
1074 static auto toStd(
const QString& s) {
return s.toStdString(); }
1076 static const auto& convert(
const std::string& str,
const char*) {
return str; }
1077 static auto convert(
const std::string& str,
const QString&)
1079 return QString::fromStdString(str);
1081 template <
typename T>
1082 static auto make_widget(
1085 const auto& values = inlet.getValues();
1086 using val_t = std::remove_reference_t<
decltype(values[0])>;
1087 auto sl =
new QComboBox{parent};
1088 for(
const auto& e : values)
1093 auto set_index = [values, sl](
const ossia::value& val) {
1094 auto v = ossia::convert<std::string>(val);
1095 auto it = ossia::find(values, convert(v, val_t{}));
1096 if(it != values.end())
1098 sl->setCurrentIndex(std::distance(values.begin(), it));
1101 set_index(inlet.value());
1104 sl, SignalUtils::QComboBox_currentIndexChanged_int(), context,
1105 [values, &inlet, &ctx](
int idx) {
1107 inlet, toStd(values[idx]));
1111 &inlet, &T::valueChanged, sl, [=](
const ossia::value& val) { set_index(val); });
1116 template <
typename T,
typename Control_T>
1117 static auto make_item(
1119 QGraphicsItem* parent, QObject* context)
1121 const auto& values = slider.getValues();
1122 using val_t = std::remove_reference_t<
decltype(values[0])>;
1124 auto sl = slider.pixmaps.empty() || slider.pixmaps[0] ==
nullptr
1127 values, slider.pixmaps,
nullptr};
1129 initWidgetProperties(inlet, *sl);
1131 auto set_index = [values, sl](
const ossia::value& val) {
1132 auto v = ossia::convert<std::string>(val);
1133 auto it = ossia::find(values, convert(v, val_t{}));
1134 if(it != values.end())
1136 sl->setValue(std::distance(values.begin(), it));
1140 set_index(inlet.value());
1143 sl, &score::QGraphicsEnum::currentIndexChanged, context,
1144 [sl, &inlet, &ctx](
int idx) {
1145 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toStd(sl->array[idx]));
1149 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1161 return Process::DefaultControlLayouts::combo();
1164 template <
typename T>
1165 static auto make_widget(
1168 const auto& values = inlet.getValues();
1170 for(
auto& e : values)
1172 sl->addItem(e.first);
1174 sl->setContentsMargins(0, 0, 0, 0);
1176 auto set_index = [values, sl](
const ossia::value& val) {
1178 = ossia::find_if(values, [&](
const auto& pair) {
return pair.second == val; });
1179 if(it != values.end())
1181 sl->setCurrentIndex(std::distance(values.begin(), it));
1184 set_index(inlet.value());
1187 sl, SignalUtils::QComboBox_currentIndexChanged_int(), context,
1188 [values, &inlet, &ctx](
int idx) {
1190 inlet, values[idx].second);
1194 &inlet, &T::valueChanged, sl, [=](
const ossia::value& val) { set_index(val); });
1199 template <
typename U,
typename Control_T>
1200 static QGraphicsItem* make_item(
1202 QGraphicsItem* parent, QObject* context)
1204 const auto N = slider.count();
1206 const auto& values = slider.getValues();
1209 for(std::size_t i = 0; i < N; i++)
1210 arr.push_back(values[i].first);
1213 initWidgetProperties(inlet, *sl);
1215 auto set_index = [values, sl](
const ossia::value& val) {
1217 = ossia::find_if(values, [&](
const auto& pair) {
return pair.second == val; });
1218 if(it != values.end())
1220 sl->setValue(std::distance(values.begin(), it));
1223 set_index(inlet.value());
1226 sl, &score::QGraphicsCombo::sliderMoved, context, [values, sl, &inlet, &ctx] {
1228 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1229 inlet, values[sl->value()].second);
1231 QObject::connect(sl, &score::QGraphicsCombo::sliderReleased, context, [sl, &ctx] {
1236 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1255 using QValidator::QValidator;
1256 State validate(QString& str,
int&)
const override
1258 auto p = ossia::get_time_signature(str.toStdString());
1260 return State::Invalid;
1262 return State::Acceptable;
1270 return Process::DefaultControlLayouts::pad();
1273 template <
typename T>
1274 static auto make_widget(
1281 template <
typename T,
typename Control_T>
1282 static QGraphicsItem* make_item(
1284 QGraphicsItem* parent, QObject* context)
1287 initWidgetProperties(inlet, *sl);
1288 sl->setRgbaValue(ossia::convert<ossia::vec4f>(inlet.value()));
1291 sl, &score::QGraphicsHSVChooser::sliderMoved, context, [=, &inlet, &ctx] {
1293 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->rgbaValue());
1296 sl, &score::QGraphicsHSVChooser::sliderReleased, context, [&ctx, sl]() {
1301 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1303 sl->setRgbaValue(ossia::convert<ossia::vec4f>(val));
1318 template <
typename T>
1319 static auto make_widget(
1326 template <
typename T,
typename Control_T>
1327 static QGraphicsItem* make_item(
1329 QGraphicsItem* parent, QObject* context)
1332 initWidgetProperties(inlet, *sl);
1333 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
1334 bindVec2Domain(slider, inlet, *sl);
1337 sl, &score::QGraphicsXYChooser::sliderMoved, context, [=, &inlet, &ctx] {
1339 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1342 sl, &score::QGraphicsXYChooser::sliderReleased, context, [&ctx, sl]() {
1347 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1349 sl->setValue(ossia::convert<ossia::vec2f>(val));
1360 return Process::DefaultControlLayouts::pad();
1363 template <
typename T>
1364 static auto make_widget(
1371 template <
typename T,
typename Control_T>
1372 static QGraphicsItem* make_item(
1374 QGraphicsItem* parent, QObject* context)
1377 initWidgetProperties(inlet, *sl);
1378 sl->setValue(ossia::convert<ossia::vec3f>(inlet.value()));
1379 bindVec3Domain(slider, inlet, *sl);
1382 sl, &score::QGraphicsXYZChooser::sliderMoved, context, [=, &inlet, &ctx] {
1384 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1387 sl, &score::QGraphicsXYZChooser::sliderReleased, context, [&ctx, sl]() {
1392 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1394 sl->setValue(ossia::convert<ossia::vec3f>(val));
1405 return Process::DefaultControlLayouts::pad();
1408 template <
typename T>
1409 static auto make_widget(
1416 static QGraphicsItem* make_item(
1417 const Process::XYSpinboxes& slider, Process::XYSpinboxes& inlet,
1420 using Control_T = Process::XYSpinboxes;
1424 initWidgetProperties(inlet, *sl);
1425 bindVec2Domain(slider, inlet, *sl);
1426 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
1429 sl, &score::QGraphicsIntXYSpinboxChooser::sliderMoved, context,
1432 auto [x, y] = sl->value();
1433 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, ossia::make_vec(x, y));
1436 sl, &score::QGraphicsIntXYSpinboxChooser::sliderReleased, context,
1443 &inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1445 sl->setValue(ossia::convert<ossia::vec2f>(val));
1453 initWidgetProperties(inlet, *sl);
1454 bindVec2Domain(slider, inlet, *sl);
1456 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(inlet.value())));
1459 sl, &score::QGraphicsXYSpinboxChooser::sliderMoved, context,
1462 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1463 inlet, LinearNormalizer::from01(*sl, sl->value()));
1466 sl, &score::QGraphicsXYSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
1472 &inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1474 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(val)));
1486 return Process::DefaultControlLayouts::pad();
1489 template <
typename T>
1490 static auto make_widget(
1497 template <
typename T,
typename Control_T>
1498 static QGraphicsItem* make_item(
1500 QGraphicsItem* parent, QObject* context)
1503 initWidgetProperties(inlet, *sl);
1504 bindVec3Domain(slider, inlet, *sl);
1506 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec3f>(inlet.value())));
1509 sl, &score::QGraphicsXYZSpinboxChooser::sliderMoved, context, [=, &inlet, &ctx] {
1511 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1512 inlet, LinearNormalizer::from01(*sl, sl->value()));
1515 sl, &score::QGraphicsXYZSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
1520 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1522 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec3f>(val)));
1533 return Process::DefaultControlLayouts::slider();
1536 template <
typename T>
1537 static auto make_widget(
1544 template <
typename T,
typename Control_T>
1545 static QGraphicsItem* make_item(
1547 QGraphicsItem* parent, QObject* context)
1550 initWidgetProperties(inlet, *sl);
1551 sl->setValue(inlet.value());
1552 sl->setRange(inlet.domain());
1555 sl, &score::QGraphicsMultiSlider::sliderMoved, context, [=, &inlet, &ctx] {
1557 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1560 sl, &score::QGraphicsMultiSlider::sliderReleased, context, [&ctx, sl]() {
1565 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1567 sl->setValue(std::move(val));
1578 return Process::DefaultControlLayouts::slider();
1581 template <
typename T>
1582 static auto make_widget(
1589 template <
typename T,
typename Control_T>
1590 static QGraphicsItem* make_item(
1592 QGraphicsItem* parent, QObject* context)
1595 initWidgetProperties(inlet, *sl);
1596 sl->setValue(inlet.value());
1597 sl->setRange(inlet.domain());
1600 sl, &score::QGraphicsMultiSliderXY::sliderMoved, context, [=, &inlet, &ctx] {
1602 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1605 sl, &score::QGraphicsMultiSliderXY::sliderReleased, context, [&ctx, sl]() {
1610 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1612 sl->setValue(std::move(val));
1623 return Process::DefaultControlLayouts::slider();
1626 template <
typename T>
1627 static auto make_widget(
1634 template <
typename T,
typename Control_T>
1635 static QGraphicsItem* make_item(
1637 QGraphicsItem* parent, QObject* context)
1640 initWidgetProperties(inlet, *sl);
1641 sl->setValue(inlet.value());
1642 sl->setRange(inlet.domain());
1645 sl, &score::QGraphicsPathGeneratorXY::sliderMoved, context, [=, &inlet, &ctx] {
1647 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1650 sl, &score::QGraphicsPathGeneratorXY::sliderReleased, context, [&ctx, sl]() {
1655 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1657 sl->setValue(std::move(val));
The CommandDispatcher class.
Definition CommandDispatcher.hpp:13
void identified_object_destroying(IdentifiedObjectAbstract *o)
To be called by subclasses.
void submit(Args &&... args)
Definition OngoingCommandDispatcher.hpp:37
void commit()
Definition OngoingCommandDispatcher.hpp:61
Definition ScriptEditor.hpp:21
Definition SetControlValue.hpp:34
Definition SetControlValue.hpp:13
Definition ComboBox.hpp:10
Definition QGraphicsCheckBox.hpp:16
Definition QGraphicsCombo.hpp:18
Definition QGraphicsEnum.hpp:17
Definition QGraphicsHSVChooser.hpp:18
Definition QGraphicsIntSlider.hpp:17
Definition QGraphicsSpinbox.hpp:64
Definition QGraphicsXYSpinbox.hpp:60
Definition QGraphicsMultiSlider.hpp:24
Definition QGraphicsMultiSliderXY.hpp:29
Definition QGraphicsPathGeneratorXY.hpp:29
Definition QGraphicsPixmapEnum.hpp:17
Definition QGraphicsRangeSlider.hpp:21
Definition QGraphicsSpinbox.hpp:15
Definition QGraphicsTextButton.hpp:16
Definition QGraphicsTimeChooser.hpp:21
Definition QGraphicsToggle.hpp:16
Definition QGraphicsXYChooser.hpp:18
Definition QGraphicsXYSpinbox.hpp:20
Definition QGraphicsXYZChooser.hpp:19
Definition QGraphicsXYZSpinbox.hpp:19
Definition RectItem.hpp:12
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:33
Definition plugins/score-lib-process/Process/Dataflow/ControlWidgets.hpp:44
Definition DocumentContext.hpp:18
Definition QGraphicsLineEdit.hpp:17
Definition lib/score/widgets/ControlWidgets.hpp:72
Definition lib/score/widgets/ControlWidgets.hpp:29