Loading...
Searching...
No Matches
VecWidgets.hpp
1#pragma once
2#include <State/Value.hpp>
3
4#include <score/widgets/MarginLess.hpp>
5#include <score/widgets/SignalUtils.hpp>
6#include <score/widgets/TextLabel.hpp>
7
8#include <ossia/network/domain/domain.hpp>
9
10#include <QDoubleSpinBox>
11#include <QFormLayout>
12#include <QHBoxLayout>
13#include <QWidget>
14
15#include <verdigris>
16
17namespace State
18{
19struct SCORE_LIB_STATE_EXPORT VecEditBase : public QWidget
20{
21 W_OBJECT(VecEditBase)
22public:
23 using QWidget::QWidget;
24
25public:
26 void changed() E_SIGNAL(SCORE_LIB_STATE_EXPORT, changed)
27};
28
29template <std::size_t N>
30class VecWidget final : public VecEditBase
31{
32public:
33 VecWidget(QWidget* parent)
34 : VecEditBase{parent}
35 {
36 auto lay = new QHBoxLayout;
37 this->setLayout(lay);
38
39 for(std::size_t i = 0; i < N; i++)
40 {
41 auto box = new QDoubleSpinBox{this};
42 box->setMinimum(-9999);
43 box->setMaximum(9999);
44 box->setValue(0);
45
46 connect(box, &QDoubleSpinBox::editingFinished, this, [this] { changed(); });
47
48 lay->addWidget(box);
49 m_boxes[i] = box;
50 }
51 }
52
53 void setValue(std::array<float, N> v)
54 {
55 for(std::size_t i = 0; i < N; i++)
56 {
57 m_boxes[i]->setValue(v[i]);
58 }
59 }
60
61 std::array<float, N> value() const
62 {
63 std::array<float, N> v;
64 for(std::size_t i = 0; i < N; i++)
65 {
66 v[i] = m_boxes[i]->value();
67 }
68 return v;
69 }
70
71private:
72 std::array<QDoubleSpinBox*, N> m_boxes;
73};
74
78
79template <std::size_t N>
80class VecDomainWidget final : public QWidget
81{
82public:
83 using domain_type = ossia::vecf_domain<N>;
84 using set_type = ossia::flat_set<float>;
85
86 VecDomainWidget(QWidget* parent)
87 : QWidget{parent}
88 {
89 auto lay = new score::MarginLess<QFormLayout>{this};
90 this->setLayout(lay);
91
92 auto min_l = new TextLabel{tr("Min"), this};
93 min_l->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
94 m_min = new VecWidget<N>{this};
95 auto max_l = new TextLabel{tr("Max"), this};
96 max_l->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
97 m_max = new VecWidget<N>{this};
98 lay->addWidget(min_l);
99 lay->addWidget(m_min);
100 lay->addWidget(max_l);
101 lay->addWidget(m_max);
102 }
103
104 static std::array<std::optional<float>, N> toOptional(const std::array<float, N>& f)
105 {
106 std::array<std::optional<float>, N> res;
107 for(std::size_t i = 0; i < N; i++)
108 {
109 res[i] = f[i];
110 }
111 return res;
112 }
113
114 static std::array<float, N> fromOptional(const std::array<std::optional<float>, N>& f)
115 {
116 std::array<float, N> res;
117 for(std::size_t i = 0; i < N; i++)
118 {
119 res[i] = f[i] ? *f[i] : 0;
120 }
121 return res;
122 }
123
124 domain_type domain() const
125 {
126 domain_type dom;
127
128 dom.min = toOptional(m_min->value());
129 dom.max = toOptional(m_max->value());
130
131 return dom;
132 }
133
134 void set_domain(ossia::domain dom_base)
135 {
136 m_min->setValue(ossia::fill_vec<N>(0));
137 m_max->setValue(ossia::fill_vec<N>(1));
138
139 if(auto dom_p = dom_base.v.target<domain_type>())
140 {
141 auto& dom = *dom_p;
142
143 m_min->setValue(fromOptional(dom.min));
144 m_max->setValue(fromOptional(dom.max));
145 }
146 }
147
148private:
149 VecWidget<N>* m_min{};
150 VecWidget<N>* m_max{};
151};
152}
Definition VecWidgets.hpp:81
Definition VecWidgets.hpp:31
Definition TextLabel.hpp:6
The MarginLess class.
Definition MarginLess.hpp:14
Utilities for OSSIA data structures.
Definition DeviceInterface.hpp:33
Definition VecWidgets.hpp:20