tcMenu
RuntimeMenuItem.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 https://www.thecoderscorner.com (Nutricherry LTD).
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 #define RANDOM_ID_START 50000
19 
21 menuid_t nextRandomId();
22 
24 int textItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
25 
27 int ipAddressRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
28 
30 int backSubItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
31 
33 int timeItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
34 
36 int dateItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
37 
39 int findPositionInEditorSet(char ch);
40 
44 enum MultiEditWireType : uint8_t {
65 };
66 
73 class RuntimeMenuItem : public MenuItem {
74 protected:
75  menuid_t id;
76  uint8_t itemPosition;
77  uint8_t noOfParts;
78 public:
79  RuntimeMenuItem(MenuType menuType, menuid_t id, RuntimeRenderingFn renderFn,
80  uint8_t itemPosition, uint8_t numberOfRows, MenuItem* next = nullptr);
81 
82  void copyValue(char* buffer, int bufferSize) const {
83  renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_VALUE, buffer, bufferSize);
84  }
85 
86  void runCallback() const { renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_INVOKE, nullptr, 0); }
87  int getRuntimeId() const { return id; }
88  int getRuntimeEeprom() const { return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_EEPROM_POS, nullptr, 0); }
89  uint8_t getNumberOfParts() const { return noOfParts; }
90  void copyRuntimeName(char* buffer, int bufferSize) const { renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_NAME, buffer, bufferSize); }
91 
92  uint8_t getNumberOfRows() const { return noOfParts; }
93 
94  void setNumberOfRows(uint8_t rows) {
95  noOfParts = rows;
96  setChanged(true);
98  }
99 };
100 
111 public:
119  : RuntimeMenuItem(MENUTYPE_BACK_VALUE, nextRandomId(), renderFn, 0, 1, next) { }
120 };
121 
125 class SubMenuItem : public RuntimeMenuItem {
126 private:
127  MenuItem* child;
128  const char* pgmNamePtr;
129 public:
139  SubMenuItem(const SubMenuInfo* info, MenuItem* child, MenuItem* next = nullptr)
140  : RuntimeMenuItem(MENUTYPE_SUB_VALUE, get_info_uint(&info->id), backSubItemRenderFn, 0, 1, next) {
141  this->child = child;
142  this->pgmNamePtr = info->name;
143  }
144 
152  SubMenuItem(menuid_t id, RuntimeRenderingFn renderFn, MenuItem* child, MenuItem* next = nullptr)
153  : RuntimeMenuItem(MENUTYPE_SUB_VALUE, id, renderFn,
154  0, 1, next) {
155  this->child = child;
156  this->pgmNamePtr = nullptr;
157  }
158 
162  MenuItem* getChild() const { return child; }
163  void setChild(MenuItem* firstChildItem) { this->child = firstChildItem; }
164 
165  const char* getNamePGMUnsafe() const { return pgmNamePtr; }
166 };
167 
168 #define LIST_PARENT_ITEM_POS 0xff
169 
180 private:
181  uint8_t activeItem;
182 public:
183  ListRuntimeMenuItem(menuid_t id, int numberOfRows, RuntimeRenderingFn renderFn, MenuItem* next = nullptr);
184 
185  RuntimeMenuItem* getChildItem(int pos);
186  RuntimeMenuItem* asParent();
187  RuntimeMenuItem* asBackMenu();
188 
189  bool isActingAsParent() const { return itemPosition == LIST_PARENT_ITEM_POS; }
190  uint8_t getActiveIndex() const { return activeItem; }
191  void setActiveIndex(uint8_t idx) {
192  activeItem = idx;
193  setChanged(true);
194  }
195 };
196 
202 public:
203  EditableMultiPartMenuItem(MenuType type, menuid_t id, int numberOfParts, RuntimeRenderingFn renderFn, MenuItem* next = nullptr)
204  : RuntimeMenuItem(type, id, renderFn, 0, numberOfParts, next) {
205  }
206 
207  uint8_t beginMultiEdit();
208 
209  int changeEditBy(int amt);
210 
211  int previousPart();
212 
213  int nextPart();
214 
215  int getCurrentRange() const {
216  return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_GETRANGE, NULL, 0);
217  }
218 
219  void stopMultiEdit();
220 
221  int getPartValueAsInt() const {
222  return renderFn((RuntimeMenuItem*)this, itemPosition, RENDERFN_GETPART, NULL, 0);
223  }
224 
225  bool valueChanged(int newVal);
226 };
227 
228 // number of characters in the edit set.
229 #define ALLOWABLE_CHARS_ENCODER_SIZE 94
230 
236 private:
237  char* data;
238  bool passwordField;
239 public:
240  TextMenuItem(RuntimeRenderingFn customRenderFn, menuid_t id, int size, MenuItem* next = nullptr);
241 
242  void setPasswordField(bool pwd) {
243  this->passwordField = pwd;
244  }
245 
246  bool isPasswordField() const {
247  return this->passwordField;
248  }
249 
250  ~TextMenuItem() { delete data; }
251 
253  uint8_t textLength() const { return noOfParts; }
254 
259  void setTextValue(const char* text, bool silent = false);
260 
262  const char* getTextValue() const { return data; }
263 
268  void cleanUpArray();
269 private:
270  bool setCharValue(uint8_t location, char val);
271  friend int textItemRenderFn(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int bufferSize);
272 };
273 
279 int findPositionInEditorSet(char ch);
280 
286 private:
287  uint8_t data[4];
288 public:
289  IpAddressMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MenuItem* next = nullptr)
290  : EditableMultiPartMenuItem(MENUTYPE_IPADDRESS, id, 4, renderFn, next) {
291  setIpAddress(127, 0, 0, 1);
292  }
293 
294  void setIpAddress(const char* source);
295 
297  void setIpAddress(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4);
298 
300  uint8_t* getIpAddress() const { return (uint8_t*)data; }
301 
303  void setIpPart(uint8_t part, uint8_t newVal);
304 };
305 
310 struct TimeStorage {
311  TimeStorage() {
312  this->hours = this->minutes = this->seconds = this->hundreds = 0;
313  }
314 
315  TimeStorage(uint8_t hours, uint8_t minutes, uint8_t seconds = 0, uint8_t hundreds = 0) {
316  this->hours = hours;
317  this->minutes = minutes;
318  this->seconds = seconds;
319  this->hundreds = hundreds;
320  }
321 
322  uint8_t hours;
323  uint8_t minutes;
324  uint8_t seconds;
325  uint8_t hundreds;
326 };
327 
331 struct DateStorage {
332  uint8_t day;
333  uint8_t month;
334  uint16_t year;
335 
336  DateStorage() {
337  year = day = month = 0;
338  }
339 
340  DateStorage(int day, int month, int year) {
341  this->day = day;
342  this->month = month;
343  this->year = year;
344  }
345 };
346 
354 private:
355  MultiEditWireType format;
356  TimeStorage data;
357 public:
358  TimeFormattedMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MultiEditWireType format, MenuItem* next = nullptr);
359 
360 
362  TimeStorage getTime() const { return data; }
363 
365  void setTime(TimeStorage newTime) { data = newTime; }
366 
368  void setTimeFromString(const char* time);
369 
371  MultiEditWireType getFormat() const { return format; }
372 
373  TimeStorage* getUnderlyingData() {return &data;}
374 };
375 
382 public:
383  enum DateFormatOption { DD_MM_YYYY, MM_DD_YYYY, YYYY_MM_DD };
384 private:
385  DateStorage data;
386  static char separator;
387  static DateFormatOption dateFormatMode;
388 public:
389  DateFormattedMenuItem(RuntimeRenderingFn renderFn, menuid_t id, MenuItem* next = nullptr)
390  : EditableMultiPartMenuItem(MENUTYPE_DATE, id, 3, renderFn, next) {
391  setDate(DateStorage(1, 1, 2020));
392  }
393 
398  static void setDateSeparator(char sep) {
399  separator = sep;
400  }
401 
405  static char getDateSeparator() {
406  return separator;
407  }
408 
413  static void setDateFormatStyle(DateFormatOption fmt) {
414  dateFormatMode = fmt;
415  }
416 
420  static DateFormatOption getDateFormatStyle() {
421  return dateFormatMode;
422  }
423 
424  DateStorage getDate() const { return data; }
425 
426  void setDate(DateStorage newDate) { data = newDate; }
427 
428  void setDateFromString(const char *dateText);
429 
430  DateStorage* getUnderlyingData() { return &data; }
431 };
432 
439 long parseIntUntilSeparator(const char* ptr, int& offset);
440 
446 inline void invokeIfSafe(MenuCallbackFn cb, MenuItem* pItem) { if(cb && pItem) cb(pItem->getId()); }
447 
453 #define RENDERING_CALLBACK_NAME_INVOKE(fnName, parent, namepgm, eepromPosition, invoke) \
454 const char fnName##Pgm[] PROGMEM = namepgm; \
455 int fnName(RuntimeMenuItem* item, uint8_t row, RenderFnMode mode, char* buffer, int buffSize) { \
456  switch(mode) { \
457  case RENDERFN_NAME: \
458  safeProgCpy(buffer, fnName##Pgm, buffSize); \
459  return true; \
460  case RENDERFN_INVOKE: \
461  invokeIfSafe(invoke, item); \
462  return true; \
463  case RENDERFN_EEPROM_POS: \
464  return eepromPosition; \
465  default: \
466  return parent(item, row, mode, buffer, buffSize); \
467  } \
468 }
469 
470 #endif //_RUNTIME_MENUITEM_H_
471 
RenderFnMode
Definition: MenuItems.h:287
MenuItem * getChild() const
Definition: RuntimeMenuItem.h:162
Definition: MenuItems.h:329
uint8_t textLength() const
Definition: RuntimeMenuItem.h:253
Definition: MenuItems.h:293
Definition: RuntimeMenuItem.h:331
Definition: RuntimeMenuItem.h:52
int findPositionInEditorSet(char ch)
Definition: RuntimeMenuItem.cpp:293
static void setDateSeparator(char sep)
Definition: RuntimeMenuItem.h:398
Definition: RuntimeMenuItem.h:285
Definition: RuntimeMenuItem.h:46
int ipAddressRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: RuntimeMenuItem.cpp:91
Definition: MenuItems.h:258
Definition: RuntimeMenuItem.h:58
Definition: RuntimeMenuItem.h:125
MultiEditWireType getFormat() const
Definition: RuntimeMenuItem.h:371
Definition: RuntimeMenuItem.h:110
TimeStorage getTime() const
Definition: RuntimeMenuItem.h:362
void setChanged(bool changed)
Definition: MenuItems.h:370
Definition: RuntimeMenuItem.h:179
Definition: MenuItems.h:289
menuid_t getId() const
Definition: MenuItems.cpp:74
const char * getTextValue() const
Definition: RuntimeMenuItem.h:262
void(* MenuCallbackFn)(int id)
Definition: MenuItems.h:40
MenuType
Definition: MenuItems.h:242
Definition: RuntimeMenuItem.h:310
menuid_t nextRandomId()
Definition: RuntimeMenuItem.cpp:14
static DateFormatOption getDateFormatStyle()
Definition: RuntimeMenuItem.h:420
Definition: MenuItems.h:291
SubMenuItem(const SubMenuInfo *info, MenuItem *child, MenuItem *next=nullptr)
Definition: RuntimeMenuItem.h:139
MultiEditWireType
Definition: RuntimeMenuItem.h:44
static void setDateFormatStyle(DateFormatOption fmt)
Definition: RuntimeMenuItem.h:413
BackMenuItem(RuntimeRenderingFn renderFn, MenuItem *next)
Definition: RuntimeMenuItem.h:118
Definition: RuntimeMenuItem.h:54
Definition: RuntimeMenuItem.h:60
Definition: RuntimeMenuItem.h:64
Definition: RuntimeMenuItem.h:353
char name[NAME_SIZE_T]
Definition: MenuItems.h:171
int backSubItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: RuntimeMenuItem.cpp:268
Definition: MenuItems.h:295
Definition: RuntimeMenuItem.h:201
Definition: RuntimeMenuItem.h:62
int textItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: RuntimeMenuItem.cpp:304
long parseIntUntilSeparator(const char *ptr, int &offset)
Definition: RuntimeMenuItem.cpp:397
static char getDateSeparator()
Definition: RuntimeMenuItem.h:405
Definition: RuntimeMenuItem.h:48
Definition: MenuItems.h:273
Definition: RuntimeMenuItem.h:73
uint8_t * getIpAddress() const
Definition: RuntimeMenuItem.h:300
Definition: MenuItems.h:301
Definition: RuntimeMenuItem.h:56
Definition: MenuItems.h:264
Definition: RuntimeMenuItem.h:50
Definition: RuntimeMenuItem.h:235
Definition: RuntimeMenuItem.h:381
void setTime(TimeStorage newTime)
Definition: RuntimeMenuItem.h:365
int dateItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: RuntimeMenuItem.cpp:224
Definition: MenuItems.h:169
SubMenuItem(menuid_t id, RuntimeRenderingFn renderFn, MenuItem *child, MenuItem *next=nullptr)
Definition: RuntimeMenuItem.h:152
void setSendRemoteNeededAll()
Definition: MenuItems.cpp:38
Definition: MenuItems.h:299
int(* RuntimeRenderingFn)(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: MenuItems.h:318
Definition: MenuItems.h:277
void invokeIfSafe(MenuCallbackFn cb, MenuItem *pItem)
Definition: RuntimeMenuItem.h:446
int timeItemRenderFn(RuntimeMenuItem *item, uint8_t row, RenderFnMode mode, char *buffer, int bufferSize)
Definition: RuntimeMenuItem.cpp:131