1
0
mirror of https://github.com/s00500/ESPUI.git synced 2024-11-21 22:50:55 +00:00

Merge branch 's00500:master' into master

This commit is contained in:
Ian Gray 2022-07-17 11:20:31 +01:00 committed by GitHub
commit a150d2db1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 258 additions and 109 deletions

View File

@ -146,26 +146,59 @@ more program memory to work with.
## Documentation ## Documentation
The heart of ESPUI is 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.
[ESPAsyncWebserver](https://github.com/me-no-dev/ESPAsyncWebServer). ESPUI's <br><br>
frontend is based on [Skeleton CSS](http://getskeleton.com/) and jQuery-like 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.
lightweight [zepto.js](https://zeptojs.com/) for handling events. The <br><br>
communication between the ESP and the client browser works using web 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.
sockets. ESPUI does not need network access and can be used in standalone access <br><br>
point mode, all resources are loaded directly from the ESPs memory. 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.
```
This section will explain in detail how the Library is to be used from the void YourClassName::setup()
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 ButtonElementId = ESPUI.addControl(
`ESPUI`. Eg: `ESPUI.button("button", &myCallback);` creates a button in the ControlType::Button,
interface that calls the `myCallback(Control *sender, int value)` function when changed. All buttons and ButtonLabel.c_str(),
items call their callback whenever there is a state change from them. This means " Button Face Text ",
the button will call the callback when it is pressed and also again when it is ControlColor::None,
released. To separate different events an integer number with the event name is ParentElementId,
passed to the callback function that can be handled in a `switch(){}case{}` [](Control *sender, int eventname, void* param)
statement. {
if(param)
{
reinterpret_cast<YourClassName*>(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<YourClassName*>(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
}
}
```
<br>
<br>
#### Button #### Button
![Buttons](docs/ui_button.png) ![Buttons](docs/ui_button.png)

View File

@ -49,6 +49,7 @@ void getTimeCallback(Control *sender, int type);
void graphAddCallback(Control *sender, int type); void graphAddCallback(Control *sender, int type);
void graphClearCallback(Control *sender, int type); void graphClearCallback(Control *sender, int type);
void randomString(char *buf, int len); void randomString(char *buf, int len);
void extendedCallback(Control* sender, int type, void* param);
//UI handles //UI handles
uint16_t wifi_ssid_text, wifi_pass_text; uint16_t wifi_ssid_text, wifi_pass_text;
@ -81,7 +82,7 @@ void setUpUI() {
auto maintab = ESPUI.addControl(Tab, "", "Basic controls"); auto maintab = ESPUI.addControl(Tab, "", "Basic controls");
ESPUI.addControl(Separator, "General controls", "", None, maintab); 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); mainLabel = ESPUI.addControl(Label, "Label", "Label text", Emerald, maintab, generalCallback);
mainSwitcher = ESPUI.addControl(Switcher, "Switcher", "", Sunflower, maintab, generalCallback); mainSwitcher = ESPUI.addControl(Switcher, "Switcher", "", Sunflower, maintab, generalCallback);
@ -360,7 +361,23 @@ void generalCallback(Control *sender, int type) {
Serial.println(sender->value); 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() { void setup() {
randomSeed(0); randomSeed(0);

View File

@ -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) switch (type)
{ {
case B_DOWN: case B_DOWN:
@ -210,7 +211,8 @@ void setup(void)
} }
#else #else
uint32_t chipid = ESP.getChipId(); uint32_t chipid = ESP.getChipId();
#endif char ap_ssid[25]; #endif
char ap_ssid[25];
snprintf(ap_ssid, 26, "ESPUI-%08X", chipid); snprintf(ap_ssid, 26, "ESPUI-%08X", chipid);
WiFi.softAP(ap_ssid); WiFi.softAP(ap_ssid);
@ -249,7 +251,7 @@ void setup(void)
button1 = ESPUI.addControl( button1 = ESPUI.addControl(
ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, Control::noParent, &buttonCallback); ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, Control::noParent, &buttonCallback);
ESPUI.addControl( 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( ESPUI.addControl(
ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, Control::noParent, &padExample); ControlType::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, Control::noParent, &padExample);
ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, Control::noParent, &padExample); ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, Control::noParent, &padExample);

View File

@ -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) switch (type)
{ {
case B_DOWN: case B_DOWN:
@ -227,7 +228,7 @@ void setup(void)
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop"); statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0"); millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press"); 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.padWithCenter("Pad with center", &padExample, ControlColor::Sunflower);
ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot); ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot);
testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false); testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false);

View File

@ -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) switch (type)
{ {
case B_DOWN: case B_DOWN:
@ -251,7 +252,7 @@ void setup(void)
ESPUI.addControl(ControlType::Label, "Millis:", "0", ControlColor::Emerald, tab1); ESPUI.addControl(ControlType::Label, "Millis:", "0", ControlColor::Emerald, tab1);
button1 = ESPUI.addControl( button1 = ESPUI.addControl(
ControlType::Button, "Push Button", "Press", ControlColor::Peterriver, tab1, &buttonCallback); 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::PadWithCenter, "Pad with center", "", ControlColor::Sunflower, tab2, &padExample);
ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, tab3, &padExample); ESPUI.addControl(ControlType::Pad, "Pad without center", "", ControlColor::Carrot, tab3, &padExample);
switchOne = ESPUI.addControl(ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, tab3, &switchExample); switchOne = ESPUI.addControl(ControlType::Switcher, "Switch one", "", ControlColor::Alizarin, tab3, &switchExample);

View File

@ -1,6 +1,6 @@
{ {
"name": "ESPUI", "name": "ESPUI",
"keywords": "espressif web interface iot control simple easy ui userinterface", "keywords": "espressif web interface iot easy ui",
"description": "ESP32 and ESP8266 Web Interface Library", "description": "ESP32 and ESP8266 Web Interface Library",
"repository": { "repository": {
"type": "git", "type": "git",
@ -31,7 +31,7 @@
"frameworks": "arduino" "frameworks": "arduino"
} }
], ],
"version": "2.1.0", "version": "2.1.1",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*" "platforms": "*"
} }

View File

@ -1,5 +1,5 @@
name=ESPUI name=ESPUI
version=2.1.0 version=2.1.1
author=Lukas Bachschwell author=Lukas Bachschwell
maintainer=Lukas Bachschwell <lukas@lbsfilm.at> maintainer=Lukas Bachschwell <lukas@lbsfilm.at>
sentence=ESP32 and ESP8266 Web Interface Library sentence=ESP32 and ESP8266 Web Interface Library

View File

@ -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) switch (type)
{ {
case B_DOWN: case B_DOWN:
@ -228,7 +229,7 @@ void setup(void)
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop"); statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0"); millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press"); 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.padWithCenter("Pad with center", &padExample, ControlColor::Sunflower);
ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot); ESPUI.pad("Pad without center", &padExample, ControlColor::Carrot);
testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false); testSwitchId = ESPUI.switcher("Switch one", &switchExample, ControlColor::Alizarin, false);

View File

@ -475,9 +475,9 @@ void onWsEvent(
return; return;
} }
if (c->callback == nullptr) if (false == c->HasCallback())
{ {
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(F("No callback found for ID ")); Serial.print(F("No callback found for ID "));
@ -490,97 +490,97 @@ void onWsEvent(
if (msg.startsWith(F("bdown:"))) if (msg.startsWith(F("bdown:")))
{ {
c->callback(c, B_DOWN); c->SendCallback(B_DOWN);
} }
else if (msg.startsWith(F("bup:"))) else if (msg.startsWith(F("bup:")))
{ {
c->callback(c, B_UP); c->SendCallback(B_UP);
} }
else if (msg.startsWith(F("pfdown:"))) else if (msg.startsWith(F("pfdown:")))
{ {
c->callback(c, P_FOR_DOWN); c->SendCallback(P_FOR_DOWN);
} }
else if (msg.startsWith(F("pfup:"))) else if (msg.startsWith(F("pfup:")))
{ {
c->callback(c, P_FOR_UP); c->SendCallback(P_FOR_UP);
} }
else if (msg.startsWith(F("pldown:"))) else if (msg.startsWith(F("pldown:")))
{ {
c->callback(c, P_LEFT_DOWN); c->SendCallback(P_LEFT_DOWN);
} }
else if (msg.startsWith(F("plup:"))) else if (msg.startsWith(F("plup:")))
{ {
c->callback(c, P_LEFT_UP); c->SendCallback(P_LEFT_UP);
} }
else if (msg.startsWith(F("prdown:"))) else if (msg.startsWith(F("prdown:")))
{ {
c->callback(c, P_RIGHT_DOWN); c->SendCallback(P_RIGHT_DOWN);
} }
else if (msg.startsWith(F("prup:"))) else if (msg.startsWith(F("prup:")))
{ {
c->callback(c, P_RIGHT_UP); c->SendCallback(P_RIGHT_UP);
} }
else if (msg.startsWith(F("pbdown:"))) else if (msg.startsWith(F("pbdown:")))
{ {
c->callback(c, P_BACK_DOWN); c->SendCallback(P_BACK_DOWN);
} }
else if (msg.startsWith(F("pbup:"))) else if (msg.startsWith(F("pbup:")))
{ {
c->callback(c, P_BACK_UP); c->SendCallback(P_BACK_UP);
} }
else if (msg.startsWith(F("pcdown:"))) else if (msg.startsWith(F("pcdown:")))
{ {
c->callback(c, P_CENTER_DOWN); c->SendCallback(P_CENTER_DOWN);
} }
else if (msg.startsWith(F("pcup:"))) else if (msg.startsWith(F("pcup:")))
{ {
c->callback(c, P_CENTER_UP); c->SendCallback(P_CENTER_UP);
} }
else if (msg.startsWith(F("sactive:"))) else if (msg.startsWith(F("sactive:")))
{ {
c->value = "1"; c->value = "1";
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, S_ACTIVE); c->SendCallback(S_ACTIVE);
} }
else if (msg.startsWith(F("sinactive:"))) else if (msg.startsWith(F("sinactive:")))
{ {
c->value = "0"; c->value = "0";
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, S_INACTIVE); c->SendCallback(S_INACTIVE);
} }
else if (msg.startsWith(F("slvalue:"))) else if (msg.startsWith(F("slvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, SL_VALUE); c->SendCallback(SL_VALUE);
} }
else if (msg.startsWith(F("nvalue:"))) else if (msg.startsWith(F("nvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, N_VALUE); c->SendCallback(N_VALUE);
} }
else if (msg.startsWith(F("tvalue:"))) else if (msg.startsWith(F("tvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, T_VALUE); c->SendCallback(T_VALUE);
} }
else if (msg.startsWith("tabvalue:")) else if (msg.startsWith("tabvalue:"))
{ {
c->callback(c, client->id()); c->SendCallback(client->id());
} }
else if (msg.startsWith(F("svalue:"))) else if (msg.startsWith(F("svalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, S_VALUE); c->SendCallback(S_VALUE);
} }
else if (msg.startsWith(F("time:"))) else if (msg.startsWith(F("time:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, TM_VALUE); c->SendCallback(TM_VALUE);
} }
else else
{ {
@ -600,10 +600,37 @@ void onWsEvent(
} }
} }
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t ESPUIClass::addControl(ControlType type, const char* label)
uint16_t parentControl, void (*callback)(Control*, int))
{ {
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) 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) bool ESPUIClass::removeControl(uint16_t id, bool force_reload_ui)
{ {
if (nullptr == this->controls) Control* PreviousControl = nullptr;
return false; Control* CurrentControl = this->controls;
Control* it = this->controls; while(nullptr != CurrentControl)
if (id == it->id)
{ {
this->controls = it->next; if (id == CurrentControl->id)
delete it;
this->controlCount--;
if (force_reload_ui)
{ {
jsonReload(); break;
}
PreviousControl = CurrentControl;
CurrentControl = CurrentControl->next;
}
if (nullptr != CurrentControl)
{
if(nullptr == PreviousControl)
{
this->controls = CurrentControl->next;
} }
else else
{ {
jsonDom(0); PreviousControl->next = CurrentControl->next;
} }
return true; delete CurrentControl;
}
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;
this->controlCount--; this->controlCount--;
if (force_reload_ui) if (force_reload_ui)
{ {
@ -685,10 +704,16 @@ uint16_t ESPUIClass::graph(const char* label, ControlColor color)
return addControl(ControlType::Graph, label, "", color); return addControl(ControlType::Graph, label, "", color);
} }
uint16_t ESPUIClass::slider( uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min, int max)
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::Min, label, String(min), ControlColor::None, sliderId);
addControl(ControlType::Max, label, String(max), 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); 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) 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); 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) uint16_t ESPUIClass::pad(const char* label, void (*callback)(Control*, int), ControlColor color)
{ {
return addControl(ControlType::Pad, label, "", color, Control::noParent, callback); 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) uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*, int), ControlColor color)
{ {
return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback); return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback);
} }
uint16_t ESPUIClass::number( uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
const char* label, void (*callback)(Control*, int), ControlColor color, int number, int min, int max) {
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); uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback);
addControl(ControlType::Min, label, String(min), ControlColor::None, numberId); addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
@ -723,6 +768,14 @@ uint16_t ESPUIClass::number(
return numberId; 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 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); 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); 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) 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); 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* ESPUIClass::getControl(uint16_t id)
{ {
Control* control = this->controls; 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) { void ESPUIClass::setVertical(uint16_t id, bool vert) {
Control* control = getControl(id); Control* control = getControl(id);
if (control) if (control)
@ -1451,4 +1513,17 @@ void ESPUIClass::setVerbosity(Verbosity v)
this->verbosity = v; this->verbosity = v;
} }
void Control::SendCallback(int type)
{
if(callback)
{
callback(this, type);
}
if (extendedCallback)
{
extendedCallback(this, type, user);
}
}
ESPUIClass ESPUI; ESPUIClass ESPUI;

View File

@ -137,6 +137,8 @@ public:
uint16_t id; // just mirroring the id here for practical reasons uint16_t id; // just mirroring the id here for practical reasons
const char* label; const char* label;
void (*callback)(Control*, int); void (*callback)(Control*, int);
void (*extendedCallback)(Control*, int, void*);
void* user;
String value; String value;
ControlColor color; ControlColor color;
bool visible; bool visible;
@ -151,11 +153,13 @@ public:
static constexpr uint16_t noParent = 0xffff; static constexpr uint16_t noParent = 0xffff;
Control(ControlType type, const char* label, void (*callback)(Control*, int), const String& value, Control(ControlType type, const char* label, void (*callback)(Control*, int, void*), void* UserData,
ControlColor color, bool visible = true, uint16_t parentControl = Control::noParent) const String& value, ControlColor color, bool visible, uint16_t parentControl)
: type(type), : type(type),
label(label), label(label),
callback(callback), callback(nullptr),
extendedCallback(callback),
user(UserData),
value(value), value(value),
color(color), color(color),
visible(visible), visible(visible),
@ -173,12 +177,16 @@ public:
id(control.id), id(control.id),
label(control.label), label(control.label),
callback(control.callback), callback(control.callback),
extendedCallback(control.extendedCallback),
user(control.user),
value(control.value), value(control.value),
color(control.color), color(control.color),
visible(control.visible), visible(control.visible),
parentControl(control.parentControl), parentControl(control.parentControl),
next(control.next) next(control.next)
{ } { }
void SendCallback(int type);
bool HasCallback() { return ((nullptr != callback) || (nullptr != extendedCallback)); }
private: private:
static uint16_t idCounter; static uint16_t idCounter;
@ -241,27 +249,37 @@ public:
// stuff into LITTLEFS // stuff into LITTLEFS
void list(); // Lists LITTLEFS directory void list(); // Lists LITTLEFS directory
uint16_t addControl(ControlType type, const char* label, const String& value = String(""), uint16_t addControl(ControlType type, const char* label);
ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent, uint16_t addControl(ControlType type, const char* label, const String& value);
void (*callback)(Control*, int) = nullptr); 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); bool removeControl(uint16_t id, bool force_reload_ui = false);
// create Elements // create Elements
uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color, // Create Event Button
const String& value = ""); // Create Event Button uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color, const String& value = "");
uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color, uint16_t button(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData);
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
uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0, uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color, bool startState = false); // Create Toggle Button
int max = 100); // Create Slider Control uint16_t switcher(const char* label, void (*callback)(Control*, int, void*), ControlColor color, bool startState, void* UserData); // Create Toggle Button
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 pad(const char* label, void (*callback)(Control*, int), ControlColor color); // Create Pad Control
uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color, uint16_t pad(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData); // Create Pad Control
const String& value = ""); // Create a Text Input 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 // Output only
uint16_t label(const char* label, ControlColor color, uint16_t label(const char* label, ControlColor color,
@ -273,6 +291,7 @@ public:
// Input only // Input only
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color); 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 // Update Elements