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