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:
99 virtual bool matches(MenuItem* item)=0;
100};
101
106private:
107 uint8_t remoteNo;
108public:
113 explicit RemoteNoMenuItemPredicate(int remoteNo) { this->remoteNo = remoteNo; }
114
120 bool matches(MenuItem* item) override;
121
126 void setRemoteNo(uint8_t newRemoteNum) { remoteNo = newRemoteNum; }
127};
128
129// the modes that can be passed to the type predicate
130#define TM_REGULAR 0
131#define TM_INVERTED 1
132#define TM_REGULAR_LOCAL_ONLY 8
133#define TM_INVERTED_LOCAL_ONLY 9
134#define TM_EXTRA_INCLUDE_SUBMENUS 16
135#define TM_BIT_INVERT 0U
136#define TM_BIT_LOCAL_ONLY 3U
137#define TM_BIT_INCLUDE_SUBMENU 4U
138
148private:
149 MenuType filterType;
150 uint8_t mode;
151public:
156 MenuItemTypePredicate(MenuType filterType, uint8_t mode = 0) {
157 this->filterType = filterType;
158 this->mode = mode;
159 }
160
166 bool matches(MenuItem* item) override;
167};
168
175class MenuItemIterator {
176private:
177 MenuItem* currentItem;
178 MenuItemPredicate* predicate;
179 MenuItem* parentItems[MAX_MENU_DEPTH];
180 uint8_t level;
181 bool processingSubMenu;
182public:
183 MenuItemIterator() {
184 reset();
185 predicate = nullptr;
186 }
187
192 void setPredicate(MenuItemPredicate* predicate) { this->predicate = predicate; }
193
197 void reset();
198
205
214};
215
216template<typename T>
217inline T *asMenuItem(MenuItem *item, MenuType expectedType, const char *typeName) {
218 if (item == nullptr || item->getMenuType() != expectedType) {
219 while (1) {
220 // literally stop here if we get a fault, continuing will lead to worse.
221 serlogF2(SER_ERROR, typeName, item == nullptr ? 0 : item->getId());
222 delay(1000);
223 }
224 }
225 return reinterpret_cast<T *>(item);
226}
227
228inline AnalogMenuItem &asAnalogItem(MenuItem *item) {
229 return *asMenuItem<AnalogMenuItem>(item, MENUTYPE_INT_VALUE, "Item not analog");
230}
231inline AnalogMenuItem& getAnalogItemById(menuid_t id) { return asAnalogItem(getMenuItemById(id)); }
232
233
234inline EnumMenuItem &asEnumItem(MenuItem *item) {
235 return *asMenuItem<EnumMenuItem>(item, MENUTYPE_ENUM_VALUE, "Item not enum");
236}
237inline EnumMenuItem& getEnumItemById(menuid_t id) { return asEnumItem(getMenuItemById(id)); }
238
239
240inline BooleanMenuItem &asBooleanItem(MenuItem *item) {
241 return *asMenuItem<BooleanMenuItem>(item, MENUTYPE_BOOLEAN_VALUE, "Item not bool");
242}
243inline BooleanMenuItem& getBooleanItemById(menuid_t id) { return asBooleanItem(getMenuItemById(id)); }
244
245inline TextMenuItem& asTextItem(MenuItem *item) {
246 return *asMenuItem<TextMenuItem>(item, MENUTYPE_TEXT_VALUE, "Item not text");
247}
248inline TextMenuItem& getTextItemById(menuid_t id) { return asTextItem(getMenuItemById(id)); }
249
250inline FloatMenuItem& asFloatItem(MenuItem *item) {
251 return *asMenuItem<FloatMenuItem>(item, MENUTYPE_FLOAT_VALUE, "Item not float");
252}
253inline FloatMenuItem& getFloatItemById(menuid_t id) { return asFloatItem(getMenuItemById(id)); }
254
255inline SubMenuItem &asSubMenu(MenuItem *item) {
256 return *asMenuItem<SubMenuItem>(item, MENUTYPE_SUB_VALUE, "Item not submenu");
257}
258inline SubMenuItem& getSubMenuById(menuid_t id) { return asSubMenu(getMenuItemById(id)); }
259
260inline ActionMenuItem &asActionItem(MenuItem *item) {
261 return *asMenuItem<ActionMenuItem>(item, MENUTYPE_ACTION_VALUE, "Item not action");
262}
263inline ActionMenuItem& getActionItemById(menuid_t id) { return asActionItem(getMenuItemById(id)); }
264
265inline IpAddressMenuItem &asIpAddressItem(MenuItem *item) {
266 return *asMenuItem<IpAddressMenuItem>(item, MENUTYPE_IPADDRESS, "Item not IP");
267}
268inline IpAddressMenuItem& getIpAddressItemById(menuid_t id) { return asIpAddressItem(getMenuItemById(id)); }
269
270inline BackMenuItem &asBackMenu(MenuItem *item) {
271 return *asMenuItem<BackMenuItem>(item, MENUTYPE_BACK_VALUE, "Item not back");
272}
273inline BackMenuItem& getBackMenuById(menuid_t id) { return asBackMenu(getMenuItemById(id)); }
274
275inline ScrollChoiceMenuItem &asScrollChoiceItem(MenuItem *item) {
276 return *asMenuItem<ScrollChoiceMenuItem>(item, MENUTYPE_SCROLLER_VALUE, "Item not scroll");
277}
278inline ScrollChoiceMenuItem& getScrollChoiceItemById(menuid_t id) { return asScrollChoiceItem(getMenuItemById(id)); }
279
280inline TimeFormattedMenuItem &asTimeItem(MenuItem *item) {
281 return *asMenuItem<TimeFormattedMenuItem>(item, MENUTYPE_TIME, "Item not time");
282}
283inline TimeFormattedMenuItem& getTimeItemById(menuid_t id) { return asTimeItem(getMenuItemById(id)); }
284
285inline DateFormattedMenuItem &asDateItem(MenuItem *item) {
286 return *asMenuItem<DateFormattedMenuItem>(item, MENUTYPE_DATE, "Item not date");
287}
288inline DateFormattedMenuItem& getDateItemById(menuid_t id) { return asDateItem(getMenuItemById(id)); }
289
290inline Rgb32MenuItem &asRgb32Item(MenuItem *item) {
291 return *asMenuItem<Rgb32MenuItem>(item, MENUTYPE_COLOR_VALUE, "Item not rgb32");
292}
293inline Rgb32MenuItem& getRgb32ItemById(menuid_t id) { return asRgb32Item(getMenuItemById(id)); }
294
295inline EditableLargeNumberMenuItem &asLargeNumberItem(MenuItem *item) {
296 return *asMenuItem<EditableLargeNumberMenuItem>(item, MENUTYPE_LARGENUM_VALUE, "Item not lgenum");
297}
298inline EditableLargeNumberMenuItem& getLargeNumberItemById(menuid_t id) { return asLargeNumberItem(getMenuItemById(id)); }
299
300inline ListRuntimeMenuItem &asListItem(MenuItem *item) {
301 return *asMenuItem<ListRuntimeMenuItem>(item, MENUTYPE_RUNTIME_LIST, "Item not list");
302}
303inline ListRuntimeMenuItem& getListItemById(menuid_t id) { return asListItem(getMenuItemById(id)); }
304
305class RemoteMenuItem; // forward declaration
306class EepromAuthenticationInfoMenuItem; // forward declaration
307
308RemoteMenuItem& asIoTRemoteItem(MenuItem *item);
309inline RemoteMenuItem& getIoTRemoteMenuById(menuid_t id) { return asIoTRemoteItem(getMenuItemById(id)); }
310
311EepromAuthenticationInfoMenuItem& asAuthenticationMenuItem(MenuItem *item);
312inline EepromAuthenticationInfoMenuItem& getAuthenticationMenuById(menuid_t id) { return asAuthenticationMenuItem(getMenuItemById(id));}
313
314
315#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:681
Definition MenuItems.h:485
Definition RuntimeMenuItem.h:116
Definition MenuItems.h:606
Definition RuntimeMenuItem.h:540
Definition EditableLargeNumberMenuItem.h:182
Definition RemoteMenuItem.h:74
Definition MenuItems.h:575
Definition MenuItems.h:634
Definition RuntimeMenuItem.h:395
Definition RuntimeMenuItem.h:198
Definition MenuItems.h:338
menuid_t getId() const
Definition MenuItems.cpp:81
MenuType getMenuType() const
Definition MenuItems.h:370
void setPredicate(MenuItemPredicate *predicate)
Definition MenuIterator.h:192
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:156
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:126
RemoteNoMenuItemPredicate(int remoteNo)
Definition MenuIterator.h:113
Definition ScrollChoiceMenuItem.h:229
Definition ScrollChoiceMenuItem.h:34
Definition RuntimeMenuItem.h:149
Definition RuntimeMenuItem.h:268
Definition RuntimeMenuItem.h:510