diff --git a/examples/softAP_UI_Test/data/css/style.css b/examples/softAP_UI_Test/data/css/style.css
index c632e53..9c35725 100644
--- a/examples/softAP_UI_Test/data/css/style.css
+++ b/examples/softAP_UI_Test/data/css/style.css
@@ -295,6 +295,7 @@
/* Lists
–––––––––––––––––––––––––––––––––––––––––––––––––– */
+/*
ul {
list-style: circle inside; }
ol {
@@ -310,7 +311,7 @@
font-size: 90%; }
li {
margin-bottom: 1rem; }
-
+*/
/* Code
–––––––––––––––––––––––––––––––––––––––––––––––––– */
@@ -398,3 +399,85 @@
content: "";
display: table;
clear: both; }
+
+ /* ButtonPad
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
+
+ .control {
+ background-color: #ddd;
+ background-image: linear-gradient(hsla(0,0%,0%,.1), hsla(0,0%,100%,.1));
+ border-radius: 50%;
+ box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,.5),
+ 0 0 1px 1px hsla(0,0%,100%,.75),
+ 0 0 1px 2px hsla(0,0%,100%,.25),
+ 0 0 1px 3px hsla(0,0%,100%,.25),
+ 0 0 1px 4px hsla(0,0%,100%,.25),
+ 0 0 1px 6px hsla(0,0%,0%,.75);
+ height: 9em;
+ margin: 3em auto;
+ position: relative;
+ width: 9em;
+}
+.control ul {
+ height: 100%;
+ padding: 0;
+ transform: rotate(45deg);
+}
+.control li {
+ border-radius: 100% 0 0 0;
+ box-shadow: inset -1px -1px 1px hsla(0,0%,100%,.5),
+ 0 0 1px hsla(0,0%,0%,.75);
+ display: inline-block;
+ height: 50%;
+ overflow: hidden;
+ width: 50%;
+}
+.control ul li:nth-child(2) {
+ transform: rotate(90deg);
+}
+.control ul li:nth-child(3) {
+ transform: rotate(-90deg);
+}
+.control ul li:nth-child(4) {
+ transform: rotate(180deg);
+}
+.control ul a {
+ height: 200%;
+ position: relative;
+ transform: rotate(-45deg);
+ width: 200%;
+}
+.control a:hover,
+.control a:focus {
+ background-color: hsla(0,0%,100%,.25);
+}
+.control a {
+ border-radius: 50%;
+ color: #333;
+ display: block;
+ font: bold 1em/3 sans-serif;
+ text-align: center;
+ text-decoration: none;
+ text-shadow: 0 1px 1px hsla(0,0%,100%,.4);
+ transition: .15s;
+}
+.control .confirm {
+ background-color: #ddd;
+ background-image: linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,100%,.25));
+ box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,.5),
+ 0 0 1px 1px hsla(0,0%,100%,.25),
+ 0 0 1px 2px hsla(0,0%,100%,.25),
+ 0 0 1px 3px hsla(0,0%,100%,.25),
+ 0 0 1px 4px hsla(0,0%,100%,.25),
+ 0 0 1px 6px hsla(0,0%,0%,.85);
+ left: 50%;
+ line-height: 3;
+ margin: -1.5em;
+ position: absolute;
+ top: 50%;
+ width: 3em;
+}
+.control .confirm:hover,
+.control .confirm:focus {
+ background-color: #eee;
+}
diff --git a/examples/softAP_UI_Test/data/index.htm b/examples/softAP_UI_Test/data/index.htm
index 1539afa..5874070 100644
--- a/examples/softAP_UI_Test/data/index.htm
+++ b/examples/softAP_UI_Test/data/index.htm
@@ -5,17 +5,18 @@
Control
-
- ControlOffline
+
+
+
diff --git a/examples/softAP_UI_Test/data/js/controls.js b/examples/softAP_UI_Test/data/js/controls.js
index a5500e0..8711475 100644
--- a/examples/softAP_UI_Test/data/js/controls.js
+++ b/examples/softAP_UI_Test/data/js/controls.js
@@ -1,9 +1,20 @@
-// TASKS:
-
-// Roadmap
-// Build changeable Labels
+// Roadmap:
// Build a serial Console?
+const UI_TITEL = 0;
+const UI_LABEL = 1;
+const UI_BUTTON = 2;
+const UI_SWITCHER = 3;
+const UI_PAD = 4;
+const UI_CPAD = 5;
+const UPDATE_LABEL = 6;
+
+const FOR = 0;
+const BACK = 1;
+const LEFT = 2;
+const RIGHT = 3;
+const CENTER = 4;
+
var websock;
function start() {
websock = new WebSocket('ws://' + window.location.hostname + '/ws');
@@ -27,29 +38,88 @@ function start() {
websock.onmessage = function(evt) {
console.log(evt);
var data = JSON.parse(evt.data);
- console.log(data);
var e = document.body;
- if (data.type === 'domButton') {
- //initial rendering of the Buttons
- $('#row').append(""+data.label+"
");
- }
- if (data.type === 'domLabel') {
- //initial rendering of the Labels
- $('#row').append(""+data.l_title+"
"+data.label+"
");
- }
- else if (data.type === 'value') {
- // Display some kind of value
- }
- else {
- console.log('unknown event');
+ var center = "";
+ switch(data.type){
+ case UI_TITEL:
+ document.title = data.label;
+ $('#mainHeader').html(data.label);
+ break;
+ case UI_LABEL:
+ $('#row').append(""+data.label+"
");
+ break;
+ case UI_BUTTON:
+ $('#row').append(""+data.label+"
");
+ $('#'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); buttonclick(data.id, true) } });
+ $('#'+data.id).on({ 'touchend' : function(e){e.preventDefault(); buttonclick(data.id, false) } });
+ break;
+ case UI_CPAD:
+ center = "OK";
+ //NO BREAK
+ case UI_PAD:
+ $('#row').append(
+ ""+data.label+"
"+
+ "
"+
+ "
");
+
+ $('#f'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); padclick(FOR, data.id, true) } });
+ $('#f'+data.id).on({ 'touchend' : function(e){e.preventDefault(); padclick(FOR, data.id, false) } });
+ $('#l'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); padclick(LEFT, data.id, true) } });
+ $('#l'+data.id).on({ 'touchend' : function(e){e.preventDefault(); padclick(LEFT, data.id, false) } });
+ $('#r'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); padclick(RIGHT, data.id, true) } });
+ $('#r'+data.id).on({ 'touchend' : function(e){e.preventDefault(); padclick(RIGHT, data.id, false) } });
+ $('#b'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); padclick(BACK, data.id, true) } });
+ $('#b'+data.id).on({ 'touchend' : function(e){e.preventDefault(); padclick(BACK,data.id, false) } });
+ $('#c'+data.id).on({ 'touchstart' : function(e){e.preventDefault(); padclick(CENTER, data.id, true) } });
+ $('#c'+data.id).on({ 'touchend' : function(e){e.preventDefault(); padclick(CENTER,data.id, false) } });
+
+ break;
+ case UPDATE_LABEL:
+ $('#'+data.id).html(data.label);
+ break;
+ default:
+ console.error('Unknown type or event');
+ break;
}
};
}
-function buttonclick(e) {
- websock.send("bdown:"+e.id);
- /*
- if release
- websock.send("bup:"+e.id);
- */
+
+function buttonclick(number, isdown) {
+ if(isdown)websock.send("bdown:"+number);
+ else websock.send("bup:"+number);
+}
+
+function padclick(type, number, isdown) {
+ switch(type){
+ case CENTER:
+ if(isdown)websock.send("pcdown:"+number);
+ else websock.send("pcup:"+number);
+ break;
+ case FOR:
+ if(isdown)websock.send("pfdown:"+number);
+ else websock.send("pfup:"+number);
+ break;
+ case BACK:
+ if(isdown)websock.send("pbdown:"+number);
+ else websock.send("pbup:"+number);
+ break;
+ case LEFT:
+ if(isdown)websock.send("pldown:"+number);
+ else websock.send("plup:"+number);
+ break;
+ case RIGHT:
+ if(isdown)websock.send("prdown:"+number);
+ else websock.send("prup:"+number);
+ break;
+
+ }
}
diff --git a/examples/softAP_UI_Test/softAP_UI_Test.ino b/examples/softAP_UI_Test/softAP_UI_Test.ino
index 7d7c152..a3f3f6b 100644
--- a/examples/softAP_UI_Test/softAP_UI_Test.ino
+++ b/examples/softAP_UI_Test/softAP_UI_Test.ino
@@ -1,36 +1,94 @@
#include
#include
-const char* ssid = "EasyUI";
+const char* ssid = "LARSUI";
const char* password = "";
+long oldTime = 0;
+
void setup(void) {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
- WiFi.softAP(ssid, password);
-
+ WiFi.setHostname(ssid);
+ WiFi.softAP(ssid);
+ //WiFi.softAP(ssid, password);
Serial.println("");
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
- EasyUI.title("LARSControl");
+ EasyUI.label("Status: Maxim Stop");
+ EasyUI.label("0");
+ EasyUI.button("MaximDance Button", &callback2);
+ EasyUI.pad("center", true, &callback3);
+ EasyUI.pad("NoCenter", false, &callback3);
+
+ EasyUI.begin("LARS Control");
- EasyUI.label("Label","123");
- EasyUI.label("Label2","456");
- EasyUI.label("Label3","789");
- EasyUI.button("LED", &callback1);
- EasyUI.begin();
}
void loop(void) {
+ if(millis()-oldTime> 5000){
+ EasyUI.print(1, String(millis()));
+ oldTime = millis();
+ }
}
-void callback1(void) {
- Serial.println("CALLBACK UNO");
+void callback1(int id, int type) {
+ switch (type) {
+ case B_DOWN:
+ Serial.println("Button DOWN");
+ break;
+ case B_UP:
+ Serial.println("Button UP");
+ break;
+ }
+
}
-void callback2(void) {
- Serial.println("CALLBACK DOS");
+
+void callback2(int id, int type) {
+ switch (type) {
+ case B_DOWN:
+ Serial.println("Maxim Start DAnce######################");
+ EasyUI.print(0, "Status: Maxim Start");
+ break;
+ case B_UP:
+ Serial.println("Maxim STOP DAnce######################");
+ EasyUI.print(0, "Status: Maxim Start");
+ break;
+ }
}
-void callback3(void) {
- Serial.println("CALLBACK TRES");
+void callback3(int id, int value) {
+ switch (value) {
+ case P_LEFT_DOWN:
+ Serial.println("left down");
+ break;
+ case P_LEFT_UP:
+ Serial.println("left up");
+ break;
+ case P_RIGHT_DOWN:
+ Serial.println("right down");
+ break;
+ case P_RIGHT_UP:
+ Serial.println("right up");
+ break;
+ case P_FOR_DOWN:
+ Serial.println("for down");
+ break;
+ case P_FOR_UP:
+ Serial.println("for up");
+ break;
+ case P_BACK_DOWN:
+ Serial.println("back down");
+ break;
+ case P_BACK_UP:
+ Serial.println("back up");
+ break;
+ case P_CENTER_DOWN:
+ Serial.println("center down");
+ break;
+ case P_CENTER_UP:
+ Serial.println("center up");
+ break;
+ }
+ Serial.println(id);
}
diff --git a/src/EasyUI.cpp b/src/EasyUI.cpp
index 92d05b1..56dbfd5 100644
--- a/src/EasyUI.cpp
+++ b/src/EasyUI.cpp
@@ -16,168 +16,124 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT
}
break;
case WS_EVT_DATA:
- Serial.print("WS Event");
String msg = "";
for (size_t i = 0; i < len; i++) {
msg += (char) data[i];
}
- Serial.println(msg);
- StaticJsonBuffer<200> jsonBuffer;
- JsonObject& root = jsonBuffer.parseObject(msg);
- String type = root["type"];
- if(type == "t"){
- //Button Action
- //TODO: get Button here
- EasyUI.buttons[0]->callback();
- //EasyUI.tbuttonStatus();
- }
- /*
- else if(mode == "tb_click"){
- String status = root["status"];
- String index = root["index"];
- //EasyUI.tbClick(index, status);
- }
- */
- break;
+ if(msg.startsWith("bdown:")){
+ EasyUI.controls[msg.substring(6).toInt()]->callback(msg.substring(6).toInt(), B_DOWN);
+ }else if(msg.startsWith("bup:")){
+ EasyUI.controls[msg.substring(4).toInt()]->callback(msg.substring(4).toInt(), B_UP);
+ }else if(msg.startsWith("pfdown:")){
+ EasyUI.controls[msg.substring(7).toInt()]->callback(msg.substring(7).toInt(), P_FOR_DOWN);
+ }else if(msg.startsWith("pfup:")){
+ EasyUI.controls[msg.substring(5).toInt()]->callback(msg.substring(5).toInt(), P_FOR_UP);
+ }else if(msg.startsWith("pldown:")){
+ EasyUI.controls[msg.substring(7).toInt()]->callback(msg.substring(7).toInt(), P_LEFT_DOWN);
+ }else if(msg.startsWith("plup:")){
+ EasyUI.controls[msg.substring(5).toInt()]->callback(msg.substring(5).toInt(), P_LEFT_UP);
+ }else if(msg.startsWith("prdown:")){
+ EasyUI.controls[msg.substring(7).toInt()]->callback(msg.substring(7).toInt(), P_RIGHT_DOWN);
+ }else if(msg.startsWith("prup:")){
+ EasyUI.controls[msg.substring(5).toInt()]->callback(msg.substring(5).toInt(), P_RIGHT_UP);
+ }else if(msg.startsWith("pbdown:")){
+ EasyUI.controls[msg.substring(7).toInt()]->callback(msg.substring(7).toInt(), P_BACK_DOWN);
+ }else if(msg.startsWith("pbup:")){
+ EasyUI.controls[msg.substring(5).toInt()]->callback(msg.substring(5).toInt(), P_BACK_UP);
+ }else if(msg.startsWith("pcdown:")){
+ EasyUI.controls[msg.substring(7).toInt()]->callback(msg.substring(7).toInt(), P_CENTER_DOWN);
+ }else if(msg.startsWith("pcup:")){
+ EasyUI.controls[msg.substring(5).toInt()]->callback(msg.substring(5).toInt(), P_CENTER_UP);
+ }
+ break;
}
}
-void EasyUIClass::title(const char* _title){
- ui_title = _title;
+void EasyUIClass::label(const char* label){
+ Control* newL = new Control();
+ newL->type = UI_LABEL;
+ newL->label = label;
+ newL->oldValue = label;
+ newL->callback = NULL;
+ controls[cIndex] = newL;
+ cIndex++;
}
-// Create Labels
-void EasyUIClass::label(const char* label_name,const char* label_val){
- label_value[l_index] = label_val;
- label_title[l_index] = label_name;
- l_index++;
-}
-/*
-// Create Toggle Buttons
-void EasyUIClass::toggleButton(uint8_t pin, const char* tbutton_label, int start_state, bool swap_state){
- pinMode(pin, OUTPUT);
- digitalWrite(pin, start_state);
- tbutton_swap[tb_index] = swap_state;
- tbutton_pinout[tb_index] = pin;
- tbuttontitle[tb_index] = tbutton_label;
- tb_index++;
-}
-*/
-// Create a generic Button
-void EasyUIClass::button(const char* bLabel, void(* callBack)()){
-
-//TODO: Implement
- Button* newB = new Button();
-
- newB->label = bLabel;
+void EasyUIClass::button(const char* label, void(* callBack)(int, int)){
+ Control* newB = new Control();
+ newB->type = UI_BUTTON;
+ newB->label = label;
newB->callback = callBack;
- buttons[bIndex] = newB;
- bIndex++;
+ controls[cIndex] = newB;
+ cIndex++;
}
-/*
-// Check Toggle Buttons States and Transfer to Webpage
-void EasyUIClass::tbuttonStatus(){
- String json;
- StaticJsonBuffer<200> jsonBuffer;
- JsonObject& root = jsonBuffer.createObject();
- root["mode"] = "t_button_startup";
- root["index"] = tb_index;
- for(int i=0; ibroadcastTXT(json);
-}
-*/
-/*
-// Handle Toggle Button Click Response
-void EasyUIClass::tbClick(String _index, String _status){
- String json;
- StaticJsonBuffer<200> jsonBuffer;
- JsonObject& root = jsonBuffer.createObject();
- String name = "tb"+_index;
- root["mode"] = "t_button_click";
- root["index"] = _index;
+void EasyUIClass::switcher(const char* label, int start_state, void(* callBack)(int, int)){
+ Control* newS = new Control();
+ newS->type = UI_SWITCHER;
+ newS->label = label;
+ newS->callback = callBack;
+ controls[cIndex] = newS;
+ cIndex++;
+ //TODO: implement switch state buffer
+ //tbutton_swap[tb_index] = swap_state;
+}
- if(_status == "on"){
- root[name] = "1";
+void EasyUIClass::pad(const char* label, bool center, void(* callBack)(int, int)){
+ Control* newP = new Control();
+ if(center)newP->type = UI_CPAD;
+ else newP->type = UI_PAD;
+ newP->label = label;
+ newP->callback = callBack;
+ controls[cIndex] = newP;
+ cIndex++;
+}
+
+void EasyUIClass::print(int labelid, String value){
+ if(labelidtype == UI_LABEL){
+ controls[labelid]->oldValue = value;
+ String json;
+ StaticJsonBuffer<200> jsonBuffer;
+ JsonObject& root = jsonBuffer.createObject();
+ root["type"] = UPDATE_LABEL;
+ root["label"] = value;
+ root["id"] = String(labelid);
root.printTo(json);
- webSocket->broadcastTXT(json);
- if(tbutton_swap[_index.toInt()]){
- digitalWrite(tbutton_pinout[_index.toInt()], LOW);
- }else{
- digitalWrite(tbutton_pinout[_index.toInt()], HIGH);
- }
- }
- else if(_status == "off"){
- root[name] = "0";
- root.printTo(json);
- webSocket->broadcastTXT(json);
- if(tbutton_swap[_index.toInt()]){
- digitalWrite(tbutton_pinout[_index.toInt()], HIGH);
+ this->ws->textAll(json);
}else{
- digitalWrite(tbutton_pinout[_index.toInt()], LOW);
- }
+ Serial.println(String("Error: ")+ String(labelid) +String(" is no label"));
}
}
-*/
+
// Convert & Transfer Arduino elements to JSON elements
void EasyUIClass::jsonDom(AsyncWebSocketClient * client){
- //SiteTitle
- //TODO: emit here
- // Labels
- for(int i=0; i jsonBuffer1;
- JsonObject& root1 = jsonBuffer1.createObject();
- root1["type"] = "domLabel";
- root1["l_title"] = String(label_title[i]);
- root1["label"] = String(label_value[i]);
- root1.printTo(json);
+ StaticJsonBuffer<200> jsonBuffer;
+ JsonObject& root = jsonBuffer.createObject();
+ if(i == -1){
+ root["type"] = UI_TITEL;
+ root["label"] = String(ui_title);
+ }else{
+ root["type"] = controls[i]->type;
+ root["label"] = String(controls[i]->label);
+ root["id"] = String(i);
+ if(controls[i]->type == UI_LABEL)root["label"] = controls[i]->oldValue;
+ }
+ root.printTo(json);
client->text(json);
}
- // Buttons
- for(int i=0; i jsonBuffer2;
- JsonObject& root2 = jsonBuffer2.createObject();
- root2["type"] = "domButton";
- root2["index"] = String(i);
- root2["label"] = buttons[i]->label;
- root2.printTo(json);
- client->text(json);
- }
-
}
-void EasyUIClass::begin(){
+void EasyUIClass::begin(const char * _title){
+ ui_title = _title;
server = new AsyncWebServer(80);
ws = new AsyncWebSocket("/ws");
- SPIFFS.begin(false);
-
+ SPIFFS.begin();
ws->onEvent(onWsEvent);
server->addHandler(ws);
-
server->serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm");
//Heap for general Servertest
diff --git a/src/EasyUI.h b/src/EasyUI.h
index 16b02dd..d902273 100644
--- a/src/EasyUI.h
+++ b/src/EasyUI.h
@@ -16,38 +16,61 @@
#include
#include
-typedef struct Button
+typedef struct Control
{
+ unsigned int type;
const char *label;
- void (*callback)();
-} Button;
+ void (*callback)(int, int);
+ String oldValue;
+} Control;
+
+// Types
+#define UI_TITEL 0
+#define UI_LABEL 1
+#define UI_BUTTON 2
+#define UI_SWITCHER 3
+#define UI_PAD 4
+#define UI_CPAD 5
+#define UPDATE_LABEL 6
+
+// Values
+#define B_DOWN -1
+#define B_UP 1
+
+#define P_LEFT_DOWN -2
+#define P_LEFT_UP 2
+#define P_RIGHT_DOWN -3
+#define P_RIGHT_UP 3
+#define P_FOR_DOWN -4
+#define P_FOR_UP 4
+#define P_BACK_DOWN -5
+#define P_BACK_UP 5
+#define P_CENTER_DOWN -6
+#define P_CENTER_UP 6
+
+
class EasyUIClass{
public:
- void begin(); // Begin HTTP Server + WebSocketsServer & Initalize All Elements
- void title(const char* _title); // Define Webpage Header Name and title
- //void toggleButton(uint8_t pin, const char* tbutton_label, int start_state = 0, bool swap_state = false); // Create Toggle Button
- void button(const char* tbutton_label, void(* callBack)()); // Create Event Button
- void label(const char* label_name, const char* label_val); // Create Label
+ void begin(const char* _title); // Setup servers and page
+
+ // Creating Elements
+ void label(const char* label); // Create Label
+ void button(const char* label, void(* callBack)(int, int)); // Create Event Button
+ void switcher(const char* label, int start_state, void(* callBack)(int, int)); // Create Toggle Button
+ void pad(const char* label, bool centerButton, void(* callBack)(int, int)); // Create Pad Control
+
+ // Update Elements
+ void print(int labelid, String value);
+
// Variables ---
- const char* ui_title = "EasyUI"; // Store UI Title and Header Name
- int bIndex; // How Many Buttons
- int l_index; // How Many Labels
-
- bool tbutton_swap[10];
- Button* buttons[10];
-
- const char* label_value[10]; // Stores Label Values - MAX 10
- const char* label_title[10]; // Stores Label Titles - MAX 10
-
- String webpage; // Coverts Arduino elements to JSON elements
-
- void tbClick(String _index, String _status);
- void tbuttonStatus();
+ const char* ui_title = "ESPUI"; // Store UI Title and Header Name
+ int cIndex; // Control index
+ Control* controls[25];
void jsonDom(AsyncWebSocketClient * client);
- private:
+private:
AsyncWebServer* server;
AsyncWebSocket* ws;
};