Created
June 13, 2022 08:54
-
-
Save Spirik/191fafd4095627cea7460ec47ae8a954 to your computer and use it in GitHub Desktop.
GEM - Create menu items with user-defined callback argument in a loop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Create menu items with user-defined callback argument in a loop. | |
*/ | |
#include <GEM_adafruit_gfx.h> | |
#include <KeyDetector.h> | |
// Hardware-specific library for ST7735. | |
// Include library that matches your setup (see https://learn.adafruit.com/adafruit-gfx-graphics-library for details) | |
#include <Adafruit_ST7735.h> | |
// Pins the buttons are connected to | |
const byte downPin = 2; | |
const byte leftPin = 3; | |
const byte rightPin = 4; | |
const byte upPin = 5; | |
const byte cancelPin = 6; | |
const byte okPin = 7; | |
// Array of Key objects that will link GEM key identifiers with dedicated pins | |
Key keys[] = {{GEM_KEY_UP, upPin}, {GEM_KEY_RIGHT, rightPin}, {GEM_KEY_DOWN, downPin}, {GEM_KEY_LEFT, leftPin}, {GEM_KEY_CANCEL, cancelPin}, {GEM_KEY_OK, okPin}}; | |
// Create KeyDetector object | |
KeyDetector myKeyDetector(keys, sizeof(keys)/sizeof(Key)); | |
// To account for switch bounce effect of the buttons (if occur) you may want to specify debounceDelay | |
// as the third argument to KeyDetector constructor: | |
// KeyDetector myKeyDetector(keys, sizeof(keys)/sizeof(Key), 10); | |
// Macro constants (aliases) for the pins TFT display is connected to. Please update the pin numbers according to your setup | |
#define TFT_CS A2 | |
#define TFT_RST -1 // Set to -1 and connect to Arduino RESET pin | |
#define TFT_DC A3 | |
// Create an instance of the Adafruit GFX library. | |
// Use constructor that matches your setup (see https://learn.adafruit.com/adafruit-gfx-graphics-library for details). | |
// ST7735 based display is used in the example. | |
// This instance is used to call all the subsequent Adafruit GFX functions (internally from GEM library, | |
// or manually in your sketch if it is required) | |
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); | |
// Declaration of Switch type | |
struct Switch { | |
const char* title; // Title of the button | |
const char* id; // ID of the button | |
}; | |
// Array of switches | |
Switch switches[] = {{"Kitchen", "light.kitchen_light" }, {"Porch", "switch.porch_button"}, {"Loft","switch.stairs_button"}}; | |
// Callback function that triggers when button is pressed. We will write (define) this function later. | |
// However, we should forward-declare it in order to pass to GEMItem constructor | |
void pressButton(GEMCallbackData callbackData); // Forward declaration | |
// Create an array of menu buttons (technincally, pointers to GEMItem). | |
// It will be populated later, in a setupMenu() function | |
GEMItem* menuItemButtons[sizeof(switches)/sizeof(Switch)]; | |
// Create menu page object of class GEMPage. Menu page holds menu items (GEMItem) and represents menu level. | |
// Menu can have multiple menu pages (linked to each other) with multiple menu items each | |
GEMPage menuPageMain("Switches"); | |
// Create menu object of class GEM_adafruit_gfx. Supply its constructor with reference to tft object we created earlier | |
GEM_adafruit_gfx menu(tft, GEM_POINTER_ROW, GEM_ITEMS_COUNT_AUTO); | |
void setup() { | |
// Push-buttons pin modes | |
pinMode(downPin, INPUT); | |
pinMode(leftPin, INPUT); | |
pinMode(rightPin, INPUT); | |
pinMode(upPin, INPUT); | |
pinMode(cancelPin, INPUT); | |
pinMode(okPin, INPUT); | |
// Serial communications setup | |
Serial.begin(115200); | |
// Use this initializer if using a 1.8" TFT screen: | |
tft.initR(INITR_BLACKTAB); // Init ST7735S chip, black tab | |
// OR use this initializer if using a 1.8" TFT screen with offset such as WaveShare: | |
// tft.initR(INITR_GREENTAB); // Init ST7735S chip, green tab | |
// See more options in Adafruit GFX library documentation | |
// Menu init, setup and draw | |
menu.init(); | |
setupMenu(); | |
menu.drawMenu(); | |
} | |
void setupMenu() { | |
// Add buttons to menu page in a loop | |
for (int i = 0; i < sizeof(switches)/sizeof(Switch); i++) { | |
// Create instance of a button. | |
// Pass button title, callback function, and a callback argument (button ID in this case) to constructor | |
menuItemButtons[i] = new GEMItem(switches[i].title, pressButton, switches[i].id); | |
// Add menu item to menu page | |
menuPageMain.addMenuItem(*menuItemButtons[i]); | |
} | |
// Add menu page to menu and set it as current | |
menu.setMenuPageCurrent(menuPageMain); | |
} | |
void loop() { | |
// If menu is ready to accept button press... | |
if (menu.readyForKey()) { | |
// ...detect key press using KeyDetector library | |
myKeyDetector.detect(); | |
// Pass pressed button to menu | |
// (pressed button ID is stored in trigger property of KeyDetector object) | |
menu.registerKeyPress(myKeyDetector.trigger); | |
} | |
} | |
void pressButton(GEMCallbackData callbackData) { | |
Serial.print("Button ID: "); | |
Serial.print(callbackData.valChar); // Accessing user-defined callback argument | |
Serial.print(" | Button title: "); | |
Serial.println(callbackData.pMenuItem->getTitle()); // Accessing menu item title | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment