-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOptionsMenu.h
113 lines (94 loc) · 3.51 KB
/
OptionsMenu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#pragma once
#include "ClockFaces.h"
#include "Definitions.h"
#include "DisplayUtils.h"
#include "Menu.h"
#include "Settings.h"
#include "Span.h"
#include "ace_time/LocalDateTime.h"
#include "zonelist.h"
#include <AceTime.h>
#include <EEPROM.h>
#include <U8g2lib.h>
struct MenuEntry {
__FlashStringHelper const* text;
// Actual menu to which this entry can navigate.
std::unique_ptr<Menu> menu;
template <typename MenuDerived>
MenuEntry(char const* text, std::unique_ptr<MenuDerived>&& menu)
: text(FPSTR(text))
, menu(std::unique_ptr<Menu> { std::forward<std::unique_ptr<MenuDerived>>(menu) })
{
}
MenuEntry(char const* text, std::nullptr_t null)
: text(FPSTR(text))
, menu(static_cast<std::unique_ptr<Menu>>(null))
{
}
};
/**
Menu that displays a list of text entries corresponding to sub-menus.
The menu can navigate to these menus and return to its parent menu.
*/
class OptionsMenu : public Menu {
private:
Span<MenuEntry> menus;
protected:
/** Index of the currently selected menu. */
uint16_t current_menu = 0;
/** Index of the menu that is currently on top of the section of menus which are displayed. */
uint16_t current_top_menu = 0;
/** Flag that specifies whether the menu display structure changed. Set by handle_button() and reset by draw_menu(). */
bool dirty = true;
/** Implementation of menu drawing that subclasses can use to draw the screen anywhere */
void perform_menu_draw(Display* display, uint8_t width, uint8_t height);
void fix_top_menu(uint8_t line_count);
public:
OptionsMenu(Span<MenuEntry> menus);
Menu* draw_menu(Display* display, uint16_t delta_millis) override;
bool should_refresh(uint16_t delta_millis) override;
Menu* handle_button(uint8_t buttons) override;
constexpr bool is_dirty() const { return dirty; }
constexpr uint16_t get_current_menu() const { return current_menu; }
constexpr size_t size() const { return menus.size(); }
};
/**
Options menu that doesn't have any real entries; whenever an entry is selected the child handles it.
*/
class DelegateOptionsMenu : public OptionsMenu {
public:
static DelegateOptionsMenu create(Span<char const*> names);
Menu* handle_button(uint8_t buttons) override;
/**
Gets called whenever one of the options is selected.
Children can override this to run their own handler when this happens, and return any new menu they like.
If nullptr is returned, the parent menu is returned instead as a default action.
*/
virtual Menu* option_selected(uint16_t menu_index) { return nullptr; }
private:
DelegateOptionsMenu(std::vector<MenuEntry> menus);
std::vector<MenuEntry> fake_entries;
};
/**
A special options menu that allows for the selection of the currently active clock face. It will use its text entries to select one of the clock faces given by the constructor function pointer array.
*/
class ClockFaceSelectMenu : public DelegateOptionsMenu {
public:
ClockFaceSelectMenu(Span<char const*> face_names, Span<ClockFaces::ClockFace> clock_faces);
Menu* draw_menu(Display* display, uint16_t delta_millis) override;
bool should_refresh(uint16_t delta_millis) override;
Menu* handle_button(uint8_t buttons) override;
virtual Menu* option_selected(uint16_t menu_index) override;
private:
Span<ClockFaces::ClockFace> clock_faces;
uint16_t time_since_button { 0 };
uint16_t last_update { 0 };
};
/**
* A special options menu that allows for the selection of the active timezone.
*/
class TimeZoneSelectMenu : public DelegateOptionsMenu {
public:
TimeZoneSelectMenu();
virtual Menu* option_selected(uint16_t menu_index) override;
};