Merge remote-tracking branch 'upstream/main' into mdev
This commit is contained in:
@@ -4,6 +4,7 @@ var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, sy
|
||||
var hasWhite = false, hasRGB = false, hasCCT = false;
|
||||
var nlDur = 60, nlTar = 0;
|
||||
var nlMode = false;
|
||||
var segLmax = 0; // size (in pixels) of largest selected segment
|
||||
var selectedFx = 0;
|
||||
var selectedPal = 0;
|
||||
var csel = 0; // selected color slot (0-2)
|
||||
@@ -63,13 +64,10 @@ function setCSL(cs)
|
||||
let w = cs.dataset.w ? parseInt(cs.dataset.w) : 0;
|
||||
let hasShadow = getComputedStyle(cs).textShadow !== "none";
|
||||
if (hasRGB && !isRgbBlack(cs.dataset)) {
|
||||
cs.style.backgroundColor = rgbStr(cs.dataset);
|
||||
if (!hasShadow) cs.style.color = rgbBri(cs.dataset) > 127 ? "#000":"#fff"; // if text has no CSS "shadow"
|
||||
if (hasWhite && w > 0) {
|
||||
cs.style.background = `linear-gradient(180deg, ${rgbStr(cs.dataset)} 30%, rgb(${w},${w},${w}))`;
|
||||
}
|
||||
cs.style.background = (hasWhite && w > 0) ? `linear-gradient(180deg, ${rgbStr(cs.dataset)} 30%, rgb(${w},${w},${w}))` : rgbStr(cs.dataset);
|
||||
} else {
|
||||
if (!hasWhite) w = 0;
|
||||
if (hasRGB && !hasWhite) w = 0;
|
||||
cs.style.background = `rgb(${w},${w},${w})`;
|
||||
if (!hasShadow) cs.style.color = w > 127 ? "#000":"#fff";
|
||||
}
|
||||
@@ -779,8 +777,7 @@ function populateSegments(s)
|
||||
<i class="icons e-icon flr" id="sege${i}" onclick="expand(${i})"></i>
|
||||
${cfg.comp.segpwr?segp:''}
|
||||
<div class="segin" id="seg${i}in">
|
||||
<input id="seg${i}fx" value="${inst.fx}" type="hidden"/>
|
||||
<input type="text" class="ptxt noslide" id="seg${i}t" autocomplete="off" maxlength=32 value="${inst.n?inst.n:""}" placeholder="Enter name..."/>
|
||||
<input type="text" class="ptxt" id="seg${i}t" autocomplete="off" maxlength=32 value="${inst.n?inst.n:""}" placeholder="Enter name..."/>
|
||||
<table class="infot segt">
|
||||
<tr>
|
||||
<td>${isM&&staX<mw*mh?'Start X':'Start LED'}</td>
|
||||
@@ -788,24 +785,24 @@ function populateSegments(s)
|
||||
<td>${isM&&staX<mw*mh?'':'Offset'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}s" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)-1}" value="${staX}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}e" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)}" value="${stoX-(cfg.comp.seglen?staX:0)}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:revert;">${isM&&staX<mw*mh?miXck+'<br>'+rvXck:''}<input class="noslide segn ${isM&&staX<mw*mh?'hide':''}" id="seg${i}of" type="number" value="${inst.of}" oninput="updateLen(${i})"></td>
|
||||
<td><input class="segn" id="seg${i}s" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)-1}" value="${staX}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="segn" id="seg${i}e" type="number" min="0" max="${(isM&&staX<mw*mh?mw:ledCount)}" value="${stoX-(cfg.comp.seglen?staX:0)}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:revert;">${isM&&staX<mw*mh?miXck+'<br>'+rvXck:''}<input class="segn ${isM&&staX<mw*mh?'hide':''}" id="seg${i}of" type="number" value="${inst.of}" oninput="updateLen(${i})"></td>
|
||||
</tr>
|
||||
${isM&&staX<mw*mh ? '<tr><td>Start Y</td><td>'+(cfg.comp.seglen?'Height':'Stop Y')+'</td><td></td></tr>'+
|
||||
'<tr>'+
|
||||
'<td><input class="noslide segn" id="seg'+i+'sY" type="number" min="0" max="'+(mh-1)+'" value="'+staY+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td><input class="noslide segn" id="seg'+i+'eY" type="number" min="0" max="'+mh+'" value="'+(stoY-(cfg.comp.seglen?staY:0))+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td><input class="segn" id="seg'+i+'sY" type="number" min="0" max="'+(mh-1)+'" value="'+staY+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td><input class="segn" id="seg'+i+'eY" type="number" min="0" max="'+mh+'" value="'+(stoY-(cfg.comp.seglen?staY:0))+'" oninput="updateLen('+i+')" onkeydown="segEnter('+i+')"></td>'+
|
||||
'<td style="text-align:revert;">'+miYck+'<br>'+rvYck+'</td>'+
|
||||
'</tr>':''}
|
||||
<tr>
|
||||
<td>Grouping</td>
|
||||
<td>Spacing</td>
|
||||
<td><!--Apply--></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="noslide segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="segn" id="seg${i}grp" type="number" min="1" max="255" value="${inst.grp}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td><input class="segn" id="seg${i}spc" type="number" min="0" max="255" value="${inst.spc}" oninput="updateLen(${i})" onkeydown="segEnter(${i})"></td>
|
||||
<td style="text-align:revert;"><button class="btn btn-xs" onclick="setSeg(${i})"><i class="icons btn-icon" id="segc${i}"></i></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -836,10 +833,13 @@ function populateSegments(s)
|
||||
for (var i = 0; i <= lSeg; i++) {
|
||||
updateLen(i, false); //WLEDMM: no draw
|
||||
updateTrail(gId(`seg${i}bri`));
|
||||
gId(`segr${i}`).style.display = "none";
|
||||
gId(`segr${i}`).classList.add("hide");
|
||||
if (!gId(`seg${i}sel`).checked && gId('selall')) gId('selall').checked = false; // uncheck if at least one is unselected.
|
||||
}
|
||||
if (segCount < 2) gId(`segd${lSeg}`).style.display = "none";
|
||||
if (segCount < 2) {
|
||||
gId(`segd${lSeg}`).classList.add("hide");
|
||||
gId(`segp0`).classList.add("hide");
|
||||
}
|
||||
if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value)<ledCount) gId(`segr${lSeg}`).style.display = "inline";
|
||||
gId('segutil2').style.display = (segCount > 1) ? "block":"none"; // rsbtn parent
|
||||
|
||||
@@ -888,6 +888,7 @@ function populateEffects()
|
||||
let m = (eP.length<4 || eP[3]==='')?'1':eP[3]; // flags
|
||||
if (id == 0) m = ''; // solid has no flags
|
||||
if (m.length>0) {
|
||||
if (m.includes('0')) nm += "•"; // 0D effects (PWM & On/Off)
|
||||
if (m.includes('1')) nm += "⋮"; // 1D effects
|
||||
if (m.includes("1.5d")) nm += "⋮"; // WLEDMM: vStrips
|
||||
if (m.includes('2')) nm += "▦"; // 2D effects
|
||||
@@ -1440,18 +1441,19 @@ function updateUI()
|
||||
}
|
||||
if (hasWhite) updateTrail(gId('sliderW'));
|
||||
|
||||
gId('wwrap').style.display = (hasWhite) ? "block":"none"; // white channel
|
||||
gId('wbal').style.display = (hasCCT) ? "block":"none"; // white balance
|
||||
var ccfg = cfg.comp.colors;
|
||||
gId('hexw').style.display = ccfg.hex ? "block":"none"; // HEX input
|
||||
gId('picker').style.display = (hasRGB && ccfg.picker) ? "block":"none"; // color picker wheel
|
||||
gId('hwrap').style.display = (hasRGB && !ccfg.picker) ? "block":"none"; // color picker wheel
|
||||
gId('swrap').style.display = (hasRGB && !ccfg.picker) ? "block":"none"; // color picker wheel
|
||||
gId('vwrap').style.display = (hasRGB /*&& ccfg.picker*/) ? "block":"none"; // brightness (value) slider
|
||||
gId('kwrap').style.display = (hasRGB && !hasCCT /*&& ccfg.picker*/) ? "block":"none"; // Kelvin slider
|
||||
gId('rgbwrap').style.display = (hasRGB && ccfg.rgb) ? "block":"none"; // RGB sliders
|
||||
gId('qcs-w').style.display = (hasRGB && ccfg.quick) ? "block":"none"; // quick selection
|
||||
//gId('palw').style.display = hasRGB ? "block":"none"; // palettes
|
||||
gId('wwrap').style.display = (hasWhite) ? "block":"none"; // white channel
|
||||
gId('wbal').style.display = (hasCCT) ? "block":"none"; // white balance
|
||||
gId('hexw').style.display = (ccfg.hex) ? "block":"none"; // HEX input
|
||||
gId('picker').style.display = (hasRGB && ccfg.picker) ? "block":"none"; // color picker wheel
|
||||
gId('hwrap').style.display = (hasRGB && !ccfg.picker) ? "block":"none"; // hue slider
|
||||
gId('swrap').style.display = (hasRGB && !ccfg.picker) ? "block":"none"; // saturation slider
|
||||
gId('vwrap').style.display = (hasRGB) ? "block":"none"; // brightness (value) slider
|
||||
gId('kwrap').style.display = (hasRGB && !hasCCT) ? "block":"none"; // Kelvin slider
|
||||
gId('rgbwrap').style.display = (hasRGB && ccfg.rgb) ? "block":"none"; // RGB sliders
|
||||
gId('qcs-w').style.display = (hasRGB && ccfg.quick) ? "block":"none"; // quick selection
|
||||
//gId('csl').style.display = (hasRGB || hasWhite) ? "block":"none"; // color selectors (hide for On/Off bus)
|
||||
//gId('palw').style.display = (hasRGB) ? "inline-block":"none"; // palettes are shown/hidden in setEffectParameters()
|
||||
|
||||
updatePA();
|
||||
updatePSliders();
|
||||
@@ -1496,7 +1498,19 @@ function updateSelectedFx()
|
||||
if (selectedEffect) {
|
||||
selectedEffect.classList.add('selected');
|
||||
setEffectParameters(selectedFx);
|
||||
|
||||
// hide non-0D effects if segment only has 1 pixel (0D)
|
||||
var fxs = parent.querySelectorAll('.lstI');
|
||||
for (const fx of fxs) {
|
||||
let opts = fx.dataset.opt.split(";");
|
||||
if (fx.dataset.id>0) {
|
||||
if (segLmax==0) fx.classList.add('hide'); // none of the segments selected (hide all effects)
|
||||
else {
|
||||
if (segLmax==1 && (!opts[3] || opts[3].indexOf("0")<0)) fx.classList.add('hide');
|
||||
else fx.classList.remove('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
// hide 2D mapping and/or sound simulation options
|
||||
var selectedName = selectedEffect.querySelector(".lstIname").innerText;
|
||||
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');
|
||||
@@ -1584,6 +1598,7 @@ function readState(s,command=false)
|
||||
var selc=0;
|
||||
var sellvl=0; // 0: selc is invalid, 1: selc is mainseg, 2: selc is first selected
|
||||
hasRGB = hasWhite = hasCCT = false;
|
||||
segLmax = 0;
|
||||
for (let i = 0; i < (s.seg||[]).length; i++)
|
||||
{
|
||||
if (sellvl == 0 && s.seg[i].id == s.mainseg) {
|
||||
@@ -1597,6 +1612,8 @@ function readState(s,command=false)
|
||||
hasRGB |= !!(lc & 0x01);
|
||||
hasWhite |= !!(lc & 0x02);
|
||||
hasCCT |= !!(lc & 0x04);
|
||||
let sLen = (s.seg[i].stop - s.seg[i].start)*(s.seg[i].stopY?(s.seg[i].stopY - s.seg[i].startY):1);
|
||||
segLmax = segLmax < sLen ? sLen : segLmax;
|
||||
}
|
||||
}
|
||||
var i=s.seg[selc];
|
||||
@@ -1617,7 +1634,7 @@ function readState(s,command=false)
|
||||
cd[e].dataset.r = i.col[e][0];
|
||||
cd[e].dataset.g = i.col[e][1];
|
||||
cd[e].dataset.b = i.col[e][2];
|
||||
if (hasWhite) { cd[e].dataset.w = i.col[e][3]; }
|
||||
if (hasWhite || (!hasRGB && !hasWhite)) { cd[e].dataset.w = i.col[e][3]; }
|
||||
setCSL(cd[e]);
|
||||
}
|
||||
selectSlot(csel);
|
||||
@@ -1769,8 +1786,8 @@ function setEffectParameters(idx)
|
||||
var palw = gId("palw"); // wrapper
|
||||
var pall = gId("pall"); // label
|
||||
// if not controlDefined or palette has a value
|
||||
if ((!controlDefined) || (paOnOff.length>0 && paOnOff[0]!="" && isNaN(paOnOff[0]))) {
|
||||
palw.style.display = hasRGB ? "inline-block" : "none";
|
||||
if (hasRGB && ((!controlDefined) || (paOnOff.length>0 && paOnOff[0]!="" && isNaN(paOnOff[0])))) {
|
||||
palw.style.display = "inline-block";
|
||||
if (paOnOff.length>0 && paOnOff[0].indexOf("=")>0) {
|
||||
// embeded default values
|
||||
var dPos = paOnOff[0].indexOf("=");
|
||||
@@ -1983,21 +2000,21 @@ function makeSeg()
|
||||
});
|
||||
var cn = `<div class="seg lstI expanded">
|
||||
<div class="segin">
|
||||
<input type="text" class="noslide" id="seg${lu}t" autocomplete="off" maxlength=32 value="" placeholder="New segment ${lu}"/>
|
||||
<input type="text" id="seg${lu}t" autocomplete="off" maxlength=32 value="" placeholder="New segment ${lu}"/>
|
||||
<table class="segt">
|
||||
<tr>
|
||||
<td width="38%">${isM?'Start X':'Start LED'}</td>
|
||||
<td width="38%">${isM?(cfg.comp.seglen?"Width":"Stop X"):(cfg.comp.seglen?"LED count":"Stop LED")}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input class="noslide segn" id="seg${lu}s" type="number" min="0" max="${isM?mw-1:ledCount-1}" value="${ns}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}e" type="number" min="0" max="${ct}" value="${ct}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="segn" id="seg${lu}s" type="number" min="0" max="${isM?mw-1:ledCount-1}" value="${ns}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="segn" id="seg${lu}e" type="number" min="0" max="${ct}" value="${ct}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><button class="btn btn-xs" onclick="setSeg(${lu});"><i class="icons bth-icon" id="segc${lu}"></i></button></td>
|
||||
</tr>
|
||||
<tr id="mkSYH" class="${isM?"":"hide"}"><td>Start Y</td><td>${cfg.comp.seglen?'Height':'Stop Y'}</td></tr>
|
||||
<tr id="mkSYD" class="${isM?"":"hide"}">
|
||||
<td><input class="noslide segn" id="seg${lu}sY" type="number" min="0" max="${mh-1}" value="0" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="noslide segn" id="seg${lu}eY" type="number" min="0" max="${mh}" value="${isM?mh:1}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="segn" id="seg${lu}sY" type="number" min="0" max="${mh-1}" value="0" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
<td><input class="segn" id="seg${lu}eY" type="number" min="0" max="${mh}" value="${isM?mh:1}" oninput="updateLen(${lu})" onkeydown="segEnter(${lu})"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="h" id="seg${lu}len">${ledCount - ns} LEDs</div>
|
||||
@@ -2122,7 +2139,7 @@ function makeP(i,pl)
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
<div id="pl${i}o1" style="display:${rep>0?"block":"none"}">
|
||||
<div class="c">Repeat <input class="noslide" type="number" id="pl${i}rp" oninput="plR(${i})" max=127 min=0 value=${rep>0?rep:1}> times</div>
|
||||
<div class="c">Repeat <input type="number" id="pl${i}rp" oninput="plR(${i})" max=127 min=0 value=${rep>0?rep:1}> times</div>
|
||||
<div class="sel">End preset:<br>
|
||||
<div class="sel-p"><select class="sel-ple" id="pl${i}selEnd" onchange="plR(${i})" data-val=${plJson[i].end?plJson[i].end:0}>
|
||||
<option value="0">None</option>
|
||||
@@ -2161,8 +2178,8 @@ ${makePlSel(plJson[i].end?plJson[i].end:0, true)}
|
||||
}
|
||||
}
|
||||
|
||||
return `<input type="text" class="ptxt noslide ${i==0?'show':''}" id="p${i}txt" autocomplete="off" maxlength=32 value="${(i>0)?pName(i):""}" placeholder="Enter name..."/>
|
||||
<div class="c">Quick load label: <input type="text" class="stxt noslide" maxlength=2 value="${qlName(i)}" id="p${i}ql" autocomplete="off"/></div>
|
||||
return `<input type="text" class="ptxt ${i==0?'show':''}" id="p${i}txt" autocomplete="off" maxlength=32 value="${(i>0)?pName(i):""}" placeholder="Enter name..."/>
|
||||
<div class="c">Quick load label: <input type="text" class="stxt" maxlength=2 value="${qlName(i)}" id="p${i}ql" autocomplete="off"/></div>
|
||||
<div class="h">(leave empty for no Quick load button)</div>
|
||||
<div ${pl&&i==0?"style='display:none'":""}>
|
||||
<label class="check revchkl">
|
||||
@@ -2173,9 +2190,9 @@ ${makePlSel(plJson[i].end?plJson[i].end:0, true)}
|
||||
<span class="checkmark"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="po2" id="p${i}o2">API command<br><textarea class="apitxt noslide" id="p${i}api"></textarea></div>
|
||||
<div class="po2" id="p${i}o2">API command<br><textarea class="apitxt" id="p${i}api"></textarea></div>
|
||||
<div class="po1" id="p${i}o1">${content}</div>
|
||||
<div class="c m6">Save to ID <input class="noslide" id="p${i}id" type="number" oninput="checkUsed(${i})" max=250 min=1 value=${(i>0)?i:getLowestUnusedP()}></div>
|
||||
<div class="c m6">Save to ID <input id="p${i}id" type="number" oninput="checkUsed(${i})" max=250 min=1 value=${(i>0)?i:getLowestUnusedP()}></div>
|
||||
<div class="c">
|
||||
<button class="btn btn-p" onclick="saveP(${i},${pl})"><i class="icons btn-icon"></i>Save</button>
|
||||
${(i>0)?'<button class="btn btn-p" id="p'+i+'del" onclick="delP('+i+')"><i class="icons btn-icon"></i>Delete':'<button class="btn btn-p" onclick="resetPUtil()">Cancel'}</button>
|
||||
@@ -2220,8 +2237,8 @@ function makePlEntry(p,i)
|
||||
<td class="c">#${i+1}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="c" width="40%"><input class="noslide segn" type="number" placeholder="Duration" max=6553.0 min=0.2 step=0.1 oninput="pleDur(${p},${i},this)" value="${plJson[p].dur[i]/10.0}">s</td>
|
||||
<td class="c" width="40%"><input class="noslide segn" type="number" placeholder="Transition" max=65.0 min=0.0 step=0.1 oninput="pleTr(${p},${i},this)" value="${plJson[p].transition[i]/10.0}">s</td>
|
||||
<td class="c" width="40%"><input class="segn" type="number" placeholder="Duration" max=6553.0 min=0.2 step=0.1 oninput="pleDur(${p},${i},this)" value="${plJson[p].dur[i]/10.0}">s</td>
|
||||
<td class="c" width="40%"><input class="segn" type="number" placeholder="Transition" max=65.0 min=0.0 step=0.1 oninput="pleTr(${p},${i},this)" value="${plJson[p].transition[i]/10.0}">s</td>
|
||||
<td class="c"><button class="btn btn-pl-del" onclick="delPl(${p},${i})"><i class="icons btn-icon"></i></button></div></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -2513,7 +2530,7 @@ function setLor(i)
|
||||
function setPreset(i)
|
||||
{
|
||||
var obj = {"ps":i};
|
||||
if (pJson && pJson[i] && (!pJson[i].win || pJson[i].win.indexOf("Please") <= 0)) {
|
||||
if (!isPlaylist(i) && pJson && pJson[i] && (!pJson[i].win || pJson[i].win.indexOf("Please") <= 0)) {
|
||||
// we will send the complete preset content as to avoid delay introduced by
|
||||
// async nature of applyPreset() and having to read the preset from file system.
|
||||
obj = {"pd":i}; // use "pd" instead of "ps" to indicate that we are sending the preset content directly
|
||||
@@ -3156,7 +3173,7 @@ function hasIroClass(classList)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//required by rangetouch.js
|
||||
function lock(e)
|
||||
{
|
||||
if (pcMode) return;
|
||||
@@ -3170,7 +3187,7 @@ function lock(e)
|
||||
|
||||
_C.classList.toggle('smooth', !(locked = true));
|
||||
}
|
||||
|
||||
//required by rangetouch.js
|
||||
function move(e)
|
||||
{
|
||||
if(!locked || pcMode) return;
|
||||
|
||||
Reference in New Issue
Block a user