Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
//Playlist option byte
#define PL_OPTION_SHUFFLE 0x01
#define PL_OPTION_RESTORE 0x02
#define PL_OPTION_DETERMINISTIC_SHUFFLE 0x04
#define PL_OPTION_CLOCK_SYNC 0x08

// Segment capability byte
#define SEG_CAPABILITY_RGB 0x01
Expand Down
80 changes: 61 additions & 19 deletions wled00/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2004,10 +2004,46 @@ function pleTr(p,i,field)
plJson[p].transition[i] = Math.floor(field.value*10);
}

function plR(p)
function plUpdateOptions(p, changed)
{
var pl = plJson[p];
pl.r = gId(`pl${p}rtgl`).checked;

const shuffle = gId(`pl${p}rtgl`).checked;
const deterministic = gId(`pl${p}deterministic`);
const clockSync = gId(`pl${p}clockSync`);
const manual = gId(`pl${p}manual`);
let manualChanged = changed == "manual";

// Ensure clock sync and manual advance can't be checked at the same time
if (clockSync.checked && manual.checked) {
if (changed == "clockSync") {
manual.checked = false;
manualChanged = true;
} else {
clockSync.checked = false;
}
}

// Reset & hide deterministic flag when not shuffling
if (!shuffle) deterministic.checked = false;
gId(`pl${p}deterministicRow`).style.display = shuffle ? "block" : "none";

pl.r = shuffle;
pl.deterministic = deterministic.checked;
pl.clockSync = clockSync.checked;

// Normalize durations when manual advance changes
if (manualChanged) {
plJson[p].dur.forEach((_,i)=>{
const e = manual.checked ? 0 : 100;
const d = gId(`pl${p}du${i}`);
plJson[p].dur[i] = e;
d.value = e/10; // 10s default
d.readOnly = manual.checked;
});
}

// Update repeat/end-preset controls
if (gId(`pl${p}rptgl`).checked) { // infinite
pl.repeat = 0;
delete pl.end;
Expand All @@ -2019,17 +2055,6 @@ function plR(p)
}
}

function plM(p)
{
const man = gId(`pl${p}manual`).checked;
plJson[p].dur.forEach((e,i)=>{
const d = gId(`pl${p}du${i}`);
plJson[p].dur[i] = e = man ? 0 : 100;
d.value = e/10; // 10s default
d.readOnly = man;
});
}

function makeP(i,pl)
{
var content = "";
Expand All @@ -2041,27 +2066,39 @@ function makeP(i,pl)
transition: [tr],
repeat: 0,
r: false,
deterministic: false,
clockSync: false,
end: 0
};
const clockSync = !!plJson[i].clockSync;
if (!plJson[i].r) plJson[i].deterministic = false;
const rep = plJson[i].repeat ? plJson[i].repeat : 0;
const man = plJson[i].dur == 0;
const man = !clockSync && plJson[i].dur.every(d => d == 0);
content =
`<div id="ple${i}" style="margin-top:10px;"></div><label class="check revchkl">Shuffle
<input type="checkbox" id="pl${i}rtgl" onchange="plR(${i})" ${plJson[i].r||rep<0?"checked":""}>
<input type="checkbox" id="pl${i}rtgl" onchange="plUpdateOptions(${i}, 'shuffle')" ${plJson[i].r||rep<0?"checked":""}>
<span class="checkmark"></span>
</label>
<label class="check revchkl" id="pl${i}deterministicRow" style="display:${plJson[i].r||rep<0?"block":"none"};margin-left:1.2em" title="Uses a repeatable shuffle order">Deterministic
<input type="checkbox" id="pl${i}deterministic" onchange="plUpdateOptions(${i}, 'deterministic')" ${plJson[i].deterministic?"checked":""}>
<span class="checkmark"></span>
</label>
<label class="check revchkl" title="Derives playlist position from wall time">Clock sync
<input type="checkbox" id="pl${i}clockSync" onchange="plUpdateOptions(${i}, 'clockSync')" ${clockSync?"checked":""}>
<span class="checkmark"></span>
</label>
<label class="check revchkl">Manual advance
<input type="checkbox" id="pl${i}manual" onchange="plM(${i})" ${man?"checked":""}>
<input type="checkbox" id="pl${i}manual" onchange="plUpdateOptions(${i}, 'manual')" ${man?"checked":""}>
<span class="checkmark"></span>
</label>
<label class="check revchkl">Repeat indefinitely
<input type="checkbox" id="pl${i}rptgl" onchange="plR(${i})" ${rep>0?"":"checked"}>
<input type="checkbox" id="pl${i}rptgl" onchange="plUpdateOptions(${i}, 'repeat')" ${rep>0?"":"checked"}>
<span class="checkmark"></span>
</label>
<div id="pl${i}o1" style="display:${rep>0?"block":"none"}">
<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="c">Repeat <input type="number" id="pl${i}rp" oninput="plUpdateOptions(${i}, 'repeat')" 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}>
<div class="sel-p"><select class="sel-ple" id="pl${i}selEnd" onchange="plUpdateOptions(${i}, 'repeat')" data-val=${plJson[i].end?plJson[i].end:0}>
<option value="0">None</option>
<option value="255" ${plJson[i].end && plJson[i].end==255?"selected":""}>Restore preset</option>
${makePlSel(i, plJson[i].end?plJson[i].end:0)}
Expand Down Expand Up @@ -2124,6 +2161,7 @@ function makePUtil()
p.classList.remove('staybot');
p.classList.add('pres');
p.innerHTML = `<div class="presin expanded">${makeP(0)}</div>`;
tooltip("#putil");
let pTx = gId('p0txt');
pTx.focus();
pTx.value = eJson.find((o)=>{return o.id==selectedFx}).name;
Expand Down Expand Up @@ -2173,6 +2211,7 @@ function makePlUtil()
p.classList.add('pres');
p.innerHTML = `<div class="presin expanded" id="seg100">${makeP(0,true)}</div></div>`;
refreshPlE(0);
tooltip("#putil");
gId('p0txt').focus();
p.scrollIntoView({
behavior: 'smooth',
Expand Down Expand Up @@ -3050,12 +3089,15 @@ function expand(i)
formatArr(plJson[p]);
if (isNaN(plJson[p].repeat)) plJson[p].repeat = 0;
if (!plJson[p].r) plJson[p].r = false;
if (!plJson[p].deterministic) plJson[p].deterministic = false;
if (!plJson[p].clockSync) plJson[p].clockSync = false;
if (isNaN(plJson[p].end)) plJson[p].end = 0;
gId('seg' +i).innerHTML = makeP(p,true);
refreshPlE(p);
} else {
gId('seg' +i).innerHTML = makeP(p);
}
tooltip('#seg' + i);
var papi = papiVal(p);
gId(`p${p}api`).value = papi;
if (papi.indexOf("Please") == 0) gId(`p${p}cstgl`).checked = false;
Expand Down
1 change: 0 additions & 1 deletion wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ void handleOverlayDraw();
// void _overlayAnalogClock(); // local function, only used in overlay.cpp

//playlist.cpp
void shufflePlaylist();
void unloadPlaylist();
int16_t loadPlaylist(JsonObject playlistObject, byte presetId = 0);
void handlePlaylist();
Expand Down
Loading