UseByRef

  1#include <ItemWidget.h>
  2#include <LcdMenu.h>
  3#include <MenuScreen.h>
  4#include <display/LiquidCrystal_I2CAdapter.h>
  5#include <input/KeyboardAdapter.h>
  6#include <renderer/CharacterDisplayRenderer.h>
  7#include <widget/WidgetBool.h>
  8#include <widget/WidgetList.h>
  9#include <widget/WidgetRange.h>
 10
 11#define LCD_ROWS 2
 12#define LCD_COLS 16
 13#define LCD_ADDR 0x27
 14
 15const char* days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
 16
 17int hour = 0;
 18uint8_t day = 0;
 19bool toggle = false;
 20
 21MENU_SCREEN(
 22    mainScreen,
 23    mainItems,
 24    ITEM_WIDGET(
 25        "Range val",
 26        [](const int value) { hour = value; },
 27        WIDGET_RANGE(hour, 1, 0, 23, "%02d", 0, false)),
 28    ITEM_WIDGET(
 29        "Range ref",
 30        [](const Ref<int> value) { Serial.println(value.value); },
 31        WIDGET_RANGE_REF(hour, 1, 0, 23, "%02d", 0, false)),
 32    ITEM_WIDGET(
 33        "List val",
 34        [](const uint8_t value) { day = value; },
 35        WIDGET_LIST(days, 7, day, "%s", 0, true)),
 36    ITEM_WIDGET(
 37        "List ref",
 38        [](const Ref<uint8_t> value) { Serial.println(days[value.value]); },
 39        WIDGET_LIST_REF(days, 7, day, "%s", 0, true)),
 40    ITEM_WIDGET(
 41        "Bool val",
 42        [](const bool value) { toggle = value; },
 43        WIDGET_BOOL(toggle, "Yes", "No", "%s")),
 44    ITEM_WIDGET(
 45        "Bool ref",
 46        [](const Ref<bool> value) { Serial.println(value.value); },
 47        WIDGET_BOOL_REF(toggle, "Yes", "No", "%s")));
 48
 49LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLS, LCD_ROWS);
 50LiquidCrystal_I2CAdapter lcdAdapter(&lcd);
 51CharacterDisplayRenderer renderer(&lcdAdapter, LCD_COLS, LCD_ROWS);
 52LcdMenu menu(renderer);
 53KeyboardAdapter keyboard(&menu, &Serial);
 54
 55void setup() {
 56    Serial.begin(115200);
 57    renderer.begin();
 58    menu.setScreen(mainScreen);
 59}
 60
 61unsigned long last = 0;
 62
 63/**
 64 * This function is used to validate the values of the day and toggle status
 65 * which are ref values in the menu items. It prints the current day and toggle.
 66 *
 67 * localDay and localToggle are used here instead of directly using the values defined above
 68 * to ensure that the ref values are correctly updated in the menu items.
 69 *
 70 * Success Scenario:
 71 * - The day and toggle status printed to the Serial monitor change every second.
 72 *
 73 * Failure Scenario:
 74 * - The day and toggle status printed to the Serial monitor do not change every second.
 75 */
 76void logger() {
 77    int localHour = static_cast<WidgetRange<int, Ref<int>>*>(static_cast<ItemWidget<int>*>(mainItems[1])->getWidgetAt(0))->getValue();
 78    uint8_t localDay = static_cast<WidgetList<char*, Ref<uint8_t>>*>(static_cast<ItemWidget<uint8_t>*>(mainItems[3])->getWidgetAt(0))->getValue();
 79    bool localToggle = static_cast<WidgetBool<Ref<bool>>*>(static_cast<ItemWidget<bool>*>(mainItems[5])->getWidgetAt(0))->getValue();
 80    Serial.print("Hour: ");
 81    Serial.print(localHour);
 82    Serial.print(", Day: ");
 83    Serial.print(days[localDay]);
 84    Serial.print(", Toggle: ");
 85    Serial.println(localToggle ? "Yes" : "No");
 86}
 87
 88void loop() {
 89    keyboard.observe();
 90    menu.poll();
 91    unsigned long now = millis();
 92    if (now - last > 1000) {
 93        if (!menu.getRenderer()->isInEditMode()) {
 94            hour++;
 95            hour %= 24;
 96            day++;
 97            day %= 7;
 98            toggle = !toggle;
 99            logger();
100        }
101        last = now;
102    }
103}