Esp32-RBGridUI
Library for creating UIs for the RBController app
Loading...
Searching...
No Matches
widget.h
Go to the documentation of this file.
1#pragma once
2
3#include <functional>
4#include <map>
5#include <mutex>
6#include <stdint.h>
7
8#include "rbjson.h"
9
10namespace gridui {
11
12class _GridUi;
13
14namespace builder {
15class Widget;
16
17template <typename Self, typename Finished>
18class BuilderMixin;
19};
20
21class WidgetState;
22
24 friend class WidgetState;
25public:
26 typedef void (*cb_trampoline_t)(void*, WidgetState*);
27 typedef void (*cb_deleter_t)(void*);
28
30 for(const auto& itr : m_callbacks) {
31 m_cb_deleter(itr.second);
32 }
33 }
34
35 void call(WidgetState* state, const std::string& event) {
36 auto itr = m_callbacks.find(event);
37 if (itr != m_callbacks.end()) {
38 (*m_cb_trampoline)(itr->second, state);
39 }
40 }
41
42 void add(const std::string& event, void *cb) {
43 auto itr = m_callbacks.find(event);
44 if(itr != m_callbacks.end()) {
45 m_cb_deleter(cb);
46 itr->second = cb;
47 } else {
48 m_callbacks[event] = cb;
49 }
50 }
51
52private:
53 CallbacksHolder(cb_trampoline_t trampoline, cb_deleter_t deleter) : m_cb_trampoline(trampoline), m_cb_deleter(deleter) { }
54
55 CallbacksHolder(const WidgetState&) = delete;
56 CallbacksHolder& operator=(const WidgetState&) = delete;
57
58 std::map<std::string, void*> m_callbacks;
59 const cb_trampoline_t m_cb_trampoline;
60 const cb_deleter_t m_cb_deleter;
61};
62
63class WidgetPos {
64 union {
65 uint32_t _encoded;
66 struct {
67 uint8_t _x;
68 uint8_t _y;
69 uint8_t _w;
70 uint8_t _h;
71 };
72 };
73
74public:
75 WidgetPos(uint32_t encoded) {
77 }
78 WidgetPos(float x, float y, float w, float h) {
79 _x = x*10.f;
80 _y = y*10.f;
81 _w = w*10.f;
82 _h = h*10.f;
83 }
84 uint32_t encoded() const { return _encoded; };
85 float x() const { return float(_x)/10.f; }
86 float y() const { return float(_y)/10.f; }
87 float w() const { return float(_w)/10.f; }
88 float h() const { return float(_h)/10.f; }
89 WidgetPos& setX(float x) { _x = x*10.f; return *this; }
90 WidgetPos& setY(float y) { _y = y*10.f; return *this; }
91 WidgetPos& setW(float w) { _w = w*10.f; return *this; }
92 WidgetPos& setH(float h) { _h = h*10.f; return *this; }
93};
94
101 friend class gridui::_GridUi;
102
103 template <typename Self, typename Finished>
105
106public:
107 WidgetState(uint16_t uuid, float x, float y, float w, float h, uint16_t tab);
108
109 uint16_t uuid() const { return m_uuid; }
110 const rbjson::Object& data() const { return m_data; }
111
112 bool set(const std::string& key, rbjson::Value* value);
113 bool setInnerObjectProp(const std::string& objectName, const std::string& propertyName,
114 rbjson::Value* value);
115
116 void markChanged(const std::string& key);
117
119 return bool(m_cb_holder);
120 }
121
122 WidgetPos pos() const {
123 return WidgetPos(m_data.getInt("p"));
124 }
125
126 void setPos(const WidgetPos& p) {
127 m_data.set("p", p.encoded());
128 }
129
130private:
131 // Each mutex is ~100 bytes of heap allocation. Let's keep just one for this.
132 static std::mutex m_mutex;
133
134 WidgetState(const WidgetState&) = delete;
135 WidgetState& operator=(const WidgetState&) = delete;
136
137 rbjson::Object& data() { return m_data; }
138
139 void update(rbjson::Object* other) {
140 m_mutex.lock();
141 for (auto itr : other->members()) {
142 const std::string name_str(itr.name, itr.name_len);
143 m_data.set(name_str, itr.value->copy());
144 markGlobalChangedLocked(name_str);
145 }
146 m_mutex.unlock();
147 }
148
149 void addCallback(CallbacksHolder::cb_trampoline_t trampoline, CallbacksHolder::cb_deleter_t deleter, const std::string& event, void *cb) {
150 if (!m_cb_holder) {
151 m_cb_holder.reset(new CallbacksHolder(trampoline, deleter));
152 }
153 m_cb_holder->add(event, cb);
154 }
155
156 void call(const std::string& event) {
157 if (!m_cb_holder)
158 return;
159 m_cb_holder->call(this, event);
160 }
161
162 void markChangedLocked(const std::string& key);
163 void markGlobalChangedLocked(const std::string& key);
164 inline bool wasChangedInTickLocked(const char *key, size_t key_len) const;
165
166 bool popChanges(rbjson::Object& state);
167 bool remarkAllChanges();
168
169 rbjson::Object m_data;
170 std::unique_ptr<CallbacksHolder> m_cb_holder;
171
172 const uint16_t m_uuid;
173
174 uint16_t m_bloom_global;
175 uint16_t m_bloom_tick;
176};
177
178class Widget {
179public:
181 : m_state(&emptyState) {
182 }
183
184 Widget(const Widget&& o)
185 : m_state(o.m_state) {
186 }
187
188 Widget(const Widget& o)
189 : m_state(o.m_state) {
190 }
191
192 Widget& operator=(const Widget&& o) {
193 m_state = o.m_state;
194 return *this;
195 }
196
199 }
200
201 uint16_t uuid() const {
202 return m_state->uuid();
203 }
204
205 void setWidgetX(float val) {
206 m_state->setPos(m_state->pos().setX(val));
207 }
208
209 float widgetX() const {
210 return m_state->pos().x();
211 }
212
213 void setWidgetY(float val) {
214 m_state->setPos(m_state->pos().setY(val));
215 }
216
217 float widgetY() const {
218 return m_state->pos().y();
219 }
220
221 void setWidgetW(float val) {
222 m_state->setPos(m_state->pos().setW(val));
223 }
224
225 float widgetW() const {
226 return m_state->pos().w();
227 }
228
229 void setWidgetH(float val) {
230 m_state->setPos(m_state->pos().setH(val));
231 }
232
233 float widgetH() const {
234 return m_state->pos().h();
235 }
236
237 void setWidgetTab(uint16_t tab) {
238 m_state->set("tab", new rbjson::Number(tab));
239 }
240
241 uint16_t widgetTab() const {
242 return data().getInt("tab");
243 }
244
245 void setCss(const std::string& propertyName, const std::string& value) {
246 m_state->setInnerObjectProp("css", propertyName, new rbjson::String(value));
247 }
248
249 std::string css(const std::string& propertyName) const {
250 auto* css = data().getObject("css");
251 if (css == nullptr)
252 return "";
253 return css->getString(propertyName);
254 }
255
256protected:
258 : m_state(state) {
259 }
260
261 Widget& operator=(const Widget&) = delete;
262
263 const rbjson::Object& data() const { return static_cast<const WidgetState*>(m_state)->data(); }
264
266
267private:
268 static WidgetState emptyState;
269};
270
271};
void call(WidgetState *state, const std::string &event)
Definition widget.h:35
friend class WidgetState
Definition widget.h:24
void(* cb_trampoline_t)(void *, WidgetState *)
Definition widget.h:26
void add(const std::string &event, void *cb)
Definition widget.h:42
void(* cb_deleter_t)(void *)
Definition widget.h:27
WidgetPos(uint32_t encoded)
Definition widget.h:75
float x() const
Definition widget.h:85
WidgetPos & setX(float x)
Definition widget.h:89
WidgetPos & setW(float w)
Definition widget.h:91
uint32_t encoded() const
Definition widget.h:84
WidgetPos & setY(float y)
Definition widget.h:90
float w() const
Definition widget.h:87
WidgetPos(float x, float y, float w, float h)
Definition widget.h:78
float h() const
Definition widget.h:88
float y() const
Definition widget.h:86
WidgetPos & setH(float h)
Definition widget.h:92
uint32_t _encoded
Definition widget.h:65
bool set(const std::string &key, rbjson::Value *value)
Definition widget.cpp:27
uint16_t uuid() const
Definition widget.h:109
void setPos(const WidgetPos &p)
Definition widget.h:126
const rbjson::Object & data() const
Definition widget.h:110
bool setInnerObjectProp(const std::string &objectName, const std::string &propertyName, rbjson::Value *value)
Definition widget.cpp:44
bool hasRegisteredCallbacks() const
Definition widget.h:118
void markChanged(const std::string &key)
Definition widget.cpp:122
WidgetPos pos() const
Definition widget.h:122
std::string css(const std::string &propertyName) const
Definition widget.h:249
float widgetY() const
Definition widget.h:217
float widgetH() const
Definition widget.h:233
void setCss(const std::string &propertyName, const std::string &value)
Definition widget.h:245
bool hasRegisteredCallbacks() const
Definition widget.h:197
WidgetState * m_state
Definition widget.h:265
void setWidgetW(float val)
Definition widget.h:221
float widgetX() const
Definition widget.h:209
const rbjson::Object & data() const
Definition widget.h:263
Widget & operator=(const Widget &&o)
Definition widget.h:192
Widget(WidgetState *state)
Definition widget.h:257
void setWidgetTab(uint16_t tab)
Definition widget.h:237
void setWidgetX(float val)
Definition widget.h:205
void setWidgetH(float val)
Definition widget.h:229
Widget(const Widget &o)
Definition widget.h:188
uint16_t uuid() const
Definition widget.h:201
float widgetW() const
Definition widget.h:225
Widget(const Widget &&o)
Definition widget.h:184
uint16_t widgetTab() const
Definition widget.h:241
void setWidgetY(float val)
Definition widget.h:213
Widget & operator=(const Widget &)=delete
Definition arm.h:8