enhancement & bugfixes in scrolling text (#4742)

* enhancement & bugfixes in scrolling text

- function now evaluates full string: allows custom text plus multiple tokens in any order
- fixed evaluation order to prevent early exit(s)
- fixed day strings (argument must be weekday() )
This commit is contained in:
Damian Schneider 2025-06-28 09:42:52 +02:00 committed by GitHub
parent 66869f8341
commit cc81cc27b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6091,9 +6091,7 @@ uint16_t mode_2Dscrollingtext(void) {
} }
char text[WLED_MAX_SEGNAME_LEN+1] = {'\0'}; char text[WLED_MAX_SEGNAME_LEN+1] = {'\0'};
if (SEGMENT.name) for (size_t i=0,j=0; i<strlen(SEGMENT.name); i++) if (SEGMENT.name[i]>31 && SEGMENT.name[i]<128) text[j++] = SEGMENT.name[i]; size_t result_pos = 0;
const bool zero = strchr(text, '0') != nullptr;
char sec[5]; char sec[5];
int AmPmHour = hour(localTime); int AmPmHour = hour(localTime);
bool isitAM = true; bool isitAM = true;
@ -6105,27 +6103,62 @@ uint16_t mode_2Dscrollingtext(void) {
sprintf_P(sec, PSTR(":%02d"), second(localTime)); sprintf_P(sec, PSTR(":%02d"), second(localTime));
} }
if (!strlen(text)) { // fallback if empty segment name: display date and time size_t len = 0;
if (SEGMENT.name) len = strlen(SEGMENT.name); // note: SEGMENT.name is limited to WLED_MAX_SEGNAME_LEN
if (len == 0) { // fallback if empty segment name: display date and time
sprintf_P(text, PSTR("%s %d, %d %d:%02d%s"), monthShortStr(month(localTime)), day(localTime), year(localTime), AmPmHour, minute(localTime), sec); sprintf_P(text, PSTR("%s %d, %d %d:%02d%s"), monthShortStr(month(localTime)), day(localTime), year(localTime), AmPmHour, minute(localTime), sec);
} else { } else {
if (text[0] == '#') for (auto &c : text) c = std::toupper(c); size_t i = 0;
if (!strncmp_P(text,PSTR("#DATE"),5)) sprintf_P(text, zero?PSTR("%02d.%02d.%04d"):PSTR("%d.%d.%d"), day(localTime), month(localTime), year(localTime)); while (i < len) {
else if (!strncmp_P(text,PSTR("#DDMM"),5)) sprintf_P(text, zero?PSTR("%02d.%02d") :PSTR("%d.%d"), day(localTime), month(localTime)); if (SEGMENT.name[i] == '#') {
else if (!strncmp_P(text,PSTR("#MMDD"),5)) sprintf_P(text, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime)); char token[7]; // copy up to 6 chars + null terminator
else if (!strncmp_P(text,PSTR("#TIME"),5)) sprintf_P(text, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec); bool zero = false; // a 0 suffix means display leading zeros
else if (!strncmp_P(text,PSTR("#HHMM"),5)) sprintf_P(text, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime)); size_t j = 0;
else if (!strncmp_P(text,PSTR("#HH"),3)) sprintf (text, zero? ("%02d") : ("%d"), AmPmHour); while (j < 6 && i + j < len) {
else if (!strncmp_P(text,PSTR("#MM"),3)) sprintf (text, zero? ("%02d") : ("%d"), minute(localTime)); token[j] = std::toupper(SEGMENT.name[i + j]);
else if (!strncmp_P(text,PSTR("#SS"),3)) sprintf (text, ("%02d") , second(localTime)); if(token[j] == '0')
else if (!strncmp_P(text,PSTR("#DD"),3)) sprintf (text, zero? ("%02d") : ("%d"), day(localTime)); zero = true; // 0 suffix found. Note: there is an edge case where a '0' could be part of a trailing text and not the token, handling it is not worth the effort
else if (!strncmp_P(text,PSTR("#DAY"),4)) sprintf (text, ("%s") , dayShortStr(day(localTime))); j++;
else if (!strncmp_P(text,PSTR("#DDDD"),5)) sprintf (text, ("%s") , dayStr(day(localTime))); }
else if (!strncmp_P(text,PSTR("#DAYL"),5)) sprintf (text, ("%s") , dayStr(day(localTime))); token[j] = '\0';
else if (!strncmp_P(text,PSTR("#MO"),3)) sprintf (text, zero? ("%02d") : ("%d"), month(localTime)); int advance = 5; // number of chars to advance in 'text' after processing the token
else if (!strncmp_P(text,PSTR("#MON"),4)) sprintf (text, ("%s") , monthShortStr(month(localTime)));
else if (!strncmp_P(text,PSTR("#MMMM"),5)) sprintf (text, ("%s") , monthStr(month(localTime))); // Process token
else if (!strncmp_P(text,PSTR("#YY"),3)) sprintf (text, ("%02d") , year(localTime)%100); char temp[32];
else if (!strncmp_P(text,PSTR("#YYYY"),5)) sprintf_P(text, zero?PSTR("%04d") : ("%d"), year(localTime)); if (!strncmp_P(token,PSTR("#DATE"),5)) sprintf_P(temp, zero?PSTR("%02d.%02d.%04d"):PSTR("%d.%d.%d"), day(localTime), month(localTime), year(localTime));
else if (!strncmp_P(token,PSTR("#DDMM"),5)) sprintf_P(temp, zero?PSTR("%02d.%02d") :PSTR("%d.%d"), day(localTime), month(localTime));
else if (!strncmp_P(token,PSTR("#MMDD"),5)) sprintf_P(temp, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime));
else if (!strncmp_P(token,PSTR("#TIME"),5)) sprintf_P(temp, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec);
else if (!strncmp_P(token,PSTR("#HHMM"),5)) sprintf_P(temp, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime));
else if (!strncmp_P(token,PSTR("#YYYY"),5)) sprintf_P(temp, PSTR("%04d") , year(localTime));
else if (!strncmp_P(token,PSTR("#MONL"),5)) sprintf (temp, ("%s") , monthStr(month(localTime)));
else if (!strncmp_P(token,PSTR("#DDDD"),5)) sprintf (temp, ("%s") , dayStr(weekday(localTime)));
else if (!strncmp_P(token,PSTR("#YY"),3)) { sprintf (temp, ("%02d") , year(localTime)%100); advance = 3; }
else if (!strncmp_P(token,PSTR("#HH"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), AmPmHour); advance = 3; }
else if (!strncmp_P(token,PSTR("#MM"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), minute(localTime)); advance = 3; }
else if (!strncmp_P(token,PSTR("#SS"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), second(localTime)); advance = 3; }
else if (!strncmp_P(token,PSTR("#MON"),4)) { sprintf (temp, ("%s") , monthShortStr(month(localTime))); advance = 4; }
else if (!strncmp_P(token,PSTR("#MO"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), month(localTime)); advance = 3; }
else if (!strncmp_P(token,PSTR("#DAY"),4)) { sprintf (temp, ("%s") , dayShortStr(weekday(localTime))); advance = 4; }
else if (!strncmp_P(token,PSTR("#DD"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), day(localTime)); advance = 3; }
else { temp[0] = '#'; temp[1] = '\0'; zero = false; advance = 1; } // Unknown token, just copy the #
if(zero) advance++; // skip the '0' suffix
size_t temp_len = strlen(temp);
if (result_pos + temp_len < WLED_MAX_SEGNAME_LEN) {
strcpy(text + result_pos, temp);
result_pos += temp_len;
}
i += advance;
}
else {
if (result_pos < WLED_MAX_SEGNAME_LEN) {
text[result_pos++] = SEGMENT.name[i++]; // no token, just copy char
} else
break; // buffer full
}
}
} }
const int numberOfLetters = strlen(text); const int numberOfLetters = strlen(text);