tcMenu
Loading...
Searching...
No Matches
RuntimeMenuItem.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry).
3 * This product is licensed under an Apache license, see the LICENSE file in the top-level directory.
4 */
5
11#ifndef _RUNTIME_MENUITEM_H_
12#define _RUNTIME_MENUITEM_H_
13
14#include "MenuItems.h"
15#include "tcUtil.h"
16
18#ifndef RANDOM_ID_START
19#define RANDOM_ID_START 30000
20#endif
21
23menuid_t nextRandomId();
24
26int textItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
27
29int ipAddressRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
30
32int backSubItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
33
35int timeItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
36
38int dateItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
39
41int findPositionInEditorSet(char ch);
42
68
75class RuntimeMenuItem : public MenuItem {
76protected:
77 menuid_t id;
78 uint8_t itemPosition;
79 uint8_t noOfParts;
80public:
81 RuntimeMenuItem(MenuType menuType, menuid_t id, RuntimeRenderingFn renderFn,
82 uint8_t itemPosition, uint8_t numberOfRows, MenuItem* next = nullptr);
83
84 RuntimeMenuItem(const AnyMenuInfo* rtInfo, bool isPgm, MenuType menuType, RuntimeRenderingFn renderFn,
85 uint8_t itemPosition, uint8_t numberOfRows, MenuItem* next = nullptr);
86
87 void copyValue(char* buffer, int bufferSize) const {
88 renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_VALUE, buffer, bufferSize);
89 }
90
91 void runCallback() const { renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_INVOKE, nullptr, 0); }
92 int getRuntimeId() const { return int(id); }
93 int getRuntimeEeprom() const { return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_EEPROM_POS, nullptr, 0); }
94 uint8_t getNumberOfParts() const { return noOfParts; }
95 void copyRuntimeName(char* buffer, int bufferSize) const { renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_NAME, buffer, bufferSize);}
96
97 uint8_t getNumberOfRows() const { return noOfParts; }
98 uint8_t getItemPosition() const { return itemPosition; }
99
100 void setNumberOfRows(uint8_t rows) {
101 noOfParts = rows;
102 setChanged(true);
104 }
105};
106
117private:
118 const char* namePtr;
119public:
127 : RuntimeMenuItem(MENUTYPE_BACK_VALUE, nextRandomId(), renderFn, 0, 1, next), namePtr(nullptr) { }
128
137 BackMenuItem(const SubMenuInfo* info, MenuItem* next, bool infoInPgm);
138
142 const char* getNameUnsafe() const { return namePtr; }
143};
144
150private:
151 MenuItem* child;
152public:
162 SubMenuItem(const SubMenuInfo* info, MenuItem* child, MenuItem* next = nullptr, bool infoInPgm = INFO_LOCATION_PGM)
163 : RuntimeMenuItem(info, infoInPgm, MENUTYPE_SUB_VALUE, backSubItemRenderFn, 0, 1, next) {
164 this->child = child;
165 }
166
174 SubMenuItem(menuid_t id, RuntimeRenderingFn renderFn, MenuItem* child, MenuItem* next = nullptr)
175 : RuntimeMenuItem(MENUTYPE_SUB_VALUE, id, renderFn,
176 0, 1, next) {
177 this->child = child;
178 }
179
183 MenuItem* getChild() const { return child; }
184 void setChild(MenuItem* firstChildItem) { this->child = firstChildItem; }
185};
186
187#define LIST_PARENT_ITEM_POS 0xff
188
199public:
200 enum ListMode: uint8_t { CUSTOM_RENDER, RAM_ARRAY, FLASH_ARRAY };
201private:
202 const char* const* dataArray;
203 uint8_t activeItem;
204 ListMode listMode = CUSTOM_RENDER;
205public:
206 ListRuntimeMenuItem(const AnyMenuInfo* info, int numberOfRows, const char* const* array, ListMode listMode, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
207 ListRuntimeMenuItem(const AnyMenuInfo* info, int numberOfRows, RuntimeRenderingFn renderFn, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
208 ListRuntimeMenuItem(menuid_t id, int numberOfRows, RuntimeRenderingFn renderFn, MenuItem* next = nullptr);
209
210 RuntimeMenuItem* getChildItem(int pos);
211 RuntimeMenuItem* asParent();
212 RuntimeMenuItem* asBackMenu();
213
214 ListMode getListMode() const {return listMode;}
215 bool isActingAsParent() const { return itemPosition == LIST_PARENT_ITEM_POS; }
216 uint8_t getActiveIndex() const { return activeItem; }
217 void setActiveIndex(uint8_t idx) {
218 activeItem = idx;
219 setChanged(true);
220 }
221 const char* const* getDataArray() { return dataArray; }
222};
223
224int defaultRtListCallback(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
225
231public:
232 EditableMultiPartMenuItem(MenuType type, menuid_t id, int numberOfParts, RuntimeRenderingFn renderFn, MenuItem* next = nullptr)
233 : RuntimeMenuItem(type, id, renderFn, 0, numberOfParts, next) {
234 }
235 EditableMultiPartMenuItem(const AnyMenuInfo* rtInfo, bool isPgm, MenuType type, int numberOfParts, RuntimeRenderingFn renderFn, MenuItem* next = nullptr)
236 : RuntimeMenuItem(rtInfo, isPgm, type, renderFn, 0, numberOfParts, next) {
237 }
238
239 uint8_t beginMultiEdit();
240
241 int changeEditBy(int amt);
242
243 int previousPart();
244
245 int nextPart();
246
247 int getCurrentRange() const {
248 return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_GETRANGE, NULL, 0);
249 }
250
251 void stopMultiEdit();
252
253 int getPartValueAsInt() const {
254 return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_GETPART, NULL, 0);
255 }
256
257 bool valueChanged(int newVal);
258};
259
260// number of characters in the edit set.
261#define ALLOWABLE_CHARS_ENCODER_SIZE 94
262
269private:
270 char* data;
271 bool passwordField;
272public:
281 TextMenuItem(RuntimeRenderingFn customRenderFn, menuid_t id, int size, MenuItem* next = nullptr);
291 TextMenuItem(RuntimeRenderingFn customRenderFn, const char* initial, menuid_t id, int size, MenuItem* next = nullptr);
300 TextMenuItem(const AnyMenuInfo* info, const char* initial, int size, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
301
311 TextMenuItem(const AnyMenuInfo* info, RuntimeRenderingFn customRenderFn, const char* initial, int size, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
312
313 void setPasswordField(bool pwd) {
314 this->passwordField = pwd;
315 }
316
320 bool isPasswordField() const {
321 return this->passwordField;
322 }
323
324 ~TextMenuItem() { delete data; }
325
327 uint8_t textLength() const { return noOfParts; }
328
334 void setTextValue(const char* text, bool silent = false);
335
337 const char* getTextValue() const { return data; }
338
343 void cleanUpArray();
344
352 bool setCharValue(uint8_t location, char val);
353
361 bool valueChangedFromKeyboard(char keyPress);
362private:
363 void initTextItem(const char* initialData);
364};
365
371int findPositionInEditorSet(char ch);
372
378private:
379 uint8_t data[4];
380public:
381 explicit IpAddressStorage(const char* address);
382 IpAddressStorage(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4);
383 IpAddressStorage(const IpAddressStorage& other) = default;
384 IpAddressStorage& operator=(const IpAddressStorage& other) = default;
385
386 void setPart(int part, uint8_t newValue) { data[part] = newValue; }
387 uint8_t* underlyingArray() { return data; }
388};
389
396private:
397 IpAddressStorage data;
398public:
405 IpAddressMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MenuItem* next = nullptr)
406 : EditableMultiPartMenuItem(MENUTYPE_IPADDRESS, id, 4, renderFn, next), data(127, 0, 0, 1) {}
407
415 IpAddressMenuItem(RuntimeRenderingFn renderFn, const IpAddressStorage& initialIp, menuid_t id, MenuItem* next = nullptr)
416 : EditableMultiPartMenuItem(MENUTYPE_IPADDRESS, id, 4, renderFn, next), data(initialIp) {}
417
427 IpAddressMenuItem(const AnyMenuInfo* info, RuntimeRenderingFn renderFn, const IpAddressStorage& initialIp, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM)
428 : EditableMultiPartMenuItem(info, isPgm, MENUTYPE_IPADDRESS, 4, renderFn, next), data(initialIp) {}
429
438 IpAddressMenuItem(const AnyMenuInfo* info, const IpAddressStorage& initialIp, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM)
439 : EditableMultiPartMenuItem(info, isPgm, MENUTYPE_IPADDRESS, 4, ipAddressRenderFn, next), data(initialIp) {}
440
441 void setIpAddress(const char* source);
442
444 void setIpAddress(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4) {
445 data = IpAddressStorage(p1, p2, p3, p4);
446 }
447
449 uint8_t* getIpAddress() { return data.underlyingArray(); }
450
451 void setUnderlying(const IpAddressStorage& other);
452
453 IpAddressStorage& getUnderlying() { return data; }
454
456 void setIpPart(uint8_t part, uint8_t newVal);
457};
458
464 TimeStorage() {
465 this->hours = this->minutes = this->seconds = this->hundreds = 0;
466 }
467 TimeStorage(uint8_t hours, uint8_t minutes, uint8_t seconds = 0, uint8_t hundreds = 0) {
468 this->hours = hours;
469 this->minutes = minutes;
470 this->seconds = seconds;
471 this->hundreds = hundreds;
472 }
473 TimeStorage(const TimeStorage& other) = default;
474 TimeStorage& operator=(const TimeStorage& other) = default;
475
476 uint8_t hours;
477 uint8_t minutes;
478 uint8_t seconds;
479 uint8_t hundreds;
480};
481
486 uint8_t day;
487 uint8_t month;
488 uint16_t year;
489
490 DateStorage() {
491 year = day = month = 0;
492 }
493
494 DateStorage(int day, int month, int year) {
495 this->day = day;
496 this->month = month;
497 this->year = year;
498 }
499
500 DateStorage(const DateStorage& other) = default;
501 DateStorage& operator=(const DateStorage& other)=default;
502};
503
511private:
512 MultiEditWireType format;
513 TimeStorage data;
514public:
515 TimeFormattedMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MultiEditWireType format, MenuItem* next = nullptr);
516 TimeFormattedMenuItem(RuntimeRenderingFn renderFn, const TimeStorage& initial, menuid_t id, MultiEditWireType format, MenuItem* next = nullptr);
517 TimeFormattedMenuItem(const AnyMenuInfo* info, RuntimeRenderingFn renderFn, const TimeStorage& initial, MultiEditWireType format, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
518 TimeFormattedMenuItem(const AnyMenuInfo* info, const TimeStorage& initial, MultiEditWireType format, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM);
519
521 TimeStorage getTime() const { return data; }
522
524 void setTime(TimeStorage newTime) { data = newTime; }
525
527 void setTimeFromString(const char* time);
528
530 MultiEditWireType getFormat() const { return format; }
531
532 TimeStorage* getUnderlyingData() {return &data;}
533};
534
541public:
542 enum DateFormatOption { DD_MM_YYYY, MM_DD_YYYY, YYYY_MM_DD };
543private:
544 DateStorage data;
545 static char separator;
546 static DateFormatOption dateFormatMode;
547public:
548 DateFormattedMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MenuItem* next = nullptr)
549 : EditableMultiPartMenuItem(MENUTYPE_DATE, id, 3, renderFn, next), data(1, 1, 2020) {}
550
551 DateFormattedMenuItem(RuntimeRenderingFn renderFn, const DateStorage& initial, menuid_t id, MenuItem* next = nullptr)
552 : EditableMultiPartMenuItem(MENUTYPE_DATE, id, 3, renderFn, next), data(initial) {}
553
554 DateFormattedMenuItem(const AnyMenuInfo* info, RuntimeRenderingFn renderFn, const DateStorage& initial, menuid_t /*id*/, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM)
555 : EditableMultiPartMenuItem(info, isPgm, MENUTYPE_DATE, 3, renderFn, next), data(initial) {}
556
557 DateFormattedMenuItem(const AnyMenuInfo* info, const DateStorage& initial, MenuItem* next = nullptr, bool isPgm = INFO_LOCATION_PGM)
558 : EditableMultiPartMenuItem(info, isPgm, MENUTYPE_DATE, 3, dateItemRenderFn, next), data(initial) {}
559
564 static void setDateSeparator(char sep) {
565 separator = sep;
566 }
567
571 static char getDateSeparator() {
572 return separator;
573 }
574
579 static void setDateFormatStyle(DateFormatOption fmt) {
580 dateFormatMode = fmt;
581 }
582
586 static DateFormatOption getDateFormatStyle() {
587 return dateFormatMode;
588 }
589
590 DateStorage getDate() const { return data; }
591
592 void setDate(DateStorage newDate) { data = newDate; }
593
594 void setDateFromString(const char *dateText);
595
596 DateStorage* getUnderlyingData() { return &data; }
597};
598
605long parseIntUntilSeparator(const char* ptr, int& offset, size_t maxDigits=10);
606
612inline void invokeIfSafe(MenuCallbackFn cb, MenuItem* pItem) { if(cb && pItem) cb(pItem->getId()); }
613
624#define RENDERING_CALLBACK_NAME_INVOKE(fnName, parent, namepgm, eepromPosition, invoke) \
625const char fnName##Pgm[] PROGMEM = namepgm; \
626int fnName(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int buffSize) { \
627 switch(mode) { \
628 case RENDERFN_NAME: \
629 safeProgCpy(buffer, fnName##Pgm, buffSize); \
630 return true; \
631 case RENDERFN_INVOKE: \
632 invokeIfSafe(invoke, item); \
633 return true; \
634 case RENDERFN_EEPROM_POS: \
635 return eepromPosition; \
636 default: \
637 return parent(item, row, mode, buffer, buffSize); \
638 } \
639}
640
651#define RENDERING_CALLBACK_NAME_OVERRIDDEN(fnName, customFn, namepgm, eepromPosition) \
652const char fnName##Pgm[] PROGMEM = namepgm; \
653int fnName(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int buffSize) { \
654 switch(mode) { \
655 case RENDERFN_NAME: \
656 if(customFn(item, row, mode, buffer, buffSize) == false) { \
657 safeProgCpy(buffer, fnName##Pgm, buffSize); \
658 } \
659 return true; \
660 case RENDERFN_EEPROM_POS: \
661 return eepromPosition; \
662 default: \
663 return customFn(item, row, mode, buffer, buffSize); \
664 } \
665}
666
667#endif //_RUNTIME_MENUITEM_H_
In TcMenu, MenuItem storage is shared between program memory and RAM. Usually each MenuItem has assoc...
RenderFnMode
Definition MenuItems.h:283
@ RENDERFN_EEPROM_POS
Definition MenuItems.h:289
@ RENDERFN_INVOKE
Definition MenuItems.h:291
@ RENDERFN_NAME
Definition MenuItems.h:287
@ RENDERFN_GETRANGE
Definition MenuItems.h:297
@ RENDERFN_GETPART
Definition MenuItems.h:299
@ RENDERFN_VALUE
Definition MenuItems.h:285
int(* RuntimeRenderingFn)(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition MenuItems.h:318
void(* MenuCallbackFn)(int id)
Definition MenuItems.h:45
MenuType
Definition MenuItems.h:238
@ MENUTYPE_IPADDRESS
Definition MenuItems.h:269
@ MENUTYPE_DATE
Definition MenuItems.h:273
@ MENUTYPE_SUB_VALUE
Definition MenuItems.h:260
@ MENUTYPE_BACK_VALUE
Definition MenuItems.h:254
Definition MenuItems.h:51
int ipAddressRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition RuntimeMenuItem.cpp:157
int dateItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition RuntimeMenuItem.cpp:300
void invokeIfSafe(MenuCallbackFn cb, MenuItem *pItem)
Definition RuntimeMenuItem.h:612
int findPositionInEditorSet(char ch)
Definition RuntimeMenuItem.cpp:372
menuid_t nextRandomId()
Definition RuntimeMenuItem.cpp:15
MultiEditWireType
Definition RuntimeMenuItem.h:46
@ EDITMODE_TIME_24H
Definition RuntimeMenuItem.h:52
@ EDITMODE_TIME_DURATION_HUNDREDS
Definition RuntimeMenuItem.h:62
@ EDITMODE_PLAIN_TEXT
Definition RuntimeMenuItem.h:48
@ EDITMODE_TIME_12H_HHMM
Definition RuntimeMenuItem.h:66
@ EDITMODE_TIME_12H
Definition RuntimeMenuItem.h:54
@ EDITMODE_IP_ADDRESS
Definition RuntimeMenuItem.h:50
@ EDITMODE_TIME_HUNDREDS_24H
Definition RuntimeMenuItem.h:56
@ EDITMODE_GREGORIAN_DATE
Definition RuntimeMenuItem.h:58
@ EDITMODE_TIME_DURATION_SECONDS
Definition RuntimeMenuItem.h:60
@ EDITMODE_TIME_24H_HHMM
Definition RuntimeMenuItem.h:64
int timeItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition RuntimeMenuItem.cpp:197
long parseIntUntilSeparator(const char *ptr, int &offset, size_t maxDigits=10)
Definition RuntimeMenuItem.cpp:511
int textItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition RuntimeMenuItem.cpp:383
Definition RuntimeMenuItem.h:116
const char * getNameUnsafe() const
Definition RuntimeMenuItem.h:142
BackMenuItem(RuntimeRenderingFn renderFn, MenuItem *next)
Definition RuntimeMenuItem.h:126
Definition RuntimeMenuItem.h:540
static void setDateSeparator(char sep)
Definition RuntimeMenuItem.h:564
static DateFormatOption getDateFormatStyle()
Definition RuntimeMenuItem.h:586
static char getDateSeparator()
Definition RuntimeMenuItem.h:571
static void setDateFormatStyle(DateFormatOption fmt)
Definition RuntimeMenuItem.h:579
Definition RuntimeMenuItem.h:230
Definition RuntimeMenuItem.h:395
void setIpPart(uint8_t part, uint8_t newVal)
Definition RuntimeMenuItem.cpp:495
IpAddressMenuItem(RuntimeRenderingFn renderFn, const IpAddressStorage &initialIp, menuid_t id, MenuItem *next=nullptr)
Definition RuntimeMenuItem.h:415
IpAddressMenuItem(const AnyMenuInfo *info, const IpAddressStorage &initialIp, MenuItem *next=nullptr, bool isPgm=INFO_LOCATION_PGM)
Definition RuntimeMenuItem.h:438
IpAddressMenuItem(const AnyMenuInfo *info, RuntimeRenderingFn renderFn, const IpAddressStorage &initialIp, MenuItem *next=nullptr, bool isPgm=INFO_LOCATION_PGM)
Definition RuntimeMenuItem.h:427
void setIpAddress(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4)
Definition RuntimeMenuItem.h:444
IpAddressMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MenuItem *next=nullptr)
Definition RuntimeMenuItem.h:405
uint8_t * getIpAddress()
Definition RuntimeMenuItem.h:449
Definition RuntimeMenuItem.h:377
Definition RuntimeMenuItem.h:198
Definition MenuItems.h:329
void setChanged(bool changed)
Definition MenuItems.cpp:112
menuid_t getId() const
Definition MenuItems.cpp:81
const AnyMenuInfo * info
Definition MenuItems.h:334
void setSendRemoteNeededAll()
Definition MenuItems.cpp:30
Definition RuntimeMenuItem.h:75
Definition RuntimeMenuItem.h:149
SubMenuItem(const SubMenuInfo *info, MenuItem *child, MenuItem *next=nullptr, bool infoInPgm=INFO_LOCATION_PGM)
Definition RuntimeMenuItem.h:162
SubMenuItem(menuid_t id, RuntimeRenderingFn renderFn, MenuItem *child, MenuItem *next=nullptr)
Definition RuntimeMenuItem.h:174
MenuItem * getChild() const
Definition RuntimeMenuItem.h:183
Definition RuntimeMenuItem.h:268
void cleanUpArray()
Definition RuntimeMenuItem.cpp:123
uint8_t textLength() const
Definition RuntimeMenuItem.h:327
const char * getTextValue() const
Definition RuntimeMenuItem.h:337
bool valueChangedFromKeyboard(char keyPress)
Definition RuntimeMenuItem.cpp:614
bool setCharValue(uint8_t location, char val)
Definition RuntimeMenuItem.cpp:133
void setTextValue(const char *text, bool silent=false)
Definition RuntimeMenuItem.cpp:112
bool isPasswordField() const
Definition RuntimeMenuItem.h:320
Definition RuntimeMenuItem.h:510
MultiEditWireType getFormat() const
Definition RuntimeMenuItem.h:530
TimeStorage getTime() const
Definition RuntimeMenuItem.h:521
void setTime(TimeStorage newTime)
Definition RuntimeMenuItem.h:524
void setTimeFromString(const char *time)
Definition RuntimeMenuItem.cpp:527
Definition RuntimeMenuItem.h:485
Definition RuntimeMenuItem.h:463
A series of utilities that used throughout tcMenu.