Factories.hpp
1 #pragma once
2 #include <Process/Dataflow/ControlWidgets.hpp>
3 
4 #include <Crousti/Executor.hpp>
5 #include <Crousti/Layer.hpp>
6 #include <Crousti/ProcessModel.hpp>
7 #include <Dataflow/WidgetInletFactory.hpp>
8 
9 #include <score/graphics/DefaultGraphicsKnobImpl.hpp>
10 #include <score/graphics/DefaultGraphicsSliderImpl.hpp>
11 #include <score/graphics/GraphicsSliderBaseImpl.hpp>
12 #include <score/graphics/widgets/QGraphicsRangeSlider.hpp>
13 #include <score/graphics/widgets/QGraphicsSlider.hpp>
14 
15 #include <ossia/detail/for_each.hpp>
16 
17 namespace oscr
18 {
19 template <typename Node>
20 struct ProcessFactory final : public Process::ProcessFactory_T<oscr::ProcessModel<Node>>
21 {
23 };
24 
25 template <typename Node>
26 struct ExecutorFactory final
27  : public Execution::ProcessComponentFactory_T<oscr::Executor<Node>>
28 {
30  oscr::Executor<Node>>::ProcessComponentFactory_T;
31 };
32 
33 template <typename N>
34 using reflect_mapped_controls =
35  typename avnd::mapped_control_input_introspection<N>::field_reflections_type;
36 
37 template <typename Field>
39 {
40  static inline constexpr auto mapper = avnd::get_mapper<Field>();
41  static float map(float val) noexcept { return mapper.map(val); }
42  static float unmap(float val) noexcept { return mapper.unmap(val); }
43 
44  template <typename T>
45  static float to01(const T& slider, float val) noexcept
46  {
47  const auto min = slider.getMin();
48  const auto max = slider.getMax();
49 
50  // [a; b] -> [0; 1] in linear space
51  const auto in_01 = (val - min) / (max - min);
52 
53  // [0; 1] -> [0; 1] in e.g. log space
54  return map(in_01);
55  }
56 
57  template <typename T>
58  static float from01(const T& slider, float in_01) noexcept
59  {
60  const auto min = slider.getMin();
61  const auto max = slider.getMax();
62 
63  // [0; 1] in e.g. log space -> [0; 1] in linear space
64  const auto unmapped = unmap(in_01);
65 
66  // [0; 1] in linear space -> [a; b]
67  return min + unmapped * (max - min);
68  }
69 };
70 
71 template <typename Field>
73 {
74 public:
75  using score::QGraphicsSlider::QGraphicsSlider;
76 
77  double getMin() const noexcept { return this->min; }
78  double getMax() const noexcept { return this->max; }
79  double unmap(double v) const noexcept
80  {
81  return NormalizerFromMapper<Field>::to01(*this, v);
82  }
83  double map(double v) const noexcept
84  {
85  return NormalizerFromMapper<Field>::from01(*this, v);
86  }
87 
88 private:
89  void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
90  override
91  {
92  score::DefaultGraphicsSliderImpl::paint(
93  *this, score::Skin::instance(), QString::number(map(m_value), 'f', 3), painter,
94  widget);
95  }
96 
97  void mousePressEvent(QGraphicsSceneMouseEvent* event) override
98  {
99  score::DefaultGraphicsSliderImpl::mousePressEvent(*this, event);
100  }
101 
102  void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override
103  {
104  score::DefaultGraphicsSliderImpl::mouseMoveEvent(*this, event);
105  }
106 
107  void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override
108  {
109  score::DefaultGraphicsSliderImpl::mouseReleaseEvent(*this, event);
110  }
111 
112  void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override
113  {
114  event->accept();
115  }
116 };
117 
118 template <typename Field>
120 {
121 public:
122  using score::QGraphicsKnob::QGraphicsKnob;
123 
124  double getMin() const noexcept { return this->min; }
125  double getMax() const noexcept { return this->max; }
126  double unmap(double v) const noexcept
127  {
128  return NormalizerFromMapper<Field>::to01(*this, v);
129  }
130  double map(double v) const noexcept
131  {
132  return NormalizerFromMapper<Field>::from01(*this, v);
133  }
134 
135 private:
136  void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
137  override
138  {
139  const double val = map(m_value);
140  const double abs = std::abs(val);
141  int pres = abs < 10. ? 3 : abs < 100. ? 2 : abs < 1000. ? 1 : 0;
142  score::DefaultGraphicsKnobImpl::paint(
143  *this, score::Skin::instance(), QString::number(val, 'f', pres), painter,
144  widget);
145  }
146 
147  void mousePressEvent(QGraphicsSceneMouseEvent* event) override
148  {
149  score::DefaultGraphicsKnobImpl::mousePressEvent(*this, event);
150  }
151 
152  void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override
153  {
154  score::DefaultGraphicsKnobImpl::mouseMoveEvent(*this, event);
155  }
156 
157  void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override
158  {
159  score::DefaultGraphicsKnobImpl::mouseReleaseEvent(*this, event);
160  }
161 
162  void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override
163  {
164  event->accept();
165  }
166 };
167 
168 template <typename Field>
170 {
172 };
173 template <typename Field>
174 requires requires
175 {
176  Field::widget::knob;
177 }
178 struct MatchingWidget<Field>
179 {
181 };
182 
183 template <typename Node, typename Refl>
185 template <typename Node, std::size_t N, typename Field>
186 struct CustomControlFactory<Node, avnd::field_reflection<N, Field>>
188  oscr::CustomFloatControl<Node, avnd::field_index<N>>,
189  WidgetFactory::FloatControl<
190  typename MatchingWidget<Field>::type, NormalizerFromMapper<Field>, true>>
191 {
192 };
193 
194 template <typename... Nodes>
195 static void instantiate_fx(
196  std::vector<score::InterfaceBase*>& v,
197  const score::ApplicationContext& ctx, const score::InterfaceKey& key)
198 {
199  if(key == Execution::ProcessComponentFactory::static_interfaceKey())
200  {
201  //static_assert((requires { std::declval<Nodes>().run({}, {}); } && ...));
202  (v.emplace_back(static_cast<Execution::ProcessComponentFactory*>(
204  ...);
205  }
206  else if(key == Process::ProcessModelFactory::static_interfaceKey())
207  {
208  (v.emplace_back(
210  ...);
211  }
212  else if(key == Process::LayerFactory::static_interfaceKey())
213  {
214  auto fun = [&]<typename type>() {
215  if constexpr(avnd::has_ui<type>)
216  {
217  v.emplace_back(
218  static_cast<Process::LayerFactory*>(new oscr::LayerFactory<type>()));
219  }
220  };
221  (fun.template operator()<Nodes>(), ...);
222  }
223  else if(key == Process::PortFactory::static_interfaceKey())
224  {
225  // Go through all the process's control inputs with a mapper
226  // Generate the matching WidgetInletFactory
227  using namespace boost::mp11;
228 
229  auto fun = [&]<typename N, typename... Fields>(avnd::typelist<Fields...>) {
230  (v.emplace_back(
231  static_cast<Process::PortFactory*>(new CustomControlFactory<N, Fields>{})),
232  ...);
233  };
234  (fun.template operator()<Nodes>(reflect_mapped_controls<Nodes>{}), ...);
235  }
236 }
237 
238 template <typename T>
239 void custom_factories(
240  std::vector<score::InterfaceBase*>& fx,
241  const score::ApplicationContext& ctx, const score::InterfaceKey& key);
242 
243 }
244 
245 namespace Avnd = oscr;
Definition: Process/Execution/ProcessComponent.hpp:119
Definition: Process/Execution/ProcessComponent.hpp:102
Definition: score-lib-process/Process/ProcessFactory.hpp:58
Definition: PortFactory.hpp:21
Definition: GenericProcessFactory.hpp:15
The ProcessFactory class.
Definition: score-lib-process/Process/ProcessFactory.hpp:35
Definition: UuidKey.hpp:343
Definition: Factories.hpp:120
Definition: Factories.hpp:73
Definition: score-plugin-avnd/Crousti/Executor.hpp:546
Definition: score-plugin-avnd/Crousti/Layer.hpp:283
Definition: QGraphicsKnob.hpp:16
Definition: QGraphicsSlider.hpp:17
Definition: WidgetInletFactory.hpp:12
Definition: Factories.hpp:184
Definition: Factories.hpp:28
Definition: Factories.hpp:170
Definition: Factories.hpp:39
Definition: Factories.hpp:21
Used to access all the application-wide state and structures.
Definition: ApplicationContext.hpp:24