diff --git a/README.md b/README.md
index e5319c9..9e5799e 100644
--- a/README.md
+++ b/README.md
@@ -146,26 +146,59 @@ more program memory to work with.
## Documentation
-The heart of ESPUI is
-[ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer). ESPUI's
-frontend is based on [Skeleton CSS](http://getskeleton.com/) and jQuery-like
-lightweight [zepto.js](https://zeptojs.com/) for handling events. The
-communication between the ESP and the client browser works using web
-sockets. ESPUI does not need network access and can be used in standalone access
-point mode, all resources are loaded directly from the ESPs memory.
-
-This section will explain in detail how the Library is to be used from the
-Arduino code side. In the arduino `setup()` routine the interface can be customised by adding UI Elements.
-This is done by calling the corresponding library methods on the Library object
-`ESPUI`. Eg: `ESPUI.button("button", &myCallback);` creates a button in the
-interface that calls the `myCallback(Control *sender, int value)` function when changed. All buttons and
-items call their callback whenever there is a state change from them. This means
-the button will call the callback when it is pressed and also again when it is
-released. To separate different events an integer number with the event name is
-passed to the callback function that can be handled in a `switch(){}case{}`
-statement.
-
+The heart of ESPUI is [ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer). ESPUI's frontend is based on [Skeleton CSS](http://getskeleton.com/) and jQuery-like lightweight [zepto.js](https://zeptojs.com/) for handling events. The communication between the ESP and the client browser works using web sockets. ESPUI does not need network access and can be used in standalone access point mode, all resources are loaded directly from the ESPs memory.
+
+This section will explain in detail how the Library is to be used from the Arduino code side. In the arduino `setup()` routine the interface can be customised by adding UI Elements. This is done by calling the corresponding library methods on the Library object `ESPUI`. Eg: `ESPUI.button("button", &myCallback);` creates a button in the interface that calls the `myCallback(Control *sender, int eventname)` function when changed. All buttons and items call their callback whenever there is a state change from them. This means the button will call the callback when it is pressed and also again when it is released. To separate different events, an integer number with the event name is passed to the callback function that can be handled in a `switch(){}case{}` statement.
+
+Alternativly you may use the extended callback funtion which provides three parameters to the callback function `myCallback(Control *sender, int eventname, void * UserParameter)`. The `UserParameter` is provided as part of the `ESPUI.addControl` method set and allows the user to define contextual information that is to be presented to the callback function in an unmodified form.
+
+The below example creates a button and defines a lambda function to implicitly create an `ExtendedCallback` which then invokes a more specialized button callback handler. The example uses the `UserParameter` to hold the `this` pointer to an object instance, providing a mechanism for sending the event to a specific object without the need for a switch / map / lookup translation of the Sender Id to an object reference.
+```
+void YourClassName::setup()
+{
+ ButtonElementId = ESPUI.addControl(
+ ControlType::Button,
+ ButtonLabel.c_str(),
+ " Button Face Text ",
+ ControlColor::None,
+ ParentElementId,
+ [](Control *sender, int eventname, void* param)
+ {
+ if(param)
+ {
+ reinterpret_cast(param)->myButtonCallback(sender, eventname);
+ }
+ },
+ this); // <-Third parameter for the extended callback
+ // or
+ ButtonElementId = ESPUI.button(
+ " Button Face Text ",
+ [](Control *sender, int eventname, void* param)
+ {
+ if(param)
+ {
+ reinterpret_cast(param)->myButtonCallback(sender, eventname);
+ }
+ },
+ this); // <-Third parameter for the extended callback
+}
+```
+```
+void YourClassName::myButtonCallback(Control* sender, int eventname)
+{
+ if (eventname == B_DOWN)
+ {
+ // Handle the button down event
+ }
+ else if (eventname == B_UP)
+ {
+ // Handle the button up event
+ }
+}
+```
+
+
#### Button
![Buttons](docs/ui_button.png)
diff --git a/examples/completeExample/completeExample.cpp b/examples/completeExample/completeExample.cpp
index f6d9aa5..ecae5c2 100644
--- a/examples/completeExample/completeExample.cpp
+++ b/examples/completeExample/completeExample.cpp
@@ -49,6 +49,7 @@ void getTimeCallback(Control *sender, int type);
void graphAddCallback(Control *sender, int type);
void graphClearCallback(Control *sender, int type);
void randomString(char *buf, int len);
+void extendedCallback(Control* sender, int type, void* param);
//UI handles
uint16_t wifi_ssid_text, wifi_pass_text;
@@ -81,7 +82,7 @@ void setUpUI() {
auto maintab = ESPUI.addControl(Tab, "", "Basic controls");
ESPUI.addControl(Separator, "General controls", "", None, maintab);
- ESPUI.addControl(Button, "Button", "Button 1", Alizarin, maintab, generalCallback);
+ ESPUI.addControl(Button, "Button", "Button 1", Alizarin, maintab, extendedCallback, (void*)19);
mainLabel = ESPUI.addControl(Label, "Label", "Label text", Emerald, maintab, generalCallback);
mainSwitcher = ESPUI.addControl(Switcher, "Switcher", "", Sunflower, maintab, generalCallback);
@@ -360,7 +361,23 @@ void generalCallback(Control *sender, int type) {
Serial.println(sender->value);
}
-
+// Most elements in this test UI are assigned this generic callback which prints some
+// basic information. Event types are defined in ESPUI.h
+// The extended param can be used to hold a pointer to additional information
+// or for C++ it can be used to return a this pointer for quick access
+// using a lambda function
+void extendedCallback(Control* sender, int type, void* param)
+{
+ Serial.print("CB: id(");
+ Serial.print(sender->id);
+ Serial.print(") Type(");
+ Serial.print(type);
+ Serial.print(") '");
+ Serial.print(sender->label);
+ Serial.print("' = ");
+ Serial.println(sender->value);
+ Serial.println(String("param = ") + String((int)param));
+}
void setup() {
randomSeed(0);
diff --git a/examples/gui-generic-api/gui-generic-api.ino b/examples/gui-generic-api/gui-generic-api.ino
index 6d1f6e9..44f0119 100644
--- a/examples/gui-generic-api/gui-generic-api.ino
+++ b/examples/gui-generic-api/gui-generic-api.ino
@@ -55,8 +55,9 @@ void buttonCallback(Control* sender, int type)
}
}
-void buttonExample(Control* sender, int type)
+void buttonExample(Control* sender, int type, void* param)
{
+ Serial.println(String("param: ") + String(int(param)));
switch (type)
{
case B_DOWN:
@@ -210,7 +211,8 @@ void setup(void)
}
#else
uint32_t chipid = ESP.getChipId();
-#endif char ap_ssid[25];
+#endif
+ char ap_ssid[25];
snprintf(ap_ssid, 26, "ESPUI-%08X", chipid);
WiFi.softAP(ap_ssid);
@@ -249,7 +251,7 @@ void setup(void)
button1 = ESPUI.addControl(
ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, Control::noParent, &buttonCallback);
ESPUI.addControl(
- ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, Control::noParent, &buttonExample);
+ ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, Control::noParent, &buttonExample, (void*)19);
ESPUI.addControl(
ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, Control::noParent, &padExample);
ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, Control::noParent, &padExample);
diff --git a/examples/gui/gui.ino b/examples/gui/gui.ino
index 361150e..c7d390c 100644
--- a/examples/gui/gui.ino
+++ b/examples/gui/gui.ino
@@ -60,8 +60,9 @@ void buttonCallback(Control* sender, int type)
}
}
-void buttonExample(Control* sender, int type)
+void buttonExample(Control* sender, int type, void* param)
{
+ Serial.println(String("param: ") + String(int(param)));
switch (type)
{
case B_DOWN:
@@ -227,7 +228,7 @@ void setup(void)
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press");
- ESPUI.button("Other Button", &buttonExample, ControlColor::Wetasphalt, "Press");
+ ESPUI.button("Other Button", &buttonExample, ControlColor::Wetasphalt, "Press", (void*)19);
ESPUI.padWithCenter("Pad with center", &padExample, ControlColor::Sunflower);
ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot);
testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false);
diff --git a/examples/tabbedGui/tabbedGui.ino b/examples/tabbedGui/tabbedGui.ino
index a1ecd31..b02ae4b 100644
--- a/examples/tabbedGui/tabbedGui.ino
+++ b/examples/tabbedGui/tabbedGui.ino
@@ -54,8 +54,9 @@ void buttonCallback(Control* sender, int type)
}
}
-void buttonExample(Control* sender, int type)
+void buttonExample(Control* sender, int type, void* param)
{
+ Serial.println(String("param: ") + String(int(param)));
switch (type)
{
case B_DOWN:
@@ -251,7 +252,7 @@ void setup(void)
ESPUI.addControl(ControlType::Label, "Millis:", "0", ControlColor::Emerald, tab1);
button1 = ESPUI.addControl(
ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, tab1, &buttonCallback);
- ESPUI.addControl(ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, tab1, &buttonExample);
+ ESPUI.addControl(ControlType::Button, "Other Button", "Press", ControlColor::Wetasphalt, tab1, &buttonExample, (void*)19);
ESPUI.addControl(ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, tab2, &padExample);
ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, tab3, &padExample);
switchOne = ESPUI.addControl(ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, tab3, &switchExample);
diff --git a/pio_examples/gui/src/gui.ino b/pio_examples/gui/src/gui.ino
index e998061..d5a9e7c 100644
--- a/pio_examples/gui/src/gui.ino
+++ b/pio_examples/gui/src/gui.ino
@@ -60,8 +60,9 @@ void buttonCallback(Control* sender, int type)
}
}
-void buttonExample(Control* sender, int type)
+void buttonExample(Control* sender, int type, void* param)
{
+ Serial.println(String("param: ") + String(int(param)));
switch (type)
{
case B_DOWN:
@@ -228,7 +229,7 @@ void setup(void)
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press");
- ESPUI.button("Other Button", &buttonExample, ControlColor::Wetasphalt, "Press");
+ ESPUI.button("Other Button", &buttonExample, ControlColor::Wetasphalt, "Press", (void*)19);
ESPUI.padWithCenter("Pad with center", &padExample, ControlColor::Sunflower);
ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot);
testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false);
diff --git a/src/ESPUI.cpp b/src/ESPUI.cpp
index a32196e..bacd91f 100644
--- a/src/ESPUI.cpp
+++ b/src/ESPUI.cpp
@@ -475,9 +475,9 @@ void onWsEvent(
return;
}
- if (c->callback == nullptr)
+ if (false == c->HasCallback())
{
- #if defined(DEBUG_ESPUI)
+#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity)
{
Serial.print(F("No callback found for ID "));
@@ -490,97 +490,97 @@ void onWsEvent(
if (msg.startsWith(F("bdown:")))
{
- c->callback(c, B_DOWN);
+ c->SendCallback(B_DOWN);
}
else if (msg.startsWith(F("bup:")))
{
- c->callback(c, B_UP);
+ c->SendCallback(B_UP);
}
else if (msg.startsWith(F("pfdown:")))
{
- c->callback(c, P_FOR_DOWN);
+ c->SendCallback(P_FOR_DOWN);
}
else if (msg.startsWith(F("pfup:")))
{
- c->callback(c, P_FOR_UP);
+ c->SendCallback(P_FOR_UP);
}
else if (msg.startsWith(F("pldown:")))
{
- c->callback(c, P_LEFT_DOWN);
+ c->SendCallback(P_LEFT_DOWN);
}
else if (msg.startsWith(F("plup:")))
{
- c->callback(c, P_LEFT_UP);
+ c->SendCallback(P_LEFT_UP);
}
else if (msg.startsWith(F("prdown:")))
{
- c->callback(c, P_RIGHT_DOWN);
+ c->SendCallback(P_RIGHT_DOWN);
}
else if (msg.startsWith(F("prup:")))
{
- c->callback(c, P_RIGHT_UP);
+ c->SendCallback(P_RIGHT_UP);
}
else if (msg.startsWith(F("pbdown:")))
{
- c->callback(c, P_BACK_DOWN);
+ c->SendCallback(P_BACK_DOWN);
}
else if (msg.startsWith(F("pbup:")))
{
- c->callback(c, P_BACK_UP);
+ c->SendCallback(P_BACK_UP);
}
else if (msg.startsWith(F("pcdown:")))
{
- c->callback(c, P_CENTER_DOWN);
+ c->SendCallback(P_CENTER_DOWN);
}
else if (msg.startsWith(F("pcup:")))
{
- c->callback(c, P_CENTER_UP);
+ c->SendCallback(P_CENTER_UP);
}
else if (msg.startsWith(F("sactive:")))
{
c->value = "1";
ESPUI.updateControl(c, client->id());
- c->callback(c, S_ACTIVE);
+ c->SendCallback(S_ACTIVE);
}
else if (msg.startsWith(F("sinactive:")))
{
c->value = "0";
ESPUI.updateControl(c, client->id());
- c->callback(c, S_INACTIVE);
+ c->SendCallback(S_INACTIVE);
}
else if (msg.startsWith(F("slvalue:")))
{
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id());
- c->callback(c, SL_VALUE);
+ c->SendCallback(SL_VALUE);
}
else if (msg.startsWith(F("nvalue:")))
{
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id());
- c->callback(c, N_VALUE);
+ c->SendCallback(N_VALUE);
}
else if (msg.startsWith(F("tvalue:")))
{
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id());
- c->callback(c, T_VALUE);
+ c->SendCallback(T_VALUE);
}
else if (msg.startsWith("tabvalue:"))
{
- c->callback(c, client->id());
+ c->SendCallback(client->id());
}
else if (msg.startsWith(F("svalue:")))
{
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id());
- c->callback(c, S_VALUE);
+ c->SendCallback(S_VALUE);
}
else if (msg.startsWith(F("time:")))
{
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id());
- c->callback(c, TM_VALUE);
+ c->SendCallback(TM_VALUE);
}
else
{
@@ -600,10 +600,37 @@ void onWsEvent(
}
}
-uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color,
- uint16_t parentControl, void (*callback)(Control*, int))
+uint16_t ESPUIClass::addControl(ControlType type, const char* label)
{
- Control* control = new Control(type, label, callback, value, color, true, parentControl);
+ return addControl(type, label, String(""));
+}
+
+uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value)
+{
+ return addControl(type, label, value, ControlColor::Turquoise);
+}
+
+uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color)
+{
+ return addControl(type, label, value, color, Control::noParent);
+}
+
+uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl)
+{
+ return addControl(type, label, value, color, parentControl, nullptr);
+}
+
+uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int))
+{
+ uint16_t id = addControl(type, label, value, color, parentControl, nullptr, nullptr);
+ // set the original style callback
+ getControl(id)->callback = callback;
+ return id;
+}
+
+uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int, void *), void * UserData)
+{
+ Control* control = new Control(type, label, callback, UserData, value, color, true, parentControl);
if (this->controls == nullptr)
{
@@ -628,38 +655,30 @@ uint16_t ESPUIClass::addControl(ControlType type, const char* label, const Strin
bool ESPUIClass::removeControl(uint16_t id, bool force_reload_ui)
{
- if (nullptr == this->controls)
- return false;
+ Control* PreviousControl = nullptr;
+ Control* CurrentControl = this->controls;
- Control* it = this->controls;
-
- if (id == it->id)
+ while(nullptr != CurrentControl)
{
- this->controls = it->next;
- delete it;
- this->controlCount--;
- if (force_reload_ui)
+ if (id == CurrentControl->id)
{
- jsonReload();
+ break;
+ }
+ PreviousControl = CurrentControl;
+ CurrentControl = CurrentControl->next;
+ }
+
+ if (nullptr != CurrentControl)
+ {
+ if(nullptr == PreviousControl)
+ {
+ this->controls = CurrentControl->next;
}
else
{
- jsonDom(0);
+ PreviousControl->next = CurrentControl->next;
}
- return true;
- }
-
- Control* it_next = it->next;
- while (nullptr != it_next && id != it_next->id)
- {
- it = it_next;
- it_next = it_next->next;
- }
-
- if (nullptr != it_next)
- {
- it->next = it_next->next;
- delete it_next;
+ delete CurrentControl;
this->controlCount--;
if (force_reload_ui)
{
@@ -685,10 +704,16 @@ uint16_t ESPUIClass::graph(const char* label, ControlColor color)
return addControl(ControlType::Graph, label, "", color);
}
-uint16_t ESPUIClass::slider(
- const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min, int max)
+uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min, int max)
{
- uint16_t sliderId = addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback);
+ uint16_t id = slider(label, nullptr, color, value, min, max, nullptr);
+ getControl(id)->callback = callback;
+ return id;
+}
+
+uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int value, int min, int max, void* userData)
+{
+ uint16_t sliderId = addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback, userData);
addControl(ControlType::Min, label, String(min), ControlColor::None, sliderId);
addControl(ControlType::Max, label, String(max), ControlColor::None, sliderId);
@@ -700,22 +725,42 @@ uint16_t ESPUIClass::button(const char* label, void (*callback)(Control*, int),
return addControl(ControlType::Button, label, value, color, Control::noParent, callback);
}
+uint16_t ESPUIClass::button(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
+{
+ return addControl(ControlType::Button, label, value, color, Control::noParent, callback, UserData);
+}
+
uint16_t ESPUIClass::switcher(const char* label, void (*callback)(Control*, int), ControlColor color, bool startState)
{
return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback);
}
+uint16_t ESPUIClass::switcher(const char* label, void (*callback)(Control*, int, void*), ControlColor color, bool startState, void* UserData)
+{
+ return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback, UserData);
+}
+
uint16_t ESPUIClass::pad(const char* label, void (*callback)(Control*, int), ControlColor color)
{
return addControl(ControlType::Pad, label, "", color, Control::noParent, callback);
}
+
+uint16_t ESPUIClass::pad(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
+{
+ return addControl(ControlType::Pad, label, "", color, Control::noParent, callback, UserData);
+}
+
uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*, int), ControlColor color)
{
return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback);
}
-uint16_t ESPUIClass::number(
- const char* label, void (*callback)(Control*, int), ControlColor color, int number, int min, int max)
+uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
+{
+ return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback, UserData);
+}
+
+uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int), ControlColor color, int number, int min, int max)
{
uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback);
addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
@@ -723,6 +768,14 @@ uint16_t ESPUIClass::number(
return numberId;
}
+uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int number, int min, int max, void* UserData)
+{
+ uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback, UserData);
+ addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
+ addControl(ControlType::Max, label, String(max), ControlColor::None, numberId);
+ return numberId;
+}
+
uint16_t ESPUIClass::gauge(const char* label, ControlColor color, int number, int min, int max)
{
uint16_t numberId = addControl(ControlType::Gauge, label, String(number), color, Control::noParent);
@@ -740,11 +793,21 @@ uint16_t ESPUIClass::accelerometer(const char* label, void (*callback)(Control*,
return addControl(ControlType::Accel, label, "", color, Control::noParent, callback);
}
+uint16_t ESPUIClass::accelerometer(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
+{
+ return addControl(ControlType::Accel, label, "", color, Control::noParent, callback, UserData);
+}
+
uint16_t ESPUIClass::text(const char* label, void (*callback)(Control*, int), ControlColor color, const String& value)
{
return addControl(ControlType::Text, label, value, color, Control::noParent, callback);
}
+uint16_t ESPUIClass::text(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
+{
+ return addControl(ControlType::Text, label, value, color, Control::noParent, callback, UserData);
+}
+
Control* ESPUIClass::getControl(uint16_t id)
{
Control* control = this->controls;
@@ -878,7 +941,6 @@ void ESPUIClass::setEnabled(uint16_t id, bool enabled, int clientId) {
}
}
-
void ESPUIClass::setVertical(uint16_t id, bool vert) {
Control* control = getControl(id);
if (control)
@@ -1451,4 +1513,17 @@ void ESPUIClass::setVerbosity(Verbosity v)
this->verbosity = v;
}
+void Control::SendCallback(int type)
+{
+ if(callback)
+ {
+ callback(this, type);
+ }
+
+ if (extendedCallback)
+ {
+ extendedCallback(this, type, user);
+ }
+}
+
ESPUIClass ESPUI;
diff --git a/src/ESPUI.h b/src/ESPUI.h
index a8bbcc3..5016a83 100644
--- a/src/ESPUI.h
+++ b/src/ESPUI.h
@@ -137,6 +137,8 @@ public:
uint16_t id; // just mirroring the id here for practical reasons
const char* label;
void (*callback)(Control*, int);
+ void (*extendedCallback)(Control*, int, void*);
+ void* user;
String value;
ControlColor color;
bool visible;
@@ -151,11 +153,13 @@ public:
static constexpr uint16_t noParent = 0xffff;
- Control(ControlType type, const char* label, void (*callback)(Control*, int), const String& value,
- ControlColor color, bool visible = true, uint16_t parentControl = Control::noParent)
+ Control(ControlType type, const char* label, void (*callback)(Control*, int, void*), void* UserData,
+ const String& value, ControlColor color, bool visible, uint16_t parentControl)
: type(type),
label(label),
- callback(callback),
+ callback(nullptr),
+ extendedCallback(callback),
+ user(UserData),
value(value),
color(color),
visible(visible),
@@ -173,12 +177,16 @@ public:
id(control.id),
label(control.label),
callback(control.callback),
+ extendedCallback(control.extendedCallback),
+ user(control.user),
value(control.value),
color(control.color),
visible(control.visible),
parentControl(control.parentControl),
next(control.next)
{ }
+ void SendCallback(int type);
+ bool HasCallback() { return ((nullptr != callback) || (nullptr != extendedCallback)); }
private:
static uint16_t idCounter;
@@ -241,27 +249,37 @@ public:
// stuff into LITTLEFS
void list(); // Lists LITTLEFS directory
- uint16_t addControl(ControlType type, const char* label, const String& value = String(""),
- ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent,
- void (*callback)(Control*, int) = nullptr);
+ uint16_t addControl(ControlType type, const char* label);
+ uint16_t addControl(ControlType type, const char* label, const String& value);
+ uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color);
+ uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl);
+ uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int));
+ uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int, void *), void* UserData);
+
bool removeControl(uint16_t id, bool force_reload_ui = false);
// create Elements
- uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color,
- const String& value = ""); // Create Event Button
- uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color,
- bool startState = false); // Create Toggle Button
- uint16_t pad(const char* label, void (*callback)(Control*, int),
- ControlColor color); // Create Pad Control
- uint16_t padWithCenter(const char* label, void (*callback)(Control*, int),
- ControlColor color); // Create Pad Control with Centerbutton
+ // Create Event Button
+ uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color, const String& value = "");
+ uint16_t button(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData);
- uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
- int max = 100); // Create Slider Control
- uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
- int max = 100); // Create a Number Input Control
- uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color,
- const String& value = ""); // Create a Text Input Control
+ uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color, bool startState = false); // Create Toggle Button
+ uint16_t switcher(const char* label, void (*callback)(Control*, int, void*), ControlColor color, bool startState, void* UserData); // Create Toggle Button
+
+ uint16_t pad(const char* label, void (*callback)(Control*, int), ControlColor color); // Create Pad Control
+ uint16_t pad(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData); // Create Pad Control
+
+ uint16_t padWithCenter(const char* label, void (*callback)(Control*, int), ControlColor color); // Create Pad Control with Centerbutton
+ uint16_t padWithCenter(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData); // Create Pad Control with Centerbutton
+
+ uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0, int max = 100); // Create Slider Control
+ uint16_t slider(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int value, int min, int max, void* UserData); // Create Slider Control
+
+ uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0, int max = 100); // Create a Number Input Control
+ uint16_t number(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int value, int min, int max, void* UserData); // Create a Number Input Control
+
+ uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color, const String& value = ""); // Create a Text Input Control
+ uint16_t text(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData); // Create a Text Input Control
// Output only
uint16_t label(const char* label, ControlColor color,
@@ -273,6 +291,7 @@ public:
// Input only
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color);
+ uint16_t accelerometer(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData);
// Update Elements