-
Notifications
You must be signed in to change notification settings - Fork 1
/
LiquidCrystalMenu.h
152 lines (117 loc) · 3.87 KB
/
LiquidCrystalMenu.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
* This library is for easily creating, and traversing, multi-level menus
* on an LCD screen. It allows for menus to go down serveral layers and
* eventually end up at an observable, where values can be updated from the
* loop().
*
* This was designed for use in a piece of hardware that would be plugged into
* a CAN bus and be able to view live data.
*
* Written by Michael Rouse for the Missouri S&T Solar Car Team
* MIT License
*/
#ifndef __LCD_MENU_H__
#define __LCD_MENU_H__
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <LiquidCrystal.h>
/**
* Constants
*/
#ifndef LCDMENU_ACTION_DEBOUNCE
#define LCDMENU_ACTION_DEBOUNCE 350
#endif
#ifndef LCDMENU_REFRESH_INTERVAL
#define LCDMENU_REFRESH_INTERVAL 750 // Number of milliseconds to allow for refreshing
#endif
// Type alias
typedef int MenuID;
/**
* Doubly Linked List node that represents something on a menu
*/
struct MenuNode {
char *title;
String (*valueFn)(void);
String *value;
MenuNode *parent;
MenuNode *submenu;
MenuNode *previous;
MenuNode *next;
};
/**
* Custom Glyphs
*/
#define MENU_ARROW_GLYPH (uint8_t)0
/**
* Class for interacting and creating a menu system on an LCD
*/
class LiquidCrystalMenu {
private:
// LCD size and object
uint8_t rows;
uint8_t cols;
LiquidCrystal* lcd;
MenuNode *root; // Root menu
MenuNode *menu; // Currently selected MenuNode
// Draw on the
void draw();
// Finds an item with a memory address
MenuNode* findNodeWithAddr(MenuNode *node, const MenuID &memAddr);
// Adds to a menu
void addNode(MenuNode *root, MenuNode *toAdd);
// Initialize (constructor)
void init();
public:
// Constructors
LiquidCrystalMenu(const uint8_t &rs, const uint8_t &rw, const uint8_t &en,
const uint8_t &d4, const uint8_t &d5, const uint8_t &d6,
const uint8_t &d7
);
LiquidCrystalMenu(const uint8_t &rs, const uint8_t &en, const uint8_t &d4,
const uint8_t &d5, const uint8_t &d6, const uint8_t &d7
);
LiquidCrystalMenu(const uint8_t &rs, const uint8_t &en, const uint8_t &d0,
const uint8_t &d1, const uint8_t &d2, const uint8_t &d3,
const uint8_t &d4, const uint8_t &d5, const uint8_t &d6,
const uint8_t &d7
);
LiquidCrystalMenu(const uint8_t &rs, const uint8_t &rw, const uint8_t &en,
const uint8_t &d0, const uint8_t &d1, const uint8_t &d2,
const uint8_t &d3, const uint8_t &d4, const uint8_t &d5,
const uint8_t &d6, const uint8_t &d7
);
// Destructor
~LiquidCrystalMenu();
// Start the library
void begin(const uint8_t &cols, const uint8_t &rows);
// Shows a splash screen
void splash(const String contents[], const uint8_t &delayMs = 4000);
// Add a new menu item (to the root menu)
MenuID addMenu(const char *title);
// Add a new menu item to a specific menu
MenuID addMenu(const MenuID &parent, const char *title);
// Add a value to the root menus
void addValue(const char *title, String (*callback)(void));
void addValue(const char *title, String *value);
// Add a value to a specific menu
void addValue(const MenuID &parent, const char *title, String (*callback)(void), String *value = nullptr );
void addValue(const MenuID &parent, const char *title, String *value);
// Refresh values currently displayed
void refreshValues();
// Move upwards in the current menu
void up();
// Move downwards in the current menu
void down();
// Select a menu option
void select();
// Back up the navigation tree
void back();
};
// Helper functions
MenuNode* newMenuNode(const char *title, String (*fn)(void) = nullptr, String *val = nullptr);
void deleteMenuNode(MenuNode *node);
MenuNode* getLastNodeInList(MenuNode *list);
#endif