Skip to content

Commit cc81cc2

Browse files
authored
enhancement & bugfixes in scrolling text (wled#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() )
1 parent 66869f8 commit cc81cc2

File tree

1 file changed

+55
-22
lines changed

1 file changed

+55
-22
lines changed

wled00/FX.cpp

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6091,9 +6091,7 @@ uint16_t mode_2Dscrollingtext(void) {
60916091
}
60926092

60936093
char text[WLED_MAX_SEGNAME_LEN+1] = {'\0'};
6094-
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];
6095-
const bool zero = strchr(text, '0') != nullptr;
6096-
6094+
size_t result_pos = 0;
60976095
char sec[5];
60986096
int AmPmHour = hour(localTime);
60996097
bool isitAM = true;
@@ -6105,27 +6103,62 @@ uint16_t mode_2Dscrollingtext(void) {
61056103
sprintf_P(sec, PSTR(":%02d"), second(localTime));
61066104
}
61076105

6108-
if (!strlen(text)) { // fallback if empty segment name: display date and time
6106+
size_t len = 0;
6107+
if (SEGMENT.name) len = strlen(SEGMENT.name); // note: SEGMENT.name is limited to WLED_MAX_SEGNAME_LEN
6108+
if (len == 0) { // fallback if empty segment name: display date and time
61096109
sprintf_P(text, PSTR("%s %d, %d %d:%02d%s"), monthShortStr(month(localTime)), day(localTime), year(localTime), AmPmHour, minute(localTime), sec);
61106110
} else {
6111-
if (text[0] == '#') for (auto &c : text) c = std::toupper(c);
6112-
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));
6113-
else if (!strncmp_P(text,PSTR("#DDMM"),5)) sprintf_P(text, zero?PSTR("%02d.%02d") :PSTR("%d.%d"), day(localTime), month(localTime));
6114-
else if (!strncmp_P(text,PSTR("#MMDD"),5)) sprintf_P(text, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime));
6115-
else if (!strncmp_P(text,PSTR("#TIME"),5)) sprintf_P(text, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec);
6116-
else if (!strncmp_P(text,PSTR("#HHMM"),5)) sprintf_P(text, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime));
6117-
else if (!strncmp_P(text,PSTR("#HH"),3)) sprintf (text, zero? ("%02d") : ("%d"), AmPmHour);
6118-
else if (!strncmp_P(text,PSTR("#MM"),3)) sprintf (text, zero? ("%02d") : ("%d"), minute(localTime));
6119-
else if (!strncmp_P(text,PSTR("#SS"),3)) sprintf (text, ("%02d") , second(localTime));
6120-
else if (!strncmp_P(text,PSTR("#DD"),3)) sprintf (text, zero? ("%02d") : ("%d"), day(localTime));
6121-
else if (!strncmp_P(text,PSTR("#DAY"),4)) sprintf (text, ("%s") , dayShortStr(day(localTime)));
6122-
else if (!strncmp_P(text,PSTR("#DDDD"),5)) sprintf (text, ("%s") , dayStr(day(localTime)));
6123-
else if (!strncmp_P(text,PSTR("#DAYL"),5)) sprintf (text, ("%s") , dayStr(day(localTime)));
6124-
else if (!strncmp_P(text,PSTR("#MO"),3)) sprintf (text, zero? ("%02d") : ("%d"), month(localTime));
6125-
else if (!strncmp_P(text,PSTR("#MON"),4)) sprintf (text, ("%s") , monthShortStr(month(localTime)));
6126-
else if (!strncmp_P(text,PSTR("#MMMM"),5)) sprintf (text, ("%s") , monthStr(month(localTime)));
6127-
else if (!strncmp_P(text,PSTR("#YY"),3)) sprintf (text, ("%02d") , year(localTime)%100);
6128-
else if (!strncmp_P(text,PSTR("#YYYY"),5)) sprintf_P(text, zero?PSTR("%04d") : ("%d"), year(localTime));
6111+
size_t i = 0;
6112+
while (i < len) {
6113+
if (SEGMENT.name[i] == '#') {
6114+
char token[7]; // copy up to 6 chars + null terminator
6115+
bool zero = false; // a 0 suffix means display leading zeros
6116+
size_t j = 0;
6117+
while (j < 6 && i + j < len) {
6118+
token[j] = std::toupper(SEGMENT.name[i + j]);
6119+
if(token[j] == '0')
6120+
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
6121+
j++;
6122+
}
6123+
token[j] = '\0';
6124+
int advance = 5; // number of chars to advance in 'text' after processing the token
6125+
6126+
// Process token
6127+
char temp[32];
6128+
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));
6129+
else if (!strncmp_P(token,PSTR("#DDMM"),5)) sprintf_P(temp, zero?PSTR("%02d.%02d") :PSTR("%d.%d"), day(localTime), month(localTime));
6130+
else if (!strncmp_P(token,PSTR("#MMDD"),5)) sprintf_P(temp, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime));
6131+
else if (!strncmp_P(token,PSTR("#TIME"),5)) sprintf_P(temp, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec);
6132+
else if (!strncmp_P(token,PSTR("#HHMM"),5)) sprintf_P(temp, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime));
6133+
else if (!strncmp_P(token,PSTR("#YYYY"),5)) sprintf_P(temp, PSTR("%04d") , year(localTime));
6134+
else if (!strncmp_P(token,PSTR("#MONL"),5)) sprintf (temp, ("%s") , monthStr(month(localTime)));
6135+
else if (!strncmp_P(token,PSTR("#DDDD"),5)) sprintf (temp, ("%s") , dayStr(weekday(localTime)));
6136+
else if (!strncmp_P(token,PSTR("#YY"),3)) { sprintf (temp, ("%02d") , year(localTime)%100); advance = 3; }
6137+
else if (!strncmp_P(token,PSTR("#HH"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), AmPmHour); advance = 3; }
6138+
else if (!strncmp_P(token,PSTR("#MM"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), minute(localTime)); advance = 3; }
6139+
else if (!strncmp_P(token,PSTR("#SS"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), second(localTime)); advance = 3; }
6140+
else if (!strncmp_P(token,PSTR("#MON"),4)) { sprintf (temp, ("%s") , monthShortStr(month(localTime))); advance = 4; }
6141+
else if (!strncmp_P(token,PSTR("#MO"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), month(localTime)); advance = 3; }
6142+
else if (!strncmp_P(token,PSTR("#DAY"),4)) { sprintf (temp, ("%s") , dayShortStr(weekday(localTime))); advance = 4; }
6143+
else if (!strncmp_P(token,PSTR("#DD"),3)) { sprintf (temp, zero? ("%02d") : ("%d"), day(localTime)); advance = 3; }
6144+
else { temp[0] = '#'; temp[1] = '\0'; zero = false; advance = 1; } // Unknown token, just copy the #
6145+
6146+
if(zero) advance++; // skip the '0' suffix
6147+
size_t temp_len = strlen(temp);
6148+
if (result_pos + temp_len < WLED_MAX_SEGNAME_LEN) {
6149+
strcpy(text + result_pos, temp);
6150+
result_pos += temp_len;
6151+
}
6152+
6153+
i += advance;
6154+
}
6155+
else {
6156+
if (result_pos < WLED_MAX_SEGNAME_LEN) {
6157+
text[result_pos++] = SEGMENT.name[i++]; // no token, just copy char
6158+
} else
6159+
break; // buffer full
6160+
}
6161+
}
61296162
}
61306163

61316164
const int numberOfLetters = strlen(text);

0 commit comments

Comments
 (0)