UseByRef

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