LiquidMenu  1.5.1
Menu creation Arduino library for LCDs, wraps LiquidCrystal.
LiquidMenu.h
Go to the documentation of this file.
1 /*
2 The MIT License (MIT)
3 
4 Copyright (c) 2016 Vasil Kalchev
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
40 #pragma once
41 
42 #include <stdint.h>
43 #if defined(__AVR__)
44 # include <avr/pgmspace.h>
45 #endif
46 #include <stdio.h>
47 #include <stdlib.h>
48 
49 #include "LiquidMenu_config.h"
50 #include "LiquidMenu_debug.h"
51 
52 
53 #if LIQUIDMENU_LIBRARY == LiquidCrystal_LIBRARY
54 # pragma message ("LiquidMenu: Selected 'LiquidCrystal' (parallel) library. Edit 'LiquidMenu_config.h' file to change it.")
55 #elif LIQUIDMENU_LIBRARY == LiquidCrystal_I2C_LIBRARY
56 # pragma message ("LiquidMenu: Selected 'LiquidCrystal_I2C' (I2C) library. Edit 'LiquidMenu_config.h' file to change it.")
57 #else
58 # pragma message ("LiquidMenu: Selected custom library. Edit 'LiquidMenu_config.h' file to change it.")
59 #endif
60 
61 #if LIQUIDMENU_DEBUG
62 # warning "LiquidMenu: Debugging messages are enabled."
63 #endif
64 
65 
66 typedef bool (*boolFnPtr)();
67 typedef int8_t (*int8tFnPtr)();
68 typedef uint8_t (*uint8tFnPtr)();
69 typedef int16_t (*int16tFnPtr)();
70 typedef uint16_t (*uint16tFnPtr)();
71 typedef int32_t (*int32tFnPtr)();
72 typedef uint32_t (*uint32tFnPtr)();
73 typedef float (*floatFnPtr)();
74 typedef double (*doubleFnPtr)();
75 typedef char (*charFnPtr)();
76 typedef char * (*charPtrFnPtr)();
77 typedef const char * (*constcharPtrFnPtr)();
78 
79 const char LIQUIDMENU_VERSION[] = "1.5";
80 
82 
85 enum class DataType : uint8_t {
86  NOT_USED = 0,
87  BOOL = 1, BOOLEAN = 1,
88  INT8_T = 8,
89  UINT8_T = 9,
90  INT16_T = 16,
91  UINT16_T = 17,
92  INT32_T = 32,
93  UINT32_T = 33,
94  FLOAT = 50, DOUBLE = 50,
95  CHAR = 60,
96  CHAR_PTR = 61,
97  CONST_CHAR_PTR = 62,
98  PROG_CONST_CHAR_PTR = 65,
99  GLYPH = 70,
100  BOOL_GETTER = 201, BOOLEAN_GETTER = 201,
101  INT8_T_GETTER = 208,
102  UINT8_T_GETTER = 209, BYTE_GETTER = 209,
103  INT16_T_GETTER = 216,
104  UINT16_T_GETTER = 217,
105  INT32_T_GETTER = 232,
106  UINT32_T_GETTER = 233,
107  FLOAT_GETTER = 240, DOUBLE_GETTER = 240,
108  CHAR_GETTER = 250,
109  CHAR_PTR_GETTER = 251,
110  CONST_CHAR_PTR_GETTER = 252
111 };
112 
114 /*
115 Used to store and set the relative or absolute position of the focus indicator.
116 */
117 enum class Position : uint8_t {
118  RIGHT = 1, NORMAL = 1,
119  LEFT = 2,
120  CUSTOM = 3,
121 };
122 
124 
128 
134 DataType recognizeType(bool variable);
135 
140 DataType recognizeType(char variable);
141 
146 DataType recognizeType(char* variable);
147 
152 DataType recognizeType(const char* variable);
153 
158 DataType recognizeType(int8_t variable);
159 
164 DataType recognizeType(uint8_t variable);
165 
170 DataType recognizeType(int16_t variable);
171 
176 DataType recognizeType(uint16_t variable);
177 
182 DataType recognizeType(int32_t variable);
183 
188 DataType recognizeType(uint32_t variable);
189 
194 DataType recognizeType(float variable);
195 
200 DataType recognizeType(double variable);
201 
202 
207 DataType recognizeType(boolFnPtr variable);
208 
209 
214 DataType recognizeType(int8tFnPtr variable);
215 
216 
221 DataType recognizeType(uint8tFnPtr variable);
222 
223 
228 DataType recognizeType(int16tFnPtr variable);
229 
230 
235 DataType recognizeType(uint16tFnPtr variable);
236 
237 
242 DataType recognizeType(int32tFnPtr variable);
243 
244 
249 DataType recognizeType(uint32tFnPtr varible);
250 
251 
256 DataType recognizeType(floatFnPtr variable);
257 
262 DataType recognizeType(doubleFnPtr variable);
263 
264 
269 DataType recognizeType(charFnPtr variable);
270 
271 
276 DataType recognizeType(charPtrFnPtr variable);
277 
278 
283 DataType recognizeType(constcharPtrFnPtr variable);
285 
286 
287 
289 
294 void print_me(uintptr_t address);
295 
296 
298 
305 class LiquidLine {
306  friend class LiquidScreen;
307 
308 public:
311 
313 
319  LiquidLine(uint8_t column, uint8_t row)
320  : _row(row), _column(column), _focusRow(row - 1),
321  _focusColumn(column - 1), _focusPosition(Position::NORMAL),
322  _variableCount(0), _focusable(false) {
323  for (uint8_t i = 0; i < MAX_VARIABLES; i++) {
324  _variable[i] = nullptr;
325  _variableType[i] = DataType::NOT_USED;
326  }
327  for (uint8_t f = 0; f < MAX_FUNCTIONS; f++) {
328  _function[f] = 0;
329  }
330  _floatDecimalPlaces = 2;
331  }
332 
334 
339  template <typename A>
340  LiquidLine(uint8_t column, uint8_t row, A &variableA)
341  : LiquidLine(column, row) {
342  add_variable(variableA);
343  }
344 
346 
352  template <typename A, typename B>
353  LiquidLine(uint8_t column, uint8_t row,
354  A &variableA, B &variableB)
355  : LiquidLine(column, row, variableA) {
356  add_variable(variableB);
357  }
358 
360 
367  template <typename A, typename B, typename C>
368  LiquidLine(uint8_t column, uint8_t row,
369  A &variableA, B &variableB, C &variableC)
370  : LiquidLine(column, row, variableA, variableB) {
371  add_variable(variableC);
372  }
373 
375 
383  template <typename A, typename B, typename C, typename D>
384  LiquidLine(uint8_t column, uint8_t row,
385  A &variableA, B &variableB, C &variableC, D &variableD)
386  : LiquidLine(column, row, variableA, variableB, variableC) {
387  add_variable(variableD);
388  }
389 
391 
392 
395 
397 
408  template <typename T>
409  bool add_variable(T &variable) {
410  print_me(reinterpret_cast<uintptr_t>(this));
411  if (_variableCount < MAX_VARIABLES) {
412  _variable[_variableCount] = (void*)&variable;
413  _variableType[_variableCount] = recognizeType(variable);
414 # if LIQUIDMENU_DEBUG
415  DEBUG(F("Added variable "));
416  // Check if the variable is actually a getter functions
417  // and don't diplay it if so.
418  if ((uint8_t)_variableType[_variableCount] < 200) { // 200+ are getters
419  DEBUG(reinterpret_cast<uintptr_t>(variable)); DEBUGLN(F(""));
420  }
421 # endif
422  _variableCount++;
423  return true;
424  }
425 # if LIQUIDMENU_DEBUG
426  DEBUG(F("Adding variable "));
427  // Check if the variable is actually a getter functions
428  // and don't diplay it if so.
429  if ((uint8_t)_variableType[_variableCount] < 200) { // 200+ are getters
430  DEBUG(reinterpret_cast<uintptr_t>(variable));
431  }
432 # endif
433  DEBUGLN(F(" failed, edit LiquidMenu_config.h to allow for more variables"));
434  return false;
435  }
436 
438 
456  bool attach_function(uint8_t number, void (*function)(void));
457 
459 
463  void set_decimalPlaces(uint8_t decimalPlaces);
464 
466 
482  bool set_focusPosition(Position position,
483  uint8_t column = 0, uint8_t row = 0);
484 
486 
495  bool set_asGlyph(uint8_t number);
496 
498 
506  bool set_asProgmem(uint8_t number);
508 
509 private:
511 
519  void print(DisplayClass *p_liquidCrystal, bool isFocused);
520 
522 
529  void print_variable(DisplayClass *p_liquidCrystal, uint8_t number);
530 
532 
540  bool is_callable(uint8_t number) const;
541 
543 
551  bool call_function(uint8_t number) const;
552 
553  uint8_t _row, _column, _focusRow, _focusColumn;
554  Position _focusPosition;
555  uint8_t _floatDecimalPlaces;
556  uint8_t _variableCount;
557  void (*_function[MAX_FUNCTIONS])(void);
558  const void *_variable[MAX_VARIABLES];
559  DataType _variableType[MAX_VARIABLES];
560  bool _focusable;
561 };
562 
563 
565 
574  friend class LiquidMenu;
575 
576 public:
577 
580 
582 
585  LiquidScreen();
586 
588 
591  explicit LiquidScreen(LiquidLine &liquidLine);
592 
594 
598  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2);
599 
601 
606  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
607  LiquidLine &liquidLine3);
608 
610 
616  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
617  LiquidLine &liquidLine3, LiquidLine &liquidLine4);
618 
620 
623 
625 
636  bool add_line(LiquidLine &liquidLine);
637 
639 
653  bool set_focusPosition(Position position);
654 
656 
666  void set_displayLineCount(uint8_t lineCount);
667 
669 
680  void hide(bool hide);
682 
683 private:
685 
691  void print(DisplayClass *p_liquidCrystal) const;
692 
694 
700  void switch_focus(bool forward = true);
701 
703 
707  bool set_focusedLine(uint8_t lineIndex);
708 
710 
713  uint8_t get_focusedLine() const;
714 
716 
724  bool is_callable(uint8_t number) const;
725 
727 
737  bool call_function(uint8_t number) const;
738 
739  LiquidLine *_p_liquidLine[MAX_LINES];
740  uint8_t _lineCount;
741  uint8_t _focus;
742  uint8_t _displayLineCount;
743  bool _hidden;
744 };
745 
746 
748 
757 class LiquidMenu {
758  friend class LiquidSystem;
759 
760 public:
761 
764 
766 
773  LiquidMenu(DisplayClass &liquidCrystal, uint8_t startingScreen = 1);
774 
776 
782  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen,
783  uint8_t startingScreen = 1);
784 
786 
793  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
794  LiquidScreen &liquidScreen2, uint8_t startingScreen = 1);
795 
797 
805  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
806  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
807  uint8_t startingScreen = 1);
808 
810 
819  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
820  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
821  LiquidScreen &liquidScreen4, uint8_t startingScreen = 1);
822 
824 
827 
829 
840  bool add_screen(LiquidScreen &liquidScreen);
841 
843 
849 
851  void next_screen();
852 
854 
857  void operator++();
858 
860 
863  void operator++(int);
864 
866  void previous_screen();
867 
869 
872  void operator--();
873 
875 
878  void operator--(int);
879 
881 
885  bool change_screen(LiquidScreen *p_liquidScreen);
886 
888 
893  bool change_screen(uint8_t number);
894 
896 
900  bool operator=(LiquidScreen *p_liquidScreen);
901 
903 
908  bool operator=(uint8_t number);
909 
911 
917  void switch_focus(bool forward = true);
918 
920 
924  bool set_focusedLine(uint8_t lineIndex);
925 
927 
930  uint8_t get_focusedLine() const;
931 
933 
947  bool set_focusPosition(Position position);
948 
950 
963  bool set_focusSymbol(Position position, uint8_t symbol[8]);
964 
966 
974  bool is_callable(uint8_t number) const;
975 
977 
988  bool call_function(uint8_t number) const;
989 
991 
994  void update() const;
995 
997 
1003  void softUpdate() const;
1004 
1006 
1011  void init() const;
1012 
1014 
1015 private:
1016  DisplayClass *_p_liquidCrystal;
1017  LiquidScreen *_p_liquidScreen[MAX_SCREENS];
1018  uint8_t _screenCount;
1019  uint8_t _currentScreen;
1020 };
1021 
1022 
1024 
1035 public:
1036 
1039 
1041 
1046  explicit LiquidSystem(uint8_t startingMenu = 1);
1047 
1049 
1054  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
1055  uint8_t startingMenu = 1);
1056 
1058 
1064  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
1065  LiquidMenu &liquidMenu3, uint8_t startingMenu = 1);
1066 
1068 
1075  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
1076  LiquidMenu &liquidMenu3, LiquidMenu &liquidMenu4,
1077  uint8_t startingMenu = 1);
1078 
1080 
1083 
1085 
1096  bool add_menu(LiquidMenu &liquidMenu);
1097 
1099 
1103  bool change_menu(LiquidMenu &p_liquidMenu);
1104 
1106 
1112 
1114  void next_screen();
1115 
1117 
1120  void operator++();
1121 
1123 
1126  void operator++(int);
1127 
1129  void previous_screen();
1130 
1132 
1135  void operator--();
1136 
1138 
1141  void operator--(int);
1142 
1144 
1148  bool change_screen(LiquidScreen *p_liquidScreen);
1149 
1151 
1156  bool change_screen(uint8_t number);
1157 
1159 
1163  bool operator=(LiquidScreen *p_liquidScreen);
1164 
1166 
1171  bool operator=(uint8_t number);
1172 
1174 
1180  void switch_focus(bool forward = true);
1181 
1183 
1187  bool set_focusedLine(uint8_t lineIndex);
1188 
1190 
1193  uint8_t get_focusedLine() const;
1194 
1196 
1210  bool set_focusPosition(Position position);
1211 
1213 
1226  bool set_focusSymbol(Position position, uint8_t symbol[8]);
1227 
1229 
1237  bool is_callable(uint8_t number) const;
1238 
1240 
1251  bool call_function(uint8_t number) const;
1252 
1254 
1257  void update() const;
1258 
1260 
1266  void softUpdate() const;
1267 
1269 
1270 private:
1271  LiquidMenu *_p_liquidMenu[MAX_MENUS];
1272  uint8_t _menuCount;
1273  uint8_t _currentMenu;
1274 };
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB, C &variableC)
Constructor for three variables/constants.
Definition: LiquidMenu.h:368
void operator--()
Switches to the previous screen.
Definition: LiquidSystem.cpp:109
uint8_t get_focusedLine() const
Get the index of the currently focused line.
Definition: LiquidMenu.cpp:177
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidMenu.cpp:167
bool is_callable(uint8_t number) const
Check if there is an attached function at the specified number.
Definition: LiquidSystem.cpp:153
LiquidSystem(uint8_t startingMenu=1)
The main constructor.
Definition: LiquidSystem.cpp:32
Represents a collection of menus forming a menu system.
Definition: LiquidMenu.h:1034
bool change_screen(LiquidScreen *p_liquidScreen)
Switches to the specified screen.
Definition: LiquidSystem.cpp:121
uint8_t get_focusedLine() const
Get the index of the currently focused line.
Definition: LiquidSystem.cpp:141
Represents the individual lines printed on the display.
Definition: LiquidMenu.h:305
void update() const
Prints the current screen to the display.
Definition: LiquidSystem.cpp:164
bool set_focusedLine(uint8_t lineIndex)
Directly select focused line.
Definition: LiquidSystem.cpp:137
void softUpdate() const
Prints the current screen to the display (without clearing).
Definition: LiquidSystem.cpp:168
bool set_asGlyph(uint8_t number)
Converts a byte variable into a glyph index.
Definition: LiquidLine.cpp:77
bool set_asProgmem(uint8_t number)
Converts a const char pointer variable into const char pointer PROGMEM one.
Definition: LiquidLine.cpp:89
void operator--()
Switches to the previous screen.
Definition: LiquidMenu.cpp:118
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidSystem.cpp:133
void operator++()
Switches to the next screen.
Definition: LiquidMenu.cpp:97
bool add_variable(T &variable)
Adds a variable to the line.
Definition: LiquidMenu.h:409
const uint8_t MAX_SCREENS
Configures the number of available screens per menu.
Definition: LiquidMenu_config.h:70
bool set_focusedLine(uint8_t lineIndex)
Directly select focused line.
Definition: LiquidMenu.cpp:173
void set_displayLineCount(uint8_t lineCount)
Specifies the line size of the display (required for scrolling).
Definition: LiquidScreen.cpp:91
LiquidMenu(DisplayClass &liquidCrystal, uint8_t startingScreen=1)
The main constructor.
Definition: LiquidMenu.cpp:35
const uint8_t MAX_VARIABLES
Configures the number of available variables per line.
Definition: LiquidMenu_config.h:61
void softUpdate() const
Prints the current screen to the display (without clearing).
Definition: LiquidMenu.cpp:239
void previous_screen()
Switches to the previous screen.
Definition: LiquidSystem.cpp:105
bool set_focusPosition(Position position)
Sets the focus position for the whole menu at once.
Definition: LiquidMenu.cpp:181
LiquidScreen * get_currentScreen() const
Returns a reference to the current screen.
Definition: LiquidMenu.cpp:80
bool set_focusPosition(Position position)
Sets the focus position for the whole menu at once.
Definition: LiquidSystem.cpp:145
void next_screen()
Switches to the next screen.
Definition: LiquidMenu.cpp:84
void init() const
Initializes the menu object.
Definition: LiquidMenu.cpp:268
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB)
Constructor for two variables/constants.
Definition: LiquidMenu.h:353
Represents a screen shown on the display.
Definition: LiquidMenu.h:573
#define DEBUG(x)
Debug print.
Definition: LiquidMenu_debug.h:23
bool set_focusSymbol(Position position, uint8_t symbol[8])
Changes the focus indicator&#39;s symbol.
Definition: LiquidSystem.cpp:149
void update() const
Prints the current screen to the display.
Definition: LiquidMenu.cpp:234
bool change_screen(LiquidScreen *p_liquidScreen)
Switches to the specified screen.
Definition: LiquidMenu.cpp:141
bool call_function(uint8_t number) const
Calls an attached function specified by the number.
Definition: LiquidSystem.cpp:157
const uint8_t MAX_LINES
Configures the number of available lines per screen.
Definition: LiquidMenu_config.h:67
bool operator=(LiquidScreen *p_liquidScreen)
Switches to the specified screen.
Definition: LiquidSystem.cpp:129
bool add_menu(LiquidMenu &liquidMenu)
Adds a LiquidMenu object to the menu system.
Definition: LiquidSystem.cpp:58
bool add_line(LiquidLine &liquidLine)
Adds a LiquidLine object to the screen.
Definition: LiquidScreen.cpp:57
LiquidLine(uint8_t column, uint8_t row)
The main constructor.
Definition: LiquidMenu.h:319
void hide(bool hide)
Hides the screen.
Definition: LiquidScreen.cpp:95
bool change_menu(LiquidMenu &p_liquidMenu)
Switches to the specified menu.
Definition: LiquidSystem.cpp:73
LiquidScreen()
The main constructor.
Definition: LiquidScreen.cpp:32
bool is_callable(uint8_t number) const
Check if there is an attached function at the specified number.
Definition: LiquidMenu.cpp:224
const char LIQUIDMENU_VERSION[]
The version of the library.
Definition: LiquidMenu.h:79
Represents a collection of screens forming a menu.
Definition: LiquidMenu.h:757
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB, C &variableC, D &variableD)
Constructor for four variables/constants.
Definition: LiquidMenu.h:384
bool operator=(LiquidScreen *p_liquidScreen)
Switches to the specified screen.
Definition: LiquidMenu.cpp:163
Position
Position enum.
Definition: LiquidMenu.h:117
bool set_focusSymbol(Position position, uint8_t symbol[8])
Changes the focus indicator&#39;s symbol.
Definition: LiquidMenu.cpp:195
bool attach_function(uint8_t number, void(*function)(void))
Attaches a callback function to the line.
Definition: LiquidLine.cpp:39
DataType recognizeType(bool variable)
Definition: recognizeType.cpp:9
bool set_focusPosition(Position position, uint8_t column=0, uint8_t row=0)
Configures the focus indicator position for the line.
Definition: LiquidLine.cpp:58
void set_decimalPlaces(uint8_t decimalPlaces)
Sets the decimal places for floating point variables.
Definition: LiquidLine.cpp:53
void next_screen()
Switches to the next screen.
Definition: LiquidSystem.cpp:93
DataType
Data type enum.
Definition: LiquidMenu.h:85
LiquidScreen * get_currentScreen() const
Returns a reference to the current screen.
Definition: LiquidSystem.cpp:89
void print_me(uintptr_t address)
Prints the number passed to it in a specific way.
Definition: LiquidLine.cpp:32
const uint8_t MAX_MENUS
Configures the number of available menus per menus system.
Definition: LiquidMenu_config.h:73
bool call_function(uint8_t number) const
Calls an attached function specified by the number.
Definition: LiquidMenu.cpp:228
const uint8_t MAX_FUNCTIONS
Configures the number of available functions per line.
Definition: LiquidMenu_config.h:64
bool add_screen(LiquidScreen &liquidScreen)
Adds a LiquidScreen object to the menu.
Definition: LiquidMenu.cpp:67
LiquidLine(uint8_t column, uint8_t row, A &variableA)
Constructor for one variable/constant.
Definition: LiquidMenu.h:340
#define DEBUGLN(x)
Debug print with newline.
Definition: LiquidMenu_debug.h:25
void previous_screen()
Switches to the previous screen.
Definition: LiquidMenu.cpp:105
void operator++()
Switches to the next screen.
Definition: LiquidSystem.cpp:97
bool set_focusPosition(Position position)
Sets the focus position for the whole screen at once.
Definition: LiquidScreen.cpp:77