Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
Loading