`+
+ `
`+
- `
`+
+ `
`+
`
${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};`+
(inst.n ? inst.n : "Segment "+i) +
`
`+
`
ɸ${String.fromCharCode(inst.set+"A".charCodeAt(0))};`+
`
➊➋➌➍
`+
`
`+
- `
`+
+ `
`+
`
`+
- `
`+
+ `
`+
(cfg.comp.segpwr ? segp : '') +
- `
`+
+ `
`+
`
`+
`
`+
``+
@@ -834,6 +869,7 @@ function populateSegments(s)
}
gId('segcont').innerHTML = cn;
+ gId("segcont").classList.remove("hide");
let noNewSegs = (lowestUnused >= maxSeg);
resetUtil(noNewSegs);
if (gId('selall')) gId('selall').checked = true;
@@ -847,6 +883,8 @@ function populateSegments(s)
if (segCount < 2) {
gId(`segd${lSeg}`).classList.add("hide");
if (parseInt(gId("seg0bri").value)==255) gId(`segp0`).classList.add("hide");
+ // hide segment controls if there is only one segment in simplified UI
+ if (simplifiedUI) gId("segcont").classList.add("hide");
}
if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value) 1) ? "block":"none"; // rsbtn parent
@@ -1258,6 +1296,12 @@ function updateSelectedPalette(s)
var selectedPalette = parent.querySelector(`.lstI[data-id="${s}"]`);
if (selectedPalette) parent.querySelector(`.lstI[data-id="${s}"]`).classList.add('selected');
+ // Display selected palette name on button in simplified UI
+ let selectedName = selectedPalette.querySelector(".lstIname").innerText;
+ if (simplifiedUI) {
+ gId("palwbtn").innerText = "Palette: " + selectedName;
+ }
+
// in case of special palettes (* Colors...), force show color selectors (if hidden by effect data)
let cd = gId('csl').children; // color selectors
if (s > 1 && s < 6) {
@@ -1299,8 +1343,15 @@ function updateSelectedFx()
}
}
});
- // hide 2D mapping and/or sound simulation options
var selectedName = selectedEffect.querySelector(".lstIname").innerText;
+
+ // Display selected effect name on button in simplified UI
+ let selectedNameOnlyAscii = selectedName.replace(/[^\x00-\x7F]/g, "");
+ if (simplifiedUI) {
+ gId("fxbtn").innerText = "Effect: " + selectedNameOnlyAscii;
+ }
+
+ // hide 2D mapping and/or sound simulation options
var segs = gId("segcont").querySelectorAll(`div[data-map="map2D"]`);
for (const seg of segs) if (selectedName.indexOf("\u25A6")<0) seg.classList.remove('hide'); else seg.classList.add('hide');
var segs = gId("segcont").querySelectorAll(`div[data-snd="si"]`);
@@ -1441,25 +1492,31 @@ function readState(s,command=false)
gId('checkO3').checked = !(!i.o3);
if (s.error && s.error != 0) {
- var errstr = "";
- switch (s.error) {
- case 10:
- errstr = "Could not mount filesystem!";
- break;
- case 11:
- errstr = "Not enough space to save preset!";
- break;
- case 12:
- errstr = "Preset not found.";
- break;
- case 13:
- errstr = "Missing ir.json.";
- break;
- case 19:
- errstr = "A filesystem error has occured.";
- break;
+ var errstr = "";
+ switch (s.error) {
+ case 8:
+ errstr = "Effect RAM depleted!";
+ break;
+ case 9:
+ errstr = "JSON parsing error!";
+ break;
+ case 10:
+ errstr = "Could not mount filesystem!";
+ break;
+ case 11:
+ errstr = "Not enough space to save preset!";
+ break;
+ case 12:
+ errstr = "Preset not found.";
+ break;
+ case 13:
+ errstr = "Missing ir.json.";
+ break;
+ case 19:
+ errstr = "A filesystem error has occured.";
+ break;
}
- showToast('Error ' + s.error + ": " + errstr, true);
+ showToast('Error ' + s.error + ": " + errstr, true);
}
selectedPal = i.pal;
@@ -1530,6 +1587,7 @@ function setEffectParameters(idx)
// set the bottom position of selected effect (sticky) as the top of sliders div
function setSelectedEffectPosition() {
+ if (simplifiedUI) return;
let top = parseInt(getComputedStyle(gId("sliders")).height);
top += 5;
let sel = d.querySelector('#fxlist .selected');
@@ -1596,6 +1654,10 @@ function setEffectParameters(idx)
// disable palette list
text += ' not used';
palw.style.display = "none";
+ // Close palette dialog if not available
+ if (gId("palw").lastElementChild.tagName == "DIALOG") {
+ gId("palw").lastElementChild.close();
+ }
}
pall.innerHTML = icon + text;
// not all color selectors shown, hide palettes created from color selectors
@@ -1661,6 +1723,7 @@ function requestJson(command=null)
parseInfo(i);
populatePalettes(i);
if (isInfo) populateInfo(i);
+ if (simplifiedUI) simplifyUI();
}
var s = json.state ? json.state : json;
readState(s);
@@ -1673,8 +1736,13 @@ function requestJson(command=null)
});
},25);
reqsLegal = true;
+ retry = false;
})
.catch((e)=>{
+ if (!retry) {
+ retry = true;
+ setTimeout(requestJson,500);
+ }
showToast(e, true);
});
}
@@ -2093,7 +2161,7 @@ function selGrp(g)
var sel = gId(`segcont`).querySelectorAll(`div[data-set="${g}"]`);
var obj = {"seg":[]};
for (let i=0; i<=lSeg; i++) if (gId(`seg${i}`)) obj.seg.push({"id":i,"sel":false});
- if (sel) for (let s of sel||[]) {
+ for (let s of (sel||[])) {
let i = parseInt(s.id.substring(3));
obj.seg[i] = {"id":i,"sel":true};
}
@@ -2259,6 +2327,12 @@ function setFX(ind = null)
} else {
d.querySelector(`#fxlist input[name="fx"][value="${ind}"]`).checked = true;
}
+
+ // Close effect dialog in simplified UI
+ if (simplifiedUI) {
+ gId("fx").lastElementChild.close();
+ }
+
var obj = {"seg": {"fx": parseInt(ind), "fxdef": cfg.comp.fxdef}}; // fxdef sets effect parameters to default values
requestJson(obj);
}
@@ -2271,6 +2345,11 @@ function setPalette(paletteId = null)
d.querySelector(`#pallist input[name="palette"][value="${paletteId}"]`).checked = true;
}
+ // Close palette dialog in simplified UI
+ if (simplifiedUI) {
+ gId("palw").lastElementChild.close();
+ }
+
var obj = {"seg": {"pal": paletteId}};
requestJson(obj);
}
@@ -2722,8 +2801,10 @@ function search(field, listId = null) {
field.nextElementSibling.style.display = (field.value !== '') ? 'block' : 'none';
if (!listId) return;
+ const search = field.value !== '';
+
// clear filter if searching in fxlist
- if (listId === 'fxlist' && field.value !== '') {
+ if (listId === 'fxlist' && search) {
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { e.checked = false; });
}
@@ -2757,6 +2838,12 @@ function search(field, listId = null) {
sortedListItems.forEach(item => {
gId(listId).append(item);
});
+
+ // scroll to first search result
+ const firstVisibleItem = sortedListItems.find(item => item.style.display !== 'none' && !item.classList.contains('sticky') && !item.classList.contains('selected'));
+ if (firstVisibleItem && search) {
+ firstVisibleItem.scrollIntoView({ behavior: "instant", block: "center" });
+ }
}
function clean(clearButton) {
@@ -2903,7 +2990,7 @@ function hasIroClass(classList)
//required by rangetouch.js
function lock(e)
{
- if (pcMode) return;
+ if (pcMode || simplifiedUI) return;
var l = e.target.classList;
var pl = e.target.parentElement.classList;
@@ -2917,7 +3004,7 @@ function lock(e)
//required by rangetouch.js
function move(e)
{
- if(!locked || pcMode) return;
+ if(!locked || pcMode || simplifiedUI) return;
var clientX = unify(e).clientX;
var dx = clientX - x0;
var s = Math.sign(dx);
@@ -2963,7 +3050,7 @@ function togglePcMode(fromB = false)
gId('buttonPcm').className = (pcMode) ? "active":"";
gId('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
sCol('--bh', gId('bot').clientHeight + "px");
- _C.style.width = (pcMode)?'100%':'400%';
+ _C.style.width = (pcMode || simplifiedUI)?'100%':'400%';
}
function mergeDeep(target, ...sources)
@@ -3018,6 +3105,98 @@ function tooltip()
});
};
+// Transforms the default UI into the simple UI
+function simplifyUI() {
+ // Create dropdown dialog
+ function createDropdown(id, buttonText, dialogElements = null) {
+ // Create dropdown dialog
+ const dialog = document.createElement("dialog");
+ // Move every dialogElement to the dropdown dialog or if none are given, move all children of the element with the given id
+ if (dialogElements) {
+ dialogElements.forEach((e) => {
+ dialog.appendChild(e);
+ });
+ } else {
+ while (gId(id).firstChild) {
+ dialog.appendChild(gId(id).firstChild);
+ }
+ }
+
+ // Create button for the dropdown
+ const btn = document.createElement("button");
+ btn.id = id + "btn";
+ btn.classList.add("btn");
+ btn.innerText = buttonText;
+ function toggleDialog(e) {
+ if (e.target != btn && e.target != dialog) return;
+ if (dialog.open) {
+ dialog.close();
+ return;
+ }
+ // Prevent autofocus on dialog open
+ dialog.inert = true;
+ dialog.showModal();
+ dialog.inert = false;
+ clean(dialog.firstElementChild.children[1]);
+ dialog.scrollTop = 0;
+ };
+ btn.addEventListener("click", toggleDialog);
+ dialog.addEventListener("click", toggleDialog);
+
+ // Add the dialog and button to the element with the given id
+ gId(id).append(btn);
+ gId(id).append(dialog);
+ }
+
+ // Check if the UI was already simplified
+ if (gId("Colors").classList.contains("simplified")) return;
+
+ // Disable PC Mode as it does not exist in simple UI
+ if (pcMode) togglePcMode(true);
+ _C.style.width = '100%'
+ _C.style.setProperty('--n', 1);
+
+ gId("Colors").classList.add("simplified");
+ // Put effects below palett list
+ gId("Colors").append(gId("fx"));
+ gId("Colors").append(gId("sliders"));
+ // Put segments before palette list
+ gId("Colors").insertBefore(gId("segcont"), gId("pall"));
+ // Put preset quick load before palette list and segemts
+ gId("Colors").insertBefore(gId("pql"), gId("pall"));
+
+ // Create dropdown for palette list
+ createDropdown("palw", "Change palette");
+ createDropdown("fx", "Change effect", [gId("fxFind"), gId("fxlist")]);
+
+ // Hide pallete label
+ gId("pall").style.display = "none";
+ gId("Colors").insertBefore(document.createElement("br"), gId("pall"));
+ // Hide effect label
+ gId("modeLabel").style.display = "none";
+
+ // Hide buttons in top bar
+ gId("buttonNl").style.display = "none";
+ gId("buttonSync").style.display = "none";
+ gId("buttonSr").style.display = "none";
+ gId("buttonPcm").style.display = "none";
+
+ // Hide bottom bar
+ gId("bot").style.display = "none";
+ document.documentElement.style.setProperty('--bh', '0px');
+
+ // Hide other tabs
+ gId("Effects").style.display = "none";
+ gId("Segments").style.display = "none";
+ gId("Presets").style.display = "none";
+
+ // Hide filter options
+ gId("filters").style.display = "none";
+
+ // Hide buttons for pixel art and custom palettes (add / delete)
+ gId("btns").style.display = "none";
+}
+
size();
_C.style.setProperty('--n', N);
diff --git a/wled00/data/liveview.htm b/wled00/data/liveview.htm
index 60e9fb03e..8c10ba962 100644
--- a/wled00/data/liveview.htm
+++ b/wled00/data/liveview.htm
@@ -6,23 +6,33 @@
WLED Live Preview
-
+
-