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.
2898 lines
94 KiB
2898 lines
94 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
|
|
*
|
|
* ******************************************************************************
|
|
*/
|
|
|
|
#include "LCDMenuLib2.h"
|
|
#include "LCDMenuLib2_typedef.h"
|
|
|
|
/* ******************************************************************** */
|
|
LCDMenuLib2::LCDMenuLib2(LCDMenuLib2_menu &p_r, const uint8_t p_rows, const uint8_t p_cols, LCDML_FuncPtr contentUpdate, LCDML_FuncPtr contentClear, LCDML_FuncPtr menuControl)
|
|
/* ******************************************************************** */
|
|
{
|
|
// unused variables
|
|
LCDML_UNUSED(p_cols);
|
|
|
|
// initialization
|
|
curMenu = &p_r;
|
|
window_rows = p_rows;
|
|
|
|
callback_contentUpdate = contentUpdate; // callback update content
|
|
callback_contentClear = contentClear; // callback clear content
|
|
callback_menuControl = menuControl; // callback buttons
|
|
|
|
cb_screensaver = NULL;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* init methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::init(uint8_t p_last_element_id)
|
|
/* ******************************************************************** */
|
|
{
|
|
// init some variables
|
|
REG_control = 0;
|
|
REG_MenuFunction = 0;
|
|
REG_button = 0;
|
|
REG_custom_event = 0;
|
|
REG_special = 0;
|
|
REG_update = 0;
|
|
cursor_pos = 0;
|
|
layer = 0;
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
menuFunction_loopTimer = 0;
|
|
last_element_id = p_last_element_id;
|
|
|
|
MENU_resetActiveMenu();
|
|
|
|
// reset custom events callback functions
|
|
for(uint8_t i=0; i<_LCDML_CE_cb_function_cnt; i++)
|
|
{
|
|
ce_cb[i] = NULL;
|
|
}
|
|
|
|
// enable called from menu
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
|
|
// set the cursor object position to the right postion
|
|
// this is needed when the first and following elements are hidden
|
|
MENU_initFirstElement();
|
|
|
|
// update the current cursor possition
|
|
// paramter 10 => do not scroll
|
|
MENU_doScroll(10);
|
|
// update the menu
|
|
MENU_display();
|
|
DISP_menuUpdate();
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* LOOP methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::loop(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop"));
|
|
|
|
// call this function together
|
|
loop_control();
|
|
loop_menu();
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::loop_control(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control"));
|
|
|
|
// check callback
|
|
// check if this function is valid
|
|
if(callback_menuControl != NULL)
|
|
{
|
|
// in this function the user defined button control is hanedled
|
|
callback_menuControl();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// check if a "jumpTo - setCursoTo" function is active
|
|
// this check is necessary because there can be a bad timing between a timebased function call or a event and
|
|
// another OTHER_...() function.
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active) == false)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - check screensaver"));
|
|
|
|
// screensaver handling
|
|
// check if the screensaver is enabled and a callback function is defined
|
|
if(bitRead(REG_special, _LCDML_REG_special_disable_screensaver) == false && cb_screensaver != NULL)
|
|
{
|
|
// check the state when menu is active do another handling as when a function is active
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// a menu function is active
|
|
// when the screensaver function is active do nothing otherwise close the old function and call the screensaver
|
|
if(actMenu_cb_function != cb_screensaver)
|
|
{
|
|
if(TIMER_ms(screensaver_timer, screensaver_default_time))
|
|
{
|
|
// close the running function
|
|
FUNC_goBackToMenu();
|
|
loop_control();
|
|
REG_button = 0;
|
|
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - jump to screensaver"));
|
|
|
|
// open the screensaver
|
|
OTHER_jumpToFunc(cb_screensaver);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// only the menu is active
|
|
if(TIMER_ms(screensaver_timer, screensaver_default_time))
|
|
{
|
|
// reset all button states
|
|
REG_button = 0;
|
|
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - jump to screensaver"));
|
|
|
|
// open the screensaver
|
|
OTHER_jumpToFunc(cb_screensaver);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
|
|
// check custom event handling
|
|
if(CE_checkAny() == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - check event"));
|
|
|
|
for(uint8_t i=0; i<_LCDML_CE_cb_function_cnt; i++)
|
|
{
|
|
// event found
|
|
if(CE_check(i) == true)
|
|
{
|
|
// callback function found
|
|
if(ce_cb[i] != NULL)
|
|
{
|
|
// check if a function is running
|
|
if(actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - jump to event"));
|
|
|
|
// no function is active
|
|
// switch to new callback function
|
|
OTHER_jumpToFunc(ce_cb[i]);
|
|
}
|
|
else
|
|
{
|
|
// a function is active
|
|
// check if function is running
|
|
if(actMenu_cb_function != ce_cb[i])
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_control - jump to event"));
|
|
|
|
// switch to new callback function
|
|
OTHER_jumpToFunc(ce_cb[i]);
|
|
}
|
|
else
|
|
{
|
|
// do nothing, function is running
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::loop_menu(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_LOOP, F("LCDML.loop_menu"));
|
|
|
|
// local declaration
|
|
uint8_t cnt = 0;
|
|
uint8_t found = _LCDML_FIRST_ELEMENT_ID;
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
// ============================================
|
|
// check control activity
|
|
// ============================================
|
|
if(REG_button > 0)
|
|
{
|
|
SCREEN_resetTimer();
|
|
|
|
if(actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
// -- ENTER --
|
|
if(bitRead(REG_button, _LCDML_REG_button_enter) == true)
|
|
{
|
|
//menu is active
|
|
MENU_goInto();
|
|
bitSet(REG_control, _LCDML_REG_control_update_direct);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// -- UP --
|
|
if(bitRead(REG_special, _LCDML_REG_special_disable_scroll) == false)
|
|
{
|
|
if(bitRead(REG_button, _LCDML_REG_button_up) == true)
|
|
{
|
|
MENU_doScroll(0);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// -- DOWN --
|
|
if(bitRead(REG_button, _LCDML_REG_button_down) == true)
|
|
{
|
|
MENU_doScroll(1);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(bitRead(REG_button, _LCDML_REG_button_up) == true || bitRead(REG_button, _LCDML_REG_button_down) == true)
|
|
{
|
|
DISP_update();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
// -- LEFT or RIGHT --
|
|
if(bitRead(REG_button, _LCDML_REG_button_left) == true or bitRead(REG_button, _LCDML_REG_button_right) == true)
|
|
{
|
|
DISP_update();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// -- QUIT Part 1 --
|
|
if(bitRead(REG_button, _LCDML_REG_button_quit) == true)
|
|
{
|
|
MENU_enScroll();
|
|
|
|
if(layer > 0)
|
|
{
|
|
MENU_goBack();
|
|
DISP_update();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// -- QUIT Part 2 --
|
|
if(bitRead(REG_button, _LCDML_REG_button_quit) == true)
|
|
{
|
|
MENU_enScroll();
|
|
FUNC_goBackToMenu();
|
|
bitClear(REG_button, _LCDML_REG_button_quit);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// check control activity
|
|
// ============================================
|
|
if(CE_checkAny() == true)
|
|
{
|
|
// reset screensaver timer
|
|
SCREEN_resetTimer();
|
|
}
|
|
|
|
// ============================================
|
|
// jump to handling
|
|
// ============================================
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active))
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpTo.. / LCDML.OTHER_setCursorTo... - is active"));
|
|
|
|
MENU_enScroll();
|
|
|
|
bitClear(REG_special, _LCDML_REG_special_OTHER_function_active);
|
|
bitClear(REG_control, _LCDML_REG_control_dynMenuDisplayed);
|
|
|
|
// stop running function and go back to the menu
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpTo.. / LCDML.OTHER_setCursorTo... - close active function"));
|
|
|
|
// this function called be recursive (only once)
|
|
// set this bit to call the FUNC_close function when the goRoot function is called
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_close_active) == false)
|
|
{
|
|
FUNC_call(); // call active function to bring it on a stable state;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
REG_button = 0;
|
|
|
|
// Reset active menu
|
|
MENU_resetActiveMenu();
|
|
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_close_active);
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_setup);
|
|
|
|
bitClear(REG_special, _LCDML_REG_special_disable_screensaver);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// reset the old parameter from the closed function / this parameter is set when a new jumpTo.. function is called
|
|
jT_paramOld = 0;
|
|
|
|
// Root Menu
|
|
curMenu = MENU_getRootObj();
|
|
layer = 0;
|
|
cursor_pos = 0;
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
window_start = 0;
|
|
|
|
// Check if this Menu have childs
|
|
if((curMenu = curMenu->getChild(0)) != NULL)
|
|
{
|
|
// This loop runs through the menu structure and stops after checking the last element
|
|
while(true)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, curMenu->getID());
|
|
|
|
// ***
|
|
// check loop end condetions
|
|
// ***
|
|
|
|
// check if something is found:
|
|
if(jT_function != NULL)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("check function"));
|
|
|
|
if(curMenu->getCbFunction() == jT_function)
|
|
{
|
|
// something found
|
|
found = curMenu->getID();
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Debug Information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("check id"));
|
|
|
|
if(curMenu->getID() == jT_id)
|
|
{
|
|
// something found
|
|
found = curMenu->getID();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check if the last item is reached
|
|
if(last_element_id == curMenu->getID())
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("nothing found: endpoint (C) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, curMenu->getID());
|
|
|
|
break;
|
|
}
|
|
|
|
// ***
|
|
// set the next item
|
|
// ***
|
|
|
|
// check childs for childs
|
|
if(curMenu->getChild(0) != NULL)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("gointo an element"));
|
|
|
|
// -- GO INTO --
|
|
layer++;
|
|
|
|
// set next child for check
|
|
curMenu = curMenu->getChild(0);
|
|
}
|
|
else
|
|
{
|
|
if(curMenu->getSibling(1) != NULL)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("set next sibling"));
|
|
|
|
// set next sibling for check
|
|
curMenu = curMenu->getSibling(1);
|
|
}
|
|
else
|
|
{
|
|
// check parent element
|
|
if(curMenu->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("nothing found: endpoint (A) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, curMenu->getID());
|
|
|
|
// Here stands no break, because this element have to be checked (id - function_name)
|
|
}
|
|
else
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("gointo an element"));
|
|
|
|
// all childs are checked
|
|
do
|
|
{
|
|
// set next parent for check
|
|
curMenu = curMenu->getParent();
|
|
|
|
// -- GO Back --
|
|
layer--;
|
|
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("goback to parent element"));
|
|
|
|
// check if the parent element have siblings
|
|
if(curMenu->getSibling(1) != NULL)
|
|
{
|
|
// set next sibling
|
|
curMenu = curMenu->getSibling(1);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(curMenu->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// continue
|
|
}
|
|
}
|
|
} while (true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// set menu back to the parent layer
|
|
curMenu = curMenu->getParent();
|
|
}
|
|
|
|
// check element handling
|
|
if(found != _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpTo.. / LCDML.OTHER_setCursorTo... - element found"));
|
|
|
|
tmp = curMenu->getChild(0);
|
|
// get the current obj position in this layer
|
|
do
|
|
{
|
|
if(tmp->getID() == found)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// count elements
|
|
cnt++;
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
|
|
// tmp have here the pointer to the right position
|
|
//tmp = --pointer_position--
|
|
cursor_pos_abs = cnt;
|
|
cursor_obj_pos = cnt;
|
|
|
|
if(bitRead(REG_special, _LCDML_REG_special_setCursorTo) == false)
|
|
{
|
|
// OTHER jump to function ...
|
|
|
|
// check if element is a menu function and no dynamic function
|
|
//if(tmp->checkCallback() == false || tmp->checkType_menu() == false)
|
|
if(tmp->getChild(0) != NULL || tmp->checkType_menu() == false)
|
|
{
|
|
// only set the cursor to this element because it is not callable
|
|
// do nothing else here
|
|
}
|
|
else
|
|
{
|
|
// open menu element
|
|
MENU_goInto();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// OTHER set cursor to ...
|
|
if(tmp->checkCondition() == false)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorTo.. - element is hidden, the cursor cannot be set to this possition: go back to root menu"));
|
|
|
|
MENU_goRoot();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
// update the menu
|
|
DISP_update();
|
|
|
|
// set current cursor possition with hidden elements
|
|
tmp = curMenu->getChild(0);
|
|
cnt = 0;
|
|
|
|
do
|
|
{
|
|
if(tmp->checkCondition())
|
|
{
|
|
if(tmp->getID() == found)
|
|
{
|
|
cursor_pos_abs = cnt;
|
|
if(cursor_pos_abs - (window_rows-1) > 0)
|
|
{
|
|
window_start = cursor_pos_abs-(window_rows-1);
|
|
}
|
|
else
|
|
{
|
|
window_start = 0;
|
|
}
|
|
MENU_doScroll(10);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
// count visible elments
|
|
cnt++;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpTo.. / LCDML.OTHER_setCursorTo... - nothing found -> goRoot"));
|
|
MENU_goRoot();
|
|
|
|
// update the menu
|
|
DISP_update();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
|
|
// ============================================
|
|
// check if a menu function is active
|
|
// ============================================
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// check if the running function should be closed
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_end) == false && bitRead(REG_special, _LCDML_REG_special_goRoot) == false)
|
|
{
|
|
// => do not close the running function
|
|
// check if a loop time was set or a button was pressed or the function is called the first time
|
|
if( TIMER_ms(menuFunction_loopTimer, actMenu_default_time) == true ||
|
|
bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_setup) == false ||
|
|
REG_button > 0 ||
|
|
CE_checkAny() > 0 ||
|
|
bitRead(REG_update, _LCDML_REG_update_menu_function_content)
|
|
)
|
|
{
|
|
// reset update flag
|
|
bitClear(REG_update, _LCDML_REG_update_menu_function_content);
|
|
|
|
// call the current menu function
|
|
FUNC_call();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// close the running function
|
|
|
|
// set this bit to call the FUNC_close function when the goRoot function is called
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_close_active) == false)
|
|
{
|
|
FUNC_call(); // call active function to bring it on a stable state;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// Reset active menu
|
|
MENU_resetActiveMenu();
|
|
|
|
// reset the custom parameter
|
|
jT_param = 0;
|
|
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_close_active);
|
|
bitClear(REG_special, _LCDML_REG_special_disable_screensaver);
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_setup);
|
|
|
|
if(bitRead(REG_special, _LCDML_REG_special_goRoot) == true)
|
|
{
|
|
// set the cursor to the root position
|
|
bitClear(REG_special, _LCDML_REG_special_goRoot);
|
|
|
|
MENU_goRoot();
|
|
}
|
|
else
|
|
{
|
|
// check go back
|
|
for(; goBackCnt > 0; goBackCnt--)
|
|
{
|
|
MENU_goBack();
|
|
}
|
|
|
|
// check if the cursor stands on the correct possition
|
|
if(layer == 0)
|
|
{
|
|
if(curMenu->getChild(cursor_obj_pos)->checkCondition() == false)
|
|
{
|
|
MENU_goRoot();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// on going back, when the parent element is hidden, the condition is checken
|
|
// if the element is hidden, go to the next parent element and so on ...
|
|
while(layer > 0 && MENU_countChilds(curMenu) == 0)
|
|
{
|
|
MENU_goBack();
|
|
}
|
|
}
|
|
}
|
|
|
|
// only update the content when no jump function is active
|
|
DISP_update();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// ============================================
|
|
// check update handling
|
|
// ============================================
|
|
if(bitRead(REG_update, _LCDML_REG_update_menu) == true || bitRead(REG_update, _LCDML_REG_update_cursor) == true)
|
|
{
|
|
// save last cursor position
|
|
if(bitRead(REG_update, _LCDML_REG_update_cursor) == true)
|
|
{
|
|
actMenu_lastCursorPositionID = actMenu_cursorPositionID;
|
|
actMenu_cursorPositionID = curMenu->getChild(MENU_getCursorPosAbs())->getID();
|
|
}
|
|
|
|
if(actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
if(bitRead(REG_special, _LCDML_REG_special_disable_scroll) == false)
|
|
{
|
|
// clear button status from scrolling
|
|
bitClear(REG_button, _LCDML_REG_button_up);
|
|
bitClear(REG_button, _LCDML_REG_button_down);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// update content
|
|
callback_contentUpdate();
|
|
|
|
REG_button = 0;
|
|
|
|
// this update function is neccessary for dynamic contents when a low element in the menu update the content of
|
|
// a higher element
|
|
if(bitRead(REG_update, _LCDML_REG_update_update_dyn_content) == true)
|
|
{
|
|
// force a rebuild of the menu output content and cursor position
|
|
MENU_display();
|
|
bitSet(REG_update, _LCDML_REG_update_cursor);
|
|
|
|
// update content without button handling
|
|
callback_contentUpdate();
|
|
// clear this flag
|
|
MENU_clearDynFunctionContentUpdate();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// reset both values here because it can be happen on some examples, that not all values are reset
|
|
bitClear(REG_update, _LCDML_REG_update_menu);
|
|
bitClear(REG_update, _LCDML_REG_update_cursor);
|
|
}
|
|
else
|
|
{
|
|
// reset all button actions
|
|
REG_button = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* MENU methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_initFirstElement(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
//
|
|
uint8_t obj_pos = cursor_obj_pos;
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
// get the current object
|
|
if((tmp = curMenu->getChild(cursor_obj_pos)) != NULL)
|
|
{
|
|
do
|
|
{
|
|
if(tmp->checkCondition())
|
|
{
|
|
cursor_obj_pos = obj_pos;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
obj_pos++;
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_goRoot(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_goRoot"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
bitSet(REG_special, _LCDML_REG_special_goRoot);
|
|
}
|
|
else
|
|
{
|
|
// check if root position is reached
|
|
REG_button = 0;
|
|
|
|
curMenu = MENU_getRootObj();
|
|
layer = 0;
|
|
cursor_pos = 0;
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
window_start = 0;
|
|
|
|
MENU_initFirstElement();
|
|
|
|
MENU_doScroll(10);
|
|
MENU_display();
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_resetActiveMenu(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_resetActiveMenu"));
|
|
|
|
// reset callback function
|
|
actMenu_cb_function = NULL;
|
|
|
|
// save last active function
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
actMenu_lastFuncID = actMenu_id;
|
|
}
|
|
|
|
// reset variables
|
|
actMenu_id = _LCDML_NO_FUNC;
|
|
actMenu_param = 0;
|
|
actMenu_default_time = 0xFFFFFFFF; // 32 Bit
|
|
actMenu_ce_mask = 0xFFFFFFFFFFFFFFFF; // 64 Bit
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_goBack(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_goBack"));
|
|
|
|
//declare variables
|
|
LCDMenuLib2_menu *tmp;
|
|
uint8_t old_id = 0;
|
|
uint8_t j = 0;
|
|
uint8_t obj_pos = 0;
|
|
bool found_visible = false;
|
|
|
|
old_id = curMenu->getID();
|
|
tmp = curMenu->getParent();
|
|
|
|
// set the curMenu pointer to a other menu element
|
|
curMenu = curMenu->getParent();
|
|
|
|
// update the layer counter
|
|
if(layer > 0)
|
|
{
|
|
layer--;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// init the cursor_position variables to 0
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
|
|
// get childs from the current menu element
|
|
if((tmp = curMenu->getChild(0)) != NULL)
|
|
{
|
|
// search the current possition of the cursor
|
|
do
|
|
{
|
|
// check conditions
|
|
if (tmp->checkCondition())
|
|
{
|
|
// when the current element id is the same as the old_id the current cursor position is found
|
|
if(tmp->getID() == old_id)
|
|
{
|
|
cursor_pos_abs = j;
|
|
cursor_obj_pos = obj_pos;
|
|
if(cursor_pos_abs - (window_rows-1) > 0)
|
|
{
|
|
window_start = cursor_pos_abs-(window_rows-1);
|
|
}
|
|
else
|
|
{
|
|
window_start = 0;
|
|
}
|
|
|
|
MENU_doScroll(10);
|
|
found_visible = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// count all visible elements
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
obj_pos++;
|
|
// select the next sibling when it exists
|
|
} while ((tmp = tmp->getSibling(1)) != NULL);
|
|
|
|
if(found_visible == false)
|
|
{
|
|
MENU_goRoot();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Something is wrong, go to a stable state (root menu)
|
|
MENU_goRoot();
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_goInto(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_goInto"));
|
|
|
|
// check if a menu function is not active
|
|
if (actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
// check if element is a menu function
|
|
if(curMenu->getChild(cursor_obj_pos)->getChild(0) == NULL && curMenu->getChild(cursor_obj_pos)->checkType_menu() == true)
|
|
//if(curMenu->getChild(cursor_obj_pos)->checkCallback() == true && curMenu->getChild(cursor_obj_pos)->checkType_menu() == true)
|
|
{
|
|
// Menu function found
|
|
actMenu_cb_function = curMenu->getChild(cursor_obj_pos)->getCbFunction();
|
|
actMenu_id = curMenu->getChild(cursor_obj_pos)->getID();
|
|
actMenu_param = curMenu->getChild(cursor_obj_pos)->getParam();
|
|
}
|
|
else
|
|
{
|
|
if(curMenu->getChild(cursor_obj_pos)->checkType_dynParam() == true)
|
|
{
|
|
DISP_update();
|
|
}
|
|
else
|
|
{
|
|
if(curMenu->getChild(cursor_obj_pos)->getChild(0) != NULL)
|
|
{
|
|
//check if element has visible children
|
|
if(MENU_countChilds(curMenu->getChild(cursor_obj_pos)) > 0)
|
|
{
|
|
// set the curMenu pointer to a other menu element
|
|
curMenu = curMenu->getChild(cursor_obj_pos);
|
|
|
|
// new layer
|
|
window_start = 0;
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
|
|
MENU_initFirstElement();
|
|
|
|
// update the layer counter
|
|
layer++;
|
|
|
|
REG_button = 0; // reset all buttons
|
|
DISP_update();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
LCDMenuLib2_menu * LCDMenuLib2::MENU_getCurrentObj(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getCurrentObj"));
|
|
|
|
return curMenu;
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
LCDMenuLib2_menu * LCDMenuLib2::MENU_getRootObj(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getRootObj"));
|
|
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
if(curMenu->getID() != _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
tmp = curMenu;
|
|
|
|
while(true)
|
|
{
|
|
if(tmp->getID() != _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
tmp = tmp->getParent();
|
|
}
|
|
else
|
|
{
|
|
return tmp;
|
|
}
|
|
}
|
|
|
|
return tmp;
|
|
}
|
|
else
|
|
{
|
|
return curMenu;
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
LCDMenuLib2_menu * LCDMenuLib2::MENU_getDisplayedObj(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getDisplayedObj"));
|
|
|
|
LCDMenuLib2_menu *tmp;
|
|
uint8_t obj_pos = 0;
|
|
uint8_t cnt_visible = 0;
|
|
|
|
if(window_start > 0)
|
|
{
|
|
// get the current object
|
|
if((tmp = curMenu->getChild(0)) != NULL)
|
|
{
|
|
do
|
|
{
|
|
if(tmp->checkCondition())
|
|
{
|
|
if(cnt_visible == window_start)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
cnt_visible++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
obj_pos++;
|
|
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
obj_pos = 0;
|
|
}
|
|
|
|
return curMenu->getChild(obj_pos);
|
|
}
|
|
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_display(uint8_t update)
|
|
/* ******************************************************************** */
|
|
{
|
|
// update is unused because of compatibility it is not removed
|
|
LCDML_UNUSED(update);
|
|
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_display"));
|
|
|
|
//check children
|
|
|
|
bitSet(REG_update, _LCDML_REG_update_menu);
|
|
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getScroll(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getScroll"));
|
|
|
|
return window_start;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_doScroll(uint8_t state)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_doScroll"));
|
|
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
uint8_t cnt_visible = 0;
|
|
uint8_t obj_pos = 0;
|
|
uint8_t last_valid_obj_pos = 0;
|
|
bool rollover = false;
|
|
|
|
//content:
|
|
// 0 = scroll up
|
|
// 1 = scroll down
|
|
|
|
// 10 = update cursor postion
|
|
|
|
switch(state)
|
|
{
|
|
case 0: // up
|
|
|
|
obj_pos = 0;
|
|
|
|
if(cursor_pos_abs > 0)
|
|
{
|
|
if((tmp = curMenu->getChild(0)) != NULL)
|
|
{
|
|
do
|
|
{
|
|
if(obj_pos == cursor_obj_pos)
|
|
{
|
|
if(cnt_visible > 0)
|
|
{
|
|
cursor_pos_abs--;
|
|
cursor_obj_pos = last_valid_obj_pos;
|
|
//update = true;
|
|
}
|
|
else
|
|
{
|
|
// rollover is possible
|
|
rollover = true;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(tmp->checkCondition() == true)
|
|
{
|
|
cnt_visible++;
|
|
last_valid_obj_pos = obj_pos;
|
|
//update = true;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
obj_pos++;
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// rollover is possible
|
|
rollover = true;
|
|
}
|
|
|
|
if(bitRead(REG_control, _LCDML_REG_control_rollover) && rollover == true)
|
|
{
|
|
// rollover the menu
|
|
if((tmp = curMenu->getChild(0)) != NULL)
|
|
{
|
|
do
|
|
{
|
|
if(tmp->checkCondition() == true)
|
|
{
|
|
cnt_visible++;
|
|
last_valid_obj_pos = obj_pos;
|
|
//update = true;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
obj_pos++;
|
|
}
|
|
while((tmp = tmp->getSibling(1)) != NULL);
|
|
|
|
cursor_pos_abs = cnt_visible-1;
|
|
cursor_obj_pos = last_valid_obj_pos;
|
|
if(cursor_pos_abs - (window_rows-1) > 0)
|
|
{
|
|
window_start = cursor_pos_abs-(window_rows-1);
|
|
}
|
|
else
|
|
{
|
|
window_start = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
bitClear(REG_button, _LCDML_REG_button_up);
|
|
|
|
// reset the button state here or update the menu
|
|
bitSet(REG_update, _LCDML_REG_update_menu);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1: // down
|
|
|
|
obj_pos = cursor_obj_pos;
|
|
|
|
// get the next object if it exists
|
|
if((tmp = curMenu->getChild(cursor_obj_pos)) != NULL)
|
|
{
|
|
|
|
while((tmp = tmp->getSibling(1)) != NULL)
|
|
{
|
|
obj_pos++;
|
|
|
|
if(tmp->checkCondition())
|
|
{
|
|
cnt_visible++;
|
|
cursor_pos_abs++;
|
|
cursor_obj_pos = obj_pos;
|
|
//update = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
if(cnt_visible == 0)
|
|
{
|
|
rollover = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rollover = true;
|
|
}
|
|
|
|
if(bitRead(REG_control, _LCDML_REG_control_rollover) && rollover == true)
|
|
{
|
|
cursor_obj_pos = 0;
|
|
cursor_pos_abs = 0;
|
|
window_start = 0;
|
|
MENU_initFirstElement();
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// reset the button state here and update the menu
|
|
bitClear(REG_button, _LCDML_REG_button_down);
|
|
bitSet(REG_update, _LCDML_REG_update_menu);
|
|
|
|
break;
|
|
|
|
default: // all others
|
|
// do nothing
|
|
break;
|
|
}
|
|
|
|
// update window possition
|
|
// only update the window position when no the menu is not rolled over
|
|
if(rollover == false)
|
|
{
|
|
if(cursor_pos_abs - (window_rows-1) > 0 || window_start > 0)
|
|
{
|
|
switch(state)
|
|
{
|
|
case 0: // up
|
|
if(cursor_pos == 0)
|
|
{
|
|
if(window_start > 0)
|
|
{
|
|
window_start--;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
break;
|
|
|
|
case 1: // down
|
|
if(cursor_pos == (window_rows-1))
|
|
{
|
|
window_start = cursor_pos_abs - (window_rows-1);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
break;
|
|
|
|
default: // all others
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
window_start = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
// update cursor position
|
|
cursor_pos = cursor_pos_abs - window_start;
|
|
|
|
// check if the cursor position is updated
|
|
if(actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
bitSet(REG_update, _LCDML_REG_update_cursor);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_enRollover(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_enRollover"));
|
|
|
|
bitSet(REG_control, _LCDML_REG_control_rollover);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_disRollover(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_disRollover"));
|
|
|
|
bitClear(REG_control, _LCDML_REG_control_rollover);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getLayer(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getLayer"));
|
|
|
|
return layer;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getCursorPos(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getCursorPos"));
|
|
|
|
return (cursor_pos); //return the current cursor position
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getCursorPosAbs(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getCursorPosAbs"));
|
|
|
|
return cursor_pos_abs; //return the current cursor position
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_countChilds(LCDMenuLib2_menu *menu, uint8_t all)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_countChilds"));
|
|
|
|
//declaration
|
|
uint8_t j = 0;
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
//check if element has children
|
|
if(menu != NULL)
|
|
{
|
|
if ((tmp = menu->getChild(0)) != NULL)
|
|
{
|
|
do
|
|
{
|
|
if (tmp->checkCondition() || all == true)
|
|
{
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
} while ((tmp = tmp->getSibling(1)) != NULL);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
return j;
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getChilds(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getChilds"));
|
|
|
|
return MENU_countChilds(curMenu);
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getParentID(uint8_t p_layer)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getParentID"));
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
if((tmp = curMenu->getChild(0)) != NULL)
|
|
{
|
|
for(uint8_t i=0; i<p_layer; i++)
|
|
{
|
|
if(tmp->getParent()->getID() != _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
tmp = tmp->getParent();
|
|
}
|
|
else
|
|
{
|
|
return _LCDML_FIRST_ELEMENT_ID;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return tmp->getParent()->getID();
|
|
}
|
|
else
|
|
{
|
|
return _LCDML_FIRST_ELEMENT_ID;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_setDynContent(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_setDynContent"));
|
|
|
|
bitSet(REG_control, _LCDML_REG_control_dynMenuDisplayed);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_checkDynContent(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_checkDynContent"));
|
|
|
|
if(bitRead(REG_control, _LCDML_REG_control_dynMenuDisplayed))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_enScroll(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_enScroll"));
|
|
|
|
bitClear(REG_special, _LCDML_REG_special_disable_scroll);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_disScroll(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_disScroll"));
|
|
|
|
if(actMenu_id == _LCDML_NO_FUNC)
|
|
{
|
|
bitSet(REG_special, _LCDML_REG_special_disable_scroll);
|
|
}
|
|
else
|
|
{
|
|
bitClear(REG_special, _LCDML_REG_special_disable_scroll);
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::MENU_getScrollDisableStatus(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getScrollDisableStatus"));
|
|
|
|
return bitRead(REG_special, _LCDML_REG_special_disable_scroll);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getLastActiveFunctionID(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getLastActiveFunctionID"));
|
|
|
|
return actMenu_lastFuncID;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getLastCursorPositionID(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getLastCursorPositionID"));
|
|
|
|
return actMenu_lastCursorPositionID;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::MENU_getElementIDFromCursorPos(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_getElementIDFromCursorPosition"));
|
|
|
|
if(curMenu->getChild(cursor_obj_pos) != NULL)
|
|
{
|
|
return curMenu->getChild(cursor_obj_pos)->getID();
|
|
}
|
|
else
|
|
{
|
|
return _LCDML_FIRST_ELEMENT_ID;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_setDynFunctionContentUpdate(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_setMenuContentUpdate2"));
|
|
|
|
bitSet(REG_update, _LCDML_REG_update_update_dyn_content);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_clearDynFunctionContentUpdate(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_MENU, F("LCDML.MENU_clearMenuContentUpdate2"));
|
|
|
|
bitClear(REG_update, _LCDML_REG_update_update_dyn_content);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::MENU_allCondetionRefresh(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.MENU_allCondetionRefresh"));
|
|
|
|
// define local variables
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
// set object
|
|
tmp = MENU_getRootObj();
|
|
|
|
// Check if this Menu have childs
|
|
if((tmp = tmp->getChild(0)) != NULL)
|
|
{
|
|
// This loop runs through the menu structure and stops after checking the last element
|
|
while(true)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
|
|
// ***
|
|
// check loop end condetions
|
|
// ***
|
|
|
|
// check if something is found:
|
|
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("check function"));
|
|
|
|
tmp->updateCondetion();
|
|
|
|
if(last_element_id == tmp->getID())
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("nothing found: endpoint (C) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
|
|
break;
|
|
}
|
|
|
|
// ***
|
|
// set the next item
|
|
// ***
|
|
|
|
// check childs for childs
|
|
if(tmp->getChild(0) != NULL)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("gointo an element"));
|
|
|
|
// -- GO INTO --
|
|
|
|
// set next child for check
|
|
tmp = tmp->getChild(0);
|
|
}
|
|
else
|
|
{
|
|
if(tmp->getSibling(1) != NULL)
|
|
{
|
|
// set next sibling for check
|
|
tmp = tmp->getSibling(1);
|
|
}
|
|
else
|
|
{
|
|
// check parent element
|
|
if(tmp->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("end point: (A) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
}
|
|
else
|
|
{
|
|
do
|
|
{
|
|
// set next parent for check
|
|
tmp = tmp->getParent();
|
|
|
|
// -- GO Back --
|
|
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("goback to parent element"));
|
|
|
|
// check if the parent element have siblings
|
|
if(tmp->getSibling(1) != NULL)
|
|
{
|
|
// set next sibling
|
|
tmp = tmp->getSibling(1);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(tmp->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// continue
|
|
}
|
|
}
|
|
} while (true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* DISP methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::DISP_menuUpdate(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_DISP, F("LCDML.DISP_menuUpdate"));
|
|
|
|
bitSet(REG_update, _LCDML_REG_update_menu);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::DISP_clear(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_DISP, F("LCDML.DISP_clear"));
|
|
|
|
callback_contentClear();
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::DISP_checkMenuUpdate(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_DISP, F("LCDML.DISP_checkMenuUpdate"));
|
|
|
|
if (bitRead(REG_update, _LCDML_REG_update_menu))
|
|
{
|
|
bitClear(REG_update, _LCDML_REG_update_menu);
|
|
bitClear(REG_control, _LCDML_REG_control_dynMenuDisplayed);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::DISP_checkMenuCursorUpdate(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_DISP, F("LCDML.DISP_checkMenuCursorUpdate"));
|
|
|
|
if(bitRead(REG_update, _LCDML_REG_update_cursor))
|
|
{
|
|
bitClear(REG_update, _LCDML_REG_update_cursor);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::DISP_update(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_DISP, F("LCDML.DISP_update"));
|
|
|
|
MENU_doScroll(10);
|
|
MENU_display();
|
|
|
|
bitSet(REG_update, _LCDML_REG_update_menu);
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* FUNC methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::FUNC_getID(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_getID"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
return actMenu_id;
|
|
}
|
|
else
|
|
{
|
|
if(curMenu->getChild(cursor_obj_pos) != NULL)
|
|
{
|
|
if(curMenu->getChild(cursor_obj_pos)->checkType_dynParam() == true)
|
|
{
|
|
return curMenu->getChild(cursor_obj_pos)->getID();
|
|
}
|
|
else
|
|
{
|
|
return _LCDML_NO_FUNC;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return _LCDML_NO_FUNC;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_setLoopInterval(unsigned long p_t)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setLoopInterval"));
|
|
|
|
actMenu_default_time = p_t;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_call(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_call"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
if(jT_paramOld > 0)
|
|
{
|
|
actMenu_cb_function(jT_paramOld);
|
|
}
|
|
else if(jT_param > 0)
|
|
{
|
|
actMenu_cb_function(jT_param);
|
|
}
|
|
else
|
|
{
|
|
actMenu_cb_function(actMenu_param);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::FUNC_setup(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setup - check"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// function active
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_setup) == 0)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setup - check: true"));
|
|
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_setup); // run setup
|
|
DISP_clear();
|
|
REG_button = 0;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setup - check: false"));
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_setup); // run setup
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::FUNC_loop(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_loop - check"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_end) == false)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_loop - check: true"));
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_loop - check: false"));
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::FUNC_close(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_close - check"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_end) == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_close - check: true"));
|
|
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_close_active);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_close - check: false"));
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_goBackToMenu(uint8_t p_goBackCnt)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_goBackToMenu"));
|
|
|
|
// special handling
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_goBackToFuncID) == true)
|
|
{
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_goBackToFuncID);
|
|
OTHER_jumpToID(actMenu_lastFuncID);
|
|
}
|
|
|
|
// special handling
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_setCursorToID) == true)
|
|
{
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_setCursorToID);
|
|
OTHER_setCursorToID(actMenu_lastCursorPositionID);
|
|
}
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
goBackCnt = p_goBackCnt;
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_end);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_disableScreensaver(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_disableScreensaver"));
|
|
|
|
bitSet(REG_special, _LCDML_REG_special_disable_screensaver);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_setGBAToLastCursorPos(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setGBAToLastCursorPos"));
|
|
|
|
// delte other configurations
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_goBackToFuncID);
|
|
|
|
// set new configuration
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_setCursorToID);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_setGBAToLastFunc(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setGBAToLastFunc"));
|
|
|
|
// delete other configurations
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_setCursorToID);
|
|
|
|
// set new configuration
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_goBackToFuncID);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_setGBA(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setGBA"));
|
|
|
|
// decide which option is better (to function or to last cursor option)
|
|
if(bitRead(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu) == true)
|
|
{
|
|
FUNC_setGBAToLastCursorPos();
|
|
}
|
|
else
|
|
{
|
|
FUNC_setGBAToLastFunc();
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::FUNC_setCEMask(unsigned long p_mask)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_FUNC, F("LCDML.FUNC_setCEMask"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
actMenu_ce_mask = p_mask;
|
|
}
|
|
else
|
|
{
|
|
actMenu_ce_mask = 0xFFFFFFFFFFFFFFFF;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* BT and custom event methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::BT_setup(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_BT, F("LCDML.BT_setup"));
|
|
|
|
// check if the button initialisation was done
|
|
if(bitRead(REG_control, _LCDML_REG_control_bt_init_setup) == false)
|
|
{
|
|
bitSet(REG_control, _LCDML_REG_control_bt_init_setup);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::CE_setup(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_BT, F("LCDML.CE_setup"));
|
|
|
|
// check if the button initialisation was done
|
|
if(bitRead(REG_control, _LCDML_REG_control_ce_init_setup) == false)
|
|
{
|
|
bitSet(REG_control, _LCDML_REG_control_ce_init_setup);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::CE_setOnChangeCbFunction(uint8_t p_event, LCDML_FuncPtr_pu8 p_function)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_CE, F("LCDML.CE_setOnChangeCbFunction"));
|
|
|
|
if(p_event < _LCDML_CE_cb_function_cnt)
|
|
{
|
|
ce_cb[p_event] = p_function;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::CE_clearOnChangeCbFunction(uint8_t p_event)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_CE, F("LCDML.CE_clearOnChangeCbFunction"));
|
|
|
|
if(p_event < _LCDML_CE_cb_function_cnt)
|
|
{
|
|
ce_cb[p_event] = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::REG_set(uint8_t p_reg, uint8_t p_val)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_print(LCDML_DBG_function_name_BT, F("LCDML.REG_set("));
|
|
DBG_print(LCDML_DBG_function_name_BT, p_reg);
|
|
DBG_println(LCDML_DBG_function_name_BT, F(")"));
|
|
|
|
switch(p_reg)
|
|
{
|
|
case _LCDML_REG_CTRL__button:
|
|
bitSet(REG_button, p_val);
|
|
break;
|
|
case _LCDML_REG_CTRL__events:
|
|
bitSet(REG_custom_event, p_val);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::REG_reset(uint8_t p_reg, uint8_t p_val)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_print(LCDML_DBG_function_name_BT, F("LCDML.REG_reset("));
|
|
DBG_print(LCDML_DBG_function_name_BT, p_reg);
|
|
DBG_println(LCDML_DBG_function_name_BT, F(")"));
|
|
|
|
switch(p_reg)
|
|
{
|
|
case _LCDML_REG_CTRL__button:
|
|
bitClear(REG_button, p_val);
|
|
break;
|
|
case _LCDML_REG_CTRL__events:
|
|
bitClear(REG_custom_event, p_val);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::REG_resetAll(uint8_t p_reg)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_BT, F("LCDML.REG_resetAll"));
|
|
|
|
switch(p_reg)
|
|
{
|
|
case _LCDML_REG_CTRL__button:
|
|
REG_button = 0;
|
|
break;
|
|
case _LCDML_REG_CTRL__events:
|
|
REG_custom_event = 0;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::REG_check(uint8_t p_reg, uint8_t p_val)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_print(LCDML_DBG_function_name_BT, F("LCDML.REG_check("));
|
|
DBG_print(LCDML_DBG_function_name_BT, p_reg);
|
|
DBG_println(LCDML_DBG_function_name_BT, F(")"));
|
|
|
|
switch(p_reg)
|
|
{
|
|
case _LCDML_REG_CTRL__button:
|
|
return bitRead(REG_button, p_val);
|
|
break;
|
|
case _LCDML_REG_CTRL__events:
|
|
return bitRead(REG_custom_event, p_val);
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::REG_checkAny(uint8_t p_reg)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_BT, F("LCDML.REG_checkAny"));
|
|
|
|
switch(p_reg)
|
|
{
|
|
case _LCDML_REG_CTRL__button:
|
|
return (bool)(REG_button > 0);
|
|
break;
|
|
case _LCDML_REG_CTRL__events:
|
|
return (bool)(REG_custom_event > 0);
|
|
break;
|
|
|
|
default:
|
|
return false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* TIMER methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::TIMER_msReset(unsigned long &p_var)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_TIMER, F("LCDML.TIMER_msReset"));
|
|
|
|
p_var = millis();
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::TIMER_ms(unsigned long &p_var, unsigned long p_t)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_TIMER, F("LCDML.TIMER_ms"));
|
|
|
|
if((millis() - p_var) >= p_t)
|
|
{
|
|
p_var = millis();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::TIMER_usReset(unsigned long &p_var)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_TIMER, F("LCDML.TIMER_usReset"));
|
|
|
|
p_var = micros();
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
bool LCDMenuLib2::TIMER_us(unsigned long &p_var, unsigned long p_t)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_TIMER, F("LCDML.TIMER_us"));
|
|
|
|
if((micros() - p_var) >= p_t)
|
|
{
|
|
p_var = micros();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* OTHER methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::OTHER_jumpToFunc(LCDML_FuncPtr_pu8 p_search, uint8_t p_para)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc"));
|
|
|
|
if(p_search == NULL)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc - no function selected"));
|
|
}
|
|
else
|
|
{
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active) == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc - is still activ"));
|
|
}
|
|
else
|
|
{
|
|
// check if this menu function is active - do nothing
|
|
if(p_search == actMenu_cb_function)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc - function is still running"));
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc - start"));
|
|
|
|
bitSet(REG_special, _LCDML_REG_special_OTHER_function_active);
|
|
bitClear(REG_special, _LCDML_REG_special_setCursorTo);
|
|
|
|
// Save last active Menu ID
|
|
actMenu_lastFuncID = actMenu_id;
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = jT_param;
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
}
|
|
else
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = 0;
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
|
|
// Save last cursor position
|
|
actMenu_lastCursorPositionID = actMenu_cursorPositionID;
|
|
actMenu_cursorPositionID = curMenu->getChild(MENU_getCursorPosAbs())->getID();
|
|
}
|
|
|
|
// enable jump to Func
|
|
jT_id = 0;
|
|
jT_param = p_para;
|
|
jT_function = p_search;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::OTHER_jumpToID(uint8_t p_id, uint8_t p_para)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToID"));
|
|
|
|
if(p_id != _LCDML_NO_FUNC && p_id <= last_element_id)
|
|
{
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active) == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToID - is still activ"));
|
|
}
|
|
else
|
|
{
|
|
// check if this menu function is active - do nothing
|
|
if(p_id == actMenu_id)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToFunc - function is still running"));
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToID - start"));
|
|
|
|
bitSet(REG_special, _LCDML_REG_special_OTHER_function_active);
|
|
bitClear(REG_special, _LCDML_REG_special_setCursorTo);
|
|
|
|
// Save last active Menu ID
|
|
actMenu_lastFuncID = actMenu_id;
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = jT_param;
|
|
bitClear(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
}
|
|
else
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = 0;
|
|
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
|
|
// Save last cursor position
|
|
actMenu_lastCursorPositionID = actMenu_cursorPositionID;
|
|
actMenu_cursorPositionID = curMenu->getChild(MENU_getCursorPosAbs())->getID();
|
|
}
|
|
|
|
// enable jump to ID
|
|
jT_id = p_id;
|
|
jT_param = p_para;
|
|
jT_function = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToID - stop - ID range is wrong"));
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::OTHER_setCursorToFunc(LCDML_FuncPtr_pu8 p_search)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToFunc"));
|
|
|
|
if(p_search == NULL)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToFunc - no function selected"));
|
|
}
|
|
else
|
|
{
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active) == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToFunc - is still activ"));
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToFunc - start"));
|
|
|
|
// enable jump to Func
|
|
bitSet(REG_special, _LCDML_REG_special_OTHER_function_active);
|
|
bitSet(REG_special, _LCDML_REG_special_setCursorTo);
|
|
jT_id = 0;
|
|
|
|
// Save last active Menu ID
|
|
actMenu_lastFuncID = actMenu_id;
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = jT_param;
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
}
|
|
else
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = 0;
|
|
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
|
|
// Save last cursor position
|
|
actMenu_lastCursorPositionID = actMenu_cursorPositionID;
|
|
actMenu_cursorPositionID = curMenu->getChild(MENU_getCursorPosAbs())->getID();
|
|
}
|
|
|
|
jT_param = 0;
|
|
jT_function = p_search;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::OTHER_setCursorToID(uint8_t p_id)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToID"));
|
|
|
|
if(p_id != _LCDML_NO_FUNC && p_id <= last_element_id)
|
|
{
|
|
if(bitRead(REG_special, _LCDML_REG_special_OTHER_function_active) == true)
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToID - is still activ"));
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_setCursorToID - start"));
|
|
|
|
// enable jump to Func
|
|
bitSet(REG_special, _LCDML_REG_special_OTHER_function_active);
|
|
bitSet(REG_special, _LCDML_REG_special_setCursorTo);
|
|
jT_id = p_id;
|
|
|
|
// Save last active Menu ID
|
|
actMenu_lastFuncID = actMenu_id;
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
// handle paramerts
|
|
jT_paramOld = jT_param;
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
}
|
|
else
|
|
{
|
|
// handle parameters
|
|
jT_paramOld = 0;
|
|
|
|
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_called_from_menu);
|
|
|
|
// save last cursor position
|
|
actMenu_lastCursorPositionID = actMenu_cursorPositionID;
|
|
actMenu_cursorPositionID = curMenu->getChild(MENU_getCursorPosAbs())->getID();
|
|
}
|
|
|
|
jT_param = 0;
|
|
jT_function = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_jumpToID - stop - ID range is wrong"));
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
uint8_t LCDMenuLib2::OTHER_getIDFromFunction(LCDML_FuncPtr_pu8 p_function_name)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_getIDFromFunction"));
|
|
|
|
// define local variables
|
|
LCDMenuLib2_menu *tmp;
|
|
|
|
// set object
|
|
tmp = MENU_getRootObj();
|
|
|
|
// Check if this Menu have childs
|
|
if((tmp = tmp->getChild(0)) != NULL)
|
|
{
|
|
// This loop runs through the menu structure and stops after checking the last element
|
|
while(true)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
|
|
// ***
|
|
// check loop end condetions
|
|
// ***
|
|
|
|
// check if something is found:
|
|
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("check function"));
|
|
|
|
if(tmp->getCbFunction() == p_function_name)
|
|
{
|
|
// something found
|
|
return tmp->getID();
|
|
}
|
|
|
|
|
|
if(last_element_id == tmp->getID())
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("nothing found: endpoint (C) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
|
|
break;
|
|
}
|
|
|
|
// ***
|
|
// set the next item
|
|
// ***
|
|
|
|
// check childs for childs
|
|
if(tmp->getChild(0) != NULL)
|
|
{
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("gointo an element"));
|
|
|
|
// -- GO INTO --
|
|
|
|
// set next child for check
|
|
tmp = tmp->getChild(0);
|
|
}
|
|
else
|
|
{
|
|
if(tmp->getSibling(1) != NULL)
|
|
{
|
|
// set next sibling for check
|
|
tmp = tmp->getSibling(1);
|
|
}
|
|
else
|
|
{
|
|
// check parent element
|
|
if(tmp->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
// Debug information
|
|
DBG_print(LCDML_DBG_function_name_OTHER, F("end point: (A) / ID: "));
|
|
DBG_println(LCDML_DBG_function_name_OTHER, tmp->getID());
|
|
}
|
|
else
|
|
{
|
|
do
|
|
{
|
|
// set next parent for check
|
|
tmp = tmp->getParent();
|
|
|
|
// -- GO Back --
|
|
|
|
// Debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("goback to parent element"));
|
|
|
|
// check if the parent element have siblings
|
|
if(tmp->getSibling(1) != NULL)
|
|
{
|
|
// set next sibling
|
|
tmp = tmp->getSibling(1);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(tmp->getParent()->getID() == _LCDML_FIRST_ELEMENT_ID)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// continue
|
|
}
|
|
}
|
|
} while (true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// nothing found
|
|
return _LCDML_NO_FUNC;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::OTHER_updateFunc(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_OTHER, F("LCDML.OTHER_updateFunc"));
|
|
|
|
if(actMenu_id != _LCDML_NO_FUNC)
|
|
{
|
|
bitSet(REG_update, _LCDML_REG_update_menu_function_content);
|
|
}
|
|
else
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
/* SCREEN methods */
|
|
/* ******************************************************************** */
|
|
/* ******************************************************************** */
|
|
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::SCREEN_enable(LCDML_FuncPtr_pu8 function, unsigned long p_t)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_SCREEN, F("LCDML.SCREEN_enable"));
|
|
|
|
if(function != NULL)
|
|
{
|
|
cb_screensaver = function;
|
|
screensaver_default_time = p_t;
|
|
}
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::SCREEN_disable(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_SCREEN, F("LCDML.SCREEN_disable"));
|
|
|
|
cb_screensaver = NULL;
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::SCREEN_resetTimer(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_SCREEN, F("LCDML.SCREEN_resetTimer"));
|
|
|
|
TIMER_msReset(screensaver_timer);
|
|
}
|
|
|
|
/* ******************************************************************** */
|
|
void LCDMenuLib2::SCREEN_start(void)
|
|
/* ******************************************************************** */
|
|
{
|
|
// debug information
|
|
DBG_println(LCDML_DBG_function_name_SCREEN, F("LCDML.SCREEN_start"));
|
|
|
|
screensaver_timer = millis() + 1000;
|
|
} |