1
0
mirror of https://github.com/s00500/ESPUI.git synced 2024-11-24 17:30:55 +00:00

Merge pull request #147 from iangray001/designupdates

Separators, grouped controls, and wide controls
This commit is contained in:
Ian Gray 2022-01-09 11:01:46 +00:00 committed by GitHub
commit cf535110ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 424 additions and 894 deletions

View File

@ -33,6 +33,8 @@ The Library runs fine on any kind of **ESP8266** and **ESP32** (NodeMCU Boards,
- Public Access to ESPAsyncServer
- Graph Widget (Persist save graph in local storage #10)
- Inline CSS styles by @iangray001
- Separators by @iangray001
- Grouped and wide controls by @iangray001
## Further Roadmap
@ -305,6 +307,18 @@ Then all widgets for the tab need to be added to it by specifying the tab as the
`ESPUI.addControl( ControlType::Text, "Text Title:", "a Text Field", ControlColor::Alizarin, tab1, &textCall );`
### Separators
![separators](docs/ui_separators.png)
You can use separators to break up the UI and better organise your controls. Adding a separator will force any following controls onto the subsequent line. Add separators as follows:
```
ESPUI.separator("Separator name");
//or
ESPUI.addControl(ControlType::Separator, "Separator name", "", ControlColor::None, maintab);
```
### Initialisation of the UI
After all the elements are configured you can use `ESPUI.begin("Some Title");`
@ -390,6 +404,50 @@ Note: The images in this example are formed by setting a Label to contain an `<i
ESPUI.addControl(ControlType::Label, "Label", "<img src='path/to/image'>", ControlColor::Peterriver);
```
### Grouped controls
Normally, whenever a control is added to the UI, a new panel is generated with a title. However, you can instead
set the "parent" of a new control to be an existing control. This allows you to add multiple widgets into the same
panel. For example:
```
panel1 = ESPUI.addControl(ControlType::Button, "Button Set", "Button A", ControlColor::Turquoise, Control::noParent, btncallback);
ESPUI.addControl(ControlType::Button, "", "Button B", ControlColor::None, panel1, btncallback);
ESPUI.addControl(ControlType::Button, "", "Button C", ControlColor::None, panel1, btncallback);
```
The first call to `addControl` has no parent (or it could be set to a tab if you are using a tabbed UI), so therefore a new panel is added containing one button
with the value `Button A`. The two subsequent calls have their parent set to the first control we added, so instead of creating
a new panel, the result is the following:
![Grouped buttons](docs/ui_groupedbuttons.png)
The grouped controls operate entirely independently, and can be assigned different callbacks, or updated separately. The grouping
is purely visual.
Most controls can be grouped this way, but the result is not always visually pleasant. This works best with labels, sliders, switchers,
and buttons.
![Other grouped elements](docs/ui_groupedbuttons2.png)
If you group too many elements it might throw the layout of the rest of the UI out of line. Consider adding separators to correct this.
### Advanced: Wide controls
Controls can be set to be displayed "wide" with the function:
```
ESPUI.setPanelWide(controlid, true);
```
*Important!* This function should be called _before_ `ESPUI.begin` or results will be unreliable.
Setting a control to wide tells ESPUI to lay out that control as if there was only a single column, even on wide displays.
This can be applied to every element to force a single column layout, or to individual elements to customise the display.
![Wide controls](docs/ui_widecontrols.png)
Note that this will have no effect on small screens.
# Notes for Development

View File

@ -13,22 +13,44 @@
.card {
min-height: 100px;
margin-top: 2%;
border-radius: 6px;
box-shadow: 0 4px 4px rgba(204, 197, 185, 0.5);
padding-left: 20px;
padding-right: 20px;
margin-bottom: 10px;
margin-bottom: 40px;
min-width: 500px;
color: #fff;
}
@media (min-width: 1205px) {
.wide.card {
min-width: 1075px;
}
}
@media (min-width: 1790px) {
.wide.card {
min-width: 1650px;
}
}
@media (max-width: 630px) {
.card {
min-width: 98%;
}
}
.sectionbreak.columns {
color: black;
}
.sectionbreak.columns hr {
border: none;
height: 2px;
background-color: #666
}
.card-slider {}
.turquoise {
@ -137,7 +159,7 @@
.column,
.columns {
margin-right: 2%;
margin-right: 35px;
}
.column:first-child,
@ -423,6 +445,8 @@ button:active {
button,
.button {
margin-bottom: 1rem;
margin-left: 0.3rem;
margin-right: 0.3rem;
}
/* Utilities
@ -576,7 +600,8 @@ hr {
display: block;
font-size: 14px;
height: 26px;
margin-bottom: 12px;
margin-left: 0.3rem;
margin-right: 0.3rem;
position: relative;
width: 60px;
-webkit-transition: background-color 0.2s ease-in-out;
@ -933,6 +958,7 @@ input[id^="num"] {
body div>ul.navigation {
margin: 0;
margin-bottom: 30px;
padding: 0;
border-bottom: 3px solid #666;
overflow: hidden;

File diff suppressed because one or more lines are too long

651
data/js/controls.js vendored
View File

@ -52,7 +52,10 @@ const UPDATE_STEP = 116;
const UI_GAUGE = 17;
const UPDATE_GAUGE = 117;
const UI_ACCEL = 18;
const UPTDATE_ACCEL = 117;
const UPDATE_ACCEL = 118;
const UI_SEPARATOR = 19;
const UPDATE_SEPARATOR = 119;
const UP = 0;
const DOWN = 1;
@ -233,9 +236,6 @@ function start() {
var e = document.body;
var center = "";
panelStyle = data.hasOwnProperty('panelStyle') ? " style='" + data.panelStyle + "'" : "";
elementStyle = data.hasOwnProperty('elementStyle') ? " style='" + data.elementStyle + "'" : "";
switch (data.type) {
case UI_INITIAL_GUI:
// Clear current elements
@ -272,366 +272,130 @@ function start() {
$("#mainHeader").html(data.label);
break;
/*
Most elements have the same behaviour when added.
*/
case UI_LABEL:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<span id='l" +
data.id +
"' " + elementStyle + " class='label label-wrap'>" +
data.value +
"</span>" +
"</div>"
);
}
case UI_NUMBER:
case UI_TEXT_INPUT:
case UI_SELECT:
case UI_GAUGE:
case UI_SEPARATOR:
if (data.visible) addToHTML(data);
break;
/*
These elements must call additional functions after being added to the DOM
*/
case UI_BUTTON:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
if (data.visible) {
addToHTML(data);
$("#btn" + data.id).on({
touchstart: function (e) {
e.preventDefault();
buttonclick(data.id, true);
},
touchend: function (e) {
e.preventDefault();
buttonclick(data.id, false);
},
});
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='one columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<button id='btn" +
data.id +
"' " + elementStyle + " " +
"onmousedown='buttonclick(" +
data.id +
", true)' " +
"onmouseup='buttonclick(" +
data.id +
", false)'>" +
data.value +
"</button></div>"
);
$("#btn" + data.id).on({
touchstart: function (e) {
e.preventDefault();
buttonclick(data.id, true);
},
touchend: function (e) {
e.preventDefault();
buttonclick(data.id, false);
},
});
}
break;
case UI_SWITCHER:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
if (data.visible) {
addToHTML(data);
switcher(data.id, data.value);
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='one columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<label id='sl" +
data.id +
"' " + elementStyle + " class='switch " +
(data.value == "1" ? "checked" : "") +
"'>" +
"<div class='in'><input type='checkbox' id='s" +
data.id +
"' onClick='switcher(" +
data.id +
",null)' " +
(data.value == "1" ? "checked" : "") +
"/></div>" +
"</label>" +
"</div>"
);
switcher(data.id, data.value);
}
break;
case UI_CPAD:
case UI_PAD:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<nav class='control'>" +
"<ul>" +
"<li><a onmousedown='padclick(UP, " +
data.id +
", true)' onmouseup='padclick(UP, " +
data.id +
", false)' id='pf" +
data.id +
"'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(RIGHT, " +
data.id +
", true)' onmouseup='padclick(RIGHT, " +
data.id +
", false)' id='pr" +
data.id +
"'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(LEFT, " +
data.id +
", true)' onmouseup='padclick(LEFT, " +
data.id +
", false)' id='pl" +
data.id +
"'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(DOWN, " +
data.id +
", true)' onmouseup='padclick(DOWN, " +
data.id +
", false)' id='pb" +
data.id +
"'>&#9650;</a></li>" +
"</ul>" +
(data.type == UI_CPAD
? "<a class='confirm' onmousedown='padclick(CENTER," +
data.id +
", true)' onmouseup='padclick(CENTER, " +
data.id +
", false)' id='pc" +
data.id +
"'>OK</a>"
: "") +
"</nav>" +
"</div>"
);
$("#pf" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(UP, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(UP, data.id, false);
},
});
$("#pl" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(LEFT, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(LEFT, data.id, false);
},
});
$("#pr" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(RIGHT, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(RIGHT, data.id, false);
},
});
$("#pb" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(DOWN, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(DOWN, data.id, false);
},
});
$("#pc" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(CENTER, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(CENTER, data.id, false);
},
});
}
if (data.visible) {
addToHTML(data);
$("#pf" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(UP, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(UP, data.id, false);
},
});
$("#pl" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(LEFT, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(LEFT, data.id, false);
},
});
$("#pr" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(RIGHT, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(RIGHT, data.id, false);
},
});
$("#pb" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(DOWN, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(DOWN, data.id, false);
},
});
$("#pc" + data.id).on({
touchstart: function (e) {
e.preventDefault();
padclick(CENTER, data.id, true);
},
touchend: function (e) {
e.preventDefault();
padclick(CENTER, data.id, false);
},
});
}
break;
//https://codepen.io/seanstopnik/pen/CeLqA
case UI_SLIDER:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
//https://codepen.io/seanstopnik/pen/CeLqA
if (data.visible) {
addToHTML(data);
rangeSlider(!sliderContinuous);
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter card-slider " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<div class='range-slider'>" +
"<input id='sl" +
data.id +
"' type='range' min='0' max='100' value='" +
data.value +
"' " + elementStyle + " class='range-slider__range'>" +
"<span class='range-slider__value'>" +
data.value +
"</span>" +
"</div>" +
"</div>"
);
rangeSlider(!sliderContinuous);
}
break;
case UI_NUMBER:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<input style='color:black;' " + elementStyle + " id='num" +
data.id +
"' type='number' value='" +
data.value +
"' onchange='numberchange(" +
data.id +
")' />" +
"</div>"
);
}
break;
case UI_TEXT_INPUT:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<input style='color:black;' " + elementStyle + " id='text" +
data.id +
"' value='" +
data.value +
"' onchange='textchange(" +
data.id +
")' />" +
"</div>"
);
}
break;
case UI_TAB:
if (data.visible) {
$("#tabsnav").append(
"<li><a onmouseup='tabclick(" + data.id + ")' href='#tab" + data.id + "'>" + data.value + "</a></li>"
);
$("#tabscontent").append("<div id='tab" + data.id + "'></div>");
if (data.visible) {
$("#tabsnav").append(
"<li><a onmouseup='tabclick(" + data.id + ")' href='#tab" + data.id + "'>" + data.value + "</a></li>"
);
$("#tabscontent").append("<div id='tab" + data.id + "'></div>");
tabs = $(".tabscontent").tabbedContent({ loop: true }).data("api");
// switch to tab...
$("a")
.filter(function () {
return $(this).attr("href") === "#click-to-switch";
})
.on("click", function (e) {
var tab = prompt("Tab to switch to (number or id)?");
if (!tabs.switchTab(tab)) {
alert("That tab does not exist :\\");
}
e.preventDefault();
});
}
break;
case UI_SELECT:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<select style='color:black;' " + elementStyle + " id='select" +
data.id +
"' onchange='selectchange(" +
data.id +
")' />" +
"</div>"
);
}
tabs = $(".tabscontent").tabbedContent({ loop: true }).data("api");
// switch to tab...
$("a")
.filter(function () {
return $(this).attr("href") === "#click-to-switch";
})
.on("click", function (e) {
var tab = prompt("Tab to switch to (number or id)?");
if (!tabs.switchTab(tab)) {
alert("That tab does not exist :\\");
}
e.preventDefault();
});
}
break;
case UI_OPTION:
@ -677,35 +441,13 @@ function start() {
}
}
break;
case UI_GRAPH:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
if (data.visible) {
addToHTML(data);
graphData[data.id] = restoreGraphData(data.id);
renderGraphSvg(graphData[data.id], "graph" + data.id);
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"<figure id='graph" +
data.id +
"'>" +
"<figcaption>" +
data.label +
"</figcaption>" +
"</figure>" +
"</div>"
);
graphData[data.id] = restoreGraphData(data.id);
renderGraphSvg(graphData[data.id], "graph" + data.id);
}
break;
case ADD_GRAPH_POINT:
var ts = Math.round(new Date().getTime() / 1000);
@ -718,68 +460,19 @@ function start() {
saveGraphData();
renderGraphSvg(graphData[data.id], "graph" + data.id);
break;
case UI_GAUGE:
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"WILL BE A GAUGE <input style='color:black;' id='gauge" +
data.id +
"' type='number' value='" +
data.value +
"' onchange='numberchange(" +
data.id +
")' />" +
"</div>"
);
}
break;
case UI_ACCEL:
if (hasAccel) break;
var parent;
if (data.parentControl) {
parent = $("#tab" + data.parentControl);
} else {
parent = $("#row");
}
hasAccel = true;
if (data.visible) {
parent.append(
"<div id='id" +
data.id +
"' " + panelStyle + " class='two columns card tcenter " +
colorClass(data.color) +
"'>" +
"<h5>" +
data.label +
"</h5><hr/>" +
"ACCEL // Not implemented fully!<div class='accelerometer' id='accel" +
data.id +
"' ><div class='ball" +
data.id +
"'></div><pre class='accelerometeroutput" +
data.id +
"'></pre>" +
"</div>"
);
requestOrientationPermission();
}
if (data.visible) {
addToHTML(data);
requestOrientationPermission();
}
break;
/*
* Update messages change the value/style of a component without adding new HTML
*/
case UPDATE_LABEL:
$("#l" + data.id).html(data.value);
if(data.hasOwnProperty('elementStyle')) {
@ -964,3 +657,109 @@ var rangeSlider = function (isDiscrete) {
}
});
};
var addToHTML = function(data) {
panelStyle = data.hasOwnProperty('panelStyle') ? " style='" + data.panelStyle + "' " : "";
elementStyle = data.hasOwnProperty('elementStyle') ? " style='" + data.elementStyle + "' " : "";
panelwide = data.hasOwnProperty('wide') ? "wide" : "";
if(!data.hasOwnProperty('parentControl') || $("#tab" + data.parentControl).length > 0) {
//We add the control with its own panel
var parent = data.hasOwnProperty('parentControl') ?
$("#tab" + data.parentControl) :
$("#row");
var html = "";
switch(data.type) {
case UI_LABEL:
case UI_BUTTON:
case UI_SWITCHER:
case UI_CPAD:
case UI_PAD:
case UI_SLIDER:
case UI_NUMBER:
case UI_TEXT_INPUT:
case UI_SELECT:
case UI_GRAPH:
case UI_GAUGE:
case UI_ACCEL:
html = "<div id='id" + data.id + "' " + panelStyle + " class='two columns " + panelwide + " card tcenter " +
colorClass(data.color) + "'><h5>" + data.label + "</h5><hr/>" +
elementHTML(data.type, data.id, data.value, elementStyle) +
"</div>";
break;
case UI_SEPARATOR:
html = "<div id='id" + data.id + "' " + panelStyle + " class='sectionbreak columns'>" +
"<h5>" + data.label + "</h5><hr/></div>";
break;
}
parent.append(html);
} else {
//We are adding to an existing panel so we only need the HTML for the element
var parent = $("#id" + data.parentControl);
parent.append(elementHTML(data.type, data.id, data.value, elementStyle));
}
}
var elementHTML = function(type, id, value, elementStyle) {
switch(type) {
case UI_LABEL:
return "<span id='l" + id + "' " + elementStyle +
" class='label label-wrap'>" + value + "</span>";
case UI_BUTTON:
return "<button id='btn" + id + "' " + elementStyle +
" onmousedown='buttonclick(" + id + ", true)'" +
" onmouseup='buttonclick(" + id + ", false)'>" +
value + "</button>";
case UI_SWITCHER:
return "<label id='sl" + id + "' " + elementStyle +
" class='switch " + (value == "1" ? "checked" : "") + "'>" +
"<div class='in'>" +
"<input type='checkbox' id='s" + id + "' onClick='switcher(" + id + ",null)' " +
(value == "1" ? "checked" : "") + "/></div></label>";
case UI_CPAD:
case UI_PAD:
return "<nav class='control'><ul>" +
"<li><a onmousedown='padclick(UP, " + id + ", true)' " +
"onmouseup='padclick(UP, " + id + ", false)' id='pf" + id + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(RIGHT, " + id + ", true)' " +
"onmouseup='padclick(RIGHT, " + id + ", false)' id='pr" + id + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(LEFT, " + id + ", true)' " +
"onmouseup='padclick(LEFT, " + id + ", false)' id='pl" + id + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(DOWN, " + id + ", true)' " +
"onmouseup='padclick(DOWN, " + id + ", false)' id='pb" + id + "'>&#9650;</a></li>" +
"</ul>" +
(type == UI_CPAD
? "<a class='confirm' onmousedown='padclick(CENTER," + id + ", true)' " +
"onmouseup='padclick(CENTER, " + id + ", false)' id='pc" + id + "'>OK</a>"
: "") +
"</nav>";
case UI_SLIDER:
return "<div class='range-slider'>" +
"<input id='sl" + id + "' type='range' min='0' max='100' value='" + value + "' " +
elementStyle + " class='range-slider__range'><span class='range-slider__value'>" +
value + "</span></div>";
case UI_NUMBER:
return "<input style='color:black;' " + elementStyle + " id='num" + id +
"' type='number' value='" + value + "' onchange='numberchange(" + id + ")' />";
case UI_TEXT_INPUT:
return "<input style='color:black;' " + elementStyle + " id='text" + id +
"' value='" + value + "' onchange='textchange(" + id + ")' />";
case UI_SELECT:
return "<select style='color:black;' " + elementStyle + " id='select" + id +
"' onchange='selectchange(" + id + ")' />";
case UI_GRAPH:
return "<figure id='graph" + id + "'><figcaption>" + label + "</figcaption></figure>";
case UI_GAUGE:
return "WILL BE A GAUGE <input style='color:black;' id='gauge" + id +
"' type='number' value='" + value + "' onchange='numberchange(" + id + ")' />";
case UI_ACCEL:
return "ACCEL // Not implemented fully!<div class='accelerometer' id='accel" + id +
"' ><div class='ball" + id + "'></div><pre class='accelerometeroutput" + id + "'></pre>";
default:
return "";
}
}

View File

@ -1,4 +1,4 @@
const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;const UI_EXTEND_GUI=210;const UI_TITEL=0;const UI_PAD=1;const UPDATE_PAD=101;const UI_CPAD=2;const UPDATE_CPAD=102;const UI_BUTTON=3;const UPDATE_BUTTON=103;const UI_LABEL=4;const UPDATE_LABEL=104;const UI_SWITCHER=5;const UPDATE_SWITCHER=105;const UI_SLIDER=6;const UPDATE_SLIDER=106;const UI_NUMBER=7;const UPDATE_NUMBER=107;const UI_TEXT_INPUT=8;const UPDATE_TEXT_INPUT=108;const UI_GRAPH=9;const ADD_GRAPH_POINT=10;const CLEAR_GRAPH=109;const UI_TAB=11;const UPDATE_TAB=111;const UI_SELECT=12;const UPDATE_SELECT=112;const UI_OPTION=13;const UPDATE_OPTION=113;const UI_MIN=14;const UPDATE_MIN=114;const UI_MAX=15;const UPDATE_MAX=115;const UI_STEP=16;const UPDATE_STEP=116;const UI_GAUGE=17;const UPDATE_GAUGE=117;const UI_ACCEL=18;const UPTDATE_ACCEL=117;const UP=0;const DOWN=1;const LEFT=2;const RIGHT=3;const CENTER=4;const C_TURQUOISE=0;const C_EMERALD=1;const C_PETERRIVER=2;const C_WETASPHALT=3;const C_SUNFLOWER=4;const C_CARROT=5;const C_ALIZARIN=6;const C_DARK=7;const C_NONE=255;var graphData=new Array();var hasAccel=false;var sliderContinuous=false;function colorClass(colorId){colorId=Number(colorId);switch(colorId){case C_TURQUOISE:return"turquoise";case C_EMERALD:return"emerald";case C_PETERRIVER:return"peterriver";case C_WETASPHALT:return"wetasphalt";case C_SUNFLOWER:return"sunflower";case C_CARROT:return"carrot";case C_ALIZARIN:return"alizarin";case C_NONE:return"dark";default:return"";}}
const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;const UI_EXTEND_GUI=210;const UI_TITEL=0;const UI_PAD=1;const UPDATE_PAD=101;const UI_CPAD=2;const UPDATE_CPAD=102;const UI_BUTTON=3;const UPDATE_BUTTON=103;const UI_LABEL=4;const UPDATE_LABEL=104;const UI_SWITCHER=5;const UPDATE_SWITCHER=105;const UI_SLIDER=6;const UPDATE_SLIDER=106;const UI_NUMBER=7;const UPDATE_NUMBER=107;const UI_TEXT_INPUT=8;const UPDATE_TEXT_INPUT=108;const UI_GRAPH=9;const ADD_GRAPH_POINT=10;const CLEAR_GRAPH=109;const UI_TAB=11;const UPDATE_TAB=111;const UI_SELECT=12;const UPDATE_SELECT=112;const UI_OPTION=13;const UPDATE_OPTION=113;const UI_MIN=14;const UPDATE_MIN=114;const UI_MAX=15;const UPDATE_MAX=115;const UI_STEP=16;const UPDATE_STEP=116;const UI_GAUGE=17;const UPDATE_GAUGE=117;const UI_ACCEL=18;const UPDATE_ACCEL=118;const UI_SEPARATOR=19;const UPDATE_SEPARATOR=119;const UP=0;const DOWN=1;const LEFT=2;const RIGHT=3;const CENTER=4;const C_TURQUOISE=0;const C_EMERALD=1;const C_PETERRIVER=2;const C_WETASPHALT=3;const C_SUNFLOWER=4;const C_CARROT=5;const C_ALIZARIN=6;const C_DARK=7;const C_NONE=255;var graphData=new Array();var hasAccel=false;var sliderContinuous=false;function colorClass(colorId){colorId=Number(colorId);switch(colorId){case C_TURQUOISE:return"turquoise";case C_EMERALD:return"emerald";case C_PETERRIVER:return"peterriver";case C_WETASPHALT:return"wetasphalt";case C_SUNFLOWER:return"sunflower";case C_CARROT:return"carrot";case C_ALIZARIN:return"alizarin";case C_NONE:return"dark";default:return"";}}
var websock;var websockConnected=false;function requestOrientationPermission(){}
function saveGraphData(){localStorage.setItem("espuigraphs",JSON.stringify(graphData));}
function restoreGraphData(id){var savedData=localStorage.getItem("espuigraphs",graphData);if(savedData!=null){savedData=JSON.parse(savedData);return savedData[id];}
@ -7,185 +7,13 @@ function restart(){$(document).add("*").off();$("#row").html("");websock.close()
function conStatusError(){websockConnected=false;$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection &#8635;");$("#conStatus").off();$("#conStatus").on({click:restart,});}
function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}}
function start(){document.addEventListener("visibilitychange",handleVisibilityChange,false);if(window.location.port!=""||window.location.port!=80||window.location.port!=443){websock=new WebSocket("ws://"+window.location.hostname+":"+window.location.port+"/ws");}else{websock=new WebSocket("ws://"+window.location.hostname+"/ws");}
websock.onopen=function(evt){console.log("websock open");$("#conStatus").addClass("color-green");$("#conStatus").text("Connected");websockConnected=true;};websock.onclose=function(evt){console.log("websock close");conStatusError();};websock.onerror=function(evt){console.log(evt);conStatusError();};var handleEvent=function(evt){console.log(evt);var data=JSON.parse(evt.data);var e=document.body;var center="";panelStyle=data.hasOwnProperty('panelStyle')?" style='"+data.panelStyle+"'":"";elementStyle=data.hasOwnProperty('elementStyle')?" style='"+data.elementStyle+"'":"";switch(data.type){case UI_INITIAL_GUI:$("#row").html("");$("#tabsnav").html("");$("#tabscontent").html("");if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;}
data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_EXTEND_GUI:data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<span id='l"+
data.id+
"' "+elementStyle+" class='label label-wrap'>"+
data.value+
"</span>"+
"</div>");}
break;case UI_BUTTON:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='one columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<button id='btn"+
data.id+
"' "+elementStyle+" "+
"onmousedown='buttonclick("+
data.id+
", true)' "+
"onmouseup='buttonclick("+
data.id+
", false)'>"+
data.value+
"</button></div>");$("#btn"+data.id).on({touchstart:function(e){e.preventDefault();buttonclick(data.id,true);},touchend:function(e){e.preventDefault();buttonclick(data.id,false);},});}
break;case UI_SWITCHER:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='one columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<label id='sl"+
data.id+
"' "+elementStyle+" class='switch "+
(data.value=="1"?"checked":"")+
"'>"+
"<div class='in'><input type='checkbox' id='s"+
data.id+
"' onClick='switcher("+
data.id+
",null)' "+
(data.value=="1"?"checked":"")+
"/></div>"+
"</label>"+
"</div>");switcher(data.id,data.value);}
break;case UI_CPAD:case UI_PAD:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<nav class='control'>"+
"<ul>"+
"<li><a onmousedown='padclick(UP, "+
data.id+
", true)' onmouseup='padclick(UP, "+
data.id+
", false)' id='pf"+
data.id+
"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(RIGHT, "+
data.id+
", true)' onmouseup='padclick(RIGHT, "+
data.id+
", false)' id='pr"+
data.id+
"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(LEFT, "+
data.id+
", true)' onmouseup='padclick(LEFT, "+
data.id+
", false)' id='pl"+
data.id+
"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(DOWN, "+
data.id+
", true)' onmouseup='padclick(DOWN, "+
data.id+
", false)' id='pb"+
data.id+
"'>&#9650;</a></li>"+
"</ul>"+
(data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+
data.id+
", true)' onmouseup='padclick(CENTER, "+
data.id+
", false)' id='pc"+
data.id+
"'>OK</a>":"")+
"</nav>"+
"</div>");$("#pf"+data.id).on({touchstart:function(e){e.preventDefault();padclick(UP,data.id,true);},touchend:function(e){e.preventDefault();padclick(UP,data.id,false);},});$("#pl"+data.id).on({touchstart:function(e){e.preventDefault();padclick(LEFT,data.id,true);},touchend:function(e){e.preventDefault();padclick(LEFT,data.id,false);},});$("#pr"+data.id).on({touchstart:function(e){e.preventDefault();padclick(RIGHT,data.id,true);},touchend:function(e){e.preventDefault();padclick(RIGHT,data.id,false);},});$("#pb"+data.id).on({touchstart:function(e){e.preventDefault();padclick(DOWN,data.id,true);},touchend:function(e){e.preventDefault();padclick(DOWN,data.id,false);},});$("#pc"+data.id).on({touchstart:function(e){e.preventDefault();padclick(CENTER,data.id,true);},touchend:function(e){e.preventDefault();padclick(CENTER,data.id,false);},});}
break;case UI_SLIDER:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter card-slider "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<div class='range-slider'>"+
"<input id='sl"+
data.id+
"' type='range' min='0' max='100' value='"+
data.value+
"' "+elementStyle+" class='range-slider__range'>"+
"<span class='range-slider__value'>"+
data.value+
"</span>"+
"</div>"+
"</div>");rangeSlider(!sliderContinuous);}
break;case UI_NUMBER:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<input style='color:black;' "+elementStyle+" id='num"+
data.id+
"' type='number' value='"+
data.value+
"' onchange='numberchange("+
data.id+
")' />"+
"</div>");}
break;case UI_TEXT_INPUT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<input style='color:black;' "+elementStyle+" id='text"+
data.id+
"' value='"+
data.value+
"' onchange='textchange("+
data.id+
")' />"+
"</div>");}
websock.onopen=function(evt){console.log("websock open");$("#conStatus").addClass("color-green");$("#conStatus").text("Connected");websockConnected=true;};websock.onclose=function(evt){console.log("websock close");conStatusError();};websock.onerror=function(evt){console.log(evt);conStatusError();};var handleEvent=function(evt){console.log(evt);var data=JSON.parse(evt.data);var e=document.body;var center="";switch(data.type){case UI_INITIAL_GUI:$("#row").html("");$("#tabsnav").html("");$("#tabscontent").html("");if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;}
data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_EXTEND_GUI:data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GAUGE:case UI_SEPARATOR:if(data.visible)addToHTML(data);break;case UI_BUTTON:if(data.visible){addToHTML(data);$("#btn"+data.id).on({touchstart:function(e){e.preventDefault();buttonclick(data.id,true);},touchend:function(e){e.preventDefault();buttonclick(data.id,false);},});}
break;case UI_SWITCHER:if(data.visible){addToHTML(data);switcher(data.id,data.value);}
break;case UI_CPAD:case UI_PAD:if(data.visible){addToHTML(data);$("#pf"+data.id).on({touchstart:function(e){e.preventDefault();padclick(UP,data.id,true);},touchend:function(e){e.preventDefault();padclick(UP,data.id,false);},});$("#pl"+data.id).on({touchstart:function(e){e.preventDefault();padclick(LEFT,data.id,true);},touchend:function(e){e.preventDefault();padclick(LEFT,data.id,false);},});$("#pr"+data.id).on({touchstart:function(e){e.preventDefault();padclick(RIGHT,data.id,true);},touchend:function(e){e.preventDefault();padclick(RIGHT,data.id,false);},});$("#pb"+data.id).on({touchstart:function(e){e.preventDefault();padclick(DOWN,data.id,true);},touchend:function(e){e.preventDefault();padclick(DOWN,data.id,false);},});$("#pc"+data.id).on({touchstart:function(e){e.preventDefault();padclick(CENTER,data.id,true);},touchend:function(e){e.preventDefault();padclick(CENTER,data.id,false);},});}
break;case UI_SLIDER:if(data.visible){addToHTML(data);rangeSlider(!sliderContinuous);}
break;case UI_TAB:if(data.visible){$("#tabsnav").append("<li><a onmouseup='tabclick("+data.id+")' href='#tab"+data.id+"'>"+data.value+"</a></li>");$("#tabscontent").append("<div id='tab"+data.id+"'></div>");tabs=$(".tabscontent").tabbedContent({loop:true}).data("api");$("a").filter(function(){return $(this).attr("href")==="#click-to-switch";}).on("click",function(e){var tab=prompt("Tab to switch to (number or id)?");if(!tabs.switchTab(tab)){alert("That tab does not exist :\\");}
e.preventDefault();});}
break;case UI_SELECT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<select style='color:black;' "+elementStyle+" id='select"+
data.id+
"' onchange='selectchange("+
data.id+
")' />"+
"</div>");}
break;case UI_OPTION:if(data.parentControl){var parent=$("#select"+data.parentControl);parent.append("<option id='option"+
data.id+
"' value='"+
@ -198,57 +26,8 @@ data.label+
break;case UI_MIN:if(data.parentControl){var parent=$("#id"+data.parentControl+" input");if(parent.size()){parent.attr("min",data.value);}}
break;case UI_MAX:if(data.parentControl){var parent=$("#id"+data.parentControl+" input");if(parent.size()){parent.attr("max",data.value);}}
break;case UI_STEP:if(data.parentControl){var parent=$("#id"+data.parentControl+" input");if(parent.size()){parent.attr("step",data.value);}}
break;case UI_GRAPH:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"<figure id='graph"+
data.id+
"'>"+
"<figcaption>"+
data.label+
"</figcaption>"+
"</figure>"+
"</div>");graphData[data.id]=restoreGraphData(data.id);renderGraphSvg(graphData[data.id],"graph"+data.id);}
break;case ADD_GRAPH_POINT:var ts=Math.round(new Date().getTime()/1000);graphData[data.id].push({x:ts,y:data.value});saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case CLEAR_GRAPH:graphData[data.id]=[];saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case UI_GAUGE:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"WILL BE A GAUGE <input style='color:black;' id='gauge"+
data.id+
"' type='number' value='"+
data.value+
"' onchange='numberchange("+
data.id+
")' />"+
"</div>");}
break;case UI_ACCEL:if(hasAccel)break;var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
hasAccel=true;if(data.visible){parent.append("<div id='id"+
data.id+
"' "+panelStyle+" class='two columns card tcenter "+
colorClass(data.color)+
"'>"+
"<h5>"+
data.label+
"</h5><hr/>"+
"ACCEL // Not implemented fully!<div class='accelerometer' id='accel"+
data.id+
"' ><div class='ball"+
data.id+
"'></div><pre class='accelerometeroutput"+
data.id+
"'></pre>"+
"</div>");requestOrientationPermission();}
break;case UI_GRAPH:if(data.visible){addToHTML(data);graphData[data.id]=restoreGraphData(data.id);renderGraphSvg(graphData[data.id],"graph"+data.id);}
break;case ADD_GRAPH_POINT:var ts=Math.round(new Date().getTime()/1000);graphData[data.id].push({x:ts,y:data.value});saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case CLEAR_GRAPH:graphData[data.id]=[];saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case UI_ACCEL:if(hasAccel)break;hasAccel=true;if(data.visible){addToHTML(data);requestOrientationPermission();}
break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);if(data.hasOwnProperty('elementStyle')){$("#l"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_SLIDER:slider_move($("#id"+data.id),data.value,"100",false);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
@ -269,4 +48,38 @@ function buttonclick(number,isdown){if(isdown)websock.send("bdown:"+number);else
function padclick(type,number,isdown){switch(type){case CENTER:if(isdown)websock.send("pcdown:"+number);else websock.send("pcup:"+number);break;case UP:if(isdown)websock.send("pfdown:"+number);else websock.send("pfup:"+number);break;case DOWN: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;}}
function switcher(number,state){if(state==null){if($("#s"+number).is(":checked")){websock.send("sactive:"+number);$("#sl"+number).addClass("checked");}else{websock.send("sinactive:"+number);$("#sl"+number).removeClass("checked");}}else if(state==1){$("#sl"+number).addClass("checked");$("#sl"+number).prop("checked",true);}else if(state==0){$("#sl"+number).removeClass("checked");$("#sl"+number).prop("checked",false);}}
var rangeSlider=function(isDiscrete){var range=$(".range-slider__range");var slidercb=function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));};range.on({input:function(){$(this).next().html(this.value)}});range.each(function(){$(this).next().html(this.value);if($(this).attr("callbackSet")!="true"){if(!isDiscrete){$(this).on({input:slidercb});}else{$(this).on({change:slidercb});}
$(this).attr("callbackSet","true");}});};
$(this).attr("callbackSet","true");}});};var addToHTML=function(data){panelStyle=data.hasOwnProperty('panelStyle')?" style='"+data.panelStyle+"' ":"";elementStyle=data.hasOwnProperty('elementStyle')?" style='"+data.elementStyle+"' ":"";panelwide=data.hasOwnProperty('wide')?"wide":"";if(!data.hasOwnProperty('parentControl')||$("#tab"+data.parentControl).length>0){var parent=data.hasOwnProperty('parentControl')?$("#tab"+data.parentControl):$("#row");var html="";switch(data.type){case UI_LABEL:case UI_BUTTON:case UI_SWITCHER:case UI_CPAD:case UI_PAD:case UI_SLIDER:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GRAPH:case UI_GAUGE:case UI_ACCEL:html="<div id='id"+data.id+"' "+panelStyle+" class='two columns "+panelwide+" card tcenter "+
colorClass(data.color)+"'><h5>"+data.label+"</h5><hr/>"+
elementHTML(data.type,data.id,data.value,elementStyle)+
"</div>";break;case UI_SEPARATOR:html="<div id='id"+data.id+"' "+panelStyle+" class='sectionbreak columns'>"+
"<h5>"+data.label+"</h5><hr/></div>";break;}
parent.append(html);}else{var parent=$("#id"+data.parentControl);parent.append(elementHTML(data.type,data.id,data.value,elementStyle));}}
var elementHTML=function(type,id,value,elementStyle){switch(type){case UI_LABEL:return"<span id='l"+id+"' "+elementStyle+
" class='label label-wrap'>"+value+"</span>";case UI_BUTTON:return"<button id='btn"+id+"' "+elementStyle+
" onmousedown='buttonclick("+id+", true)'"+
" onmouseup='buttonclick("+id+", false)'>"+
value+"</button>";case UI_SWITCHER:return"<label id='sl"+id+"' "+elementStyle+
" class='switch "+(value=="1"?"checked":"")+"'>"+
"<div class='in'>"+
"<input type='checkbox' id='s"+id+"' onClick='switcher("+id+",null)' "+
(value=="1"?"checked":"")+"/></div></label>";case UI_CPAD:case UI_PAD:return"<nav class='control'><ul>"+
"<li><a onmousedown='padclick(UP, "+id+", true)' "+
"onmouseup='padclick(UP, "+id+", false)' id='pf"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(RIGHT, "+id+", true)' "+
"onmouseup='padclick(RIGHT, "+id+", false)' id='pr"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(LEFT, "+id+", true)' "+
"onmouseup='padclick(LEFT, "+id+", false)' id='pl"+id+"'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(DOWN, "+id+", true)' "+
"onmouseup='padclick(DOWN, "+id+", false)' id='pb"+id+"'>&#9650;</a></li>"+
"</ul>"+
(type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+id+", true)' "+
"onmouseup='padclick(CENTER, "+id+", false)' id='pc"+id+"'>OK</a>":"")+
"</nav>";case UI_SLIDER:return"<div class='range-slider'>"+
"<input id='sl"+id+"' type='range' min='0' max='100' value='"+value+"' "+
elementStyle+" class='range-slider__range'><span class='range-slider__value'>"+
value+"</span></div>";case UI_NUMBER:return"<input style='color:black;' "+elementStyle+" id='num"+id+
"' type='number' value='"+value+"' onchange='numberchange("+id+")' />";case UI_TEXT_INPUT:return"<input style='color:black;' "+elementStyle+" id='text"+id+
"' value='"+value+"' onchange='textchange("+id+")' />";case UI_SELECT:return"<select style='color:black;' "+elementStyle+" id='select"+id+
"' onchange='selectchange("+id+")' />";case UI_GRAPH:return"<figure id='graph"+id+"'><figcaption>"+label+"</figcaption></figure>";case UI_GAUGE:return"WILL BE A GAUGE <input style='color:black;' id='gauge"+id+
"' type='number' value='"+value+"' onchange='numberchange("+id+")' />";case UI_ACCEL:return"ACCEL // Not implemented fully!<div class='accelerometer' id='accel"+id+
"' ><div class='ball"+id+"'></div><pre class='accelerometeroutput"+id+"'></pre>";default:return"";}}

BIN
docs/ui_groupedbuttons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/ui_groupedbuttons2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
docs/ui_separators.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/ui_widecontrols.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -714,6 +714,10 @@ uint16_t ESPUIClass::gauge(const char* label, ControlColor color, int number, in
return numberId;
}
uint16_t ESPUIClass::separator(const char* label) {
return addControl(ControlType::Separator, label, "", ControlColor::Alizarin, Control::noParent, nullptr);
}
uint16_t ESPUIClass::accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color)
{
return addControl(ControlType::Accel, label, "", color, Control::noParent, callback);
@ -821,6 +825,14 @@ void ESPUIClass::setElementStyle(uint16_t id, String style, int clientId)
}
}
void ESPUIClass::setPanelWide(uint16_t id, bool wide) {
Control* control = getControl(id);
if (control)
{
control->wide = wide;
}
}
void ESPUIClass::updateControl(uint16_t id, int clientId)
{
Control* control = getControl(id);
@ -1034,6 +1046,8 @@ Control* ESPUIClass::prepareJSONChunk(AsyncWebSocketClient* client, Control* con
item["panelStyle"] = String(control->panelStyle);
if (control->elementStyle != 0)
item["elementStyle"] = String(control->elementStyle);
if (control->wide == true)
item["wide"] = true;
if (control->parentControl != Control::noParent)
{

View File

@ -55,6 +55,7 @@ enum ControlType : uint8_t
Step,
Gauge,
Accel,
Separator,
UpdateOffset = 100,
UpdatePad = 101,
@ -74,6 +75,7 @@ enum ControlType : uint8_t
UpdateStep,
UpdateGauge,
UpdateAccel,
UpdateSeparator,
InitialGui = 200,
Reload = 201,
@ -136,6 +138,7 @@ public:
String value;
ControlColor color;
bool visible;
bool wide;
uint16_t parentControl;
String panelStyle;
String elementStyle;
@ -151,6 +154,7 @@ public:
value(value),
color(color),
visible(visible),
wide(false),
parentControl(parentControl),
next(nullptr)
{
@ -257,6 +261,7 @@ public:
uint16_t graph(const char* label, ControlColor color); // Create Graph display
uint16_t gauge(const char* label, ControlColor color, int value, int min = 0,
int max = 100); // Create Gauge display
uint16_t separator(const char* label); //Create separator
// Input only
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color);
@ -287,6 +292,8 @@ public:
void setPanelStyle(uint16_t id, String style, int clientId = -1);
void setElementStyle(uint16_t id, String style, int clientId = -1);
void setPanelWide(uint16_t id, bool wide);
// Variables
const char* ui_title = "ESPUI"; // Store UI Title and Header Name
Control* controls = nullptr;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long