tcMenu
Loading...
Searching...
No Matches
MenuIterator.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
6#include <PlatformDetermination.h>
8
13
14#ifndef _MENUITERATOR_H
15#define _MENUITERATOR_H
16
17#ifndef MAX_MENU_DEPTH
18# define MAX_MENU_DEPTH 4
19#endif // MAX_MENU_DEPTH
20
22// forward reference of menu item
23class MenuItem;
24
28typedef void (*MenuVisitorFn)(MenuItem* item);
29
40
49inline MenuItem* getParentRoot(MenuItem* current) { return getParentRootAndVisit(current, nullptr); }
50
57
63MenuItem* getMenuItemById(menuid_t id);
64
71
77int offsetOfItem(MenuItem* itemToFind);
78
85uint8_t itemCount(MenuItem* item, bool includeNonVisble = false);
86
87
93public:
94 virtual ~MenuItemPredicate() = default;
100 virtual bool matches(MenuItem* item)=0;
101};
102
107private:
108 uint8_t remoteNo;
109public:
114 explicit RemoteNoMenuItemPredicate(int remoteNo) { this->remoteNo = remoteNo; }
115
121 bool matches(MenuItem* item) override;
122
127 void setRemoteNo(uint8_t newRemoteNum) { remoteNo = newRemoteNum; }
128};
129
130// the modes that can be passed to the type predicate
131#define TM_REGULAR 0
132#define TM_INVERTED 1
133#define TM_REGULAR_LOCAL_ONLY 8
134#define TM_INVERTED_LOCAL_ONLY 9
135#define TM_EXTRA_INCLUDE_SUBMENUS 16
136#define TM_BIT_INVERT 0U
137#define TM_BIT_LOCAL_ONLY 3U
138#define TM_BIT_INCLUDE_SUBMENU 4U
139
149private:
150 MenuType filterType;
151 uint8_t mode;
152public:
157 MenuItemTypePredicate(MenuType filterType, uint8_t mode = 0) {
158 this->filterType = filterType;
159 this->mode = mode;
160 }
161
167 bool matches(MenuItem* item) override;
168};
169
176class MenuItemIterator {
177private:
178 MenuItem* currentItem;
179 MenuItemPredicate* predicate;
180 MenuItem* parentItems[MAX_MENU_DEPTH];
181 uint8_t level;
182 bool processingSubMenu;
183public:
184 MenuItemIterator() {
185 reset();
186 predicate = nullptr;
187 }
188
193 void setPredicate(MenuItemPredicate* predicate) { this->predicate = predicate; }
194
198 void reset();
199
206
215};
216
217template<typename T>
218inline T *asMenuItem(MenuItem *item, MenuType expectedType, const char *typeName) {
219 if (item == nullptr || item->getMenuType() != expectedType) {
220 while (1) {
221 // literally stop here if we get a fault, continuing will lead to worse.
222 serlog2(SER_ERROR, typeName, item == nullptr ? 0 : item->getId());
223 delay(1000);
224 }
225 }
226 return reinterpret_cast<T *>(item);
227}
228
229inline AnalogMenuItem &asAnalogItem(MenuItem *item) {
230 return *asMenuItem<AnalogMenuItem>(item, MENUTYPE_INT_VALUE, "Item not analog");
231}
232inline AnalogMenuItem& getAnalogItemById(menuid_t id) { return asAnalogItem(getMenuItemById(id)); }
233
234
235inline EnumMenuItem &asEnumItem(MenuItem *item) {
236 return *asMenuItem<EnumMenuItem>(item, MENUTYPE_ENUM_VALUE, "Item not enum");
237}
238inline EnumMenuItem& getEnumItemById(menuid_t id) { return asEnumItem(getMenuItemById(id)); }
239
240
241inline BooleanMenuItem &asBooleanItem(MenuItem *item) {
242 return *asMenuItem<BooleanMenuItem>(item, MENUTYPE_BOOLEAN_VALUE, "Item not bool");
243}
244inline BooleanMenuItem& getBooleanItemById(menuid_t id) { return asBooleanItem(getMenuItemById(id)); }
245
246inline TextMenuItem& asTextItem(MenuItem *item) {
247 return *asMenuItem<TextMenuItem>(item, MENUTYPE_TEXT_VALUE, "Item not text");
248}
249inline TextMenuItem& getTextItemById(menuid_t id) { return asTextItem(getMenuItemById(id)); }
250
251inline FloatMenuItem& asFloatItem(MenuItem *item) {
252 return *asMenuItem<FloatMenuItem>(item, MENUTYPE_FLOAT_VALUE, "Item not float");
253}
254inline FloatMenuItem& getFloatItemById(menuid_t id) { return asFloatItem(getMenuItemById(id)); }
255
256inline SubMenuItem &asSubMenu(MenuItem *item) {
257 return *asMenuItem<SubMenuItem>(item, MENUTYPE_SUB_VALUE, "Item not submenu");
258}
259inline SubMenuItem& getSubMenuById(menuid_t id) { return asSubMenu(getMenuItemById(id)); }
260
261inline ActionMenuItem &asActionItem(MenuItem *item) {
262 return *asMenuItem<ActionMenuItem>(item, MENUTYPE_ACTION_VALUE, "Item not action");
263}
264inline ActionMenuItem& getActionItemById(menuid_t id) { return asActionItem(getMenuItemById(id)); }
265
266inline IpAddressMenuItem &asIpAddressItem(MenuItem *item) {
267 return *asMenuItem<IpAddressMenuItem>(item, MENUTYPE_IPADDRESS, "Item not IP");
268}
269inline IpAddressMenuItem& getIpAddressItemById(menuid_t id) { return asIpAddressItem(getMenuItemById(id)); }
270
271inline BackMenuItem &asBackMenu(MenuItem *item) {
272 return *asMenuItem<BackMenuItem>(item, MENUTYPE_BACK_VALUE, "Item not back");
273}
274inline BackMenuItem& getBackMenuById(menuid_t id) { return asBackMenu(getMenuItemById(id)); }
275
276inline ScrollChoiceMenuItem &asScrollChoiceItem(MenuItem *item) {
277 return *asMenuItem<ScrollChoiceMenuItem>(item, MENUTYPE_SCROLLER_VALUE, "Item not scroll");
278}
279inline ScrollChoiceMenuItem& getScrollChoiceItemById(menuid_t id) { return asScrollChoiceItem(getMenuItemById(id)); }
280
281inline TimeFormattedMenuItem &asTimeItem(MenuItem *item) {
282 return *asMenuItem<TimeFormattedMenuItem>(item, MENUTYPE_TIME, "Item not time");
283}
284inline TimeFormattedMenuItem& getTimeItemById(menuid_t id) { return asTimeItem(getMenuItemById(id)); }
285
286inline DateFormattedMenuItem &asDateItem(MenuItem *item) {
287 return *asMenuItem<DateFormattedMenuItem>(item, MENUTYPE_DATE, "Item not date");
288}
289inline DateFormattedMenuItem& getDateItemById(menuid_t id) { return asDateItem(getMenuItemById(id)); }
290
291inline Rgb32MenuItem &asRgb32Item(MenuItem *item) {
292 return *asMenuItem<Rgb32MenuItem>(item, MENUTYPE_COLOR_VALUE, "Item not rgb32");
293}
294inline Rgb32MenuItem& getRgb32ItemById(menuid_t id) { return asRgb32Item(getMenuItemById(id)); }
295
296inline EditableLargeNumberMenuItem &asLargeNumberItem(MenuItem *item) {
297 return *asMenuItem<EditableLargeNumberMenuItem>(item, MENUTYPE_LARGENUM_VALUE, "Item not lgenum");
298}
299inline EditableLargeNumberMenuItem& getLargeNumberItemById(menuid_t id) { return asLargeNumberItem(getMenuItemById(id)); }
300
301inline ListRuntimeMenuItem &asListItem(MenuItem *item) {
302 return *asMenuItem<ListRuntimeMenuItem>(item, MENUTYPE_RUNTIME_LIST, "Item not list");
303}
304inline ListRuntimeMenuItem& getListItemById(menuid_t id) { return asListItem(getMenuItemById(id)); }
305
306class RemoteMenuItem; // forward declaration
307class EepromAuthenticationInfoMenuItem; // forward declaration
308
309RemoteMenuItem& asIoTRemoteItem(MenuItem *item);
310inline RemoteMenuItem& getIoTRemoteMenuById(menuid_t id) { return asIoTRemoteItem(getMenuItemById(id)); }
311
312EepromAuthenticationInfoMenuItem& asAuthenticationMenuItem(MenuItem *item);
313inline EepromAuthenticationInfoMenuItem& getAuthenticationMenuById(menuid_t id) { return asAuthenticationMenuItem(getMenuItemById(id));}
314
315
316#endif
MenuType
Definition MenuItems.h:247
@ MENUTYPE_COLOR_VALUE
Definition MenuItems.h:286
@ MENUTYPE_IPADDRESS
Definition MenuItems.h:278
@ MENUTYPE_DATE
Definition MenuItems.h:282
@ MENUTYPE_INT_VALUE
Definition MenuItems.h:249
@ MENUTYPE_ENUM_VALUE
Definition MenuItems.h:251
@ MENUTYPE_SUB_VALUE
Definition MenuItems.h:269
@ MENUTYPE_TIME
Definition MenuItems.h:280
@ MENUTYPE_SCROLLER_VALUE
Definition MenuItems.h:267
@ MENUTYPE_FLOAT_VALUE
Definition MenuItems.h:255
@ MENUTYPE_BOOLEAN_VALUE
Definition MenuItems.h:253
@ MENUTYPE_TEXT_VALUE
Definition MenuItems.h:276
@ MENUTYPE_ACTION_VALUE
Definition MenuItems.h:257
@ MENUTYPE_RUNTIME_LIST
Definition MenuItems.h:261
@ MENUTYPE_BACK_VALUE
Definition MenuItems.h:263
@ MENUTYPE_LARGENUM_VALUE
Definition MenuItems.h:284
int offsetOfItem(MenuItem *itemToFind)
Definition MenuIterator.cpp:197
void(* MenuVisitorFn)(MenuItem *item)
Definition MenuIterator.h:28
MenuItem * getParentRoot(MenuItem *current)
Definition MenuIterator.h:49
uint8_t itemCount(MenuItem *item, bool includeNonVisble=false)
Definition MenuIterator.cpp:209
int offsetOfCurrentActive(MenuItem *root)
Definition MenuIterator.cpp:203
MenuItem * getMenuItemById(menuid_t id)
Definition MenuIterator.cpp:93
MenuItem * getSubMenuFor(MenuItem *current)
Definition MenuIterator.cpp:227
MenuItem * getParentRootAndVisit(MenuItem *current, MenuVisitorFn visitor)
Definition MenuIterator.cpp:48
contains the menu item definition for scrolling choice types, and also for RGB items
Definition MenuItems.h:689
Definition MenuItems.h:493
Definition RuntimeMenuItem.h:113
Definition MenuItems.h:614
Definition RuntimeMenuItem.h:535
Definition EditableLargeNumberMenuItem.h:182
Definition RemoteMenuItem.h:74
Definition MenuItems.h:583
Definition MenuItems.h:642
Definition RuntimeMenuItem.h:392
Definition RuntimeMenuItem.h:195
Definition MenuItems.h:338
menuid_t getId() const
Definition MenuItems.cpp:81
MenuType getMenuType() const
Definition MenuItems.h:378
void setPredicate(MenuItemPredicate *predicate)
Definition MenuIterator.h:193
void reset()
Definition MenuIterator.cpp:110
MenuItem * currentParent()
Definition MenuIterator.cpp:165
MenuItem * nextItem()
Definition MenuIterator.cpp:116
Definition MenuIterator.h:92
virtual bool matches(MenuItem *item)=0
MenuItemTypePredicate(MenuType filterType, uint8_t mode=0)
Definition MenuIterator.h:157
bool matches(MenuItem *item) override
Definition MenuIterator.cpp:187
Definition RemoteMenuItem.h:30
bool matches(MenuItem *item) override
Definition MenuIterator.cpp:178
void setRemoteNo(uint8_t newRemoteNum)
Definition MenuIterator.h:127
RemoteNoMenuItemPredicate(int remoteNo)
Definition MenuIterator.h:114
Definition ScrollChoiceMenuItem.h:229
Definition ScrollChoiceMenuItem.h:34
Definition RuntimeMenuItem.h:146
Definition RuntimeMenuItem.h:265
Definition RuntimeMenuItem.h:505