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}