You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
24 KiB
380 lines
24 KiB
/* ******************************************************************************
|
|
* LCDMenuLib2 (LCDML)
|
|
* ******************************************************************************
|
|
*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) [2020] [Nils Feldkämper]
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* ******************************************************************************
|
|
*
|
|
* BUG / ISSUES REPORTING
|
|
* https://github.com/Jomelo/LCDMenuLib2/issues
|
|
*
|
|
* ARDUINO FORUM
|
|
* http://forum.arduino.cc/index.php?topic=73816.0
|
|
*
|
|
* ******************************************************************************
|
|
*/
|
|
|
|
// File header
|
|
#ifndef LCDMenuLib2_h
|
|
#define LCDMenuLib2_h
|
|
|
|
// ####################### //
|
|
// This following defines can be changed
|
|
// ####################### //
|
|
|
|
// you can change this parameters
|
|
#define _LCDML_cfg_use_ram // enable this line when you want to use the ram mode
|
|
|
|
// set the number of custom events (this could be a button ore something else)
|
|
#define _LCDML_CE_cb_function_cnt 4 // this is the number of custom event callback functions which are supported
|
|
// 4 = default
|
|
|
|
// enable debug strings (remove comments from this line)
|
|
//#define LCDML_DBG 1
|
|
|
|
// debug special method groups // enable a flag to control the function call order
|
|
#define LCDML_DBG_function_name_LOOP 0
|
|
#define LCDML_DBG_function_name_MENU 0
|
|
#define LCDML_DBG_function_name_FUNC 0
|
|
#define LCDML_DBG_function_name_BT 0
|
|
#define LCDML_DBG_function_name_CE 0
|
|
#define LCDML_DBG_function_name_OTHER 1
|
|
#define LCDML_DBG_function_name_DISP 0
|
|
#define LCDML_DBG_function_name_TIMER 0
|
|
#define LCDML_DBG_function_name_SCREEN 0
|
|
|
|
// debug special complex functions
|
|
#define LCDML_DBG_search 0
|
|
|
|
// ####################### //
|
|
// Do nothing change here
|
|
// ####################### //
|
|
|
|
// create DBG_print makro when debugging is enabled
|
|
#ifdef LCDML_DBG
|
|
#define DBG_print(enable, str) if(enable == 1) { Serial.print(str); }
|
|
#define DBG_println(enable, str) if(enable == 1) { Serial.println(str); }
|
|
#define DBG_printstrln(enable, str, val, form) if(enable == 1) { Serial.print(str); Serial.println(val, form);}
|
|
#else
|
|
#define DBG_print(enable, str)
|
|
#define DBG_println(enable, str)
|
|
#define DBG_printstrln(enable, str, val, form)
|
|
#endif
|
|
|
|
// Version
|
|
#define _LCDML_VERSION "LCDML2 v2.2.2 - 27.04.2020"
|
|
|
|
// this makro is for unused variables which exists for compatibility tings ...
|
|
#define LCDML_UNUSED(expr) do { (void)(expr); } while (0)
|
|
|
|
// Include Arduino ios
|
|
#include "Arduino.h"
|
|
|
|
// Arduino specific settings
|
|
#if ARDUINO >= 160
|
|
#define _LCDMenuLib2_arduino_version 1 // for new Arduino version like 1.6.0 or higher
|
|
#else
|
|
#define _LCDMenuLib2_arduino_version 0 // for old Arduino version like 1.0.6 or 1.0.5
|
|
#endif
|
|
|
|
// ESP specific settings
|
|
#if defined( ESP8266 ) || defined( ESP32 )
|
|
#ifndef _LCDML_cfg_use_ram
|
|
#define _LCDML_cfg_use_ram
|
|
#endif
|
|
#endif
|
|
|
|
// 64 this is the number of events which are supported
|
|
#define _LCDML_CE_events_cnt 64
|
|
|
|
// No function constant
|
|
#define _LCDML_NO_FUNC 255
|
|
#define _LCDML_FIRST_ELEMENT_ID 255
|
|
|
|
// Bit pos control flags
|
|
#define _LCDML_REG_control_dynMenuDisplayed 7
|
|
#define _LCDML_REG_control_ce_init_setup 6
|
|
#define _LCDML_REG_control_menu_func_active 5
|
|
#define _LCDML_REG_control_bt_init_setup 4
|
|
#define _LCDML_REG_control_update_direct 3
|
|
#define _LCDML_REG_control_free_2 2
|
|
#define _LCDML_REG_control_rollover 1
|
|
#define _LCDML_REG_control_free_0 0
|
|
|
|
// screensaver, jump to function, go Root, ...
|
|
#define _LCDML_REG_special_setCursorTo 7
|
|
#define _LCDML_REG_special_OTHER_function_active 6
|
|
#define _LCDML_REG_special_free_5 5
|
|
#define _LCDML_REG_special_free_4 4
|
|
#define _LCDML_REG_special_free_3 3
|
|
#define _LCDML_REG_special_goRoot 2
|
|
#define _LCDML_REG_special_disable_scroll 1
|
|
#define _LCDML_REG_special_disable_screensaver 0
|
|
|
|
// menu function flags
|
|
#define _LCDML_REG_MenuFunction_called_from_menu 7
|
|
#define _LCDML_REG_MenuFunction_free_6 6
|
|
#define _LCDML_REG_MenuFunction_free_5 5
|
|
#define _LCDML_REG_MenuFunction_goBackToFuncID 4
|
|
#define _LCDML_REG_MenuFunction_setCursorToID 3
|
|
#define _LCDML_REG_MenuFunction_close_active 2
|
|
#define _LCDML_REG_MenuFunction_setup 1
|
|
#define _LCDML_REG_MenuFunction_end 0
|
|
|
|
// button flags
|
|
#define _LCDML_REG_button_do_not_use_1 7
|
|
#define _LCDML_REG_button_do_not_use_2 6
|
|
#define _LCDML_REG_button_quit 5
|
|
#define _LCDML_REG_button_enter 4
|
|
#define _LCDML_REG_button_up 3
|
|
#define _LCDML_REG_button_down 2
|
|
#define _LCDML_REG_button_left 1
|
|
#define _LCDML_REG_button_right 0
|
|
|
|
// display update handling
|
|
#define _LCDML_REG_update_content 7
|
|
#define _LCDML_REG_update_cursor 6
|
|
#define _LCDML_REG_update_menu 5
|
|
#define _LCDML_REG_update_menu_function_content 4
|
|
#define _LCDML_REG_update_free_3 3
|
|
#define _LCDML_REG_update_free_2 2
|
|
#define _LCDML_REG_update_free_1 1
|
|
#define _LCDML_REG_update_free_0 0
|
|
|
|
// Configure Arduino flash lib and load it*/
|
|
#ifndef __PROG_TYPES_COMPAT__
|
|
#define __PROG_TYPES_COMPAT__
|
|
#endif
|
|
|
|
// Include PGMSPACE
|
|
#ifndef _LCDML_cfg_use_ram
|
|
#include <avr/pgmspace.h>
|
|
#endif
|
|
|
|
// Include menu class
|
|
#include "LCDMenuLib2_typedef.h"
|
|
#include "LCDMenuLib2_menu.h"
|
|
|
|
// types for advanced menu function (this types are used by the menu element initialisation)
|
|
#define _LCDML_TYPE_f7 128
|
|
#define _LCDML_TYPE_f6 64
|
|
#define _LCDML_TYPE_f5 32
|
|
#define _LCDML_TYPE_f4 16
|
|
#define _LCDML_TYPE_f3 8
|
|
#define _LCDML_TYPE_f2 4
|
|
#define _LCDML_TYPE_dynParam 2
|
|
#define _LCDML_TYPE_default 1
|
|
|
|
// Include macros for this lib
|
|
#include "LCDMenuLib2_macros.h"
|
|
|
|
//# =======================
|
|
//# LCD Menu Lib
|
|
//# =======================
|
|
class LCDMenuLib2
|
|
{
|
|
private:
|
|
// object pointer
|
|
LCDMenuLib2_menu *curMenu; // currrent menu structure
|
|
|
|
// callback functions
|
|
LCDML_FuncPtr callback_menuControl; // a callback function which checks the input buttons
|
|
LCDML_FuncPtr callback_contentUpdate; // a callback function which contains the menu function content
|
|
LCDML_FuncPtr callback_contentClear; // a callback function which clears the display
|
|
LCDML_FuncPtr_pu8 cb_screensaver; // a callback function as screensaver (a normal menu function, but a defined name)
|
|
|
|
LCDML_FuncPtr_pu8 ce_cb[_LCDML_CE_cb_function_cnt]; // callback functions for custom events
|
|
|
|
// activ menu values
|
|
LCDML_FuncPtr_pu8 actMenu_cb_function; // Menu Function callback
|
|
uint8_t actMenu_id; // Name of this menu
|
|
uint8_t actMenu_param; // Parameter this menu
|
|
uint8_t actMenu_lastFuncID; // History of the last three active menu functions
|
|
uint8_t actMenu_cursorPositionID; // current cursor position id
|
|
uint8_t actMenu_lastCursorPositionID; // Save the last Cursor position before a new function was called
|
|
unsigned long actMenu_default_time; // default loop time
|
|
uint64_t actMenu_ce_mask; // ce mask
|
|
|
|
// jump To variables
|
|
uint8_t jT_id; // contains the jumpTo id
|
|
uint8_t jT_param; // contains the jumpTo param
|
|
uint8_t jT_paramOld; // contains the jumpTo param
|
|
LCDML_FuncPtr_pu8 jT_function; // contains the jumpTo function
|
|
|
|
// menu intern values
|
|
uint8_t window_rows; // the maximum rows of the current windows (1 is the minium)
|
|
uint8_t window_start; // the window start
|
|
|
|
uint8_t cursor_obj_pos;
|
|
uint8_t cursor_pos; // the current cursor position on the lcd
|
|
uint8_t cursor_pos_abs;
|
|
|
|
uint8_t layer; // contains the current layer
|
|
|
|
// variables with bitfields => bit register
|
|
uint8_t REG_button; // control flags for button actions
|
|
uint8_t REG_control; // control flags
|
|
uint8_t REG_MenuFunction; // control flags for menu functions
|
|
uint8_t REG_special; // control flags for special function like screensaver, jumpTo, setCursorTo, goRoot, ..
|
|
uint8_t REG_update; // control flags to update the content
|
|
uint64_t REG_custom_event; // control flags for custom event actions
|
|
|
|
// variables for handling with menu function
|
|
uint8_t goBackCnt; // save the layer to go back
|
|
|
|
// timer variable for the loop time of a menu function
|
|
unsigned long menuFunction_loopTimer;
|
|
|
|
// timer variable for the screensaver
|
|
unsigned long screensaver_timer;
|
|
unsigned long screensaver_default_time;
|
|
|
|
// private methods
|
|
void MENU_goInto(void); // activate the menu under the cursor
|
|
void MENU_goBack(void); // move to the parent menu
|
|
void MENU_doScroll(uint8_t state); // scroll the menu
|
|
uint8_t MENU_countChilds(LCDMenuLib2_menu *menu, uint8_t all=false); // how many children exists on next layer
|
|
void MENU_initFirstElement(void); // set counter to the first object child
|
|
void MENU_resetActiveMenu(void); // clear all neccessary variables
|
|
|
|
// callback function
|
|
void FUNC_call(void);
|
|
|
|
public:
|
|
|
|
// constructor
|
|
LCDMenuLib2(LCDMenuLib2_menu &p_r ,const uint8_t p_rows, const uint8_t p_cols, LCDML_FuncPtr contentUpdate, LCDML_FuncPtr contentClear, LCDML_FuncPtr menuControl);
|
|
|
|
// init method
|
|
void init(); // initialisation of the menu / reset the complete menu
|
|
|
|
// loop methods
|
|
void loop(void); // call the loop_menu and the loop_control function
|
|
void loop_control(void); // call callback function to control the menu
|
|
void loop_menu(void); // checks if a button or a menu function are needed and call them
|
|
|
|
// menu methods
|
|
void MENU_display(uint8_t update=0); // update the current menu structure but do not display it
|
|
void MENU_goRoot(void); // set the cursor to the root element
|
|
void MENU_enRollover(void); // enable menu rollover (first to last or last to first element on a layer)
|
|
void MENU_disRollover(void); // disable the menu rollover function
|
|
void MENU_enScroll(void); // enable the scroll function (this function can be disabled on dyn content elements and when a encoder is used)
|
|
void MENU_disScroll(void); // disable the scroll function to catch the cursor to an dyn content element when a encoder is used
|
|
void MENU_setDynContent(void); // set this value when dyn content is shown on the current windows of the display
|
|
uint8_t MENU_checkDynContent(void); // check if dyn content is displayed
|
|
bool MENU_getScrollDisableStatus(void); // check if the scroll function is disabled
|
|
uint8_t MENU_getLayer(void); // get the current layer of the menu
|
|
uint8_t MENU_getCursorPos(void); // get the current cursor position (row 0, row 1, row 2, ...)
|
|
uint8_t MENU_getCursorPosAbs(void); // get the current cursor postion absolute (..., row 10, row 11, ..) based on the menu structure
|
|
uint8_t MENU_getChilds(void); // get the current number of childs on this layer
|
|
uint8_t MENU_getParentID(uint8_t p_layer=0); // get the parent id of a selected higher layer
|
|
uint8_t MENU_getScroll(void); // get the current scroll value
|
|
uint8_t MENU_getLastActiveFunctionID(void); // returns the id of the last active function
|
|
uint8_t MENU_getLastCursorPositionID(void); // returns the last cursor position function id
|
|
uint8_t MENU_getElementIDFromCursorPos(void); // returns the menu element id from current cursor position
|
|
|
|
LCDMenuLib2_menu * MENU_getDisplayedObj(void); // get the objection with the current content to display
|
|
LCDMenuLib2_menu * MENU_getCurrentObj(void); // get the current menu child object
|
|
LCDMenuLib2_menu * MENU_getRootObj(void); // get the root menu object
|
|
|
|
// BT = button methods
|
|
bool BT_setup(void); // check if the button initialisation was done
|
|
void BT_enter(void); // set button enter
|
|
void BT_up(void); // set button up
|
|
void BT_down(void); // set button down
|
|
void BT_left(void); // set button left
|
|
void BT_right(void); // set button right
|
|
void BT_quit(void); // set button quit
|
|
//
|
|
void BT_resetAll(void); // reset all button states
|
|
void BT_resetEnter(void); // reset enter button state
|
|
void BT_resetUp(void); // reset up button state
|
|
void BT_resetDown(void); // reset down button state
|
|
void BT_resetLeft(void); // reset left button state
|
|
void BT_resetRight(void); // reset right button state
|
|
void BT_resetQuit(void); // reset quit button state
|
|
//
|
|
bool BT_checkAny(void); // check if any button was pressed
|
|
bool BT_checkEnter(void); // check enter button
|
|
bool BT_checkUp(void); // check up button
|
|
bool BT_checkDown(void); // check down button
|
|
bool BT_checkLeft(void); // check left button
|
|
bool BT_checkRight(void); // check right button
|
|
bool BT_checkQuit(void); // check quit button
|
|
|
|
// CE = custom event
|
|
bool CE_setup(void); // check if the button initialisation was done
|
|
void CE_set(uint8_t p_event); // set button enter
|
|
//
|
|
void CE_resetAll(void); // reset all button states
|
|
void CE_reset(uint8_t p_event); // reset enter button state
|
|
//
|
|
bool CE_checkAny(void); // check if any button was pressed
|
|
bool CE_check(uint8_t p_event); // check enter button
|
|
//
|
|
void CE_setOnChangeCbFunction(uint8_t p_event, LCDML_FuncPtr_pu8 p_function); // add callback function
|
|
void CE_clearOnChangeCbFunction(uint8_t p_event); // remove callback function
|
|
|
|
// display methods
|
|
void DISP_update(void); // display the content and update the menu structure
|
|
void DISP_menuUpdate(void); // display the content but do not update the menu structure
|
|
void DISP_clear(void); // calls the callback function to clear the display
|
|
bool DISP_checkMenuUpdate(void); // check if there is new content to display
|
|
bool DISP_checkMenuCursorUpdate(void); // check if the cursor was moved
|
|
uint8_t DISP_getMenuContentId(uint8_t n); // get the id`s from a contentelement for a special line
|
|
|
|
// menu function methods
|
|
bool FUNC_setup(void); // check if a menu function is called the first time to init some things
|
|
bool FUNC_loop(void); // check if a menu function is running in a loop
|
|
bool FUNC_close(void); // check if a menu function is closed to reach a stable state
|
|
void FUNC_goBackToMenu(uint8_t p_goBackCnt=0); // close the current menu function (the FUNC_close check is true when this is set)
|
|
uint8_t FUNC_getID(void); // get the ID of the current menu function
|
|
void FUNC_setLoopInterval(unsigned long p_t); // set a loop intervall for the current menu function the default loop intervall is 100000000 ms
|
|
void FUNC_disableScreensaver(void); // disable the screensaver for the current menu function
|
|
void FUNC_setGBAToLastCursorPos(void); // set a special "go back handling"
|
|
void FUNC_setGBAToLastFunc(void); // set a special "go back handling"
|
|
void FUNC_setGBA(void); // set a special "go back handling" which decide between the two function above
|
|
void FUNC_setCEMask(unsigned long p_mask); // set a mask to enable only special events for a menu function
|
|
|
|
// timer methods
|
|
bool TIMER_ms(unsigned long &p_var, unsigned long p_t); // a small timer based on the millis() function
|
|
void TIMER_msReset(unsigned long &p_var); // reset the millis timer
|
|
bool TIMER_us(unsigned long &p_var, unsigned long p_t); // a small timer based on the micros() function
|
|
void TIMER_usReset(unsigned long &p_var); // reset the micros timer
|
|
|
|
// other methods
|
|
void OTHER_jumpToFunc(LCDML_FuncPtr_pu8 p_search, uint8_t p_para = 0); // jumpTo a defined function based on the function name
|
|
void OTHER_jumpToID(uint8_t p_search, uint8_t p_para = 0); // jumpTo a defined function based on the function id
|
|
void OTHER_setCursorToID(uint8_t p_search); // set the cursor to a defined function based on the id
|
|
void OTHER_setCursorToFunc(LCDML_FuncPtr_pu8 p_search); // set the cursor to a defined function based on the function name
|
|
uint8_t OTHER_getIDFromFunction(LCDML_FuncPtr_pu8 p_search); // get the menu element id from a menu element function name
|
|
void OTHER_updateFunc(void); // update a menu function directly when it runs
|
|
|
|
// screensaver methods
|
|
void SCREEN_enable(LCDML_FuncPtr_pu8 p_function, unsigned long p_t); // enable the screensaver feature
|
|
void SCREEN_disable(void); // disable the screensaver feature
|
|
void SCREEN_resetTimer(void); // reset the screensaver timer
|
|
void SCREEN_start(void); // start the screensaver directly
|
|
};
|
|
#endif
|
|
|