Move encoder stack to separate class MenuStack. Add menu record to MenuStack.

It was needed to add menuFunc_t menu to stack, as in some places in menu, it is impossible to hardcode parent menu. Example: lcd_babystep_z can be invoked both from main_menu() and settings_menu() depending on printer status.
This commit is contained in:
Marek Bel 2018-03-06 19:47:27 +01:00
parent e906405662
commit 235803bc2a
3 changed files with 97 additions and 25 deletions

29
Firmware/MenuStack.cpp Normal file
View File

@ -0,0 +1,29 @@
/**
* @file
* @author Marek Bel
*/
#include "MenuStack.h"
/**
* @brief Push menu on stack
* @param menu
* @param position selected position in menu being pushed
*/
void MenuStack::push(menuFunc_t menu, uint8_t position)
{
if (m_index >= max_depth) return;
m_stack[m_index].menu = menu;
m_stack[m_index].position = position;
++m_index;
}
/**
* @brief Pop menu from stack
* @return Record containing menu function pointer and previously selected line number
*/
MenuStack::Record MenuStack::pop()
{
if (m_index != 0) m_index--;
return m_stack[m_index];
}

33
Firmware/MenuStack.h Normal file
View File

@ -0,0 +1,33 @@
/**
* @file
* @author Marek Bel
*/
#ifndef MENUSTACK_H
#define MENUSTACK_H
#include <stdint.h>
/** Pointer to function implementing menu.*/
typedef void (*menuFunc_t)();
/**
* @brief Stack implementation for navigating menu structure
*/
class MenuStack
{
public:
struct Record
{
menuFunc_t menu;
uint8_t position;
};
MenuStack():m_stack(),m_index(0) {}
void push(menuFunc_t menu, uint8_t position);
Record pop();
private:
static const int max_depth = 3;
Record m_stack[max_depth];
uint8_t m_index;
};
#endif /* FIRMWARE_MENUSTACK_H_ */

View File

@ -1,6 +1,7 @@
#include "temperature.h"
#include "ultralcd.h"
#ifdef ULTRA_LCD
#include "MenuStack.h"
#include "Marlin.h"
#include "language.h"
#include "cardreader.h"
@ -39,7 +40,7 @@ extern bool fsensor_enabled;
#endif //PAT9125
//Function pointer to menu functions.
typedef void (*menuFunc_t)();
static void lcd_sd_updir();
@ -223,7 +224,7 @@ static void lcd_delta_calibrate_menu();
static void lcd_quick_feedback();//Cause an LCD refresh, and give the user visual or audible feedback that something has happened
/* Different types of actions that can be used in menu items. */
static void menu_action_back(menuFunc_t data);
static void menu_action_back(menuFunc_t data = 0);
#define menu_action_back_RAM menu_action_back
static void menu_action_submenu(menuFunc_t data);
static void menu_action_gcode(const char* pgcode);
@ -339,6 +340,22 @@ uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD nee
// float raw_Ki, raw_Kd;
#endif
/**
* @brief Go to menu
*
* This function should not be used directly, use
* menu_action_back and menu_action_submenu instead.
*
* @param menu target menu
* @param encoder position in target menu
* @param feedback
* * true sound feedback (click)
* * false no feedback
* @param reset_menu_state
* * true reset menu state global union
* * false do not reset menu state global union
*/
static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder = 0, const bool feedback = true, bool reset_menu_state = true)
{
asm("cli");
@ -6647,32 +6664,25 @@ static void lcd_quick_feedback()
lcd_implementation_quick_feedback();
}
#define ENC_STACK_SIZE 3
static uint8_t enc_stack[ENC_STACK_SIZE]; //encoder is originaly uint16, but for menu
static uint8_t enc_stack_cnt = 0;
static void lcd_push_encoder(void)
{
if (enc_stack_cnt >= ENC_STACK_SIZE) return;
enc_stack[enc_stack_cnt] = encoderPosition;
enc_stack_cnt++;
}
static void lcd_pop_encoder(void)
{
if (enc_stack_cnt == 0) return;
enc_stack_cnt--;
encoderPosition = enc_stack[enc_stack_cnt];
}
/** Menu action functions **/
static void menu_action_back(menuFunc_t data) {
lcd_goto_menu(data);
lcd_pop_encoder();
static MenuStack menuStack;
/**
* @brief Go up in menu structure
* @param data unused parameter
*/
static void menu_action_back(menuFunc_t data)
{
MenuStack::Record record = menuStack.pop();
lcd_goto_menu(record.menu);
encoderPosition = record.position;
}
/**
* @brief Go deeper into menu structure
* @param data nested menu
*/
static void menu_action_submenu(menuFunc_t data) {
lcd_push_encoder();
menuStack.push(currentMenu, encoderPosition);
lcd_goto_menu(data);
}
static void menu_action_gcode(const char* pgcode) {