LiquidMenu  1.3.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 <inttypes.h>
43 #include <avr/pgmspace.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 
47 #include "LiquidMenu_config.h"
48 #include "LiquidMenu_debug.h"
49 
50 #if I2C
51 #include <LiquidCrystal_I2C.h>
52 #define DisplayClass LiquidCrystal_I2C
53 #warning "LiquidMenu: Configured for I2C. Edit 'LiquidMenu_config.h' file to change it."
54 #else
55 #include <LiquidCrystal.h>
56 #define DisplayClass LiquidCrystal
57 #warning "LiquidMenu: Configured for Parallel. Edit 'LiquidMenu_config.h' file to change it."
58 #endif
59 
60 #if LIQUIDMENU_DEBUG
61 #warning "LiquidMenu: Debugging messages are enabled."
62 #endif
63 
64 const char LIQUIDMENU_VERSION[] = "1.3";
65 
67 
70 enum class DataType : uint8_t {
71  NOT_USED = 0,
72  BOOL = 1, BOOLEAN = 1,
73  INT8_T = 8,
74  UINT8_T = 9, BYTE = 9,
75  INT16_T = 16,
76  UINT16_T = 17,
77  INT32_T = 32,
78  UINT32_T = 33,
79  FLOAT = 50, DOUBLE = 50,
80  CHAR = 60,
81  CHAR_PTR = 61,
82  CONST_CHAR_PTR = 62,
83  PROG_CONST_CHAR_PTR = 65,
84  GLYPH = 70,
85 };
86 
88 /*
89 Used to store and set the relative or absolute position of the focus indicator.
90 */
91 enum class Position : uint8_t {
92  RIGHT = 1, NORMAL = 1,
93  LEFT = 2,
94  CUSTOM = 3,
95 };
96 
98 
102 
108 DataType recognizeType(bool variable);
109 
114 DataType recognizeType(char variable);
115 
120 DataType recognizeType(char* variable);
121 
126 DataType recognizeType(const char* variable);
127 
132 DataType recognizeType(int8_t variable);
133 
138 DataType recognizeType(uint8_t variable);
139 
144 DataType recognizeType(int16_t variable);
145 
150 DataType recognizeType(uint16_t variable);
151 
156 DataType recognizeType(int32_t variable);
157 
162 DataType recognizeType(uint32_t variable);
163 
168 DataType recognizeType(float variable);
169 
174 DataType recognizeType(double variable);
176 
177 
179 
184 void print_me(uintptr_t address);
185 
186 
188 
195 class LiquidLine {
196  friend class LiquidScreen;
197 
198 public:
201 
203 
209  LiquidLine(uint8_t column, uint8_t row)
210  : _row(row), _column(column), _focusRow(row - 1),
211  _focusColumn(column - 1), _focusPosition(Position::NORMAL),
212  _variableCount(0), _focusable(false) {
213  for (uint8_t i = 0; i < MAX_VARIABLES; i++) {
214  _variable[i] = nullptr;
215  _variableType[i] = DataType::NOT_USED;
216  }
217  for (uint8_t f = 0; f < MAX_FUNCTIONS; f++) {
218  _function[f] = 0;
219  }
220  }
221 
223 
228  template <typename A>
229  LiquidLine(uint8_t column, uint8_t row, A &variableA)
230  : LiquidLine(column, row) {
231  add_variable(variableA);
232  }
233 
235 
241  template <typename A, typename B>
242  LiquidLine(uint8_t column, uint8_t row,
243  A &variableA, B &variableB)
244  : LiquidLine(column, row, variableA) {
245  add_variable(variableB);
246  }
247 
249 
256  template <typename A, typename B, typename C>
257  LiquidLine(uint8_t column, uint8_t row,
258  A &variableA, B &variableB, C &variableC)
259  : LiquidLine(column, row, variableA, variableB) {
260  add_variable(variableC);
261  }
262 
264 
272  template <typename A, typename B, typename C, typename D>
273  LiquidLine(uint8_t column, uint8_t row,
274  A &variableA, B &variableB, C &variableC, D &variableD)
275  : LiquidLine(column, row, variableA, variableB, variableC) {
276  add_variable(variableD);
277  }
278 
280 
281 
284 
286 
297  template <typename T>
298  bool add_variable(T &variable) {
299  print_me((uintptr_t)this);
300  if (_variableCount < MAX_VARIABLES) {
301  _variable[_variableCount] = (void*)&variable;
302  _variableType[_variableCount] = recognizeType(variable);
303  DEBUG(F("Added variable '")); DEBUG(variable); DEBUGLN(F("'"));
304  _variableCount++;
305  return true;
306  }
307  DEBUG(F("Adding variable ")); DEBUG(variable);
308  DEBUGLN(F(" failed, edit LiquidMenu_config.h to allow for more variables"));
309  return false;
310  }
311 
313 
331  bool attach_function(uint8_t number, void (*function)(void));
332 
334 
350  bool set_focusPosition(Position position,
351  uint8_t column = 0, uint8_t row = 0);
352 
354 
363  bool set_asGlyph(uint8_t number);
364 
366 
374  bool set_asProgmem(uint8_t number);
376 
377 private:
379 
387  void print(DisplayClass *p_liquidCrystal, bool isFocused);
388 
390 
397  void print_variable(DisplayClass *p_liquidCrystal, uint8_t number);
398 
400 
408  bool call_function(uint8_t number) const;
409 
410  uint8_t _row, _column, _focusRow, _focusColumn;
411  Position _focusPosition;
412  uint8_t _variableCount;
413  void (*_function[MAX_FUNCTIONS])(void);
414  const void *_variable[MAX_VARIABLES];
415  DataType _variableType[MAX_VARIABLES];
416  bool _focusable;
417 };
418 
419 
421 
430  friend class LiquidMenu;
431 
432 public:
433 
436 
438 
441  LiquidScreen();
442 
444 
447  explicit LiquidScreen(LiquidLine &liquidLine);
448 
450 
454  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2);
455 
457 
462  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
463  LiquidLine &liquidLine3);
464 
466 
472  LiquidScreen(LiquidLine &liquidLine1, LiquidLine &liquidLine2,
473  LiquidLine &liquidLine3, LiquidLine &liquidLine4);
474 
476 
479 
481 
492  bool add_line(LiquidLine &liquidLine);
493 
495 
509  bool set_focusPosition(Position position);
510 
512 
523  void hide(bool hide);
525 
526 private:
528 
534  void print(DisplayClass *p_liquidCrystal) const;
535 
537 
543  void switch_focus(bool forward = true);
544 
546 
556  bool call_function(uint8_t number) const;
557 
558  LiquidLine *_p_liquidLine[MAX_LINES];
559  uint8_t _lineCount;
560  uint8_t _focus;
561  bool _hidden;
562 };
563 
564 
566 
575 class LiquidMenu {
576  friend class LiquidSystem;
577 
578 public:
579 
582 
584 
591  LiquidMenu(DisplayClass &liquidCrystal, uint8_t startingScreen = 1);
592 
594 
600  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen,
601  uint8_t startingScreen = 1);
602 
604 
611  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
612  LiquidScreen &liquidScreen2, uint8_t startingScreen = 1);
613 
615 
623  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
624  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
625  uint8_t startingScreen = 1);
626 
628 
637  LiquidMenu(DisplayClass &liquidCrystal, LiquidScreen &liquidScreen1,
638  LiquidScreen &liquidScreen2, LiquidScreen &liquidScreen3,
639  LiquidScreen &liquidScreen4, uint8_t startingScreen = 1);
640 
642 
645 
647 
658  bool add_screen(LiquidScreen &liquidScreen);
659 
661  void next_screen();
662 
664 
667  void operator++();
668 
670 
673  void operator++(int);
674 
676  void previous_screen();
677 
679 
682  void operator--();
683 
685 
688  void operator--(int);
689 
691 
695  bool change_screen(LiquidScreen &p_liquidScreen);
696 
698 
703  bool change_screen(uint8_t number);
704 
706 
710  bool operator=(LiquidScreen &p_liquidScreen);
711 
713 
718  bool operator=(uint8_t number);
719 
721 
727  void switch_focus(bool forward = true);
728 
730 
744  bool set_focusPosition(Position position);
745 
747 
760  bool set_focusSymbol(Position position, uint8_t symbol[8]);
761 
763 
774  bool call_function(uint8_t number) const;
775 
777 
780  void update() const;
781 
783 
789  void softUpdate() const;
790 
792 
797  void init() const;
798 
800 
801 private:
802  DisplayClass *_p_liquidCrystal;
803  LiquidScreen *_p_liquidScreen[MAX_SCREENS];
804  uint8_t _screenCount;
805  uint8_t _currentScreen;
806 };
807 
808 
810 
821 public:
822 
825 
827 
832  explicit LiquidSystem(uint8_t startingMenu = 1);
833 
835 
840  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
841  uint8_t startingMenu = 1);
842 
844 
850  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
851  LiquidMenu &liquidMenu3, uint8_t startingMenu = 1);
852 
854 
861  LiquidSystem(LiquidMenu &liquidMenu1, LiquidMenu &liquidMenu2,
862  LiquidMenu &liquidMenu3, LiquidMenu &liquidMenu4,
863  uint8_t startingMenu = 1);
864 
866 
869 
871 
882  bool add_menu(LiquidMenu &liquidMenu);
883 
885 
889  bool change_menu(LiquidMenu &p_liquidMenu);
890 
892  void next_screen();
893 
895 
898  void operator++();
899 
901 
904  void operator++(int);
905 
907  void previous_screen();
908 
910 
913  void operator--();
914 
916 
919  void operator--(int);
920 
922 
926  bool change_screen(LiquidScreen &p_liquidScreen);
927 
929 
934  bool change_screen(uint8_t number);
935 
937 
941  bool operator=(LiquidScreen &p_liquidScreen);
942 
944 
949  bool operator=(uint8_t number);
950 
952 
958  void switch_focus(bool forward = true);
959 
961 
975  bool set_focusPosition(Position position);
976 
978 
991  bool set_focusSymbol(Position position, uint8_t symbol[8]);
992 
994 
1005  bool call_function(uint8_t number) const;
1006 
1008 
1011  void update() const;
1012 
1014 
1020  void softUpdate() const;
1021 
1023 
1024 private:
1025  LiquidMenu *_p_liquidMenu[MAX_MENUS];
1026  uint8_t _menuCount;
1027  uint8_t _currentMenu;
1028 };
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB, C &variableC)
Constructor for three variables/constants.
Definition: LiquidMenu.h:257
void operator--()
Switches to the previous screen.
Definition: LiquidSystem.cpp:102
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidMenu.cpp:167
bool operator=(LiquidScreen &p_liquidScreen)
Switches to the specified screen.
Definition: LiquidSystem.cpp:122
Represents a collection of menus forming a menu system.
Definition: LiquidMenu.h:820
Represents the individual lines printed on the display.
Definition: LiquidMenu.h:195
void update() const
Prints the current screen to the display.
Definition: LiquidSystem.cpp:145
void softUpdate() const
Prints the current screen to the display (without clearing).
Definition: LiquidSystem.cpp:149
void switch_focus(bool forward=true)
Switches the focus.
Definition: LiquidSystem.cpp:126
bool add_variable(T &variable)
Adds a variable to the line.
Definition: LiquidMenu.h:298
const uint8_t MAX_SCREENS
Configures the number of available screens per menu.
Definition: LiquidMenu_config.h:24
const uint8_t MAX_VARIABLES
Configures the number of available variables per line.
Definition: LiquidMenu_config.h:15
void previous_screen()
Switches to the previous screen.
Definition: LiquidSystem.cpp:98
bool set_focusPosition(Position position)
Sets the focus position for the whole menu at once.
Definition: LiquidMenu.cpp:173
bool set_focusPosition(Position position)
Sets the focus position for the whole menu at once.
Definition: LiquidSystem.cpp:130
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB)
Constructor for two variables/constants.
Definition: LiquidMenu.h:242
Represents a screen shown on the display.
Definition: LiquidMenu.h:429
#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:134
bool call_function(uint8_t number) const
Calls an attached function specified by the number.
Definition: LiquidSystem.cpp:138
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:114
LiquidLine(uint8_t column, uint8_t row)
The main constructor.
Definition: LiquidMenu.h:209
const char LIQUIDMENU_VERSION[]
The version of the library.
Definition: LiquidMenu.h:64
Represents a collection of screens forming a menu.
Definition: LiquidMenu.h:575
LiquidLine(uint8_t column, uint8_t row, A &variableA, B &variableB, C &variableC, D &variableD)
Constructor for four variables/constants.
Definition: LiquidMenu.h:273
Position
Position enum.
Definition: LiquidMenu.h:91
DataType recognizeType(bool variable)
Definition: recognizeType.cpp:9
void next_screen()
Switches to the next screen.
Definition: LiquidSystem.cpp:86
DataType
Data type enum.
Definition: LiquidMenu.h:70
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:216
const uint8_t MAX_FUNCTIONS
Configures the number of available functions per line.
Definition: LiquidMenu_config.h:18
LiquidLine(uint8_t column, uint8_t row, A &variableA)
Constructor for one variable/constant.
Definition: LiquidMenu.h:229
#define DEBUGLN(x)
Debug print with newline.
Definition: LiquidMenu_debug.h:25
void operator++()
Switches to the next screen.
Definition: LiquidSystem.cpp:90
bool set_focusPosition(Position position)
Sets the focus position for the whole screen at once.
Definition: LiquidScreen.cpp:71