Skip to content

Instantly share code, notes, and snippets.

@TheV360 TheV360/menu.ino
Created Jul 3, 2019

Embed
What would you like to do?
fear
const char MENU_BACK[] PROGMEM = {0x1B, 0x20, 0x42, 0x61, 0x63, 0x6B}; // Says "<- Back"
... /*
Other strings.
Since they don't really matter, they'll be referred to as
MENU_OTHER
*/ ...
enum class MenuItemType : uint8_t {
Button, InvertedButton, Checkbox, Info
};
// Buttons/InvButtons use ROM function pointers,
// Checkboxes use RAM variable pointers.
struct MenuItem {
uint8_t x; // The display X
uint8_t y; // The display Y
MenuItemType type; // The type
const char *textPointer; // Pointer to a ROM string
void *actionPointer; // Can be either a ROM function pointer or a RAM variable pointer
};
struct MenuItemInfo {
const MenuItem *items; // Pointer to the MenuItem array
uint8_t length; // How long the MenuItem array is
};
const MenuItem MENU_ITEMS_MAIN[] PROGMEM {
{14, 26, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 26, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{14, 42, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 42, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer}
};
const MenuItem MENU_ITEMS_MODE[] PROGMEM {
{14, 10, MenuItemType::InvertedButton, MENU_BACK, menuItem_FuncPointer},
{66, 10, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{14, 26, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 26, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{14, 42, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 42, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer}
};
const MenuItem MENU_ITEMS_MODE_A[] PROGMEM {
{14, 18, MenuItemType::InvertedButton, MENU_BACK, menuItem_FuncPointer},
{66, 18, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{14, 34, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 34, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer}
};
const MenuItem MENU_ITEMS_MODE_B[] PROGMEM {
{14, 18, MenuItemType::InvertedButton, MENU_BACK, menuItem_FuncPointer},
{66, 18, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{14, 34, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer},
{66, 34, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer}
};
const MenuItem MENU_ITEMS_OPTIONS[] PROGMEM {
{14, 18, MenuItemType::InvertedButton, MENU_BACK, menuItem_FuncPointer},
{66, 18, MenuItemType::Checkbox, MENU_OTHER, &boolPointer1},
{14, 34, MenuItemType::Checkbox, MENU_OTHER, &boolPointer2},
{66, 34, MenuItemType::Button, MENU_OTHER, menuItem_FuncPointer}
};
const MenuItemInfo *MENU_ITEMS_LOOKUP[] {
{MENU_ITEMS_MAIN, 4},
{MENU_ITEMS_MODE, 6},
{MENU_ITEMS_MODE_A, 4},
{MENU_ITEMS_MODE_B, 4},
{MENU_ITEMS_OPTIONS, 4}
};
uint8_t menuCursor = 1;
uint8_t menuLength = 0;
MenuItem menuItems[6];
void updateMenu() {
// TODO
}
void loadMenuItems(uint8_t index) {
menuLength = pgm_read_byte(MENU_ITEMS_LOOKUP[index]->length);
memcpy_P(menuItems, MENU_ITEMS_LOOKUP[index]->items, sizeof(MenuItem) * menuLength);
}
void drawAllMenuItems() {
// TODO
}
void triggerItem(uint8_t index) {
if (menuItems[index].type == MenuItemType::Button || menuItems[index].type == MenuItemType::InvertedButton) {
// actionPointer is in ROM.
// It's a function. Run it.
(*(menuItems[index].actionPointer))();
} else if (menuItems[index].type == MenuItemType::Checkbox) {
// actionPointer is in RAM.
// It's a bool. Toggle it.
// [whatever actionPointer is pointing to in RAM.] = ![whatever actionPointer is pointing to in RAM, casted to a boolean.]
*(menuItems[index].actionPointer) = !*TO_(bool*, menuItems[index].actionPointer);
}
}
// cursor == buttonIndex ? (ab.buttonDown(B_BUTTON) ? ButtonsState::Pressed : ButtonState::Selected) : ButtonState::Unselected
void drawButton(const char *TEXT, uint8_t x, uint8_t y, uint8_t width, uint8_t height, ButtonState state, bool invert) {
switch (state) {
default: case ButtonState::Unselected:
ab.drawRect(x, y, width, height);
break;
case ButtonState::Selected:
y -= 2;
ab.drawRect(x, y, width, height + 2);
ab.drawFastHLine(x + 1, y + height - 1, width - 2);
break;
case ButtonState::Pressed:
y++;
ab.drawRect(x, y, width, height);
break;
}
if (invert) {
ab.setTextColor(BLACK);
ab.setTextBackground(WHITE);
} else {
ab.setTextColor(WHITE);
ab.setTextBackground(BLACK);
}
ab.setCursor(x + 2, y + 2);
ab.print((__FlashStringHelper*)(TEXT));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.