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/TextItem.hpp>
14 #include <score/graphics/widgets/QGraphicsMultiSlider.hpp>
15 #include <score/graphics/widgets/QGraphicsTextButton.hpp>
16 #include <score/graphics/widgets/QGraphicsXYSpinbox.hpp>
17 #include <score/graphics/widgets/QGraphicsXYZSpinbox.hpp>
18 #include <score/tools/Unused.hpp>
19 #include <score/widgets/ComboBox.hpp>
20 #include <score/widgets/ControlWidgets.hpp>
21 #include <score/widgets/SignalUtils.hpp>
23 #include <ossia/detail/algorithms.hpp>
24 #include <ossia/network/domain/domain_functions.hpp>
25 #include <ossia/network/value/value_conversion.hpp>
28 #include <QFileDialog>
29 #include <QGraphicsItem>
30 #include <QGraphicsSceneDragDropEvent>
33 #include <QTextDocument>
35 #include <private/qwidgettextcontrol_p.h>
37 #include <score_lib_process_export.h>
58 struct SCORE_LIB_PROCESS_EXPORT
LineEditItem :
public QGraphicsTextItem
63 : QGraphicsTextItem{parent}
65 setTextInteractionFlags(Qt::TextEditorInteraction);
66 auto ctl = this->findChild<QWidgetTextControl*>();
69 ctl->setAcceptRichText(
false);
73 void dropEvent(QGraphicsSceneDragDropEvent* drop)
override
75 QGraphicsItem::dropEvent(drop);
76 const auto& urlList = drop->mimeData()->urls();
78 if(!urlList.isEmpty())
80 this->setPlainText(urlList[0].toLocalFile());
84 void sizeChanged(QSizeF sz) E_SIGNAL(SCORE_LIB_PROCESS_EXPORT, sizeChanged, sz)
88 namespace WidgetFactory
90 static_assert(std::numeric_limits<float>::is_iec559,
"IEEE 754 required");
92 using SetControlValue =
typename std::conditional_t<
96 template <
typename Normalizer,
typename T>
97 using ConcreteNormalizer = std::conditional_t<
98 std::is_base_of_v<Process::ControlInlet, T>
99 || std::is_base_of_v<Process::ControlOutlet, T>,
100 UpdatingNormalizer<Normalizer, T>, FixedNormalizer<Normalizer>>;
101 template <
typename ControlUI,
typename Normalizer,
bool Control>
108 std::is_same_v<score::QGraphicsKnob, ControlUI>
109 || std::is_same_v<score::QGraphicsLogKnob, ControlUI>)
111 return DefaultControlLayouts::knob();
115 return DefaultControlLayouts::slider();
119 template <
typename T,
typename Control_T>
120 static auto make_widget(
122 QWidget* parent, QObject* context)
124 ConcreteNormalizer<Normalizer, T> norm{slider};
127 sl->setOrientation(Qt::Horizontal);
128 sl->setContentsMargins(0, 0, 0, 0);
129 bindFloatDomain(slider, inlet, *sl);
130 sl->setValue(norm.to01(ossia::convert<double>(inlet.value())));
132 if constexpr(Control)
135 sl, &score::DoubleSlider::sliderMoved, context,
136 [sl, norm, &inlet, &ctx](
double v) {
138 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
139 inlet, norm.from01(sl->value()));
142 sl, &score::DoubleSlider::sliderReleased, context, [sl, norm, &inlet, &ctx]() {
143 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
144 inlet, norm.from01(sl->value()));
151 &inlet, &Control_T::valueChanged, sl, [sl, norm](
const ossia::value& val) {
152 if constexpr(Control)
155 sl->setValue(norm.to01(ossia::convert<double>(val)));
159 sl->setValue(norm.to01(ossia::convert<double>(val)));
166 template <
typename T,
typename Control_T>
167 static auto make_item(
169 QGraphicsItem* parent, QObject* context)
171 ConcreteNormalizer<Normalizer, T> norm{slider};
173 auto sl =
new ControlUI{
nullptr};
174 bindFloatDomain(slider, inlet, *sl);
175 sl->setValue(norm.to01(ossia::convert<double>(inlet.value())));
177 if constexpr(Control)
179 QObject::connect(sl, &ControlUI::sliderMoved, context, [sl, norm, &inlet, &ctx] {
181 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
182 inlet, norm.from01(sl->value()));
185 sl, &ControlUI::sliderReleased, context, [sl, norm, &inlet, &ctx] {
186 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
187 inlet, norm.from01(sl->value()));
194 &inlet, &Control_T::valueChanged, sl, [sl, norm](
const ossia::value& val) {
195 if constexpr(Control)
198 sl->setValue(norm.to01(ossia::convert<double>(val)));
202 sl->setValue(norm.to01(ossia::convert<double>(val)));
206 &inlet, &Control_T::executionValueChanged, sl,
207 [sl, norm](
const ossia::value& val) {
208 sl->setExecutionValue(norm.to01(ossia::convert<double>(val)));
210 QObject::connect(&inlet, &Control_T::executionReset, sl, &ControlUI::resetExecution);
227 return Process::DefaultControlLayouts::slider();
230 template <
typename T,
typename Control_T>
231 static auto make_widget(
233 QWidget* parent, QObject* context)
236 sl->setOrientation(Qt::Horizontal);
237 bindIntDomain(slider, inlet, *sl);
238 sl->setValue(ossia::convert<int>(inlet.value()));
239 sl->setContentsMargins(0, 0, 0, 0);
242 sl, &score::IntSlider::sliderMoved, context, [sl, &inlet, &ctx](
int p) {
244 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, p);
246 QObject::connect(sl, &score::IntSlider::sliderReleased, context, [sl, &inlet, &ctx] {
247 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
253 &inlet, &Control_T::valueChanged, sl, [sl](
const ossia::value& val) {
255 sl->setValue(ossia::convert<int>(val));
261 template <
typename T,
typename Control_T>
262 static QGraphicsItem* make_item(
264 QGraphicsItem* parent, QObject* context)
267 bindIntDomain(slider, inlet, *sl);
268 sl->setValue(ossia::convert<int>(inlet.value()));
271 sl, &score::QGraphicsIntSlider::sliderMoved, context, [=, &inlet, &ctx] {
273 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
276 sl, &score::QGraphicsIntSlider::sliderReleased, context, [&ctx, sl]() {
281 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
283 sl->setValue(ossia::convert<int>(val));
286 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
287 sl->setExecutionValue(ossia::convert<int>(val));
290 &inlet, &Control_T::executionReset, sl,
291 &score::QGraphicsIntSlider::resetExecution);
301 return Process::DefaultControlLayouts::slider();
304 template <
typename T,
typename Control_T>
305 static auto make_widget(
307 QWidget* parent, QObject* context)
313 template <
typename T,
typename Control_T>
314 static QGraphicsItem* make_item(
316 QGraphicsItem* parent, QObject* context)
319 bindIntDomain(slider, inlet, *sl);
320 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
323 sl, &score::QGraphicsRangeSlider::sliderMoved, context, [=, &inlet, &ctx] {
325 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
328 sl, &score::QGraphicsRangeSlider::sliderReleased, context, [&ctx, sl]() {
333 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
335 sl->setValue(ossia::convert<ossia::vec2f>(val));
338 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
343 &inlet, &Control_T::executionReset, sl,
344 &score::QGraphicsRangeSlider::resetExecution);
353 return Process::DefaultControlLayouts::slider();
356 template <
typename T,
typename Control_T>
357 static auto make_widget(
359 QWidget* parent, QObject* context)
365 template <
typename T,
typename Control_T>
366 static QGraphicsItem* make_item(
368 QGraphicsItem* parent, QObject* context)
371 bindFloatDomain(slider, inlet, *sl);
372 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
375 sl, &score::QGraphicsRangeSlider::sliderMoved, context, [=, &inlet, &ctx] {
377 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
380 sl, &score::QGraphicsRangeSlider::sliderReleased, context, [&ctx, sl]() {
385 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
387 sl->setValue(ossia::convert<ossia::vec2f>(val));
390 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
395 &inlet, &Control_T::executionReset, sl,
396 &score::QGraphicsRangeSlider::resetExecution);
405 return Process::DefaultControlLayouts::pad();
408 template <
typename T,
typename Control_T>
409 static auto make_widget(
411 QWidget* parent, QObject* context)
417 template <
typename T,
typename Control_T>
418 static QGraphicsItem* make_item(
420 QGraphicsItem* parent, QObject* context)
423 bindVec2Domain(slider, inlet, *sl);
425 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(inlet.value())));
428 sl, &score::QGraphicsXYSpinboxChooser::sliderMoved, context, [=, &inlet, &ctx] {
430 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
431 inlet, LinearNormalizer::from01(*sl, sl->value()));
434 sl, &score::QGraphicsXYSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
439 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
441 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(val)));
452 return Process::DefaultControlLayouts::spinbox();
455 template <
typename T,
typename Control_T>
456 static auto make_widget(
458 QWidget* parent, QObject* context)
460 auto sl =
new QSpinBox{parent};
461 bindIntDomain(slider, inlet, *sl);
462 sl->setValue(ossia::convert<int>(inlet.value()));
463 sl->setContentsMargins(0, 0, 0, 0);
466 sl, SignalUtils::QSpinBox_valueChanged_int(), context, [&inlet, &ctx](
int val) {
472 &inlet, &Control_T::valueChanged, sl,
473 [sl](
const ossia::value& val) { sl->setValue(ossia::convert<int>(val)); });
478 template <
typename T,
typename Control_T>
479 static QGraphicsItem* make_item(
481 QGraphicsItem* parent, QObject* context)
484 bindIntDomain(slider, inlet, *sl);
485 sl->setValue(ossia::convert<int>(inlet.value()));
488 sl, &score::QGraphicsIntSpinbox::sliderMoved, context, [=, &inlet, &ctx] {
490 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
493 sl, &score::QGraphicsIntSpinbox::sliderReleased, context, [&ctx, sl]() {
498 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
500 sl->setValue(ossia::convert<int>(val));
504 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
506 sl->setExecutionValue(ossia::convert<int>(val));
509 &inlet, &Control_T::executionReset, sl,
510 &score::QGraphicsIntSpinbox::resetExecution);
520 return Process::DefaultControlLayouts::spinbox();
523 template <
typename T,
typename Control_T>
524 static auto make_widget(
526 QWidget* parent, QObject* context)
528 auto sl =
new QDoubleSpinBox{parent};
529 bindFloatDomain(slider, inlet, *sl);
530 sl->setValue(ossia::convert<float>(inlet.value()));
531 sl->setContentsMargins(0, 0, 0, 0);
534 sl, SignalUtils::QDoubleSpinBox_valueChanged_double(), context,
535 [&inlet, &ctx](
double val) {
541 &inlet, &Control_T::valueChanged, sl,
542 [sl](
const ossia::value& val) { sl->setValue(ossia::convert<float>(val)); });
547 template <
typename T,
typename Control_T>
548 static QGraphicsItem* make_item(
550 QGraphicsItem* parent, QObject* context)
552 ConcreteNormalizer<LinearNormalizer, T> norm{slider};
555 bindFloatDomain(slider, inlet, *sl);
556 sl->setValue(norm.to01(ossia::convert<float>(inlet.value())));
559 sl, &score::QGraphicsSpinbox::sliderMoved, context,
562 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, norm.from01(sl->value()));
565 sl, &score::QGraphicsSpinbox::sliderReleased, context, [&ctx, sl]() {
570 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
572 sl->setValue(norm.to01(ossia::convert<float>(val)));
576 &inlet, &Control_T::executionValueChanged, sl, [=](
const ossia::value& val) {
578 sl->setExecutionValue(norm.to01(ossia::convert<float>(val)));
581 &inlet, &Control_T::executionReset, sl,
582 &score::QGraphicsSpinbox::resetExecution);
593 return DefaultControlLayouts::knob();
596 template <
typename T,
typename Control_T>
597 static auto make_widget(
599 QWidget* parent, QObject* context)
605 template <
typename T,
typename Control_T>
606 static auto make_item(
608 QGraphicsItem* parent, QObject* context)
612 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
615 sl, &score::QGraphicsTimeChooser::sliderMoved, context, [sl, &inlet, &ctx] {
616 sl->knob.moving =
true;
617 sl->combo.moving =
true;
618 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
621 sl, &score::QGraphicsTimeChooser::sliderReleased, context, [sl, &inlet, &ctx] {
622 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
624 sl->knob.moving =
false;
625 sl->combo.moving =
false;
629 &inlet, &Control_T::valueChanged, sl, [sl](
const ossia::value& val) {
630 if(!sl->knob.moving && !sl->combo.moving)
632 sl->setValue(ossia::convert<ossia::vec2f>(val));
636 &inlet, &Control_T::executionValueChanged, sl, [sl](
const ossia::value& val) {
637 sl->setExecutionValue(ossia::convert<ossia::vec2f>(val));
640 &inlet, &Control_T::executionReset, sl,
641 &score::QGraphicsTimeChooser::resetExecution);
651 return Process::DefaultControlLayouts::toggle();
654 template <
typename T,
typename Control_T>
655 static auto make_widget(
657 QWidget* parent, QObject* context)
659 auto sl =
new QCheckBox{parent};
660 sl->setChecked(ossia::convert<bool>(inlet.value()));
661 QObject::connect(sl, &QCheckBox::toggled, context, [&inlet, &ctx](
bool val) {
667 &inlet, &Control_T::valueChanged, sl,
668 [sl](
const ossia::value& val) { sl->setChecked(ossia::convert<bool>(val)); });
673 template <
typename T,
typename Control_T>
674 static QGraphicsItem* make_item(
676 QGraphicsItem* parent, QObject* context)
679 cb->setState(ossia::convert<bool>(inlet.value()));
682 cb, &score::QGraphicsCheckBox::toggled, context,
683 [=, &inlet, &ctx](
bool toggled) {
684 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toggled);
689 &inlet, &Control_T::valueChanged, cb,
690 [cb](
const ossia::value& val) { cb->setState(ossia::convert<bool>(val)); });
700 return Process::DefaultControlLayouts::bang();
703 template <
typename T,
typename Control_T>
704 static auto make_widget(
706 QWidget* parent, QObject* context)
708 auto sl =
new QPushButton{parent};
709 const auto& name = inlet.visualName();
710 sl->setText(name.isEmpty() ? QObject::tr(
"Bang") : name);
711 sl->setContentsMargins(0, 0, 0, 0);
713 auto& cinlet =
const_cast<Control_T&
>(inlet);
714 QObject::connect(sl, &QPushButton::pressed, context, [&cinlet] {
715 cinlet.valueChanged(ossia::impulse{});
721 template <
typename T,
typename Control_T>
722 static QGraphicsItem* make_item(
724 QGraphicsItem* parent, QObject* context)
729 toggle, &score::QGraphicsButton::pressed, context, [=, &inlet](
bool pressed) {
732 inlet.valueChanged(ossia::impulse{});
744 return Process::DefaultControlLayouts::bang();
747 template <
typename T,
typename Control_T>
748 static auto make_widget(
750 QWidget* parent, QObject* context)
752 auto sl =
new QPushButton{parent};
753 const auto& name = inlet.visualName();
754 sl->setText(name.isEmpty() ? QObject::tr(
"Bang") : name);
755 sl->setContentsMargins(0, 0, 0, 0);
758 auto& cinlet =
const_cast<Control_T&
>(inlet);
760 sl, &QPushButton::pressed, context, [&cinlet] { cinlet.setValue(
true); });
762 sl, &QPushButton::released, context, [&cinlet] { cinlet.setValue(
false); });
767 template <
typename T,
typename Control_T>
768 static QGraphicsItem* make_item(
770 QGraphicsItem* parent, QObject* context)
775 toggle, &score::QGraphicsButton::pressed, context,
776 [=, &inlet, &ctx](
bool pressed) {
777 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, pressed);
789 return Process::DefaultControlLayouts::chooser_toggle();
792 template <
typename T>
793 static constexpr
auto getAlternatives(
const T& t) -> decltype(
auto)
795 if constexpr(std::is_member_function_pointer_v<decltype(&T::alternatives)>)
797 return t.alternatives();
801 return t.alternatives;
804 template <
typename T,
typename Control_T>
805 static auto make_widget(
807 QWidget* parent, QObject* context)
810 const auto& alts = getAlternatives(control);
811 SCORE_ASSERT(alts.size() == 2);
813 toggleBtn->setCheckable(
true);
814 bool b = ossia::convert<bool>(inlet.value());
815 if(b && !toggleBtn->isChecked())
817 else if(!b && toggleBtn->isChecked())
821 toggleBtn, &score::ToggleButton::toggled, context, [&inlet, &ctx](
bool val) {
827 &inlet, &Control_T::valueChanged, toggleBtn,
828 [toggleBtn](
const ossia::value& val) {
829 bool b = ossia::convert<bool>(val);
830 if(b && !toggleBtn->isChecked())
832 else if(!b && toggleBtn->isChecked())
839 template <
typename T,
typename Control_T>
840 static QGraphicsItem* make_item(
842 QGraphicsItem* parent, QObject* context)
844 const auto& alts = getAlternatives(control);
845 SCORE_ASSERT(alts.size() == 2);
847 toggle->setState(ossia::convert<bool>(inlet.value()));
850 toggle, &score::QGraphicsToggle::toggled, context,
851 [=, &inlet, &ctx](
bool toggled) {
852 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toggled);
857 &inlet, &Control_T::valueChanged, toggle, [toggle](
const ossia::value& val) {
858 toggle->setState(ossia::convert<bool>(val));
869 return Process::DefaultControlLayouts::lineedit();
872 template <
typename T,
typename Control_T>
873 static auto make_widget(
875 QWidget* parent, QObject* context)
877 auto sl =
new QLineEdit{parent};
878 sl->setText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
879 sl->setContentsMargins(0, 0, 0, 0);
880 sl->setMaximumWidth(70);
881 QObject::connect(sl, &QLineEdit::editingFinished, context, [sl, &inlet, &ctx]() {
883 inlet, sl->text().toStdString());
887 &inlet, &Control_T::valueChanged, sl, [sl](
const ossia::value& val) {
888 sl->setText(QString::fromStdString(ossia::convert<std::string>(val)));
894 template <
typename T,
typename Control_T>
897 QGraphicsItem* parent, QObject* context)
900 sl->setTextWidth(180.);
901 sl->setDefaultTextColor(QColor{
"#E0B01E"});
902 sl->setCursor(Qt::IBeamCursor);
904 sl->setPlainText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
906 auto doc = sl->document();
908 doc, &QTextDocument::contentsChanged, context,
909 [=, &inlet, &ctx, r = sl->boundingRect()]()
mutable {
910 auto cur_str = ossia::convert<std::string>(inlet.value());
911 if(cur_str != doc->toPlainText().toStdString())
913 CommandDispatcher<>{ctx.commandStack}.submit<SetControlValue<Control_T>>(
914 inlet, doc->toPlainText().toStdString());
917 if(r != sl->boundingRect())
919 r = sl->boundingRect();
920 sl->sizeChanged(r.size());
923 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
924 auto str = QString::fromStdString(ossia::convert<std::string>(val));
925 if(str != doc->toPlainText())
926 doc->setPlainText(str);
941 this->setText(QString::fromStdString(ossia::convert<std::string>(port.value())));
943 &QWidget::deleteLater);
946 void on_accepted()
override
948 this->setError(0, QString{});
949 auto cur = ossia::convert<std::string>(m_port.value());
950 auto next = this->text().toStdString();
965 return Process::DefaultControlLayouts::lineedit();
968 template <
typename T,
typename Control_T>
969 static auto make_widget(
971 QWidget* parent, QObject* context)
973 auto toggle =
new QPushButton{QObject::tr(
"Edit..."), parent};
974 QObject::connect(toggle, &QPushButton::clicked, context, [=, &inlet, &ctx] {
975 createDialog(inlet, ctx);
980 template <
typename T,
typename Control_T>
981 static auto make_item(
983 QGraphicsItem* parent, QObject* context)
988 toggle, &score::QGraphicsTextButton::pressed, context,
989 [=, &inlet, &ctx] { createDialog(inlet, ctx); });
1006 return Process::DefaultControlLayouts::lineedit();
1008 template <
typename T,
typename Control_T>
1009 static auto make_widget(
1011 QWidget* parent, QObject* context)
1013 auto sl =
new QLineEdit{parent};
1014 auto act =
new QAction{sl};
1016 act->setStatusTip(QObject::tr(
"Opening a File"));
1017 act->setIcon(QIcon(
":/icons/search.png"));
1018 sl->setPlaceholderText(QObject::tr(
"Open File"));
1019 auto on_open = [=, &inlet] {
1021 = QFileDialog::getOpenFileName(
nullptr,
"Open File", {}, inlet.filters());
1022 if(filename.isEmpty())
1024 sl->setText(filename);
1027 QObject::connect(sl, &QLineEdit::returnPressed, on_open);
1028 QObject::connect(act, &QAction::triggered, on_open);
1029 sl->addAction(act, QLineEdit::TrailingPosition);
1031 sl->setText(QString::fromStdString(ossia::convert<std::string>(inlet.value())));
1032 sl->setContentsMargins(0, 0, 0, 0);
1035 QObject::connect(sl, &QLineEdit::editingFinished, context, [sl, &inlet, &ctx]() {
1037 inlet, sl->text().toStdString());
1040 &inlet, &Control_T::valueChanged, sl, [sl](
const ossia::value& val) {
1041 sl->setText(QString::fromStdString(ossia::convert<std::string>(val)));
1046 template <
typename T,
typename Control_T>
1049 QGraphicsItem* parent, QObject* context)
1052 auto on_open = [&inlet, &ctx] {
1054 = QFileDialog::getOpenFileName(
nullptr,
"Open File", {}, inlet.filters());
1055 if(filename.isEmpty())
1059 inlet, filename.toStdString());
1061 auto on_set = [&inlet, &ctx](
const QString& filename) {
1062 if(filename.isEmpty())
1066 inlet, filename.toStdString());
1068 QObject::connect(bt, &score::QGraphicsTextButton::pressed, &inlet, on_open);
1069 QObject::connect(bt, &score::QGraphicsTextButton::dropped, &inlet, on_set);
1070 auto set = [=](
const ossia::value& val) {
1071 auto str = QString::fromStdString(ossia::convert<std::string>(val));
1072 if(str != bt->text())
1075 bt->setText(str.split(
"/").back());
1077 bt->setText(
"Choose a file...");
1081 set(slider.value());
1082 QObject::connect(&inlet, &Control_T::valueChanged, bt, set);
1092 return Process::DefaultControlLayouts::list();
1095 static const auto& toStd(
const char*
const& s) {
return s; }
1096 static const auto& toStd(
const std::string& s) {
return s; }
1097 static auto toStd(
const QString& s) {
return s.toStdString(); }
1099 static const auto& convert(
const std::string& str,
const char*) {
return str; }
1100 static auto convert(
const std::string& str,
const QString&)
1102 return QString::fromStdString(str);
1105 template <
typename T,
typename Control_T>
1106 static auto make_widget(
1108 QWidget* parent, QObject* context)
1110 const auto& values = slider.getValues();
1111 using val_t = std::remove_reference_t<decltype(values[0])>;
1112 auto sl =
new QComboBox{parent};
1113 for(
const auto& e : values)
1118 auto set_index = [values, sl](
const ossia::value& val) {
1119 auto v = ossia::convert<std::string>(val);
1120 auto it = ossia::find(values, convert(v, val_t{}));
1121 if(it != values.end())
1123 sl->setCurrentIndex(std::distance(values.begin(), it));
1126 set_index(inlet.value());
1129 sl, SignalUtils::QComboBox_currentIndexChanged_int(), context,
1130 [values, &inlet, &ctx](
int idx) {
1132 inlet, toStd(values[idx]));
1135 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1142 template <
typename T,
typename Control_T>
1143 static auto make_item(
1145 QGraphicsItem* parent, QObject* context)
1147 const auto& values = slider.getValues();
1148 using val_t = std::remove_reference_t<decltype(values[0])>;
1150 auto sl = slider.pixmaps.empty() || slider.pixmaps[0] ==
nullptr
1153 values, slider.pixmaps,
nullptr};
1155 auto set_index = [values, sl](
const ossia::value& val) {
1156 auto v = ossia::convert<std::string>(val);
1157 auto it = ossia::find(values, convert(v, val_t{}));
1158 if(it != values.end())
1160 sl->setValue(std::distance(values.begin(), it));
1164 set_index(inlet.value());
1167 sl, &score::QGraphicsEnum::currentIndexChanged, context,
1168 [sl, &inlet, &ctx](
int idx) {
1169 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, toStd(sl->array[idx]));
1173 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1185 return Process::DefaultControlLayouts::combo();
1188 template <
typename U,
typename Control_T>
1189 static auto make_widget(
1191 QWidget* parent, QObject* context)
1193 const auto& values = slider.getValues();
1195 for(
auto& e : values)
1197 sl->addItem(e.first);
1199 sl->setContentsMargins(0, 0, 0, 0);
1201 auto set_index = [values, sl](
const ossia::value& val) {
1203 = ossia::find_if(values, [&](
const auto& pair) {
return pair.second == val; });
1204 if(it != values.end())
1206 sl->setCurrentIndex(std::distance(values.begin(), it));
1209 set_index(inlet.value());
1212 sl, SignalUtils::QComboBox_currentIndexChanged_int(), context,
1213 [values, &inlet, &ctx](
int idx) {
1215 inlet, values[idx].second);
1218 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1225 template <
typename U,
typename Control_T>
1226 static QGraphicsItem* make_item(
1228 QGraphicsItem* parent, QObject* context)
1230 const auto N = slider.count();
1232 const auto& values = slider.getValues();
1235 for(std::size_t i = 0; i < N; i++)
1236 arr.push_back(values[i].first);
1240 auto set_index = [values, sl](
const ossia::value& val) {
1242 = ossia::find_if(values, [&](
const auto& pair) {
return pair.second == val; });
1243 if(it != values.end())
1245 sl->setValue(std::distance(values.begin(), it));
1248 set_index(inlet.value());
1251 sl, &score::QGraphicsCombo::sliderMoved, context, [values, sl, &inlet, &ctx] {
1253 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1254 inlet, values[sl->value()].second);
1256 QObject::connect(sl, &score::QGraphicsCombo::sliderReleased, context, [sl, &ctx] {
1261 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1280 using QValidator::QValidator;
1281 State validate(QString& str,
int&)
const override
1283 auto p = ossia::get_time_signature(str.toStdString());
1285 return State::Invalid;
1287 return State::Acceptable;
1295 return Process::DefaultControlLayouts::pad();
1298 template <
typename T,
typename Control_T>
1299 static auto make_widget(
1301 QWidget* parent, QObject* context)
1307 template <
typename T,
typename Control_T>
1308 static QGraphicsItem* make_item(
1310 QGraphicsItem* parent, QObject* context)
1313 sl->setRgbaValue(ossia::convert<ossia::vec4f>(inlet.value()));
1316 sl, &score::QGraphicsHSVChooser::sliderMoved, context, [=, &inlet, &ctx] {
1318 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->rgbaValue());
1321 sl, &score::QGraphicsHSVChooser::sliderReleased, context, [&ctx, sl]() {
1326 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1328 sl->setRgbaValue(ossia::convert<ossia::vec4f>(val));
1343 template <
typename T,
typename Control_T>
1344 static auto make_widget(
1346 QWidget* parent, QObject* context)
1352 template <
typename T,
typename Control_T>
1353 static QGraphicsItem* make_item(
1355 QGraphicsItem* parent, QObject* context)
1358 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
1359 bindVec2Domain(slider, inlet, *sl);
1362 sl, &score::QGraphicsXYChooser::sliderMoved, context, [=, &inlet, &ctx] {
1364 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1367 sl, &score::QGraphicsXYChooser::sliderReleased, context, [&ctx, sl]() {
1372 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1374 sl->setValue(ossia::convert<ossia::vec2f>(val));
1385 return Process::DefaultControlLayouts::pad();
1388 template <
typename T,
typename Control_T>
1389 static auto make_widget(
1391 QWidget* parent, QObject* context)
1397 template <
typename T,
typename Control_T>
1398 static QGraphicsItem* make_item(
1400 QGraphicsItem* parent, QObject* context)
1403 sl->setValue(ossia::convert<ossia::vec3f>(inlet.value()));
1404 bindVec3Domain(slider, inlet, *sl);
1407 sl, &score::QGraphicsXYZChooser::sliderMoved, context, [=, &inlet, &ctx] {
1409 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1412 sl, &score::QGraphicsXYZChooser::sliderReleased, context, [&ctx, sl]() {
1417 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1419 sl->setValue(ossia::convert<ossia::vec3f>(val));
1430 return Process::DefaultControlLayouts::pad();
1433 template <
typename T,
typename Control_T>
1434 static auto make_widget(
1436 QWidget* parent, QObject* context)
1442 static QGraphicsItem* make_item(
1443 const Process::XYSpinboxes& slider, Process::XYSpinboxes& inlet,
1446 using Control_T = Process::XYSpinboxes;
1450 bindVec2Domain(slider, inlet, *sl);
1451 sl->setValue(ossia::convert<ossia::vec2f>(inlet.value()));
1454 sl, &score::QGraphicsIntXYSpinboxChooser::sliderMoved, context,
1457 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1460 sl, &score::QGraphicsIntXYSpinboxChooser::sliderReleased, context,
1467 &inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1469 sl->setValue(ossia::convert<ossia::vec2f>(val));
1477 bindVec2Domain(slider, inlet, *sl);
1479 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(inlet.value())));
1482 sl, &score::QGraphicsXYSpinboxChooser::sliderMoved, context,
1485 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1486 inlet, LinearNormalizer::from01(*sl, sl->value()));
1489 sl, &score::QGraphicsXYSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
1495 &inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1497 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec2f>(val)));
1509 return Process::DefaultControlLayouts::pad();
1512 template <
typename T,
typename Control_T>
1513 static auto make_widget(
1515 QWidget* parent, QObject* context)
1521 template <
typename T,
typename Control_T>
1522 static QGraphicsItem* make_item(
1524 QGraphicsItem* parent, QObject* context)
1527 bindVec3Domain(slider, inlet, *sl);
1529 LinearNormalizer::to01(*sl, ossia::convert<ossia::vec3f>(inlet.value())));
1532 sl, &score::QGraphicsXYZSpinboxChooser::sliderMoved, context, [=, &inlet, &ctx] {
1534 ctx.dispatcher.
submit<SetControlValue<Control_T>>(
1535 inlet, LinearNormalizer::from01(*sl, sl->value()));
1538 sl, &score::QGraphicsXYZSpinboxChooser::sliderReleased, context, [&ctx, sl]() {
1543 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1545 sl->setValue(LinearNormalizer::to01(*sl, ossia::convert<ossia::vec3f>(val)));
1556 return Process::DefaultControlLayouts::slider();
1559 template <
typename T,
typename Control_T>
1560 static auto make_widget(
1562 QWidget* parent, QObject* context)
1568 template <
typename T,
typename Control_T>
1569 static QGraphicsItem* make_item(
1571 QGraphicsItem* parent, QObject* context)
1574 sl->setValue(inlet.value());
1575 sl->setRange(inlet.domain());
1578 sl, &score::QGraphicsMultiSlider::sliderMoved, context, [=, &inlet, &ctx] {
1580 ctx.dispatcher.
submit<SetControlValue<Control_T>>(inlet, sl->value());
1583 sl, &score::QGraphicsMultiSlider::sliderReleased, context, [&ctx, sl]() {
1588 QObject::connect(&inlet, &Control_T::valueChanged, sl, [=](
const ossia::value& val) {
1590 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: score-lib-process/Process/Dataflow/Port.hpp:202
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:62
Definition: QGraphicsXYSpinbox.hpp:58
Definition: QGraphicsMultiSlider.hpp:24
Definition: QGraphicsPixmapEnum.hpp:17
Definition: QGraphicsRangeSlider.hpp:21
Definition: QGraphicsSpinbox.hpp:16
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
Base classes and tools to implement processes and layers.
Definition: JSONVisitor.hpp:1324
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: plugins/score-lib-process/Process/Dataflow/ControlWidgets.hpp:44
Definition: plugins/score-lib-process/Process/Dataflow/ControlWidgets.hpp:59
Definition: score-lib-process/Process/Dataflow/Port.hpp:90
Definition: DocumentContext.hpp:18
Definition: lib/score/widgets/ControlWidgets.hpp:72
Definition: lib/score/widgets/ControlWidgets.hpp:29