UI: show color controls based on segment light capabilities (#2567)
* Dynamic hiding of unused color controls in UI (e.g. a PWM white bus with no auto white mode will not display the color wheel or palette list) * Store segment capabilities Don't use palettes if no RGB supported Make it safe to update busses using `/json/cfg`
This commit is contained in:
parent
85b1c309d1
commit
9c864c9759
11
wled00/FX.h
11
wled00/FX.h
@ -247,7 +247,7 @@ class WS2812FX {
|
|||||||
|
|
||||||
// segment parameters
|
// segment parameters
|
||||||
public:
|
public:
|
||||||
typedef struct Segment { // 30 (32 in memory) bytes
|
typedef struct Segment { // 31 (32 in memory) bytes
|
||||||
uint16_t start;
|
uint16_t start;
|
||||||
uint16_t stop; //segment invalid if stop == 0
|
uint16_t stop; //segment invalid if stop == 0
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
@ -260,6 +260,7 @@ class WS2812FX {
|
|||||||
uint8_t opacity;
|
uint8_t opacity;
|
||||||
uint32_t colors[NUM_COLORS];
|
uint32_t colors[NUM_COLORS];
|
||||||
uint8_t cct; //0==1900K, 255==10091K
|
uint8_t cct; //0==1900K, 255==10091K
|
||||||
|
uint8_t _capabilities;
|
||||||
char *name;
|
char *name;
|
||||||
bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed
|
bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed
|
||||||
if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false;
|
if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false;
|
||||||
@ -335,7 +336,8 @@ class WS2812FX {
|
|||||||
return vLength;
|
return vLength;
|
||||||
}
|
}
|
||||||
uint8_t differs(Segment& b);
|
uint8_t differs(Segment& b);
|
||||||
uint8_t getLightCapabilities();
|
inline uint8_t getLightCapabilities() {return _capabilities;}
|
||||||
|
void refreshLightCapabilities();
|
||||||
} segment;
|
} segment;
|
||||||
|
|
||||||
// segment runtime parameters
|
// segment runtime parameters
|
||||||
@ -887,14 +889,15 @@ class WS2812FX {
|
|||||||
|
|
||||||
uint32_t _colors_t[3];
|
uint32_t _colors_t[3];
|
||||||
uint8_t _bri_t;
|
uint8_t _bri_t;
|
||||||
|
bool _no_rgb = false;
|
||||||
|
|
||||||
uint8_t _segment_index = 0;
|
uint8_t _segment_index = 0;
|
||||||
uint8_t _segment_index_palette_last = 99;
|
uint8_t _segment_index_palette_last = 99;
|
||||||
uint8_t _mainSegment;
|
uint8_t _mainSegment;
|
||||||
|
|
||||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element
|
||||||
// start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[]
|
// start, stop, offset, speed, intensity, palette, mode, options, grouping, spacing, opacity (unused), color[], capabilities
|
||||||
{0, 7, 0, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}}
|
{0, 7, 0, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}, 0}
|
||||||
};
|
};
|
||||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element
|
||||||
friend class Segment_runtime;
|
friend class Segment_runtime;
|
||||||
|
@ -152,7 +152,14 @@ void WS2812FX::service() {
|
|||||||
_colors_t[slot] = transitions[t].currentColor(SEGMENT.colors[slot]);
|
_colors_t[slot] = transitions[t].currentColor(SEGMENT.colors[slot]);
|
||||||
}
|
}
|
||||||
if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB);
|
if (!cctFromRgb || correctWB) busses.setSegmentCCT(_cct_t, correctWB);
|
||||||
for (uint8_t c = 0; c < 3; c++) _colors_t[c] = gamma32(_colors_t[c]);
|
_no_rgb = !(SEGMENT.getLightCapabilities() & 0x01);
|
||||||
|
for (uint8_t c = 0; c < NUM_COLORS; c++) {
|
||||||
|
// if segment is not RGB capable, treat RGB channels of main segment colors as if 0
|
||||||
|
// this prevents Dual mode with white value 0 from setting White channel from inaccessible RGB values
|
||||||
|
// If not RGB capable, also treat palette as if default (0), as palettes set white channel to 0
|
||||||
|
if (_no_rgb) _colors_t[c] = _colors_t[c] & 0xFF000000;
|
||||||
|
_colors_t[c] = gamma32(_colors_t[c]);
|
||||||
|
}
|
||||||
handle_palette();
|
handle_palette();
|
||||||
delay = (this->*_mode[SEGMENT.mode])(); //effect function
|
delay = (this->*_mode[SEGMENT.mode])(); //effect function
|
||||||
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++;
|
||||||
@ -561,8 +568,10 @@ uint8_t WS2812FX::Segment::differs(Segment& b) {
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t WS2812FX::Segment::getLightCapabilities() {
|
void WS2812FX::Segment::refreshLightCapabilities() {
|
||||||
if (!isActive()) return 0;
|
if (!isActive()) {
|
||||||
|
_capabilities = 0; return;
|
||||||
|
}
|
||||||
uint8_t capabilities = 0;
|
uint8_t capabilities = 0;
|
||||||
uint8_t awm = Bus::getAutoWhiteMode();
|
uint8_t awm = Bus::getAutoWhiteMode();
|
||||||
bool whiteSlider = (awm == RGBW_MODE_DUAL || awm == RGBW_MODE_MANUAL_ONLY);
|
bool whiteSlider = (awm == RGBW_MODE_DUAL || awm == RGBW_MODE_MANUAL_ONLY);
|
||||||
@ -588,7 +597,7 @@ uint8_t WS2812FX::Segment::getLightCapabilities() {
|
|||||||
}
|
}
|
||||||
if (correctWB && type != TYPE_ANALOG_1CH) capabilities |= 0x04; //white balance correction (uses CCT slider)
|
if (correctWB && type != TYPE_ANALOG_1CH) capabilities |= 0x04; //white balance correction (uses CCT slider)
|
||||||
}
|
}
|
||||||
return capabilities;
|
_capabilities = capabilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
//used for JSON API info.leds.rgbw. Little practical use, deprecate with info.leds.rgbw.
|
//used for JSON API info.leds.rgbw. Little practical use, deprecate with info.leds.rgbw.
|
||||||
@ -627,7 +636,8 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
|
|||||||
Segment& seg = _segments[n];
|
Segment& seg = _segments[n];
|
||||||
|
|
||||||
//return if neither bounds nor grouping have changed
|
//return if neither bounds nor grouping have changed
|
||||||
if (seg.start == i1 && seg.stop == i2
|
bool boundsUnchanged = (seg.start == i1 && seg.stop == i2);
|
||||||
|
if (boundsUnchanged
|
||||||
&& (!grouping || (seg.grouping == grouping && seg.spacing == spacing))
|
&& (!grouping || (seg.grouping == grouping && seg.spacing == spacing))
|
||||||
&& (offset == UINT16_MAX || offset == seg.offset)) return;
|
&& (offset == UINT16_MAX || offset == seg.offset)) return;
|
||||||
|
|
||||||
@ -652,6 +662,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
|
|||||||
}
|
}
|
||||||
if (offset < UINT16_MAX) seg.offset = offset;
|
if (offset < UINT16_MAX) seg.offset = offset;
|
||||||
_segment_runtimes[n].markForReset();
|
_segment_runtimes[n].markForReset();
|
||||||
|
if (!boundsUnchanged) seg.refreshLightCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::restartRuntime() {
|
void WS2812FX::restartRuntime() {
|
||||||
@ -741,6 +752,8 @@ void WS2812FX::fixInvalidSegments() {
|
|||||||
{
|
{
|
||||||
if (_segments[i].start >= _length) setSegment(i, 0, 0);
|
if (_segments[i].start >= _length) setSegment(i, 0, 0);
|
||||||
if (_segments[i].stop > _length) setSegment(i, _segments[i].start, _length);
|
if (_segments[i].stop > _length) setSegment(i, _segments[i].start, _length);
|
||||||
|
// this is always called as the last step after finalizeInit(), update covered bus types
|
||||||
|
getSegment(i).refreshLightCapabilities();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,22 +1129,17 @@ void WS2812FX::handle_palette(void)
|
|||||||
*/
|
*/
|
||||||
uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
uint32_t IRAM_ATTR WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri)
|
||||||
{
|
{
|
||||||
if (SEGMENT.palette == 0 && mcol < 3) {
|
if ((SEGMENT.palette == 0 && mcol < 3) || _no_rgb) {
|
||||||
uint32_t color = SEGCOLOR(mcol);
|
uint32_t color = SEGCOLOR(mcol);
|
||||||
if (pbri != 255) {
|
if (pbri == 255) return color;
|
||||||
CRGB crgb_color = col_to_crgb(color);
|
return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri));
|
||||||
crgb_color.nscale8_video(pbri);
|
|
||||||
return crgb_to_col(crgb_color);
|
|
||||||
} else {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t paletteIndex = i;
|
uint8_t paletteIndex = i;
|
||||||
if (mapping && SEGLEN > 1) paletteIndex = (i*255)/(SEGLEN -1);
|
if (mapping && SEGLEN > 1) paletteIndex = (i*255)/(SEGLEN -1);
|
||||||
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||||
CRGB fastled_col;
|
CRGB fastled_col;
|
||||||
fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
|
fastled_col = ColorFromPalette(currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND);
|
||||||
|
|
||||||
return crgb_to_col(fastled_col);
|
return crgb_to_col(fastled_col);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
||||||
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
||||||
Bus::setAutoWhiteMode(hw_led[F("rgbwm")] | Bus::getAutoWhiteMode());
|
Bus::setAutoWhiteMode(hw_led[F("rgbwm")] | Bus::getAutoWhiteMode());
|
||||||
|
strip.fixInvalidSegments(); // refreshes segment light capabilities (in case auto white mode changed)
|
||||||
CJSON(correctWB, hw_led["cct"]);
|
CJSON(correctWB, hw_led["cct"]);
|
||||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||||
@ -91,7 +92,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
|
|
||||||
if (fromFS || !ins.isNull()) {
|
if (fromFS || !ins.isNull()) {
|
||||||
uint8_t s = 0; // bus iterator
|
uint8_t s = 0; // bus iterator
|
||||||
busses.removeAll();
|
if (fromFS) busses.removeAll(); // can't safely manipulate busses directly in network callback
|
||||||
uint32_t mem = 0;
|
uint32_t mem = 0;
|
||||||
for (JsonObject elm : ins) {
|
for (JsonObject elm : ins) {
|
||||||
if (s >= WLED_MAX_BUSSES) break;
|
if (s >= WLED_MAX_BUSSES) break;
|
||||||
@ -113,11 +114,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
|
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
|
||||||
bool reversed = elm["rev"];
|
bool reversed = elm["rev"];
|
||||||
bool refresh = elm["ref"] | false;
|
bool refresh = elm["ref"] | false;
|
||||||
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
||||||
s++;
|
s++;
|
||||||
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
|
if (fromFS) {
|
||||||
mem += BusManager::memUsage(bc);
|
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
|
||||||
if (mem <= MAX_LED_MEMORY && busses.getNumBusses() <= WLED_MAX_BUSSES) busses.add(bc); // finalization will be done in WLED::beginStrip()
|
mem += BusManager::memUsage(bc);
|
||||||
|
if (mem <= MAX_LED_MEMORY && busses.getNumBusses() <= WLED_MAX_BUSSES) busses.add(bc); // finalization will be done in WLED::beginStrip()
|
||||||
|
} else {
|
||||||
|
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||||
|
busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
|
||||||
|
doInitBusses = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// finalization done in beginStrip()
|
// finalization done in beginStrip()
|
||||||
}
|
}
|
||||||
|
@ -533,7 +533,8 @@ input[type=range]:active + .sliderbubble {
|
|||||||
display: inline;
|
display: inline;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
#wwrap, #wbal {
|
/* hide color controls until enabled in updateUI() */
|
||||||
|
#pwrap, #wwrap, #wbal, #rgbwrap, #palwrap {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,10 +567,6 @@ input[type=range]:active + .sliderbubble {
|
|||||||
width: 260px;
|
width: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rgbwrap {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
@ -623,6 +620,7 @@ input[type=range]:active + .sliderbubble {
|
|||||||
/* Quick color select buttons wrapper div */
|
/* Quick color select buttons wrapper div */
|
||||||
#qcs-w {
|
#qcs-w {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Quick color select buttons */
|
/* Quick color select buttons */
|
||||||
|
@ -44,13 +44,15 @@
|
|||||||
|
|
||||||
<div class ="container">
|
<div class ="container">
|
||||||
<div id="Colors" class="tabcontent">
|
<div id="Colors" class="tabcontent">
|
||||||
<div id="picker" class="noslide"></div>
|
<div id="pwrap">
|
||||||
<div id="vwrap">
|
<div id="picker" class="noslide"></div>
|
||||||
<div class="sliderwrap il" id="vwrap">
|
<div id="vwrap">
|
||||||
<input id="sliderV" class="noslide" oninput="fromV()" onchange="setColor(0)" max="100" min="0" type="range" value="128" step="any" />
|
<div class="sliderwrap il" id="vwrap">
|
||||||
<div class="sliderdisplay"></div>
|
<input id="sliderV" class="noslide" oninput="fromV()" onchange="setColor(0)" max="100" min="0" type="range" value="128" step="any" />
|
||||||
</div><br>
|
<div class="sliderdisplay"></div>
|
||||||
</div>
|
</div><br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="kwrap">
|
<div id="kwrap">
|
||||||
<div class="sliderwrap il">
|
<div class="sliderwrap il">
|
||||||
<input id="sliderK" class="noslide" oninput="fromK()" onchange="setColor(0)" max="10091" min="1900" type="range" value="6550" />
|
<input id="sliderK" class="noslide" oninput="fromK()" onchange="setColor(0)" max="10091" min="1900" type="range" value="6550" />
|
||||||
@ -108,32 +110,26 @@
|
|||||||
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter()" autocomplete="off" maxlength="8" />
|
<input id="hexc" type="text" class="noslide" onkeydown="hexEnter()" autocomplete="off" maxlength="8" />
|
||||||
<button id="hexcnf" class="xxs btn" onclick="fromHex();"><i class="icons no-margin"></i></button>
|
<button id="hexcnf" class="xxs btn" onclick="fromHex();"><i class="icons no-margin"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<p class="labels">
|
<div id="palwrap">
|
||||||
<i class="icons sel-icon" onclick="tglHex()"></i>
|
<p class="labels">
|
||||||
Color palette
|
<i class="icons sel-icon" onclick="tglHex()"></i>
|
||||||
</p>
|
Color palette
|
||||||
<div class="il">
|
</p>
|
||||||
<div id="pallist" class="list">
|
<div class="il">
|
||||||
<div class="lstI" data-id="0">
|
<div id="pallist" class="list">
|
||||||
<label class="check schkl">
|
<div class="lstI" data-id="0">
|
||||||
|
<label class="check schkl">
|
||||||
<input type="radio" value="${palettes[i].id}" name="palette" onChange="setPalette()">
|
|
||||||
<span class="radiomark schk"></span>
|
<input type="radio" value="${palettes[i].id}" name="palette" onChange="setPalette()">
|
||||||
</label>
|
<span class="radiomark schk"></span>
|
||||||
<div class="lstIcontent">
|
</label>
|
||||||
<span class="lstIname">
|
<div class="lstIcontent">
|
||||||
Default
|
<span class="lstIname">
|
||||||
</span>
|
Default
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lstI">
|
|
||||||
<div class="lstIcontent">
|
|
||||||
<span class="lstIname">
|
|
||||||
Loading...
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
//page js
|
//page js
|
||||||
var loc = false, locip;
|
var loc = false, locip;
|
||||||
var noNewSegs = false;
|
var noNewSegs = false;
|
||||||
var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true, isRgbw = false;
|
var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true;
|
||||||
|
var hasWhite = false, hasRGB = false, hasCCT = false;
|
||||||
var whites = [0,0,0];
|
var whites = [0,0,0];
|
||||||
var colors = [[0,0,0],[0,0,0],[0,0,0]];
|
var colors = [[0,0,0],[0,0,0],[0,0,0]];
|
||||||
var expanded = [false];
|
var expanded = [false];
|
||||||
@ -60,6 +61,10 @@ function sCol(na, col) {
|
|||||||
d.documentElement.style.setProperty(na, col);
|
d.documentElement.style.setProperty(na, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRgbBlack(a, s) {
|
||||||
|
return (a[s][0] == 0 && a[s][1] == 0 && a[s][2] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// returns RGB color from a given slot s 0-2 from color array a
|
// returns RGB color from a given slot s 0-2 from color array a
|
||||||
function rgbStr(a, s) {
|
function rgbStr(a, s) {
|
||||||
return "rgb(" + a[s][0] + "," + a[s][1] + "," + a[s][2] + ")";
|
return "rgb(" + a[s][0] + "," + a[s][1] + "," + a[s][2] + ")";
|
||||||
@ -72,10 +77,20 @@ function rgbBri(a, s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sets background of color slot selectors
|
// sets background of color slot selectors
|
||||||
function setCSL(a, s) {
|
function setCSL(s) {
|
||||||
var cd = d.getElementsByClassName('cl')[s];
|
var cd = d.getElementsByClassName('cl')[s];
|
||||||
cd.style.backgroundColor = rgbStr(a, s);
|
var w = whites[s];
|
||||||
cd.style.color = rgbBri(a, s) > 127 ? "#000":"#fff";
|
if (hasRGB && !isRgbBlack(colors, s)) {
|
||||||
|
cd.style.background = rgbStr(colors, s);
|
||||||
|
cd.style.color = rgbBri(colors, s) > 127 ? "#000":"#fff";
|
||||||
|
if (hasWhite && w > 0) {
|
||||||
|
cd.style.background = `linear-gradient(180deg, ${rgbStr(colors, s)} 30%, ${rgbStr([[w,w,w]], 0)})`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!hasWhite) w = 0;
|
||||||
|
cd.style.background = rgbStr([[w,w,w]], 0);
|
||||||
|
cd.style.color = w > 127 ? "#000":"#fff";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCfg()
|
function applyCfg()
|
||||||
@ -83,13 +98,7 @@ function applyCfg()
|
|||||||
cTheme(cfg.theme.base === "light");
|
cTheme(cfg.theme.base === "light");
|
||||||
var bg = cfg.theme.color.bg;
|
var bg = cfg.theme.color.bg;
|
||||||
if (bg) sCol('--c-1', bg);
|
if (bg) sCol('--c-1', bg);
|
||||||
var ccfg = cfg.comp.colors;
|
if (lastinfo.leds) updateUI(); // update component visibility
|
||||||
d.getElementById('hexw').style.display = ccfg.hex ? "block":"none";
|
|
||||||
d.getElementById('picker').style.display = ccfg.picker ? "block":"none";
|
|
||||||
d.getElementById('vwrap').style.display = ccfg.picker ? "block":"none";
|
|
||||||
d.getElementById('kwrap').style.display = ccfg.picker ? "block":"none";
|
|
||||||
d.getElementById('rgbwrap').style.display = ccfg.rgb ? "block":"none";
|
|
||||||
d.getElementById('qcs-w').style.display = ccfg.quick ? "block":"none";
|
|
||||||
var l = cfg.comp.labels;
|
var l = cfg.comp.labels;
|
||||||
var e = d.querySelectorAll('.tab-label');
|
var e = d.querySelectorAll('.tab-label');
|
||||||
for (var i of e)
|
for (var i of e)
|
||||||
@ -918,22 +927,19 @@ function updateLen(s)
|
|||||||
function updatePA()
|
function updatePA()
|
||||||
{
|
{
|
||||||
var ps = d.getElementsByClassName("pres"); //reset all preset buttons
|
var ps = d.getElementsByClassName("pres"); //reset all preset buttons
|
||||||
for (let i = 0; i < ps.length; i++) {
|
for (var i of ps) {
|
||||||
//ps[i].style.backgroundColor = "var(--c-2)";
|
i.classList.remove("selected");
|
||||||
ps[i].classList.remove("selected");
|
|
||||||
}
|
}
|
||||||
ps = d.getElementsByClassName("psts"); //reset all quick selectors
|
ps = d.getElementsByClassName("psts"); //reset all quick selectors
|
||||||
for (let i = 0; i < ps.length; i++) {
|
for (var i of ps) {
|
||||||
ps[i].style.backgroundColor = "var(--c-2)";
|
i.classList.remove("selected");
|
||||||
}
|
}
|
||||||
if (currentPreset > 0) {
|
if (currentPreset > 0) {
|
||||||
var acv = d.getElementById(`p${currentPreset}o`);
|
var acv = d.getElementById(`p${currentPreset}o`);
|
||||||
if (acv && !expanded[currentPreset+100])
|
if (acv && !expanded[currentPreset+100])
|
||||||
//acv.style.background = "var(--c-6)"; //highlight current preset
|
|
||||||
acv.classList.add("selected");
|
acv.classList.add("selected");
|
||||||
acv = d.getElementById(`p${currentPreset}qlb`);
|
acv = d.getElementById(`p${currentPreset}qlb`);
|
||||||
if (acv)
|
if (acv)
|
||||||
//acv.style.background = "var(--c-6)"; //highlight quick selector
|
|
||||||
acv.classList.add("selected");
|
acv.classList.add("selected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -947,9 +953,15 @@ function updateUI()
|
|||||||
updateTrail(d.getElementById('sliderBri'));
|
updateTrail(d.getElementById('sliderBri'));
|
||||||
updateTrail(d.getElementById('sliderSpeed'));
|
updateTrail(d.getElementById('sliderSpeed'));
|
||||||
updateTrail(d.getElementById('sliderIntensity'));
|
updateTrail(d.getElementById('sliderIntensity'));
|
||||||
d.getElementById('wwrap').style.display = (isRgbw) ? "block":"none";
|
d.getElementById('wwrap').style.display = (hasWhite) ? "block":"none";
|
||||||
d.getElementById('wbal').style.display = (lastinfo.leds.cct) ? "block":"none";
|
d.getElementById('wbal').style.display = (hasCCT) ? "block":"none";
|
||||||
d.getElementById('kwrap').style.display = (lastinfo.leds.cct) ? "none":"block";
|
var ccfg = cfg.comp.colors;
|
||||||
|
d.getElementById('hexw').style.display = ccfg.hex ? "block":"none";
|
||||||
|
d.getElementById('pwrap').style.display = (hasRGB && ccfg.picker) ? "block":"none";
|
||||||
|
d.getElementById('kwrap').style.display = (hasRGB && !hasCCT && ccfg.picker) ? "block":"none";
|
||||||
|
d.getElementById('rgbwrap').style.display = (hasRGB && ccfg.rgb) ? "block":"none";
|
||||||
|
d.getElementById('qcs-w').style.display = (hasRGB && ccfg.quick) ? "block":"none";
|
||||||
|
d.getElementById('palwrap').style.display = hasRGB ? "block":"none";
|
||||||
|
|
||||||
updatePA();
|
updatePA();
|
||||||
updatePSliders();
|
updatePSliders();
|
||||||
@ -1031,13 +1043,32 @@ function readState(s,command=false) {
|
|||||||
tr = s.transition;
|
tr = s.transition;
|
||||||
d.getElementById('tt').value = tr/10;
|
d.getElementById('tt').value = tr/10;
|
||||||
|
|
||||||
var selc=0; var ind=0;
|
|
||||||
populateSegments(s);
|
populateSegments(s);
|
||||||
|
var selc=0;
|
||||||
|
var sellvl=0; // 0: selc is invalid, 1: selc is mainseg, 2: selc is first selected
|
||||||
|
hasRGB = hasWhite = hasCCT = false;
|
||||||
for (let i = 0; i < (s.seg||[]).length; i++)
|
for (let i = 0; i < (s.seg||[]).length; i++)
|
||||||
{
|
{
|
||||||
if(s.seg[i].sel) {selc = ind; break;} ind++;
|
if (sellvl == 0 && s.seg[i].id == s.mainseg) {
|
||||||
|
selc = i;
|
||||||
|
sellvl = 1;
|
||||||
|
}
|
||||||
|
if (s.seg[i].sel) {
|
||||||
|
if (sellvl < 2) selc = i; // get first selected segment
|
||||||
|
sellvl = 2;
|
||||||
|
var lc = lastinfo.leds.seglc[s.seg[i].id];
|
||||||
|
hasRGB |= lc & 0x01;
|
||||||
|
hasWhite |= lc & 0x02;
|
||||||
|
hasCCT |= lc & 0x04;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var i=s.seg[selc];
|
var i=s.seg[selc];
|
||||||
|
if (sellvl == 1) {
|
||||||
|
var lc = lastinfo.leds.seglc[i.id];
|
||||||
|
hasRGB = lc & 0x01;
|
||||||
|
hasWhite = lc & 0x02;
|
||||||
|
hasCCT = lc & 0x04;
|
||||||
|
}
|
||||||
if (!i) {
|
if (!i) {
|
||||||
showToast('No Segments!', true);
|
showToast('No Segments!', true);
|
||||||
updateUI();
|
updateUI();
|
||||||
@ -1047,8 +1078,8 @@ function readState(s,command=false) {
|
|||||||
colors = i.col;
|
colors = i.col;
|
||||||
for (let e = 2; e >= 0; e--)
|
for (let e = 2; e >= 0; e--)
|
||||||
{
|
{
|
||||||
setCSL(colors, e);
|
if (i.col[e].length > 3) whites[e] = parseInt(i.col[e][3]);
|
||||||
if (isRgbw) whites[e] = parseInt(i.col[e][3]);
|
setCSL(e);
|
||||||
selectSlot(csel);
|
selectSlot(csel);
|
||||||
}
|
}
|
||||||
if (i.cct != null && i.cct>=0) d.getElementById("sliderA").value = i.cct;
|
if (i.cct != null && i.cct>=0) d.getElementById("sliderA").value = i.cct;
|
||||||
@ -1199,7 +1230,6 @@ function requestJson(command, rinfo = true) {
|
|||||||
name = "(L) " + name;
|
name = "(L) " + name;
|
||||||
}
|
}
|
||||||
d.title = name;
|
d.title = name;
|
||||||
isRgbw = info.leds.wv;
|
|
||||||
ledCount = info.leds.count;
|
ledCount = info.leds.count;
|
||||||
syncTglRecv = info.str;
|
syncTglRecv = info.str;
|
||||||
maxSeg = info.leds.maxseg;
|
maxSeg = info.leds.maxseg;
|
||||||
@ -1889,13 +1919,9 @@ function setColor(sr) {
|
|||||||
if (sr != 2) whites[csel] = parseInt(d.getElementById('sliderW').value);
|
if (sr != 2) whites[csel] = parseInt(d.getElementById('sliderW').value);
|
||||||
var col = cpick.color.rgb;
|
var col = cpick.color.rgb;
|
||||||
colors[csel] = [col.r, col.g, col.b, whites[csel]];
|
colors[csel] = [col.r, col.g, col.b, whites[csel]];
|
||||||
setCSL(colors, csel);
|
setCSL(csel);
|
||||||
var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}};
|
var obj = {"seg": {"col": [[],[],[]]}};
|
||||||
if (csel == 1) {
|
obj.seg.col[csel] = colors[csel];
|
||||||
obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}};
|
|
||||||
} else if (csel == 2) {
|
|
||||||
obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}};
|
|
||||||
}
|
|
||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4430
wled00/html_ui.h
4430
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user