mirror of
https://github.com/s00500/ESPUI.git
synced 2025-07-04 11:20:19 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
b421b84b11 | |||
f1012b2fe2 | |||
cc633a7c85 | |||
40b13430cb | |||
dda4e9e771 | |||
1390b73218 | |||
5f7f8dd4e5 |
@ -51,7 +51,7 @@ Download the [Repository](https://github.com/s00500/ESPUI/archive/master.zip), G
|
|||||||
ESPUI **NEEDS** its files burnt on the SPIFFS filesystem on the ESP. **Without this ESPUI will NOT work at all**
|
ESPUI **NEEDS** its files burnt on the SPIFFS filesystem on the ESP. **Without this ESPUI will NOT work at all**
|
||||||
There are now two ways to do this: you can either use the upload tool or you use the library function `ESPUI.prepareFileSystem()`
|
There are now two ways to do this: you can either use the upload tool or you use the library function `ESPUI.prepareFileSystem()`
|
||||||
|
|
||||||
#### Simple filesystem preparation (recomended)
|
#### Simple filesystem preparation (recomended, but currently not working well on esp32, see issues)
|
||||||
|
|
||||||
Just open the example sketch **prepareFileSystem** and run it on the ESP, (give it 5 - 10 seconds),
|
Just open the example sketch **prepareFileSystem** and run it on the ESP, (give it 5 - 10 seconds),
|
||||||
The library will create all needed files.
|
The library will create all needed files.
|
||||||
@ -81,10 +81,13 @@ Now you are set to go and use any code you want to with this library
|
|||||||
- ~~Setup SPIFFS using values in program memory~~
|
- ~~Setup SPIFFS using values in program memory~~
|
||||||
- ~~ESP8266 support~~
|
- ~~ESP8266 support~~
|
||||||
- Document slider
|
- Document slider
|
||||||
|
- New images in docu
|
||||||
- proper return value (as int and not as string) for slider
|
- proper return value (as int and not as string) for slider
|
||||||
- Maybe a slider range setting, meanwhile please use map()
|
- Maybe a slider range setting, meanwhile please use map()
|
||||||
- Improve slider stability
|
- Improve slider stability
|
||||||
- Improve general stability
|
- Improve general stability
|
||||||
|
- Multiline Labels
|
||||||
|
- PlattformIO Integration
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=ESPUI
|
name=ESPUI
|
||||||
version=1.4.4
|
version=1.4.6
|
||||||
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
|
||||||
|
143
src/ESPUI.cpp
143
src/ESPUI.cpp
@ -2,33 +2,35 @@
|
|||||||
|
|
||||||
#include "uploadDataIndex.h"
|
#include "uploadDataIndex.h"
|
||||||
|
|
||||||
|
|
||||||
#include "uploadDataStyle.h"
|
|
||||||
#include "uploadDataNormalize.h"
|
#include "uploadDataNormalize.h"
|
||||||
|
#include "uploadDataStyle.h"
|
||||||
|
|
||||||
#include "uploadDataControls.h"
|
#include "uploadDataControls.h"
|
||||||
#include "uploadDataZepto.h"
|
|
||||||
#include "uploadDataSlider.h"
|
#include "uploadDataSlider.h"
|
||||||
|
#include "uploadDataZepto.h"
|
||||||
|
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
// ################# Spiffs functions
|
// ################# Spiffs functions
|
||||||
|
#if defined(ESP32)
|
||||||
void listDir(const char *dirname, uint8_t levels) {
|
void listDir(const char *dirname, uint8_t levels) {
|
||||||
Serial.printf("Listing directory: %s\n", dirname);
|
Serial.printf("Listing directory: %s\n", dirname);
|
||||||
|
|
||||||
File root = SPIFFS.open(dirname);
|
File root = SPIFFS.open(dirname);
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
Serial.println("Failed to open directory");
|
Serial.println("Failed to open directory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root.isDirectory()) {
|
if (!root.isDirectory()) {
|
||||||
Serial.println("Not a directory");
|
Serial.println("Not a directory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = root.openNextFile();
|
File file = root.openNextFile();
|
||||||
|
|
||||||
while (file) {
|
while (file) {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
Serial.print(" DIR : ");
|
Serial.print(" DIR : ");
|
||||||
@ -42,9 +44,45 @@ void listDir(const char * dirname, uint8_t levels){
|
|||||||
Serial.print(" SIZE: ");
|
Serial.print(" SIZE: ");
|
||||||
Serial.println(file.size());
|
Serial.println(file.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
file = root.openNextFile();
|
file = root.openNextFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
void listDir(const char *dirname, uint8_t levels) {
|
||||||
|
// ignoring levels for esp8266
|
||||||
|
Serial.printf("Listing directory: %s\n", dirname);
|
||||||
|
|
||||||
|
String str = "";
|
||||||
|
Dir dir = SPIFFS.openDir("/");
|
||||||
|
while (dir.next()) {
|
||||||
|
Serial.print(" FILE: ");
|
||||||
|
Serial.print(dir.fileName());
|
||||||
|
Serial.print(" SIZE: ");
|
||||||
|
Serial.println(dir.fileSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ESPUIClass::list() {
|
||||||
|
if (!SPIFFS.begin()) {
|
||||||
|
Serial.println("SPIFFS Mount Failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
listDir("/", 1);
|
||||||
|
#if defined(ESP32)
|
||||||
|
Serial.println(SPIFFS.totalBytes());
|
||||||
|
Serial.println(SPIFFS.usedBytes());
|
||||||
|
#else
|
||||||
|
FSInfo fs_info;
|
||||||
|
SPIFFS.info(fs_info);
|
||||||
|
|
||||||
|
Serial.println(fs_info.totalBytes);
|
||||||
|
Serial.println(fs_info.usedBytes);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void deleteFile(const char *path) {
|
void deleteFile(const char *path) {
|
||||||
Serial.print(SPIFFS.exists(path));
|
Serial.print(SPIFFS.exists(path));
|
||||||
@ -70,11 +108,19 @@ void writeFile(const char * path, const char * data) {
|
|||||||
Serial.println("Failed to open file for writing");
|
Serial.println("Failed to open file for writing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#if defined(ESP32)
|
||||||
|
if (file.print(data)) {
|
||||||
|
Serial.println("File written");
|
||||||
|
} else {
|
||||||
|
Serial.println("Write failed");
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (file.print(FPSTR(data))) {
|
if (file.print(FPSTR(data))) {
|
||||||
Serial.println("File written");
|
Serial.println("File written");
|
||||||
} else {
|
} else {
|
||||||
Serial.println("Write failed");
|
Serial.println("Write failed");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +137,7 @@ Serial.println("About to prepare filesystem...");
|
|||||||
Serial.println("SPIFFS Mount Failed");
|
Serial.println("SPIFFS Mount Failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
listDir("/", 1);
|
||||||
Serial.println("SPIFFS Mount ESP32 Done");
|
Serial.println("SPIFFS Mount ESP32 Done");
|
||||||
#else
|
#else
|
||||||
SPIFFS.format();
|
SPIFFS.format();
|
||||||
@ -98,9 +145,8 @@ Serial.println("About to prepare filesystem...");
|
|||||||
Serial.println("SPIFFS Mount ESP8266 Done");
|
Serial.println("SPIFFS Mount ESP8266 Done");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
listDir("/", 1);
|
// TODO: This is a workaround, have to find out why SPIFFS on ESP32 behaves
|
||||||
|
// incredibly strangely, see issue #6
|
||||||
//TODO: This is a workaround, have to find out why SPIFFS on ESP32 behaves incredibly strangely, see issue #6
|
|
||||||
/*
|
/*
|
||||||
deleteFile("/index.htm");
|
deleteFile("/index.htm");
|
||||||
|
|
||||||
@ -125,30 +171,33 @@ writeFile("/js/controls.js", JS_CONTROLS);
|
|||||||
writeFile("/js/slider.js", JS_SLIDER);
|
writeFile("/js/slider.js", JS_SLIDER);
|
||||||
|
|
||||||
Serial.println("Done Initializing filesystem :-)");
|
Serial.println("Done Initializing filesystem :-)");
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
listDir("/", 1);
|
listDir("/", 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
SPIFFS.end();
|
SPIFFS.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::list() {
|
|
||||||
if(!SPIFFS.begin()) {
|
|
||||||
Serial.println("SPIFFS Mount Failed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
listDir("/", 1);
|
|
||||||
|
|
||||||
Serial.println(SPIFFS.totalBytes());
|
|
||||||
Serial.println(SPIFFS.usedBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handle Websockets Communication
|
// Handle Websockets Communication
|
||||||
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client,
|
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client,
|
||||||
AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
AwsEventType type, void *arg, uint8_t *data, size_t len) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case WS_EVT_DISCONNECT:
|
case WS_EVT_DISCONNECT: {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.printf("Disconnected!\n");
|
Serial.printf("Disconnected!\n");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case WS_EVT_PONG: {
|
||||||
|
if (debug)
|
||||||
|
Serial.printf("Received PONG!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WS_EVT_ERROR: {
|
||||||
|
if (debug)
|
||||||
|
Serial.printf("WebSocket Error!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WS_EVT_CONNECT: {
|
case WS_EVT_CONNECT: {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
Serial.print("Connected: ");
|
Serial.print("Connected: ");
|
||||||
@ -159,18 +208,20 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client,
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
Serial.println("JSON Data Sent to Client!");
|
Serial.println("JSON Data Sent to Client!");
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
case WS_EVT_DATA: {
|
||||||
case WS_EVT_DATA:
|
|
||||||
String msg = "";
|
String msg = "";
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
msg += (char)data[i];
|
msg += (char)data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = msg.substring(msg.lastIndexOf(':') + 1).toInt();
|
int id = msg.substring(msg.lastIndexOf(':') + 1).toInt();
|
||||||
if (id >= ESPUI.cIndex) {
|
if (id >= ESPUI.cIndex) {
|
||||||
if(debug) Serial.println("Maleformated id in websocket message");
|
if (debug)
|
||||||
|
Serial.println("Maleformated id in websocket message");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *c = ESPUI.controls[msg.substring(msg.lastIndexOf(':') + 1).toInt()];
|
Control *c = ESPUI.controls[msg.substring(msg.lastIndexOf(':') + 1).toInt()];
|
||||||
|
|
||||||
if (msg.startsWith("bdown:")) {
|
if (msg.startsWith("bdown:")) {
|
||||||
@ -204,20 +255,24 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client,
|
|||||||
ESPUI.updateSwitcher(c->id, false);
|
ESPUI.updateSwitcher(c->id, false);
|
||||||
c->callback(*c, S_INACTIVE);
|
c->callback(*c, S_INACTIVE);
|
||||||
} else if (msg.startsWith("slvalue:")) {
|
} else if (msg.startsWith("slvalue:")) {
|
||||||
int value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')).toInt();
|
int value =
|
||||||
|
msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')).toInt();
|
||||||
ESPUI.updateSlider(c->id, value, client->id());
|
ESPUI.updateSlider(c->id, value, client->id());
|
||||||
c->callback(*c, SL_VALUE);
|
c->callback(*c, SL_VALUE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::label(const char *label, int color, String value) {
|
int ESPUIClass::label(const char *label, int color, String value) {
|
||||||
if (labelExists(label)) {
|
if (labelExists(label)) {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println("UI ERROR: Element " + String(label) +
|
Serial.println("UI ERROR: Element " + String(label) +
|
||||||
" exists, skipping creating element!");
|
" exists, skipping creating element!");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *newL = new Control();
|
Control *newL = new Control();
|
||||||
@ -232,15 +287,17 @@ void ESPUIClass::label(const char *label, int color, String value) {
|
|||||||
newL->id = cIndex;
|
newL->id = cIndex;
|
||||||
controls[cIndex] = newL;
|
controls[cIndex] = newL;
|
||||||
cIndex++;
|
cIndex++;
|
||||||
|
return cIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this still needs a range setting
|
// TODO: this still needs a range setting
|
||||||
void ESPUIClass::slider(const char *label, void (*callBack)(Control, int), int color, String value) {
|
int ESPUIClass::slider(const char *label, void (*callBack)(Control, int),
|
||||||
|
int color, String value) {
|
||||||
if (labelExists(label)) {
|
if (labelExists(label)) {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println("UI ERROR: Element " + String(label) +
|
Serial.println("UI ERROR: Element " + String(label) +
|
||||||
" exists, skipping creating element!");
|
" exists, skipping creating element!");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *newSL = new Control();
|
Control *newSL = new Control();
|
||||||
@ -255,15 +312,16 @@ void ESPUIClass::slider(const char *label, void (*callBack)(Control, int), int c
|
|||||||
newSL->id = cIndex;
|
newSL->id = cIndex;
|
||||||
controls[cIndex] = newSL;
|
controls[cIndex] = newSL;
|
||||||
cIndex++;
|
cIndex++;
|
||||||
|
return cIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::button(const char *label, void (*callBack)(Control, int),
|
int ESPUIClass::button(const char *label, void (*callBack)(Control, int),
|
||||||
int color, String value) {
|
int color, String value) {
|
||||||
if (labelExists(label)) {
|
if (labelExists(label)) {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println("UI ERROR: Element " + String(label) +
|
Serial.println("UI ERROR: Element " + String(label) +
|
||||||
" exists, skipping creating element!");
|
" exists, skipping creating element!");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *newB = new Control();
|
Control *newB = new Control();
|
||||||
@ -280,15 +338,16 @@ void ESPUIClass::button(const char *label, void (*callBack)(Control, int),
|
|||||||
newB->id = cIndex;
|
newB->id = cIndex;
|
||||||
controls[cIndex] = newB;
|
controls[cIndex] = newB;
|
||||||
cIndex++;
|
cIndex++;
|
||||||
|
return cIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::switcher(const char *label, bool startState,
|
int ESPUIClass::switcher(const char *label, bool startState,
|
||||||
void (*callBack)(Control, int), int color) {
|
void (*callBack)(Control, int), int color) {
|
||||||
if (labelExists(label)) {
|
if (labelExists(label)) {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println("UI ERROR: Element " + String(label) +
|
Serial.println("UI ERROR: Element " + String(label) +
|
||||||
" exists, skipping creating element!");
|
" exists, skipping creating element!");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *newS = new Control();
|
Control *newS = new Control();
|
||||||
@ -300,15 +359,16 @@ void ESPUIClass::switcher(const char *label, bool startState,
|
|||||||
newS->id = cIndex;
|
newS->id = cIndex;
|
||||||
controls[cIndex] = newS;
|
controls[cIndex] = newS;
|
||||||
cIndex++;
|
cIndex++;
|
||||||
|
return cIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::pad(const char *label, bool center,
|
int ESPUIClass::pad(const char *label, bool center,
|
||||||
void (*callBack)(Control, int), int color) {
|
void (*callBack)(Control, int), int color) {
|
||||||
if (labelExists(label)) {
|
if (labelExists(label)) {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println("UI ERROR: Element " + String(label) +
|
Serial.println("UI ERROR: Element " + String(label) +
|
||||||
" exists, skipping creating element!");
|
" exists, skipping creating element!");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *newP = new Control();
|
Control *newP = new Control();
|
||||||
@ -322,6 +382,7 @@ void ESPUIClass::pad(const char *label, bool center,
|
|||||||
newP->id = cIndex;
|
newP->id = cIndex;
|
||||||
controls[cIndex] = newP;
|
controls[cIndex] = newP;
|
||||||
cIndex++;
|
cIndex++;
|
||||||
|
return cIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::print(int id, String value) {
|
void ESPUIClass::print(int id, String value) {
|
||||||
@ -382,8 +443,7 @@ void ESPUIClass::updateSlider(int id, int nValue, int clientId ) {
|
|||||||
textThem(json, clientId);
|
textThem(json, clientId);
|
||||||
} else {
|
} else {
|
||||||
if (debug)
|
if (debug)
|
||||||
Serial.println(String("Error: ") + String(id) +
|
Serial.println(String("Error: ") + String(id) + String(" is no slider"));
|
||||||
String(" is no slider"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +457,8 @@ void ESPUIClass::updateSwitcher(String label, bool nValue, int clientId) {
|
|||||||
updateSwitcher(getIdByLabel(label), nValue, clientId);
|
updateSwitcher(getIdByLabel(label), nValue, clientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a hacky workaround because ESPAsyncWebServer does not have a function like this and it's clients array is private
|
// This is a hacky workaround because ESPAsyncWebServer does not have a function
|
||||||
|
// like this and it's clients array is private
|
||||||
void ESPUIClass::textThem(String text, int clientId) {
|
void ESPUIClass::textThem(String text, int clientId) {
|
||||||
int tryId = 0;
|
int tryId = 0;
|
||||||
for (int count = 0; count < this->ws->count();) {
|
for (int count = 0; count < this->ws->count();) {
|
||||||
@ -455,13 +516,15 @@ void ESPUIClass::begin(const char *_title) {
|
|||||||
ws = new AsyncWebSocket("/ws");
|
ws = new AsyncWebSocket("/ws");
|
||||||
|
|
||||||
if (!SPIFFS.begin()) {
|
if (!SPIFFS.begin()) {
|
||||||
Serial.println("SPIFFS Mount Failed, PLEASE CHECK THE README ON HOW TO PREPARE YOUR ESP!!!!!!!");
|
Serial.println("SPIFFS Mount Failed, PLEASE CHECK THE README ON HOW TO "
|
||||||
|
"PREPARE YOUR ESP!!!!!!!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
listDir("/", 1);
|
listDir("/", 1);
|
||||||
|
|
||||||
if (!SPIFFS.exists("/index.htm")) {
|
if (!SPIFFS.exists("/index.htm")) {
|
||||||
Serial.println("Please read the README!!!!!!!, Make sure to ESPUI.prepareFileSystem() once in an empty sketch");
|
Serial.println("Please read the README!!!!!!!, Make sure to "
|
||||||
|
"ESPUI.prepareFileSystem() once in an empty sketch");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/ESPUI.h
10
src/ESPUI.h
@ -91,15 +91,15 @@ public:
|
|||||||
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of stuff into SPIFFS
|
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of stuff into SPIFFS
|
||||||
void list();
|
void list();
|
||||||
// Creating Elements
|
// Creating Elements
|
||||||
void label(const char *label, int color, String value = ""); // Create Label
|
int label(const char *label, int color, String value = ""); // Create Label
|
||||||
void button(const char *label, void (*callBack)(Control, int), int color,
|
int button(const char *label, void (*callBack)(Control, int), int color,
|
||||||
String value = ""); // Create Event Button
|
String value = ""); // Create Event Button
|
||||||
void switcher(const char *label, bool startState,
|
int switcher(const char *label, bool startState,
|
||||||
void (*callBack)(Control, int),
|
void (*callBack)(Control, int),
|
||||||
int color); // Create Toggle Button
|
int color); // Create Toggle Button
|
||||||
void pad(const char *label, bool centerButton, void (*callBack)(Control, int),
|
int pad(const char *label, bool centerButton, void (*callBack)(Control, int),
|
||||||
int color); // Create Pad Control
|
int color); // Create Pad Control
|
||||||
void slider(const char *label, void (*callBack)(Control, int), int color, String value); // Create Slider Control
|
int slider(const char *label, void (*callBack)(Control, int), int color, String value); // Create Slider Control
|
||||||
|
|
||||||
// Update Elements
|
// Update Elements
|
||||||
void print(int id, String value);
|
void print(int id, String value);
|
||||||
|
Reference in New Issue
Block a user