LiquidMenu  1.4.0
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 #if I2C
53 #include <LiquidCrystal_I2C.h>
54 #define DisplayClass LiquidCrystal_I2C
55 #pragma message ("LiquidMenu: Configured for I2C. Edit 'LiquidMenu_config.h' file to change it.")
56 #else
57 #include <LiquidCrystal.h>
58 #define DisplayClass LiquidCrystal
59 #pragma message ("LiquidMenu: Configured for Parallel. Edit 'LiquidMenu_config.h' file to change it.")
60 #endif
61 
62 #if LIQUIDMENU_DEBUG
63 #warning "LiquidMenu: Debugging messages are enabled."
64 #endif
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.4";
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, BYTE = 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 call_function(uint8_t number) const;
541 
542  uint8_t _row, _column, _focusRow, _focusColumn;
543  Position _focusPosition;
544  uint8_t _floatDecimalPlaces;
545  uint8_t _variableCount;
546  void (*_function[MAX_FUNCTIONS])(void);
547  const void *_variable[MAX_VARIABLES];
548  DataType _variableType[MAX_VARIABLES];
549  bool _focusable;
550 };
551 
552 
554 
563  friend class LiquidMenu;
564 
565 public:
566 
569 
571 
574  LiquidScreen();
575 
577 
580  explicit LiquidScreen(LiquidLine &liquidLine);
581 
583 
587  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2);
588 
590 
595  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
596  LiquidLine &liquidLine3);
597 
599 
605  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
606  LiquidLine &liquidLine3, LiquidLine &liquidLine4);
607 
609 
612 
614 
625  bool add_line(LiquidLine &liquidLine);
626 
628 
642  bool set_focusPosition(Position position);
643 
645 
655  void set_displayLineCount(uint8_t lineCount);
656 
658 
669  void hide(bool hide);
671 
672 private:
674 
680  void print(DisplayClass *p_liquidCrystal) const;
681 
683 
689  void switch_focus(bool forward = true);
690 
692 
702  bool call_function(uint8_t number) const;
703 
704  LiquidLine *_p_liquidLine[MAX_LINES];
705  uint8_t _lineCount;
706  uint8_t _focus;
707  uint8_t _displayLineCount;
708  bool _hidden;
709 };
710 
711 
713 
722 class LiquidMenu {
723  friend class LiquidSystem;
724 
725 public:
726 
729 
731 
738  LiquidMenu(DisplayClass &liquidCrystal, uint8_t startingScreen = 1);
739 
741 
747  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen,
748  uint8_t startingScreen = 1);
749 
751 
758  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
759  LiquidScreen &liquidScreen2, uint8_t startingScreen = 1);
760 
762 
770  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
771  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
772  uint8_t startingScreen = 1);
773 
775 
784  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
785  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
786  LiquidScreen &liquidScreen4, uint8_t startingScreen = 1);
787 
789 
792 
794 
805  bool add_screen(LiquidScreen &liquidScreen);
806 
808 
814 
816  void next_screen();
817 
819 
822  void operator++();
823 
825 
828  void operator++(int);
829 
831  void previous_screen();
832 
834 
837  void operator--();
838 
840 
843  void operator--(int);
844 
846 
850  bool change_screen(LiquidScreen &p_liquidScreen);
851 
853 
858  bool change_screen(uint8_t number);
859 
861 
865  bool operator=(LiquidScreen &p_liquidScreen);
866 
868 
873  bool operator=(uint8_t number);
874 
876 
882  void switch_focus(bool forward = true);
883 
885 
899  bool set_focusPosition(Position position);
900 
902 
915  bool set_focusSymbol(Position position, uint8_t symbol[8]);
916 
918 
929  bool call_function(uint8_t number) const;
930 
932 
935  void update() const;
936 
938 
944  void softUpdate() const;
945 
947 
952  void init() const;
953 
955 
956 private:
957  DisplayClass *_p_liquidCrystal;
958  LiquidScreen *_p_liquidScreen[MAX_SCREENS];
959  uint8_t _screenCount;
960  uint8_t _currentScreen;
961 };
962 
963 
965 
976 public:
977 
980 
982 
987  explicit LiquidSystem(uint8_t startingMenu = 1);
988 
990 
995  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
996  uint8_t startingMenu = 1);
997 
999 
1005  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
1006  LiquidMenu &liquidMenu3, uint8_t startingMenu = 1);
1007 
1009 
1016  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
1017  LiquidMenu &liquidMenu3, LiquidMenu &liquidMenu4,
1018  uint8_t startingMenu = 1);
1019 
1021 
1024 
1026 
1037  bool add_menu(LiquidMenu &liquidMenu);
1038 
1040 
1044  bool change_menu(LiquidMenu &p_liquidMenu);
1045 
1047 
1053 
1055  void next_screen();
1056 
1058 
1061  void operator++();
1062 
1064 
1067  void operator++(int);
1068 
1070  void previous_screen();
1071 
1073 
1076  void operator--();
1077 
1079 
1082  void operator--(int);
1083 
1085 
1089  bool change_screen(LiquidScreen &p_liquidScreen);
1090 
1092 
1097  bool change_screen(uint8_t number);
1098 
1100 
1104  bool operator=(LiquidScreen &p_liquidScreen);
1105 
1107 
1112  bool operator=(uint8_t number);
1113 
1115 
1121  void switch_focus(bool forward = true);
1122 
1124 
1138  bool set_focusPosition(Position position);
1139 
1141 
1154  bool set_focusSymbol(Position position, uint8_t symbol[8]);
1155 
1157 
1168  bool call_function(uint8_t number) const;
1169 
1171 
1174  void update() const;
1175 
1177 
1183  void softUpdate() const;
1184 
1186 
1187 private:
1188  LiquidMenu *_p_liquidMenu[MAX_MENUS];
1189  uint8_t _menuCount;
1190  uint8_t _currentMenu;
1191 };
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
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidMenu.cpp:171
LiquidSystem(uint8_t startingMenu=1)
The main constructor.
Definition: LiquidSystem.cpp:32
bool operator=(LiquidScreen &p_liquidScreen)
Switches to the specified screen.
Definition: LiquidSystem.cpp:129
Represents a collection of menus forming a menu system.
Definition: LiquidMenu.h:975
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:152
void softUpdate() const
Prints the current screen to the display (without clearing).
Definition: LiquidSystem.cpp:156
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:123
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidSystem.cpp:133
void operator++()
Switches to the next screen.
Definition: LiquidMenu.cpp:102
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:24
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:15
void softUpdate() const
Prints the current screen to the display (without clearing).
Definition: LiquidMenu.cpp:231
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:177
LiquidScreen * get_currentScreen() const
Returns a reference to the current screen.
Definition: LiquidMenu.cpp:85
bool set_focusPosition(Position position)
Sets the focus position for the whole menu at once.
Definition: LiquidSystem.cpp:137
void next_screen()
Switches to the next screen.
Definition: LiquidMenu.cpp:89
void init() const
Initializes the menu object.
Definition: LiquidMenu.cpp:245
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:562
#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:141
void update() const
Prints the current screen to the display.
Definition: LiquidMenu.cpp:226
bool call_function(uint8_t number) const
Calls an attached function specified by the number.
Definition: LiquidSystem.cpp:145
const uint8_t MAX_LINES
Configures the number of available lines per screen.
Definition: LiquidMenu_config.h:21
bool change_screen(LiquidScreen &p_liquidScreen)
Switches to the specified screen.
Definition: LiquidSystem.cpp:121
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:96
bool change_menu(LiquidMenu &p_liquidMenu)
Switches to the specified menu.
Definition: LiquidSystem.cpp:73
LiquidScreen()
The main constructor.
Definition: LiquidScreen.cpp:32
const char LIQUIDMENU_VERSION[]
The version of the library.
Definition: LiquidMenu.h:79
Represents a collection of screens forming a menu.
Definition: LiquidMenu.h:722
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 change_screen(LiquidScreen &p_liquidScreen)
Switches to the specified screen.
Definition: LiquidMenu.cpp:146
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:191
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 operator=(LiquidScreen &p_liquidScreen)
Switches to the specified screen.
Definition: LiquidMenu.cpp:167
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:27
bool call_function(uint8_t number) const
Calls an attached function specified by the number.
Definition: LiquidMenu.cpp:220
const uint8_t MAX_FUNCTIONS
Configures the number of available functions per line.
Definition: LiquidMenu_config.h:18
bool add_screen(LiquidScreen &liquidScreen)
Adds a LiquidScreen object to the menu.
Definition: LiquidMenu.cpp:72
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:110
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