5#ifdef USTD_FEATURE_PROGRAMPLAYER
15#define MUPDISP_FEATURE_MONO B00000001
16#define MUPDISP_FEATURE_COLOR B00000010
17#define MUPDISP_FEATURE_FONTS B00000100
18#define MUPDISP_FEATURE_PROGRAMPLAYER B00001000
26 static const char *formatTokens[];
27 static const char *colorTokens[];
29#ifdef USTD_FEATURE_PROGRAMPLAYER
30 static const char *modeTokens[];
50#ifdef USTD_FEATURE_PROGRAMPLAYER
55 ustd::timeout duration;
65 enum ProgramState { None, FadeIn, Wait, FadeOut, Finished };
81#ifdef USTD_FEATURE_PROGRAMPLAYER
83 ustd::array<ProgramItem> program;
84 ProgramItem default_item;
85 int16_t program_counter;
86 ProgramState program_state;
88 int16_t program_width;
89 uint8_t program_height;
90 unsigned long anonymous_counter;
101 MuppletDisplay(String name, uint8_t features) : name(name), features(features) {
104 current_fg = features && MUPDISP_FEATURE_COLOR ? 0xffff : 1;
105#ifdef USTD_FEATURE_PROGRAMPLAYER
106 this->features |= MUPDISP_FEATURE_PROGRAMPLAYER;
108 this->features &= (~MUPDISP_FEATURE_PROGRAMPLAYER);
112#ifdef USTD_FEATURE_PROGRAMPLAYER
117 void setPlayer(int16_t posY = -1, uint8_t height = 0) {
120 if (posY < 0 || height == 0) {
122 displayClear(0, program_pos, w, program_height);
127 if (posY > (h - height)) {
132 program_height = height;
135 displayClear(0, program_pos, w, program_height);
148 void setDefaults(Mode mode,
unsigned long duration, int16_t repeat, uint8_t speed, uint8_t font,
149 uint16_t color = 0xffff, uint16_t bg = 0x0000) {
150 default_item.mode = mode;
151 default_item.duration = duration;
152 default_item.repeat = repeat;
153 default_item.speed = speed > 16 ? 16 : speed;
154 default_item.font = font < getTextFontCount() ? font : 0;
155 default_item.color = features & MUPDISP_FEATURE_COLOR ? color : color ? 1 : 0;
156 default_item.bg = features & MUPDISP_FEATURE_COLOR ? bg : bg ? 1 : 0;
164 program_state = None;
165 displayClear(0, program_pos, program_width, program_height);
170#ifdef USTD_FEATURE_PROGRAMPLAYER
173 default_item.mode = Left;
174 default_item.duration = 2000;
175 default_item.repeat = 1;
176 default_item.speed = 16;
177 default_item.font = 0;
178 default_item.color = features && MUPDISP_FEATURE_COLOR ? 0xffff : 1;
186 program_state = None;
187 anonymous_counter = 0;
191 if (program.length() == 0 || program_height == 0 || program_pos < 0) {
196 bool cur_wrap = getTextWrap();
197 uint8_t cur_font = current_font;
198 uint16_t cur_fg = current_fg;
199 uint16_t cur_bg = current_bg;
203 if (program_state == None) {
204 startProgramItem(program[program_counter], x, y, w, h);
206 if (program_state == FadeIn) {
207 fadeInProgramItem(program[program_counter], x, y, w, h);
209 if (program_state == Wait) {
210 waitProgramItem(program[program_counter], x, y, w, h);
212 if (program_state == FadeOut) {
213 fadeOutProgramItem(program[program_counter], x, y, w, h);
215 if (program_state == Finished) {
216 endProgramItem(program[program_counter], x, y, w, h);
218 if (program.length() == 0) {
219 displayClear(0, program_pos, program_width, program_height);
223 setTextColor(cur_fg, cur_bg);
224 setTextFont(cur_font, 0);
225 setTextWrap(cur_wrap);
230 virtual bool commandParser(String command, String args, String topic) {
231 if (command.startsWith(
"cmnd/")) {
232 return commandCmdParser(command.substring(5), args);
233 }
else if (command.startsWith(
"cursor/")) {
234 return cursorParser(command.substring(7), args, topic +
"/cursor");
235 }
else if (command.startsWith(
"wrap/")) {
236 return wrapParser(command.substring(5), args, topic +
"/wrap");
237 }
else if (command.startsWith(
"color/")) {
238 return colorParser(command.substring(6), args, topic +
"/color",
true);
239 }
else if (command.startsWith(
"background/")) {
240 return colorParser(command.substring(11), args, topic +
"/background",
false);
241#ifdef USTD_FEATURE_PROGRAMPLAYER
242 }
else if (command ==
"count/get") {
243 return publishItemsCount();
244 }
else if (command.startsWith(
"default/")) {
245 return commandDefaultParser(command.substring(8), args, topic +
"/default");
246 }
else if (command.startsWith(
"items/")) {
247 return commandItemsParser(command.substring(6), args, topic +
"/items");
248 }
else if (command.startsWith(
"content/")) {
249 return commandContentParser(command.substring(8), args, topic +
"/content");
255 virtual bool commandCmdParser(String command, String args) {
256 int16_t x, y, w, h, d, width, height;
258 array<String> params;
259 if (command ==
"clear") {
261 split(args,
';', params);
263 getDimensions(width, height);
264 fs = getTextFontSize();
265 switch (params.length()) {
268 displayClear(0, 0, width, height);
269 setCursor(0, 0 + fs.baseLine);
273 y = parseLong(params[0], 0);
274 displayClear(0, y * fs.yAdvance, width, fs.yAdvance);
275 setCursor(0, y + fs.baseLine);
279 x = parseLong(params[0], 0);
280 y = parseLong(params[1], 0);
281 displayClear(x, y, width, height);
282 setCursor(x, y + fs.baseLine);
286 x = parseLong(params[0], 0);
287 y = parseLong(params[1], 0);
288 w = parseLong(params[2], 0);
289 h = parseLong(params[3], 0);
290 displayClear(x, y, w, h);
291 setCursor(x, y + fs.baseLine);
294 }
else if (command ==
"print") {
297 }
else if (command ==
"println") {
298 displayPrint(args,
true);
300 }
else if (command ==
"printat") {
301 getDimensions(width, height);
302 x = parseRangedLong(shift(args,
';',
"0"), 0, width - 1, 0, width - 1);
303 y = parseRangedLong(shift(args,
';',
"0"), 0, height - 1, 0, height - 1);
307 }
else if (command ==
"format") {
308 getDimensions(width, height);
309 x = parseLong(shift(args,
';',
""), 0);
310 y = parseLong(shift(args,
';',
""), 0);
311 h = parseToken(shift(args,
';',
"left"), formatTokens);
314 String size = shift(args,
';');
315 w = parseLong(shift(size,
'.',
""), width);
316 d = parseRangedLong(size, 0, w, 0, w);
317 if (args.length() == 0) {
319 fs = getTextFontSize();
320 displayClear(x, y, w, fs.yAdvance);
321 }
else if (!isNumber(args.c_str())) {
323 displayError(x, y, w, 2);
325 args = String(atof(args.c_str()), d);
326 if (!displayFormat(x, y, w, 2, args, current_font, current_fg, current_bg)) {
328 displayError(x, y, w, 2);
334 w = parseLong(shift(args,
';',
""), width);
335 displayFormat(x, y, w, h, args, current_font, current_fg, current_bg);
341 bool cursorParser(String command, String args, String topic) {
342 int16_t x, y, width, height;
343 if (command ==
"get") {
345 pSched->publish(topic, String(x) +
";" + String(y));
347 }
else if (command ==
"set") {
348 getDimensions(width, height);
349 setCursor(parseRangedLong(shift(args,
';'), 0, width - 1, 0, width - 1),
350 parseRangedLong(shift(args,
';'), 0, height - 1, 0, height - 1));
352 pSched->publish(topic, String(x) +
";" + String(y));
354 }
else if (command ==
"x/get") {
356 pSched->publish(topic +
"/x", String(x));
358 }
else if (command ==
"x/set") {
360 getDimensions(width, height);
361 setCursor(parseRangedLong(shift(args,
';'), 0, width - 1, 0, width - 1), y);
363 pSched->publish(topic +
"/x", String(x));
365 }
else if (command ==
"y/get") {
367 pSched->publish(topic +
"/y", String(y));
368 }
else if (command ==
"y/set") {
370 getDimensions(width, height);
371 setCursor(x, parseRangedLong(shift(args,
';'), 0, height - 1, 0, height - 1));
373 pSched->publish(topic +
"/y", String(y));
379 bool wrapParser(String command, String args, String topic) {
380 if (command ==
"get") {
381 pSched->publish(topic, getTextWrap() ?
"on" :
"off");
383 }
else if (command ==
"set") {
384 int8_t wrap = parseBoolean(args);
386 setTextWrap(wrap == 1);
387 pSched->publish(topic, getTextWrap() ?
"on" :
"off");
394 bool colorParser(String command, String args, String topic,
bool fg) {
395 if (features & MUPDISP_FEATURE_MONO) {
396 if (command ==
"get") {
397 pSched->publish(topic, (fg ? current_fg : current_bg) ?
"0x1" :
"0x0");
399 }
else if (command ==
"set") {
401 current_fg = parseColor(args, current_fg) ? 1 : 0;
402 setTextColor(current_fg, current_bg);
403 pSched->publish(topic, current_fg ?
"0x1" :
"0x0");
405 current_bg = parseColor(args, current_bg) ? 1 : 0;
406 setTextColor(current_fg, current_bg);
407 pSched->publish(topic, current_bg ?
"0x1" :
"0x0");
410 }
else if (features & MUPDISP_FEATURE_COLOR) {
411 if (command ==
"get") {
412 pSched->publish(topic,
"0x" + String(fg ? current_fg : current_bg, HEX));
414 }
else if (command ==
"set") {
416 current_fg = parseColor(args, current_fg);
417 setTextColor(current_fg, current_bg);
418 pSched->publish(topic,
"0x" + String(current_fg, HEX));
420 current_bg = parseColor(args, current_bg);
421 setTextColor(current_fg, current_bg);
422 pSched->publish(topic,
"0x" + String(current_bg, HEX));
429 uint16_t parseColor(String &args, uint16_t defaultVal) {
431 switch (parseToken(args, colorTokens)) {
433 return features & MUPDISP_FEATURE_COLOR ? 0x0000 : 0;
435 return features & MUPDISP_FEATURE_COLOR ? 0x1111 : 1;
437 return features & MUPDISP_FEATURE_COLOR ? 0xF800 : 1;
439 return features & MUPDISP_FEATURE_COLOR ? 0x07E0 : 1;
441 return features & MUPDISP_FEATURE_COLOR ? 0x001F : 1;
443 return features & MUPDISP_FEATURE_COLOR ? 0x07FF : 1;
445 return features & MUPDISP_FEATURE_COLOR ? 0xF81F : 1;
447 return features & MUPDISP_FEATURE_COLOR ? 0xFFE0 : 1;
449 return features & MUPDISP_FEATURE_COLOR ? 0xFC00 : 1;
451 if (args.length() == 0) {
455 if (args.startsWith(
"0x")) {
456 if (args.length() > 6) {
459 for (
const char *pPtr = args.c_str() + 2; *pPtr; pPtr++) {
461 if (*pPtr >=
'0' && *pPtr <=
'9') {
462 color |= (*pPtr -
'0');
463 }
else if (*pPtr >=
'A' && *pPtr <=
'F') {
464 color |= (*pPtr - 55);
465 }
else if (*pPtr >=
'a' && *pPtr <=
'f') {
466 color |= (*pPtr - 87);
476#ifdef USTD_FEATURE_PROGRAMPLAYER
477 bool commandDefaultParser(String command, String args, String topic) {
478 if (command ==
"get") {
479 return publishDefaults(topic);
480 }
else if (command ==
"set") {
481 if (parseDefaults(args)) {
482 return publishDefaults(topic);
484 }
else if (command ==
"mode/get") {
485 return publishDefaultMode(topic +
"/mode");
486 }
else if (command ==
"mode/set") {
487 if (parseMode(args, default_item)) {
488 return publishDefaultMode(topic +
"/mode");
490 }
else if (command ==
"repeat/get") {
491 return publishDefaultRepeat(topic +
"/repeat");
492 }
else if (command ==
"repeat/set") {
493 if (parseRepeat(args, default_item)) {
494 return publishDefaultRepeat(topic +
"/repeat");
496 }
else if (command ==
"duration/get") {
497 return publishDefaultDuration(topic +
"/duration");
498 }
else if (command ==
"duration/set") {
499 if (parseDuration(args, default_item)) {
500 return publishDefaultDuration(topic +
"/duration");
502 }
else if (command ==
"speed/get") {
503 return publishDefaultSpeed(topic +
"/speed");
504 }
else if (command ==
"speed/set") {
505 if (parseSpeed(args, default_item)) {
506 return publishDefaultSpeed(topic +
"/speed");
508 }
else if (command ==
"font/get") {
509 return publishDefaultFont(topic +
"/font");
510 }
else if (command ==
"font/set") {
511 if (parseFont(args, default_item)) {
512 return publishDefaultFont(topic +
"/font");
514 }
else if (command ==
"color/get") {
515 return publishDefaultColor(topic +
"/color");
516 }
else if (command ==
"color/set") {
517 if (parseColor(args, default_item)) {
518 return publishDefaultColor(topic +
"/Color");
520 }
else if (command ==
"background/get") {
521 return publishDefaultBackground(topic +
"/background");
522 }
else if (command ==
"background/set") {
523 if (parseBackground(args, default_item)) {
524 return publishDefaultBackground(topic +
"/background");
530 bool commandItemsParser(String command, String args, String topic) {
531 String name, operation;
532 if (command ==
"clear") {
534 return publishItemsCount();
535 }
else if (command ==
"get") {
536 return publishItems(topic);
537 }
else if (command ==
"add") {
538 addItem(
"unnamed_" + String(++anonymous_counter), args);
539 return publishItemsCount();
540 }
else if (parseItemCommand(command, name, operation)) {
541 int16_t index = findItemByName(name.c_str());
542 if (operation ==
"set") {
544 index = addItem(name, args);
546 index = replaceItem(index, args);
549 return publishItem(topic, index);
551 }
else if (operation ==
"get") {
552 return publishItem(topic, index);
553 }
else if (operation ==
"jump") {
554 if (jumpItem(index)) {
555 return publishItem(topic, index);
557 }
else if (operation ==
"clear") {
558 if (clearItem(index)) {
559 return publishItemsCount();
566 bool commandContentParser(String command, String args, String topic) {
567 String name, operation;
568 if (command ==
"clear") {
570 return publishItemsCount();
571 }
else if (command ==
"get") {
572 return publishContents(topic);
573 }
else if (command ==
"add") {
574 addContent(
"unnamed_" + String(++anonymous_counter), args);
575 return publishItemsCount();
576 }
else if (parseItemCommand(command, name, operation)) {
577 int16_t index = findItemByName(name.c_str());
578 if (operation ==
"set") {
580 index = addContent(name, args);
582 index = replaceContent(index, args);
585 return publishContent(topic, index);
587 }
else if (operation ==
"get") {
588 return publishContent(topic, index);
589 }
else if (operation ==
"jump") {
590 if (jumpItem(index)) {
591 return publishContent(topic, index);
593 }
else if (operation ==
"clear") {
594 if (clearItem(index)) {
595 return publishItemsCount();
602 bool parseItemCommand(String command, String &name, String &operation) {
603 const char *pPtr = command.c_str();
604 const char *pOperation = strrchr(pPtr,
'/');
608 size_t len = pOperation - pPtr;
609 operation = pOperation + 1;
612 return name.length() && operation.length();
615 bool publishItemsCount() {
616 pSched->publish(name +
"/display/count", String(program.length()));
620 bool parseDefaults(String args) {
621 bool changed = parseMode(shift(args,
';'), default_item);
622 changed = changed || parseRepeat(shift(args,
';'), default_item);
623 changed = changed || parseDuration(shift(args,
';'), default_item);
624 changed = changed || parseSpeed(shift(args,
';'), default_item);
625 changed = changed || parseFont(shift(args,
';'), default_item);
626 changed = changed || parseColor(shift(args,
';'), default_item);
627 changed = changed || parseBackground(shift(args,
';'), default_item);
631 bool publishDefaults(String topic) {
632 pSched->publish(topic, getItemString(default_item));
636 bool parseMode(String args, ProgramItem &item) {
637 int16_t iMode = parseToken(args, modeTokens);
638 if (iMode >= 0 && iMode != item.mode) {
639 item.mode = (Mode)iMode;
645 bool publishDefaultMode(String topic) {
646 pSched->publish(topic +
"/mode", modeTokens[default_item.mode]);
650 bool parseRepeat(String args, ProgramItem &item) {
652 int16_t value = parseRangedLong(args, 0, 32767, 0, 32767);
653 if (value != item.repeat) {
661 bool publishDefaultRepeat(String topic) {
662 pSched->publish(topic +
"/repeat", String(default_item.repeat));
666 bool parseDuration(String args, ProgramItem &item) {
668 long value = atol(args.c_str());
669 if (value >= 0 && (
unsigned long)value != item.duration) {
670 item.duration = value;
677 bool publishDefaultDuration(String topic) {
678 pSched->publish(topic +
"/duration", String(default_item.duration));
682 bool parseSpeed(String args, ProgramItem &item) {
684 long value = parseRangedLong(args, 1, 16, 0, 16);
685 if (value && value != item.speed) {
693 bool publishDefaultSpeed(String topic) {
694 pSched->publish(topic +
"/speed", String(default_item.speed));
698 bool parseFont(String args, ProgramItem &item) {
700 int value = atoi(args.c_str());
701 if (value >= 0 && value < (
int)getTextFontCount() && value != item.font) {
709 bool publishDefaultFont(String topic) {
710 pSched->publish(topic +
"/font", String(default_item.font));
714 bool parseColor(String args, ProgramItem &item) {
716 item.color = parseColor(args, item.color);
721 bool publishDefaultColor(String topic) {
722 pSched->publish(topic +
"/color",
"0x" + String(default_item.color, HEX));
726 bool parseBackground(String args, ProgramItem &item) {
728 item.bg = parseColor(args, item.bg);
733 bool publishDefaultBackground(String topic) {
734 pSched->publish(topic +
"/background",
"0x" + String(default_item.bg, HEX));
738 int16_t addItem(String name, String args) {
739 ProgramItem item = default_item;
741 parseMode(shift(args,
';'), item);
742 parseRepeat(shift(args,
';'), item);
743 parseDuration(shift(args,
';'), item);
744 parseSpeed(shift(args,
';'), item);
745 parseFont(shift(args,
';'), item);
746 parseColor(shift(args,
';'), item);
747 parseBackground(shift(args,
';'), item);
749 return program.add(item);
752 int16_t replaceItem(int16_t i, String args) {
753 if (i < 0 || i > (int16_t)program.length() - 1) {
756 ProgramItem item = program[i];
757 parseMode(shift(args,
';'), item);
758 parseRepeat(shift(args,
';'), item);
759 parseDuration(shift(args,
';'), item);
760 parseSpeed(shift(args,
';'), item);
761 parseFont(shift(args,
';'), item);
762 parseColor(shift(args,
';'), item);
763 parseBackground(shift(args,
';'), item);
766 if (program_counter == i) {
767 changedProgramItem(program[i]);
772 bool jumpItem(int16_t i) {
773 if (i < 0 || i > (int16_t)program.length() - 1) {
777 program_state = None;
781 bool clearItem(int16_t i) {
782 if (i < 0 || i > (int16_t)program.length() - 1) {
786 if (program_counter > i) {
789 }
else if (program_counter == i) {
792 program_state = None;
793 if (program_counter >= (int16_t)program.length()) {
797 if (program.length() == 0) {
798 displayClear(0, program_pos, program_width, program_height);
803 bool publishItem(String topic, int16_t i) {
804 if (i < 0 || i > (int16_t)program.length() - 1) {
807 pSched->publish(topic +
"/" + program[i].name, getItemString(program[i]));
811 bool publishItems(String topic) {
812 for (
unsigned int i = 0; i < program.length(); i++) {
813 pSched->publish(topic +
"/" + program[i].name, getItemString(program[i]));
818 int16_t addContent(String name, String args) {
819 ProgramItem item = default_item;
823 return program.length();
826 int16_t replaceContent(int16_t i, String args) {
827 if (i < 0 || i > (int16_t)program.length() - 1) {
830 program[i].content = args;
831 if (program_counter == i) {
832 changedProgramItem(program[i]);
837 bool publishContent(String topic, int16_t i) {
838 if (i < 0 || i > (int16_t)program.length() - 1) {
841 pSched->publish(topic +
"/" + program[i].name, program[i].content);
845 bool publishContents(String topic) {
846 for (
unsigned int i = 0; i < program.length(); i++) {
847 pSched->publish(topic +
"/" + program[i].name, program[i].content);
852 int16_t findItemByName(
const char *name) {
853 for (int16_t i = 0; i < (int16_t)program.length(); i++) {
854 if (program[i].name == name) {
861 String getItemString(ProgramItem &item) {
862 String itemString = modeTokens[item.mode];
863 itemString.concat(
";");
864 itemString.concat(item.repeat);
865 itemString.concat(
";");
866 itemString.concat(item.duration);
867 itemString.concat(
";");
868 itemString.concat(item.speed);
869 itemString.concat(
";");
870 itemString.concat(item.font);
871 itemString.concat(
";");
872 itemString.concat(
"0x" + String(item.color, HEX));
873 itemString.concat(
";");
874 itemString.concat(
"0x" + String(item.bg, HEX));
875 if (item.content.length()) {
876 itemString.concat(
";");
877 itemString.concat(item.content);
884 bool isNumber(
const char *value,
bool integer =
false) {
891 bool decimalpoint =
false;
893 if (*value < '0' || *value >
'9') {
894 if (integer || decimalpoint || *value !=
'.') {
905 void displayError(int16_t x, int16_t y, int16_t w, int16_t align) {
907 displayFormat(x, y, w, align,
"Error", current_font, current_fg, current_bg);
909 displayFormat(x, y, w, align,
"Err", current_font, current_fg, current_bg);
911 displayFormat(x, y, w, align,
"E", current_font, current_fg, current_bg);
916 virtual void getDimensions(int16_t &width, int16_t &height) = 0;
917 virtual bool getTextWrap() = 0;
918 virtual void setTextWrap(
bool wrap) = 0;
919 virtual FontSize getTextFontSize() = 0;
920 virtual uint8_t getTextFontCount() = 0;
921 virtual void setTextFont(uint8_t font, int16_t baseLineAdjustment) = 0;
922 virtual void setTextColor(uint16_t fg, uint16_t bg) = 0;
923 virtual void getCursor(int16_t &x, int16_t &y) = 0;
924 virtual void setCursor(int16_t x, int16_t y) = 0;
925 virtual void displayClear(int16_t x, int16_t y, int16_t w, int16_t h) = 0;
926 virtual void displayClear(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t bg) = 0;
927 virtual void displayPrint(String content,
bool ln =
false) = 0;
928 virtual bool displayFormat(int16_t x, int16_t y, int16_t w, int16_t align, String content,
929 uint8_t font, uint16_t color, uint16_t bg) = 0;
931#ifdef USTD_FEATURE_PROGRAMPLAYER
932 virtual void changedProgramItem(ProgramItem &item) {
935 displayFormat(0, program_pos, program_width, 0, item.content, item.font, item.color,
939 displayFormat(0, program_pos, program_width, 1, item.content, item.font, item.color,
943 displayFormat(0, program_pos, program_width, 2, item.content, item.font, item.color,
947 if (program_state == FadeIn && charPos < item.content.length() - 1) {
949 displayFormat(0, program_pos, program_width, 0, item.content.substring(0, charPos),
950 item.font, item.color, item.bg);
953 initNextCharDimensions(item);
955 displayFormat(0, program_pos, program_width, 0, item.content, item.font, item.color,
957 program_state = Wait;
965 virtual void startProgramItem(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
966 item.duration.reset();
969 displayFormat(0, program_pos, program_width, 0, item.content, item.font, item.color,
971 program_state = Wait;
974 displayFormat(0, program_pos, program_width, 1, item.content, item.font, item.color,
976 program_state = Wait;
979 displayFormat(0, program_pos, program_width, 2, item.content, item.font, item.color,
981 program_state = Wait;
986 delayCtr = 17 - item.speed;
988 if (initNextCharDimensions(item)) {
989 displayClear(0, program_pos, program_width, program_height);
990 program_state = FadeIn;
992 displayFormat(0, program_pos, program_width, 0, item.content, item.font, item.color,
994 program_state = Wait;
998 program_state = Finished;
1003 virtual void fadeInProgramItem(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1004 if (item.mode == SlideIn) {
1008 delayCtr = 17 - item.speed;
1010 displayFormat(slidePos, program_pos, program_width - slidePos, 0,
1011 item.content.substring(charPos, charPos + 1), item.font, item.color,
1015 if (slidePos <= lastPos) {
1019 if (lastPos >= slidePos) {
1021 fadeInEnd(item, x, y, w, h);
1025 if (!initNextCharDimensions(item)) {
1027 fadeInEnd(item, x, y, w, h);
1032 fadeInEnd(item, x, y, w, h);
1037 virtual void fadeInEnd(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1038 item.duration.reset();
1039 program_state = Wait;
1042 virtual void waitProgramItem(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1043 if (item.duration.test()) {
1044 program_state = FadeOut;
1048 virtual void fadeOutProgramItem(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1056 fadeOutEnd(item, x, y, w, h);
1059 virtual void fadeOutEnd(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1060 program_state = Finished;
1063 virtual void endProgramItem(ProgramItem &item, int16_t x, int16_t y, int16_t w, int16_t h) {
1064 program_state = None;
1066 if (--item.repeat) {
1071 program.erase(program_counter);
1076 if (program_counter >= (int16_t)program.length()) {
1077 program_counter = 0;
1081 virtual bool initNextCharDimensions(ProgramItem &item) = 0;
1086const char *MuppletDisplay::formatTokens[] = {
"left",
"center",
"right",
"number",
nullptr};
1087const char *MuppletDisplay::colorTokens[] = {
"black",
"white",
"red",
"green",
"blue",
1088 "cyan",
"magenta",
"yellow",
"orange",
nullptr};
1090#ifdef USTD_FEATURE_PROGRAMPLAYER
1091const char *MuppletDisplay::modeTokens[] = {
"left",
"center",
"right",
"slidein",
nullptr};
The base class for all display mupplets.
Definition: mup_display.h:24
The muwerk namespace.
Definition: display_digits_max72xx.h:10