Loading...
Searching...
No Matches
EffectLayout.hpp
1#pragma once
2#include <Process/Dataflow/PortFactory.hpp>
3#include <Process/Dataflow/PortItem.hpp>
4
5#include <score/graphics/RectItem.hpp>
6#include <score/graphics/TextItem.hpp>
7
8#include <QPointF>
9
10#include <cmath>
11
12#include <cstdint>
13namespace Process
14{
15
16static const constexpr int MaxRowsInEffect = 5;
17
18// TODO not very efficient since it recomputes everything every time...
19// Does a grid layout with maximum N rows per column.
20template <typename F>
21QPointF currentWidgetPos(int controlIndex, F getControlSize) noexcept(
22 noexcept(getControlSize(0)))
23{
24 int N = MaxRowsInEffect * (controlIndex / MaxRowsInEffect);
25 qreal x = 0;
26 for(int i = 0; i < N;)
27 {
28 qreal w = 0;
29 for(int j = i; j < i + MaxRowsInEffect && j < N; j++)
30 {
31 auto sz = getControlSize(j);
32 w = std::max(w, sz.width());
33 }
34 x += w;
35 i += MaxRowsInEffect;
36 }
37
38 qreal y = 0;
39 for(int j = N; j < controlIndex; j++)
40 {
41 auto sz = getControlSize(j);
42 y += sz.height();
43 }
44
45 return {x, y};
46}
47
48template <
49 typename CreatePort, typename CreateControl, typename GetControlSize,
50 typename GetName, typename GetFactory>
52{
53 CreatePort createPort;
54 CreateControl createControl;
55 GetControlSize getControlSize;
56 GetName name;
57 GetFactory getFactory;
58};
59
60template <typename... Args>
61auto controlSetup(Args&&... args)
62{
63 if constexpr(sizeof...(Args) == 4)
64 {
65 return controlSetup(
66 std::forward<Args>(args)...,
67 [](const Process::PortFactoryList& portFactory, Process::Port& port)
68 -> Process::PortFactory& { return *portFactory.get(port.concreteKey()); });
69 }
70 else
71 {
72 return ControlSetup<Args...>{std::forward<Args>(args)...};
73 }
74}
75
76template <typename T>
77[[deprecated]] auto createControl(
78 int i,
79 const auto& setup, // See ControlSetup
80 T& port, const Process::PortFactoryList& portFactory, const Process::Context& doc,
81 QGraphicsItem* parentItem, QObject* parent)
82{
83 // TODO put the port at the correct order wrt its index ?
84 auto item = new score::EmptyRectItem{parentItem};
85
86 // Create the port
87 auto& fact = setup.getFactory(portFactory, port);
88 auto portItem = setup.createPort(fact, port, doc, item, parent);
89
90 // Create the label
91 auto lab = Dataflow::makePortLabel(port, item);
92
93 // Create the control
94 struct Controls
95 {
97 Dataflow::PortItem* port{};
98 QGraphicsItem* widg{};
99 score::SimpleTextItem* label{};
100 QRectF itemRect;
101 };
102
103 if(QGraphicsItem* widg = setup.createControl(fact, port, doc, item, parent))
104 {
105 widg->setParentItem(item);
106
107 // Layout the items
108 const qreal labelHeight = 10;
109 const qreal labelWidth = lab->boundingRect().width();
110 const auto wrect = widg->boundingRect();
111 const qreal widgetHeight = wrect.height();
112 const qreal widgetWidth = wrect.width();
113
114 auto h = std::max(20., (qreal)(widgetHeight + labelHeight + 7.));
115 auto w = std::max(90., std::max(25. + labelWidth, widgetWidth));
116
117 portItem->setPos(8., 4.);
118 lab->setPos(20., 2);
119 widg->setPos(18., labelHeight + 5.);
120
121 const auto itemRect = QRectF{0., 0, w, h};
122
123 QPointF pos = Process::currentWidgetPos(i, setup.getControlSize);
124 item->setPos(pos);
125 item->setRect(itemRect);
126 item->setToolTip(QString("%1\n%2").arg(port.name(), port.description()));
127
128 return Controls{item, portItem, widg, lab, itemRect};
129 }
130 else
131 {
132 QRectF itemRect{0., 0, 90., 30.};
133 QPointF pos = Process::currentWidgetPos(i, setup.getControlSize);
134 portItem->setPos(8., 4.);
135 lab->setPos(20., 2);
136 item->setPos(pos);
137 item->setRect(itemRect);
138 item->setToolTip(QString("%1\n%2").arg(port.name(), port.description()));
139
140 return Controls{item, portItem, nullptr, lab, itemRect};
141 }
142}
143
144template <typename C, typename T>
145[[deprecated]] static auto makeControl(
146 C& ctrl, T& inlet, QGraphicsItem& parent, QObject& context,
147 const Process::Context& doc, const Process::PortFactoryList& portFactory)
148{
149 auto item = new score::EmptyItem{&parent};
150
151 // Port
152 Process::PortFactory* fact = portFactory.get(inlet.concreteKey());
153 auto port = fact->makePortItem(inlet, doc, item, &context);
154 port->setPos(0, 1.);
155
156 // Text
157 auto lab = Dataflow::makePortLabel(inlet, item);
158 lab->setPos(12, 0);
159
160 // Control
161 auto widg = ctrl.make_item(ctrl, inlet, doc, nullptr, &context);
162 widg->setParentItem(item);
163 widg->setPos(0, 12.);
164
165 // Create a single control
166 struct ControlItem
167 {
168 QGraphicsItem& root;
169 Dataflow::PortItem& port;
171 decltype(*widg)& control;
172 };
173 return ControlItem{*item, *port, *lab, *widg};
174}
175
176template <typename C, typename T>
177[[deprecated]] static auto makeControlNoText(
178 C& ctrl, T& inlet, QGraphicsItem& parent, QObject& context,
179 const Process::Context& doc, const Process::PortFactoryList& portFactory)
180{
181 auto item = new score::EmptyItem{&parent};
182
183 // Control
184 auto widg = ctrl.make_item(ctrl, inlet, doc, nullptr, &context);
185 widg->setParentItem(item);
186
187 // Port
188 Process::PortFactory* fact = portFactory.get(inlet.concreteKey());
189 auto port = fact->makePortItem(inlet, doc, item, &context);
190
191 // Create a single control
192 struct ControlItem
193 {
194 score::EmptyItem& root;
195 Dataflow::PortItem& port;
196 decltype(*widg)& control;
197 };
198 return ControlItem{*item, *port, *widg};
199}
200}
Definition score-lib-process/Process/Dataflow/PortItem.hpp:39
Definition PortFactory.hpp:30
Definition PortFactory.hpp:74
Definition Port.hpp:102
Definition RectItem.hpp:123
Definition RectItem.hpp:64
FactoryType * get(const key_type &k) const noexcept
Get a particular factory from its ConcreteKey.
Definition InterfaceList.hpp:123
Definition TextItem.hpp:28
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1324
Definition ProcessContext.hpp:12
Definition EffectLayout.hpp:52