Skip to content

Commit 0205435

Browse files
committed
Dynamic limit of LED output type
- wled#5014
1 parent 45b012b commit 0205435

File tree

1 file changed

+40
-26
lines changed

1 file changed

+40
-26
lines changed

wled00/data/settings_leds.htm

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
function gT(t) { for (let type of d.ledTypes) if (t == type.i) return type; } // getType from available ledTypes
1414
function isPWM(t) { return gT(t).t.charAt(0) === "A"; } // is PWM type
1515
function isAna(t) { return gT(t).t === "" || isPWM(t); } // is analog type
16-
function isDig(t) { return gT(t).t === "D" || isD2P(t); } // is digital type
16+
function isD1P(t) { return gT(t).t === "D"; } // is digital 1 pin type
1717
function isD2P(t) { return gT(t).t === "2P"; } // is digital 2 pin type
18+
function isDig(t) { return isD1P(t) || isD2P(t); } // is digital type
1819
function isNet(t) { return gT(t).t === "N"; } // is network type
1920
function isVir(t) { return gT(t).t === "V" || isNet(t); } // is virtual type
2021
function hasRGB(t) { return !!(gT(t).c & 0x01); } // has RGB
@@ -254,10 +255,10 @@
254255
}
255256

256257
// enable/disable LED fields
258+
updateTypeDropdowns(change);
257259
let dC = 0; // count of digital buses (for parallel I2S)
258260
let LTs = d.Sf.querySelectorAll("#mLC select[name^=LT]");
259261
LTs.forEach((s,i)=>{
260-
s.disabled = (i < LTs.length-1); // prevent changing type (as we can't update options)
261262
var n = s.name.substring(2,3); // bus number (0-Z)
262263
var t = parseInt(s.value);
263264
memu += getMem(t, n); // calc memory
@@ -405,17 +406,7 @@
405406
function addLEDs(n,init=true) {
406407
var o = gEBCN("iST");
407408
var i = o.length;
408-
let disable = (sel,opt) => { sel.querySelectorAll(opt).forEach((o)=>{o.disabled=true;}); }
409-
410409
var f = gId("mLC");
411-
let digitalB = 0, analogB = 0, twopinB = 0, virtB = 0;
412-
f.querySelectorAll("select[name^=LT]").forEach((s)=>{
413-
let t = s.value;
414-
if (isDig(t) && !isD2P(t)) digitalB++;
415-
if (isD2P(t)) twopinB++;
416-
if (isPWM(t)) analogB += numPins(t); // each GPIO is assigned to a channel
417-
if (isVir(t)) virtB++;
418-
});
419410

420411
if ((n==1 && i>=36) || (n==-1 && i==0)) return; // used to be i>=maxB+maxV when virtual buses were limited (now :"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
421412
var s = chrID(i);
@@ -424,7 +415,7 @@
424415
// npm run build has trouble minimizing spaces inside string
425416
var cn = `<div class="iST" draggable="true" ondragstart="hDS(event)" id="l${s}" style="cursor:grab;">
426417
<hr class="sml">
427-
<span id="n${s}">${i+1}</span>:
418+
<span id="n${s}">${++i}</span>:
428419
<select name="LT${s}" onchange="UI(true)"></select><br>
429420
<div id="abl${s}">
430421
mA/LED: <select name="LL${s}" onchange="enLA(this);UI();">
@@ -450,7 +441,7 @@
450441
<div id="dig${s}w" style="display:none">Swap: <select name="WO${s}"><option value="0">None</option><option value="1">W & B</option><option value="2">W & G</option><option value="3">W & R</option><option data-opt="CCT" value="4">WW & CW</option></select></div>
451442
<div id="dig${s}l" style="display:none">Clock: <select name="SP${s}"><option value="0">Slowest</option><option value="1">Slow</option><option value="2">Normal</option><option value="3">Fast</option><option value="4">Fastest</option></select></div>
452443
<div>
453-
<span id="psd${s}">Start:</span> <input type="number" name="LS${s}" id="ls${s}" class="l starts" min="0" max="8191" value="${lastEnd(i)}" oninput="startsDirty[${i}]=true;UI();" required />&nbsp;
444+
<span id="psd${s}">Start:</span> <input type="number" name="LS${s}" id="ls${s}" class="l starts" min="0" max="8191" value="${lastEnd(i-1)}" oninput="startsDirty[${i}]=true;UI();" required />&nbsp;
454445
<div id="dig${s}c" style="display:inline">Length: <input type="number" name="LC${s}" class="l" min="1" max="${maxPB}" value="1" required oninput="UI()" /></div><br>
455446
</div>
456447
<span id="p0d${s}">GPIO:</span><input type="number" name="L0${s}" required class="s" onchange="UI();pinUpd(this);"/>
@@ -480,25 +471,18 @@
480471
}
481472
});
482473
enLA(gN("LL"+s)); // update LED mA
483-
// disable inappropriate LED types
484474
let sel = gN("LT"+s);
485-
// 32 & S2 supports mono I2S as well as parallel so we need to take that into account; S3 only supports parallel
486-
let maxDB = maxD - (is32() || isS2() || isS3() ? (!gN("PR").checked)*8 - (!isS3()) : 0); // adjust max digital buses if parallel I2S is not used
487-
if (digitalB >= maxDB) disable(sel,'option[data-type="D"]'); // NOTE: see isDig()
488-
if (twopinB >= 2) disable(sel,'option[data-type="2P"]'); // NOTE: see isD2P() (we will only allow 2 2pin buses)
489-
disable(sel,`option[data-type^="${'A'.repeat(maxA-analogB+1)}"]`); // NOTE: see isPWM()
490-
sel.selectedIndex = sel.querySelector('option:not(:disabled)').index;
475+
sel.selectedIndex = sel.querySelector('option:not([data-type])').index; // select On/Off by default
491476
}
492477
if (n==-1) {
493-
o[--i].remove();--i;
494-
o[i].querySelector("[name^=LT]").disabled = false;
478+
o[--i].remove();
495479
}
496480

497-
gId("+").style.display = (i<35) ? "inline":"none"; // was maxB+maxV-1 when virtual buses were limited (now :"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
498-
gId("-").style.display = (i>0) ? "inline":"none";
481+
gId("+").style.display = (i<36) ? "inline":"none"; // was maxB+maxV-1 when virtual buses were limited (now :"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
482+
gId("-").style.display = (i>1) ? "inline":"none";
499483

500484
if (!init) {
501-
UI();
485+
UI(true);
502486
}
503487
}
504488

@@ -828,6 +812,36 @@
828812
}
829813
return opt;
830814
}
815+
// dynamically enforce bus type availability based on current usage
816+
function updateTypeDropdowns(change=false) {
817+
let LTs = d.Sf.querySelectorAll("#mLC select[name^=LT]");
818+
let digitalB = 0, analogB = 0, twopinB = 0, virtB = 0;
819+
// count currently used buses (including last added bus)
820+
LTs.forEach((sel,i) => {
821+
let t = parseInt(sel.value);
822+
if (isD1P(t)) digitalB++;
823+
if (isPWM(t)) analogB += numPins(t);
824+
if (isD2P(t)) twopinB++;
825+
if (isVir(t)) virtB++;
826+
});
827+
// now enable/disable type options according to limits in dropdowns
828+
LTs.forEach((sel,i) => {
829+
const last = i == LTs.length-1;
830+
const curType = parseInt(sel.value);
831+
const disable = (q) => sel.querySelectorAll(q).forEach(o => o.disabled = true);
832+
const enable = (q) => sel.querySelectorAll(q).forEach(o => o.disabled = false);
833+
enable('option'); // reset all first
834+
// max digital count
835+
let maxDB = maxD - ((is32() || isS2() || isS3()) ? (!d.Sf["PR"].checked) * 8 - (!isS3()) : 0);
836+
// disallow adding more of a type that has reached its limit
837+
if (digitalB >= maxDB && !isD1P(curType)) disable('option[data-type="D"]');
838+
if (twopinB >= 2 && !isD2P(curType)) disable('option[data-type="2P"]');
839+
// determine available analog pins
840+
disable(`option[data-type^="${'A'.repeat(maxA - analogB + (isPWM(curType) ? numPins(curType) : 0) + 1)}"]`);
841+
// if last added bus has an invalid type, change it to first available
842+
if (last && sel.selectedOptions[0].disabled) sel.selectedIndex = sel.querySelector('option:not(:disabled)').index;
843+
});
844+
}
831845
</script>
832846
<style>@import url("style.css");</style>
833847
</head>

0 commit comments

Comments
 (0)