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
70 friend class gridui::_GridUi;
71
72 template <typename Self, typename Finished>
74
75public:
76 WidgetState(uint16_t uuid, float x, float y, float w, float h, uint16_t tab);
77
78 uint16_t uuid() const { return m_uuid; }
79 const rbjson::Object& data() const { return m_data; }
80
81 bool set(const std::string& key, rbjson::Value* value);
82 bool setInnerObjectProp(const std::string& objectName, const std::string& propertyName,
83 rbjson::Value* value);
84
85 void markChanged(const std::string& key);
86
87private:
88 // Each mutex is ~100 bytes of heap allocation. Let's keep just one for this.
89 static std::mutex m_mutex;
90
91 WidgetState(const WidgetState&) = delete;
92 WidgetState& operator=(const WidgetState&) = delete;
93
94 rbjson::Object& data() { return m_data; }
95
96 void update(rbjson::Object* other) {
97 m_mutex.lock();
98 for (auto itr : other->members()) {
99 m_data.set(itr.first, itr.second->copy());
100 markGlobalChangedLocked(itr.first);
101 }
102 m_mutex.unlock();
103 }
104
105 void addCallback(CallbacksHolder::cb_trampoline_t trampoline, CallbacksHolder::cb_deleter_t deleter, const std::string& event, void *cb) {
106 if (!m_cb_holder) {
107 m_cb_holder.reset(new CallbacksHolder(trampoline, deleter));
108 }
109 m_cb_holder->add(event, cb);
110 }
111
112 void call(const std::string& event) {
113 if (!m_cb_holder)
114 return;
115 m_cb_holder->call(this, event);
116 }
117
118 void markChangedLocked(const std::string& key);
119 void markGlobalChangedLocked(const std::string& key);
120 inline bool wasChangedInTickLocked(const std::string& key) const;
121
122 bool popChanges(rbjson::Object& state);
123 bool remarkAllChanges();
124
125 rbjson::Object m_data;
126 std::unique_ptr<CallbacksHolder> m_cb_holder;
127
128 const uint16_t m_uuid;
129
130 uint16_t m_bloom_global;
131 uint16_t m_bloom_tick;
132};
133
134class Widget {
135public:
137 : m_state(&emptyState) {
138 }
139
140 Widget(const Widget&& o)
141 : m_state(o.m_state) {
142 }
143
144 Widget& operator=(const Widget&& o) {
145 m_state = o.m_state;
146 return *this;
147 }
148
149 uint16_t uuid() const {
150 return m_state->uuid();
151 }
152
153 void setWidgetX(float val) {
154 m_state->set("x", new rbjson::Number(val));
155 }
156
157 float widgetX() const {
158 return data().getDouble("x");
159 }
160
161 void setWidgetY(float val) {
162 m_state->set("y", new rbjson::Number(val));
163 }
164
165 float widgetY() const {
166 return data().getDouble("y");
167 }
168
169 void setWidgetW(float val) {
170 m_state->set("w", new rbjson::Number(val));
171 }
172
173 float widgetW() const {
174 return data().getDouble("w");
175 }
176
177 void setWidgetH(float val) {
178 m_state->set("h", new rbjson::Number(val));
179 }
180
181 float widgetH() const {
182 return data().getDouble("h");
183 }
184
185 void setWidgetTab(uint16_t tab) {
186 m_state->set("tab", new rbjson::Number(tab));
187 }
188
189 uint16_t widgetTab() const {
190 return data().getInt("tab");
191 }
192
193 void setCss(const std::string& propertyName, const std::string& value) {
194 m_state->setInnerObjectProp("css", propertyName, new rbjson::String(value));
195 }
196
197 std::string css(const std::string& propertyName) const {
198 auto* css = data().getObject("css");
199 if (css == nullptr)
200 return "";
201 return css->getString(propertyName);
202 }
203
204protected:
206 : m_state(state) {
207 }
208
209 Widget(const Widget&) = delete;
210 Widget& operator=(const Widget&) = delete;
211
212 const rbjson::Object& data() const { return static_cast<const WidgetState*>(m_state)->data(); }
213
215
216private:
217 static WidgetState emptyState;
218};
219
220};
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
bool set(const std::string &key, rbjson::Value *value)
Definition widget.cpp:25
uint16_t uuid() const
Definition widget.h:78
const rbjson::Object & data() const
Definition widget.h:79
bool setInnerObjectProp(const std::string &objectName, const std::string &propertyName, rbjson::Value *value)
Definition widget.cpp:42
void markChanged(const std::string &key)
Definition widget.cpp:120
std::string css(const std::string &propertyName) const
Definition widget.h:197
float widgetY() const
Definition widget.h:165
float widgetH() const
Definition widget.h:181
void setCss(const std::string &propertyName, const std::string &value)
Definition widget.h:193
WidgetState * m_state
Definition widget.h:214
void setWidgetW(float val)
Definition widget.h:169
float widgetX() const
Definition widget.h:157
const rbjson::Object & data() const
Definition widget.h:212
Widget & operator=(const Widget &&o)
Definition widget.h:144
Widget(WidgetState *state)
Definition widget.h:205
void setWidgetTab(uint16_t tab)
Definition widget.h:185
void setWidgetX(float val)
Definition widget.h:153
void setWidgetH(float val)
Definition widget.h:177
uint16_t uuid() const
Definition widget.h:149
Widget(const Widget &)=delete
float widgetW() const
Definition widget.h:173
Widget(const Widget &&o)
Definition widget.h:140
uint16_t widgetTab() const
Definition widget.h:189
void setWidgetY(float val)
Definition widget.h:161
Widget & operator=(const Widget &)=delete
Definition arm.h:8