Multiple links to single menu? #88
-
Let's say I have a main menu that is set up like this: Main MenuButton 1 Config (sub menu) Then in each of the sub menus I have something like Button 1 MenuButton 1 Value (int) Button 2 and 3 menus are the same as button 1. I was wondering if it was possible to use a single sub menu to handle all three, my approach would be to have a menu that works on a generic set of values (value, color, name) and then we could copy the Button 1 / 2 / 3 values into that set for the menu. When the user exits the sub menu the values would be copied back to the correct place. I understand it's very easy to make separate menus for everything, but I eventually may have dozens of these to present to the user. Making a change on one menu would require making changes on dozens of them, so I would rather just have one sub-menu to access and only keep track of the index and the values to push / pop back into their original spots. My real question is can I fire a function upon entering and exiting a sub-menu? I know I can do this with a "button" item such as the "print" button in the Blink example, but is there a way to do something as a result of entering or exiting a sub-menu? Failing that, is there a way to know which menu we are in? I was thinking something like: // exit sub menu here |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Hello there! Hopefully I will have a chance to look into it later this weekend. I think I may come up with some solution (that may or may not involve inheriting or overriding GEM classes to expose some internal methods and properties or to expand its functionality). |
Beta Was this translation helpful? Give feedback.
-
I think I managed to implement something remotely similar to what you would like to achieve. GEM doesn't support callbacks for entering or exiting menu pages. However similar behavior can be achieved by additional check for Consider we would like to have three config menu pages with identical structure of two variables: one Variables that we would like to edit: // Create variables
int number[] = {128, 256, 512};
bool enablePrint[] = {true, false, true}; Names of config pages and index of currently selected one: // Config pages names
const char* configPageName[] = {"Config 0", "Config 1", "Config 2"};
byte currentConfigIndex = 0; Then we need our proxy (or buffer) variables, that will temporarily hold values of a real ones when we enter corresponding config menu page: // Create variables that will be editable through the menu and assign them initial values
int numberProxy = 0;
bool enablePrintProxy = false; Create menu items for our editable proxy variables, callbacks will be used to copy values from proxy variables to the real ones upon save: // Create two menu item objects of class GEMItem, linked to numberProxy and enablePrintProxy variables
void numberProxySaveCallback();
GEMItem menuItemInt("Number:", numberProxy, numberProxySaveCallback);
void enablePrintProxySaveCallback();
GEMItem menuItemBool("Enable print:", enablePrintProxy, enablePrintProxySaveCallback); Create proxy config menu page: GEMPage menuPageConfig("Config", menuPageMain); // Config submenu Create a number of menu items linked to the same single config menu page: // Create menu item linked to Config menu page
GEMItem menuItemMainConfig[] {
{configPageName[0], menuPageConfig},
{configPageName[1], menuPageConfig},
{configPageName[2], menuPageConfig}
}; Add menu items to main menu page and config page: void setupMenu() {
// Add menu items to menu page
menuPageMain
.addMenuItem(menuItemMainConfig[0])
.addMenuItem(menuItemMainConfig[1])
.addMenuItem(menuItemMainConfig[2]);
// Add menu items to Config menu page
menuPageConfig
.addMenuItem(menuItemInt)
.addMenuItem(menuItemBool);
...
} Then in ...
const char* title = menu.getCurrentMenuPage()->getCurrentMenuItem()->getTitle();
for (byte i = 0; i < 3; i++) {
if (strcmp(title, configPageName[i]) == 0) {
currentConfigIndex = i;
}
}
menuPageConfig.setTitle(menuItemMainConfig[currentConfigIndex].getTitle());
passValuesToProxy();
... Lastly define callback functions that will pass values between real and proxy variables: void passValuesToProxy() {
numberProxy = number[currentConfigIndex];
enablePrintProxy = enablePrint[currentConfigIndex];
}
void numberProxySaveCallback() {
number[currentConfigIndex] = numberProxy;
}
void enablePrintProxySaveCallback() {
enablePrint[currentConfigIndex] = enablePrintProxy;
} Here's link to Wokwi simulator: https://wokwi.com/projects/393255597641436161 Above examples use rotary encoder as an input device, but can be easily modified to use basic push-buttons (with either KeyDetector or U8g2 button press detection). Also it is possible to go slightly different route, and create all necessary config menu pages dynamically in a loop: that will be less memory efficient than above proxy/buffer solution, but is also viable. I don't have full example of dynamic menu pages creation, however there is one for menu items: https://gist.github.com/Spirik/191fafd4095627cea7460ec47ae8a954 . Hope that will help you in some way! |
Beta Was this translation helpful? Give feedback.
-
I think that will work great, thanks very much! The key here is the separate function that responds to the OK button so we know that we're entering a menu, and then using the getCurrentMenuPage()->getCurrentMenuItem()->getTitle() to match to the config menu names. Thanks for your help with this! |
Beta Was this translation helpful? Give feedback.
I think I managed to implement something remotely similar to what you would like to achieve.
GEM doesn't support callbacks for entering or exiting menu pages. However similar behavior can be achieved by additional check for
GEM_KEY_OK
presses in a main loop and subsequent checks for current menu item indexGEMPage::getCurrentMenuItemIndex()
or titleGEMItem::getTitle()
(as in the following example).Consider we would like to have three config menu pages with identical structure of two variables: one
int
number and onebool
flag (this code is loosely based on GEM Basic example with encoder, so thats where test variables come from).Variables that we would like to edit: