mirror of
https://github.com/wled/WLED.git
synced 2025-07-18 08:16:32 +00:00
Merge branch '0_15' of https://github.com/Aircoookie/WLED into ledmaps-realtime
This commit is contained in:
commit
4fc69c9a2c
@ -298,7 +298,7 @@ class Animated_Staircase : public Usermod {
|
|||||||
|
|
||||||
// shorten the strip transition time to be equal or shorter than segment delay
|
// shorten the strip transition time to be equal or shorter than segment delay
|
||||||
transitionDelay = segment_delay_ms;
|
transitionDelay = segment_delay_ms;
|
||||||
strip.setTransition(segment_delay_ms/100);
|
strip.setTransition(segment_delay_ms);
|
||||||
strip.trigger();
|
strip.trigger();
|
||||||
} else {
|
} else {
|
||||||
if (togglePower && !on && offMode) toggleOnOff(); // toggle power on if off
|
if (togglePower && !on && offMode) toggleOnOff(); // toggle power on if off
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
| `pinSourceSelect` | GPIO that is connected to SD's `SS`(source select) / `CS`(chip select) | 16 |
|
| `pinSourceSelect` | GPIO that is connected to SD's `SS`(source select) / `CS`(chip select) | 16 |
|
||||||
| `pinSourceClock` | GPIO that is connected to SD's `SCLK` (source clock) / `CLK`(clock) | 14 |
|
| `pinSourceClock` | GPIO that is connected to SD's `SCLK` (source clock) / `CLK`(clock) | 14 |
|
||||||
| `pinPoci` | GPIO that is connected to SD's `POCI`<sup>☨</sup> (Peripheral-Out-Ctrl-In) / `MISO` (deprecated) | 36 |
|
| `pinPoci` | GPIO that is connected to SD's `POCI`<sup>☨</sup> (Peripheral-Out-Ctrl-In) / `MISO` (deprecated) | 36 |
|
||||||
| `pinPico` | GPIO that is connected to SD's `PICO`<sup>☨</sup> (Peripheral-In-Ctrl-Out) / `MOSI` (deprecated) | 14 |
|
| `pinPico` | GPIO that is connected to SD's `PICO`<sup>☨</sup> (Peripheral-In-Ctrl-Out) / `MOSI` (deprecated) | 15 |
|
||||||
| `sdEnable` | Enable to read data from the SD-card | true |
|
| `sdEnable` | Enable to read data from the SD-card | true |
|
||||||
|
|
||||||
<sup>☨</sup><sub>Following new naming convention of [OSHWA](https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/)</sub>
|
<sup>☨</sup><sub>Following new naming convention of [OSHWA](https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/)</sub>
|
||||||
|
@ -91,6 +91,7 @@ class StairwayWipeUsermod : public Usermod {
|
|||||||
void startWipe()
|
void startWipe()
|
||||||
{
|
{
|
||||||
bri = briLast; //turn on
|
bri = briLast; //turn on
|
||||||
|
jsonTransitionOnce = true;
|
||||||
strip.setTransition(0); //no transition
|
strip.setTransition(0); //no transition
|
||||||
effectCurrent = FX_MODE_COLOR_WIPE;
|
effectCurrent = FX_MODE_COLOR_WIPE;
|
||||||
resetTimebase(); //make sure wipe starts from beginning
|
resetTimebase(); //make sure wipe starts from beginning
|
||||||
@ -105,6 +106,7 @@ class StairwayWipeUsermod : public Usermod {
|
|||||||
|
|
||||||
void turnOff()
|
void turnOff()
|
||||||
{
|
{
|
||||||
|
jsonTransitionOnce = true;
|
||||||
#ifdef STAIRCASE_WIPE_OFF
|
#ifdef STAIRCASE_WIPE_OFF
|
||||||
strip.setTransition(0); //turn off immediately after wipe completed
|
strip.setTransition(0); //turn off immediately after wipe completed
|
||||||
#else
|
#else
|
||||||
|
@ -1714,7 +1714,7 @@ uint16_t mode_multi_comet(void) {
|
|||||||
}
|
}
|
||||||
comets[i]++;
|
comets[i]++;
|
||||||
} else {
|
} else {
|
||||||
if(!random(SEGLEN)) {
|
if(!random16(SEGLEN)) {
|
||||||
comets[i] = 0;
|
comets[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1990,7 +1990,7 @@ uint16_t mode_fire_2012() {
|
|||||||
|
|
||||||
// Step 1. Cool down every cell a little
|
// Step 1. Cool down every cell a little
|
||||||
for (int i = 0; i < SEGLEN; i++) {
|
for (int i = 0; i < SEGLEN; i++) {
|
||||||
uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random(4);
|
uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4);
|
||||||
uint8_t minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
|
uint8_t minTemp = (i<ignition) ? (ignition-i)/4 + 16 : 0; // should not become black in ignition area
|
||||||
uint8_t temp = qsub8(heat[i], cool);
|
uint8_t temp = qsub8(heat[i], cool);
|
||||||
heat[i] = temp<minTemp ? minTemp : temp;
|
heat[i] = temp<minTemp ? minTemp : temp;
|
||||||
@ -4075,6 +4075,7 @@ static const char _data_FX_MODE_PHASEDNOISE[] PROGMEM = "Phased Noise@!,!;!,!;!"
|
|||||||
|
|
||||||
|
|
||||||
uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline.
|
uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline.
|
||||||
|
uint16_t prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function
|
||||||
random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through.
|
random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through.
|
||||||
|
|
||||||
for (int i = 0; i < SEGLEN; i++) {
|
for (int i = 0; i < SEGLEN; i++) {
|
||||||
@ -4084,6 +4085,7 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine
|
|||||||
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri));
|
SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_TWINKLEUP[] PROGMEM = "Twinkleup@!,Intensity;!,!;!;;m12=0";
|
static const char _data_FX_MODE_TWINKLEUP[] PROGMEM = "Twinkleup@!,Intensity;!,!;!;;m12=0";
|
||||||
@ -4566,15 +4568,15 @@ class AuroraWave {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void init(uint32_t segment_length, CRGB color) {
|
void init(uint32_t segment_length, CRGB color) {
|
||||||
ttl = random(500, 1501);
|
ttl = random16(500, 1501);
|
||||||
basecolor = color;
|
basecolor = color;
|
||||||
basealpha = random(60, 101) / (float)100;
|
basealpha = random8(60, 101) / (float)100;
|
||||||
age = 0;
|
age = 0;
|
||||||
width = random(segment_length / 20, segment_length / W_WIDTH_FACTOR); //half of width to make math easier
|
width = random16(segment_length / 20, segment_length / W_WIDTH_FACTOR); //half of width to make math easier
|
||||||
if (!width) width = 1;
|
if (!width) width = 1;
|
||||||
center = random(101) / (float)100 * segment_length;
|
center = random8(101) / (float)100 * segment_length;
|
||||||
goingleft = random(0, 2) == 0;
|
goingleft = random8(0, 2) == 0;
|
||||||
speed_factor = (random(10, 31) / (float)100 * W_MAX_SPEED / 255);
|
speed_factor = (random8(10, 31) / (float)100 * W_MAX_SPEED / 255);
|
||||||
alive = true;
|
alive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4659,7 +4661,7 @@ uint16_t mode_aurora(void) {
|
|||||||
waves = reinterpret_cast<AuroraWave*>(SEGENV.data);
|
waves = reinterpret_cast<AuroraWave*>(SEGENV.data);
|
||||||
|
|
||||||
for (int i = 0; i < SEGENV.aux1; i++) {
|
for (int i = 0; i < SEGENV.aux1; i++) {
|
||||||
waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3))));
|
waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random8(0, 3))));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
waves = reinterpret_cast<AuroraWave*>(SEGENV.data);
|
waves = reinterpret_cast<AuroraWave*>(SEGENV.data);
|
||||||
@ -4671,7 +4673,7 @@ uint16_t mode_aurora(void) {
|
|||||||
|
|
||||||
if(!(waves[i].stillAlive())) {
|
if(!(waves[i].stillAlive())) {
|
||||||
//If a wave dies, reinitialize it starts over.
|
//If a wave dies, reinitialize it starts over.
|
||||||
waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3))));
|
waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random8(0, 3))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5025,7 +5027,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) {
|
if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) {
|
||||||
SEGENV.step = strip.now;
|
SEGENV.step = strip.now;
|
||||||
SEGENV.aux0 = 0;
|
SEGENV.aux0 = 0;
|
||||||
random16_set_seed(millis()>>2); //seed the random generator
|
//random16_set_seed(millis()>>2); //seed the random generator
|
||||||
|
|
||||||
//give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen)
|
//give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen)
|
||||||
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) {
|
for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) {
|
||||||
@ -5755,7 +5757,7 @@ uint16_t mode_2Dcrazybees(void) {
|
|||||||
uint8_t posX, posY, aimX, aimY, hue;
|
uint8_t posX, posY, aimX, aimY, hue;
|
||||||
int8_t deltaX, deltaY, signX, signY, error;
|
int8_t deltaX, deltaY, signX, signY, error;
|
||||||
void aimed(uint16_t w, uint16_t h) {
|
void aimed(uint16_t w, uint16_t h) {
|
||||||
random16_set_seed(millis());
|
//random16_set_seed(millis());
|
||||||
aimX = random8(0, w);
|
aimX = random8(0, w);
|
||||||
aimY = random8(0, h);
|
aimY = random8(0, h);
|
||||||
hue = random8();
|
hue = random8();
|
||||||
@ -5842,7 +5844,7 @@ uint16_t mode_2Dghostrider(void) {
|
|||||||
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
||||||
SEGENV.aux0 = cols;
|
SEGENV.aux0 = cols;
|
||||||
SEGENV.aux1 = rows;
|
SEGENV.aux1 = rows;
|
||||||
random16_set_seed(strip.now);
|
//random16_set_seed(strip.now);
|
||||||
lighter->angleSpeed = random8(0,20) - 10;
|
lighter->angleSpeed = random8(0,20) - 10;
|
||||||
lighter->gAngle = random16();
|
lighter->gAngle = random16();
|
||||||
lighter->Vspeed = 5;
|
lighter->Vspeed = 5;
|
||||||
@ -5883,7 +5885,7 @@ uint16_t mode_2Dghostrider(void) {
|
|||||||
if (lighter->reg[i]) {
|
if (lighter->reg[i]) {
|
||||||
lighter->lightersPosY[i] = lighter->gPosY;
|
lighter->lightersPosY[i] = lighter->gPosY;
|
||||||
lighter->lightersPosX[i] = lighter->gPosX;
|
lighter->lightersPosX[i] = lighter->gPosX;
|
||||||
lighter->Angle[i] = lighter->gAngle + random(-10, 10);
|
lighter->Angle[i] = lighter->gAngle + ((int)random8(20) - 10);
|
||||||
lighter->time[i] = 0;
|
lighter->time[i] = 0;
|
||||||
lighter->reg[i] = false;
|
lighter->reg[i] = false;
|
||||||
} else {
|
} else {
|
||||||
@ -6744,7 +6746,7 @@ uint16_t mode_puddlepeak(void) { // Puddlepeak. By Andrew Tuline.
|
|||||||
|
|
||||||
uint16_t size = 0;
|
uint16_t size = 0;
|
||||||
uint8_t fadeVal = map(SEGMENT.speed,0,255, 224, 254);
|
uint8_t fadeVal = map(SEGMENT.speed,0,255, 224, 254);
|
||||||
uint16_t pos = random(SEGLEN); // Set a random starting position.
|
uint16_t pos = random16(SEGLEN); // Set a random starting position.
|
||||||
|
|
||||||
um_data_t *um_data;
|
um_data_t *um_data;
|
||||||
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) {
|
||||||
|
@ -469,6 +469,7 @@ button {
|
|||||||
height: 54px;
|
height: 54px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* New tooltip */
|
/* New tooltip */
|
||||||
@ -1240,6 +1241,7 @@ TD .checkmark, TD .radiomark {
|
|||||||
.filter .fchkl {
|
.filter .fchkl {
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
min-width: 20px;
|
min-width: 20px;
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lbl-l {
|
.lbl-l {
|
||||||
|
@ -197,33 +197,33 @@
|
|||||||
<div id="Effects" class="tabcontent">
|
<div id="Effects" class="tabcontent">
|
||||||
<div id="fx">
|
<div id="fx">
|
||||||
<p class="labels hd" id="modeLabel">Effect mode</p>
|
<p class="labels hd" id="modeLabel">Effect mode</p>
|
||||||
<div class="staytop fnd" id="fxFind">
|
<div class="staytop fnd" id="fxFind" onmousedown="preventBlur(event);">
|
||||||
<input type="text" placeholder="Search" oninput="search(this,'fxlist')" onfocus="filterFocus(event);search(this,'fxlist');" onblur="filterFocus(event);" />
|
<input type="text" placeholder="Search" oninput="search(this,'fxlist')" onfocus="filterFocus(event);search(this,'fxlist');" onblur="filterFocus(event);">
|
||||||
<i class="icons clear-icon" onclick="clean(this);"></i>
|
<i class="icons clear-icon" onclick="clean(this);"></i>
|
||||||
<i class="icons search-icon" style="cursor:pointer;"></i>
|
<i class="icons search-icon" style="cursor:pointer;"></i>
|
||||||
<div id="filters" class="filter fade">
|
<div id="filters" class="filter fade">
|
||||||
<label id="filterPal" tooltip="Uses palette" class="check fchkl">🎨
|
<label id="filterPal" tooltip="Uses palette" class="check fchkl">🎨
|
||||||
<input type="checkbox" data-flt="🎨" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="🎨" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
<label id="filter0D" tooltip="Single pixel" class="check fchkl">•
|
<label id="filter0D" tooltip="Single pixel" class="check fchkl">•
|
||||||
<input type="checkbox" data-flt="•" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="•" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
<label id="filter1D" tooltip="1D" class="check fchkl">⋮
|
<label id="filter1D" tooltip="1D" class="check fchkl">⋮
|
||||||
<input type="checkbox" data-flt="⋮" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="⋮" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
<label id="filter2D" tooltip="2D" class="check fchkl">▦
|
<label id="filter2D" tooltip="2D" class="check fchkl">▦
|
||||||
<input type="checkbox" data-flt="▦" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="▦" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
<label id="filterVol" tooltip="Volume" class="check fchkl">♪
|
<label id="filterVol" tooltip="Volume" class="check fchkl">♪
|
||||||
<input type="checkbox" data-flt="♪" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="♪" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
<label id="filterFreq" tooltip="Frequency" class="check fchkl">♫
|
<label id="filterFreq" tooltip="Frequency" class="check fchkl">♫
|
||||||
<input type="checkbox" data-flt="♫" onchange="filterFx(this);">
|
<input type="checkbox" data-flt="♫" onchange="filterFx();">
|
||||||
<span class="checkmark"></span>
|
<span class="checkmark"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -232,6 +232,7 @@ function onLoad()
|
|||||||
|
|
||||||
tooltip();
|
tooltip();
|
||||||
resetPUtil();
|
resetPUtil();
|
||||||
|
initFilters();
|
||||||
|
|
||||||
if (localStorage.getItem('pcm') == "true" || (!/Mobi/.test(navigator.userAgent) && localStorage.getItem('pcm') == null)) togglePcMode(true);
|
if (localStorage.getItem('pcm') == "true" || (!/Mobi/.test(navigator.userAgent) && localStorage.getItem('pcm') == null)) togglePcMode(true);
|
||||||
applyCfg();
|
applyCfg();
|
||||||
@ -2716,58 +2717,94 @@ function hideModes(txt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
function search(f,l=null)
|
function search(field, listId = null) {
|
||||||
{
|
field.nextElementSibling.style.display = (field.value !== '') ? 'block' : 'none';
|
||||||
f.nextElementSibling.style.display=(f.value!=='')?'block':'none';
|
if (!listId) return;
|
||||||
if (!l) return;
|
|
||||||
var el = gId(l).querySelectorAll('.lstI');
|
// clear filter if searching in fxlist
|
||||||
|
if (listId === 'fxlist' && field.value !== '') {
|
||||||
|
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { e.checked = false; });
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not search if filter is active
|
||||||
|
if (gId("filters").querySelectorAll("input[type=checkbox]:checked").length) return;
|
||||||
|
|
||||||
|
const listItems = gId(listId).querySelectorAll('.lstI');
|
||||||
// filter list items but leave (Default & Solid) always visible
|
// filter list items but leave (Default & Solid) always visible
|
||||||
for (i = (l==='pcont'?0:1); i < el.length; i++) {
|
for (i = (listId === 'pcont' ? 0 : 1); i < listItems.length; i++) {
|
||||||
var it = el[i];
|
const listItem = listItems[i];
|
||||||
var itT = it.querySelector('.lstIname').innerText.toUpperCase();
|
const listItemName = listItem.querySelector('.lstIname').innerText.toUpperCase();
|
||||||
it.style.display = (itT.indexOf(f.value.toUpperCase())<0) ? 'none' : '';
|
const searchIndex = listItemName.indexOf(field.value.toUpperCase());
|
||||||
|
listItem.style.display = (searchIndex < 0) ? 'none' : '';
|
||||||
|
listItem.dataset.searchIndex = searchIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sort list items by search index and name
|
||||||
|
const sortedListItems = Array.from(listItems).sort((a, b) => {
|
||||||
|
const aSearchIndex = parseInt(a.dataset.searchIndex);
|
||||||
|
const bSearchIndex = parseInt(b.dataset.searchIndex);
|
||||||
|
|
||||||
|
if (aSearchIndex !== bSearchIndex) {
|
||||||
|
return aSearchIndex - bSearchIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const aName = a.querySelector('.lstIname').innerText.toUpperCase();
|
||||||
|
const bName = b.querySelector('.lstIname').innerText.toUpperCase();
|
||||||
|
|
||||||
|
return aName.localeCompare(bName);
|
||||||
|
});
|
||||||
|
sortedListItems.forEach(item => {
|
||||||
|
gId(listId).append(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean(c)
|
function clean(clearButton) {
|
||||||
{
|
clearButton.style.display = 'none';
|
||||||
c.style.display='none';
|
const inputField = clearButton.previousElementSibling;
|
||||||
var i=c.previousElementSibling;
|
inputField.value = '';
|
||||||
i.value='';
|
search(inputField, clearButton.parentElement.nextElementSibling.id);
|
||||||
i.focus();
|
|
||||||
i.dispatchEvent(new Event('input'));
|
|
||||||
if (i.parentElement.id=='fxFind') {
|
|
||||||
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e)=>{e.checked=false;});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterFocus(e)
|
function initFilters() {
|
||||||
{
|
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { e.checked = false; });
|
||||||
let f = gId("filters");
|
}
|
||||||
|
|
||||||
|
function filterFocus(e) {
|
||||||
|
const f = gId("filters");
|
||||||
if (e.type === "focus") f.classList.remove('fade'); // immediately show (still has transition)
|
if (e.type === "focus") f.classList.remove('fade'); // immediately show (still has transition)
|
||||||
// compute sticky top (with delay for transition)
|
// compute sticky top (with delay for transition)
|
||||||
setTimeout(()=>{
|
setTimeout(() => {
|
||||||
let sti = parseInt(getComputedStyle(d.documentElement).getPropertyValue('--sti')) + (e.type === "focus" ? 1 : -1) * f.offsetHeight;
|
const sti = parseInt(getComputedStyle(d.documentElement).getPropertyValue('--sti')) + (e.type === "focus" ? 1 : -1) * f.offsetHeight;
|
||||||
sCol('--sti', sti+"px");
|
sCol('--sti', sti + "px");
|
||||||
}, 252);
|
}, 252);
|
||||||
if (e.type === "blur") {
|
if (e.type === "blur") {
|
||||||
let t = e.relatedTarget ? e.relatedTarget : e.explicitOriginalTarget;
|
setTimeout(() => {
|
||||||
do {
|
if (e.target === document.activeElement && document.hasFocus()) return;
|
||||||
if (t.id && (t.id === "fxFind")) { setTimeout(()=>{t.firstElementChild.focus();},150); return; }
|
// do not hide if filter is active
|
||||||
t = t.parentElement;
|
if (gId("filters").querySelectorAll("input[type=checkbox]:checked").length) return;
|
||||||
} while (t.tagName !== "BODY");
|
f.classList.add('fade');
|
||||||
setTimeout(()=>{f.classList.add('fade');},255); // wait with hiding
|
}, 255); // wait with hiding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterFx(o)
|
function filterFx() {
|
||||||
{
|
const inputField = gId('fxFind').children[0];
|
||||||
if (!o) return;
|
inputField.value = '';
|
||||||
let i = gId('fxFind').children[0];
|
inputField.focus();
|
||||||
i.value=!o.checked?'':o.dataset.flt;
|
clean(inputField.nextElementSibling);
|
||||||
i.focus();
|
const listItems = gId("fxlist").querySelectorAll('.lstI');
|
||||||
i.dispatchEvent(new Event('input'));
|
for (let i = 1; i < listItems.length; i++) {
|
||||||
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e)=>{if(e!==o)e.checked=false;});
|
const listItem = listItems[i];
|
||||||
|
const listItemName = listItem.querySelector('.lstIname').innerText;
|
||||||
|
let hide = false;
|
||||||
|
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { if (e.checked && !listItemName.includes(e.dataset.flt)) hide = true; });
|
||||||
|
listItem.style.display = hide ? 'none' : '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function preventBlur(e) {
|
||||||
|
if (e.target === gId("fxFind").children[0] || e.target === gId("filters")) return;
|
||||||
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure "dur" and "transition" are arrays with at least the length of "ps"
|
// make sure "dur" and "transition" are arrays with at least the length of "ps"
|
||||||
|
@ -52,51 +52,55 @@
|
|||||||
maxB = b; maxV = v; maxM = m; maxPB = p; maxL = l;
|
maxB = b; maxV = v; maxM = m; maxPB = p; maxL = l;
|
||||||
}
|
}
|
||||||
function pinsOK() {
|
function pinsOK() {
|
||||||
var LCs = d.Sf.querySelectorAll("#mLC input[name^=L]"); // input fields
|
var ok = true;
|
||||||
for (i=0; i<LCs.length; i++) {
|
var nList = d.Sf.querySelectorAll("#mLC input[name^=L]");
|
||||||
var nm = LCs[i].name.substring(0,2);
|
nList.forEach((LC,i)=>{
|
||||||
|
if (!ok) return; // prevent iteration after conflict
|
||||||
|
let nm = LC.name.substring(0,2);
|
||||||
|
let n = LC.name.substring(2);
|
||||||
|
let t = parseInt(d.Sf["LT"+n].value, 10); // LED type SELECT
|
||||||
// ignore IP address
|
// ignore IP address
|
||||||
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3") {
|
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3") {
|
||||||
var n = LCs[i].name.substring(2);
|
if (t>=80) return;
|
||||||
var t = parseInt(d.getElementsByName("LT"+n)[0].value, 10); // LED type SELECT
|
|
||||||
if (t>=80) continue;
|
|
||||||
}
|
}
|
||||||
//check for pin conflicts
|
//check for pin conflicts
|
||||||
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3" || nm=="L4"/* || nm=="RL" || nm=="BT" || nm=="IR"*/)
|
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3" || nm=="L4")
|
||||||
if (LCs[i].value!="" && LCs[i].value!="-1") {
|
if (LC.value!="" && LC.value!="-1") {
|
||||||
var p = d.rsvd.concat(d.um_p); // used pin array
|
let p = d.rsvd.concat(d.um_p); // used pin array
|
||||||
d.Sf.querySelectorAll("select.pin").forEach((e)=>{if(e.value>-1)p.push(parseInt(e.value));}) // buttons, IR & relay
|
d.Sf.querySelectorAll("select.pin").forEach((e)=>{if(e.value>-1)p.push(parseInt(e.value));}) // buttons, IR & relay
|
||||||
if (p.some((e)=>e==parseInt(LCs[i].value))) {
|
if (p.some((e)=>e==parseInt(LC.value))) {
|
||||||
alert(`Sorry, pins ${JSON.stringify(p)} can't be used.`);
|
alert(`Sorry, pins ${JSON.stringify(p)} can't be used.`);
|
||||||
LCs[i].value="";
|
LC.value="";
|
||||||
LCs[i].focus();
|
LC.focus();
|
||||||
return false;
|
ok = false;
|
||||||
}
|
return;
|
||||||
else if (/*!(nm == "IR" || nm=="BT") &&*/ d.ro_gpio.some((e)=>e==parseInt(LCs[i].value))) {
|
} else if (d.ro_gpio.some((e)=>e==parseInt(LC.value))) {
|
||||||
alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);
|
alert(`Sorry, pins ${JSON.stringify(d.ro_gpio)} are input only.`);
|
||||||
LCs[i].value="";
|
LC.value="";
|
||||||
LCs[i].focus();
|
LC.focus();
|
||||||
return false;
|
ok = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
for (j=i+1; j<LCs.length; j++) {
|
for (j=i+1; j<nList.length; j++) {
|
||||||
var n2 = LCs[j].name.substring(0,2);
|
let n2 = nList[j].name.substring(0,2);
|
||||||
if (n2=="L0" || n2=="L1" || n2=="L2" || n2=="L3" || n2=="L4"/* || n2=="RL" || n2=="BT" || n2=="IR"*/) {
|
if (n2=="L0" || n2=="L1" || n2=="L2" || n2=="L3" || n2=="L4") {
|
||||||
if (n2.substring(0,1)==="L") {
|
if (n2.substring(0,1)==="L") {
|
||||||
var m = LCs[j].name.substring(2);
|
var m = nList[j].name.substring(2);
|
||||||
var t2 = parseInt(d.getElementsByName("LT"+m)[0].value, 10);
|
var t2 = parseInt(d.Sf["LT"+m].value, 10);
|
||||||
if (t2>=80) continue;
|
if (t2>=80) continue;
|
||||||
}
|
}
|
||||||
if (LCs[j].value!="" && LCs[i].value==LCs[j].value) {
|
if (nList[j].value!="" && nList[i].value==nList[j].value) {
|
||||||
alert(`Pin conflict between ${LCs[i].name}/${LCs[j].name}!`);
|
alert(`Pin conflict between ${LC.name}/${nList[j].name}!`);
|
||||||
LCs[j].value="";
|
nList[j].value="";
|
||||||
LCs[j].focus();
|
nList[j].focus();
|
||||||
return false;
|
ok = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return true;
|
return ok;
|
||||||
}
|
}
|
||||||
function trySubmit(e) {
|
function trySubmit(e) {
|
||||||
d.Sf.data.value = '';
|
d.Sf.data.value = '';
|
||||||
@ -206,7 +210,7 @@
|
|||||||
|
|
||||||
// enumerate pins
|
// enumerate pins
|
||||||
for (p=1; p<5; p++) {
|
for (p=1; p<5; p++) {
|
||||||
var LK = d.getElementsByName("L"+p+n)[0]; // secondary pins
|
var LK = d.Sf["L"+p+n]; // secondary pins
|
||||||
if (!LK) continue;
|
if (!LK) continue;
|
||||||
if (((t>=80 && t<96) && p<4) || (t>49 && p==1) || (t>41 && t < 50 && (p+40 < t))) // TYPE_xxxx values from const.h
|
if (((t>=80 && t<96) && p<4) || (t>49 && p==1) || (t>41 && t < 50 && (p+40 < t))) // TYPE_xxxx values from const.h
|
||||||
{
|
{
|
||||||
@ -222,7 +226,7 @@
|
|||||||
}
|
}
|
||||||
if (change) {
|
if (change) {
|
||||||
gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state
|
gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state
|
||||||
if (t > 31 && t < 48) d.getElementsByName("LC"+n)[0].value = 1; // for sanity change analog count just to 1 LED
|
if (t > 31 && t < 48) d.Sf["LC"+n].value = 1; // for sanity change analog count just to 1 LED
|
||||||
d.Sf["LA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 1;
|
d.Sf["LA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 1;
|
||||||
d.Sf["MA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 250;
|
d.Sf["MA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 250;
|
||||||
}
|
}
|
||||||
@ -230,7 +234,7 @@
|
|||||||
gRGBW |= isRGBW = ((t > 17 && t < 22) || (t > 28 && t < 32) || (t > 40 && t < 46 && t != 43) || t == 88); // RGBW checkbox, TYPE_xxxx values from const.h
|
gRGBW |= isRGBW = ((t > 17 && t < 22) || (t > 28 && t < 32) || (t > 40 && t < 46 && t != 43) || t == 88); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||||
gId("co"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide color order for PWM
|
gId("co"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide color order for PWM
|
||||||
gId("dig"+n+"w").style.display = (t > 28 && t < 32) ? "inline":"none"; // show swap channels dropdown
|
gId("dig"+n+"w").style.display = (t > 28 && t < 32) ? "inline":"none"; // show swap channels dropdown
|
||||||
if (!(t > 28 && t < 32)) d.getElementsByName("WO"+n)[0].value = 0; // reset swapping
|
if (!(t > 28 && t < 32)) d.Sf["WO"+n].value = 0; // reset swapping
|
||||||
gId("dig"+n+"c").style.display = (t >= 40 && t < 48) ? "none":"inline"; // hide count for analog
|
gId("dig"+n+"c").style.display = (t >= 40 && t < 48) ? "none":"inline"; // hide count for analog
|
||||||
gId("dig"+n+"r").style.display = (t >= 80 && t < 96) ? "none":"inline"; // hide reversed for virtual
|
gId("dig"+n+"r").style.display = (t >= 80 && t < 96) ? "none":"inline"; // hide reversed for virtual
|
||||||
gId("dig"+n+"s").style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
gId("dig"+n+"s").style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
||||||
@ -249,75 +253,69 @@
|
|||||||
d.Sf.AW.selectedIndex = 0;
|
d.Sf.AW.selectedIndex = 0;
|
||||||
d.Sf.CR.checked = false;
|
d.Sf.CR.checked = false;
|
||||||
}
|
}
|
||||||
// check for pin conflicts
|
// update start indexes, max values, calculate current, etc
|
||||||
var LCs = d.Sf.querySelectorAll("#mLC input[name^=L]"); // input fields
|
var nList = d.Sf.querySelectorAll("#mLC input[name^=L]");
|
||||||
for (i=0; i<LCs.length; i++) {
|
nList.forEach((LC,i)=>{
|
||||||
var nm = LCs[i].name.substring(0,2); // field name
|
let nm = LC.name.substring(0,2); // field name
|
||||||
var n = LCs[i].name.substring(2); // bus number
|
let n = LC.name.substring(2); // bus number
|
||||||
|
let t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||||
// do we have a led count field
|
// do we have a led count field
|
||||||
if (nm=="LC") {
|
if (nm=="LC") {
|
||||||
var c=parseInt(LCs[i].value,10); //get LED count
|
let c = parseInt(LC.value,10); //get LED count
|
||||||
if (!customStarts || !startsDirty[n]) gId("ls"+n).value=sLC; //update start value
|
if (!customStarts || !startsDirty[n]) gId("ls"+n).value=sLC; //update start value
|
||||||
gId("ls"+n).disabled = !customStarts; //enable/disable field editing
|
gId("ls"+n).disabled = !customStarts; //enable/disable field editing
|
||||||
if(c){
|
if (c) {
|
||||||
var s = parseInt(gId("ls"+n).value); //start value
|
let s = parseInt(gId("ls"+n).value); //start value
|
||||||
if (s+c > sLC) sLC = s+c; //update total count
|
if (s+c > sLC) sLC = s+c; //update total count
|
||||||
if(c>maxLC)maxLC=c; //max per output
|
if (c > maxLC) maxLC = c; //max per output
|
||||||
var t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
if (t < 80) sPC += c; //virtual out busses do not count towards physical LEDs
|
||||||
if (t<80) sPC+=c; //virtual out busses do not count towards physical LEDs
|
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) sDI += c;
|
||||||
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) sDI+=c;
|
|
||||||
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) {
|
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) {
|
||||||
let maPL = parseInt(d.Sf["LA"+n].value);
|
let maPL = parseInt(d.Sf["LA"+n].value);
|
||||||
if (maPL==255) maPL = 12;
|
if (maPL == 255) maPL = 12;
|
||||||
busMA += maPL*c;
|
busMA += maPL*c;
|
||||||
}
|
}
|
||||||
} // increase led count
|
} // increase led count
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
// do we have led pins for digital leds
|
// do we have led pins for digital leds
|
||||||
if (nm=="L0" || nm=="L1") {
|
if (nm=="L0" || nm=="L1") {
|
||||||
var lc=d.Sf["LC"+n];
|
d.Sf["LC"+n].max = maxPB; // update max led count value
|
||||||
lc.max=maxPB; // update max led count value
|
|
||||||
}
|
}
|
||||||
// ignore IP address (stored in pins for virtual busses)
|
// ignore IP address (stored in pins for virtual busses)
|
||||||
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3") {
|
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3") {
|
||||||
var t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
|
||||||
if (t>=80) {
|
if (t>=80) {
|
||||||
LCs[i].max = 255;
|
LC.max = 255;
|
||||||
LCs[i].min = 0;
|
LC.min = 0;
|
||||||
LCs[i].style.color="#fff";
|
LC.style.color="#fff";
|
||||||
continue; // do not check conflicts
|
return; // do not check conflicts
|
||||||
} else {
|
} else {
|
||||||
LCs[i].max = d.max_gpio;
|
LC.max = d.max_gpio;
|
||||||
LCs[i].min = -1;
|
LC.min = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check for pin conflicts
|
// check for pin conflicts & color fields
|
||||||
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3" || nm=="L4"/* || nm=="RL" || nm=="BT" || nm=="IR"*/)
|
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3" || nm=="L4")
|
||||||
if (LCs[i].value!="" && LCs[i].value!="-1") {
|
if (LC.value!="" && LC.value!="-1") {
|
||||||
var p = d.rsvd.concat(d.um_p); // used pin array
|
let p = d.rsvd.concat(d.um_p); // used pin array
|
||||||
d.Sf.querySelectorAll("select.pin").forEach((e)=>{if(e.value>-1)p.push(parseInt(e.value));}) // buttons, IR & relay
|
d.Sf.querySelectorAll("select.pin").forEach((e)=>{if(e.value>-1)p.push(parseInt(e.value));}) // buttons, IR & relay
|
||||||
for (j=0; j<LCs.length; j++) {
|
for (j=0; j<nList.length; j++) {
|
||||||
if (i==j) continue;
|
if (i==j) continue;
|
||||||
var n2 = LCs[j].name.substring(0,2);
|
let n2 = nList[j].name.substring(0,2);
|
||||||
if (n2=="L0" || n2=="L1" || n2=="L2" || n2=="L3" || n2=="L4"/* || n2=="RL" || n2=="BT" || n2=="IR"*/) {
|
if (n2=="L0" || n2=="L1" || n2=="L2" || n2=="L3" || n2=="L4") {
|
||||||
if (n2.substring(0,1)==="L") {
|
if (n2.substring(0,1)==="L") {
|
||||||
var m = LCs[j].name.substring(2);
|
let m = nList[j].name.substring(2);
|
||||||
var t2 = parseInt(d.Sf["LT"+m].value, 10);
|
let t2 = parseInt(d.Sf["LT"+m].value, 10);
|
||||||
if (t2>=80) continue;
|
if (t2 >= 80) continue;
|
||||||
}
|
}
|
||||||
if (LCs[j].value!="" && LCs[j].value!="-1") p.push(parseInt(LCs[j].value,10)); // add current pin
|
if (nList[j].value!="" && nList[j].value!="-1") p.push(parseInt(nList[j].value,10)); // add current pin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now check for conflicts
|
// now check for conflicts
|
||||||
if (p.some((e)=>e==parseInt(LCs[i].value))) LCs[i].style.color="red"; else LCs[i].style.color=d.ro_gpio.some((e)=>e==parseInt(LCs[i].value))?"orange":"#fff";
|
if (p.some((e)=>e==parseInt(LC.value))) LC.style.color = "red";
|
||||||
}
|
else LC.style.color = d.ro_gpio.some((e)=>e==parseInt(LC.value)) ? "orange" : "#fff";
|
||||||
// check buttons, IR & relay
|
|
||||||
//if (nm=="IR" || nm=="BT" || nm=="RL") {
|
|
||||||
// LCs[i].max = d.max_gpio;
|
|
||||||
// LCs[i].min = -1;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
d.Sf.querySelectorAll("#mLC input[name^=LC]").forEach((s,n)=>{
|
d.Sf.querySelectorAll("#mLC input[name^=LC]").forEach((s,n)=>{
|
||||||
let c = parseInt(s.value,10); //get LED count
|
let c = parseInt(s.value,10); //get LED count
|
||||||
let t = parseInt(d.Sf["LT"+n].value);
|
let t = parseInt(d.Sf["LT"+n].value);
|
||||||
|
File diff suppressed because it is too large
Load Diff
4086
wled00/html_ui.h
4086
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -495,6 +495,16 @@ void WLED::setup()
|
|||||||
initServer();
|
initServer();
|
||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
|
// Seed FastLED random functions with an esp random value, which already works properly at this point.
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
const uint32_t seed32 = esp_random();
|
||||||
|
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
const uint32_t seed32 = RANDOM_REG32;
|
||||||
|
#else
|
||||||
|
const uint32_t seed32 = random(std::numeric_limits<long>::max());
|
||||||
|
#endif
|
||||||
|
random16_set_seed((uint16_t)((seed32 & 0xFFFF) ^ (seed32 >> 16)));
|
||||||
|
|
||||||
#if WLED_WATCHDOG_TIMEOUT > 0
|
#if WLED_WATCHDOG_TIMEOUT > 0
|
||||||
enableWatchdog();
|
enableWatchdog();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user