commit
f487691070
29
Firmware/MenuStack.cpp
Normal file
29
Firmware/MenuStack.cpp
Normal 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];
|
||||
}
|
34
Firmware/MenuStack.h
Normal file
34
Firmware/MenuStack.h
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @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();
|
||||
void reset(){m_index = 0;}
|
||||
private:
|
||||
static const int max_depth = 4;
|
||||
Record m_stack[max_depth];
|
||||
uint8_t m_index;
|
||||
};
|
||||
|
||||
#endif /* FIRMWARE_MENUSTACK_H_ */
|
@ -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();
|
||||
|
||||
@ -117,7 +118,7 @@ union Data
|
||||
byte b[2];
|
||||
int value;
|
||||
};
|
||||
|
||||
static MenuStack menuStack;
|
||||
int8_t ReInitLCD = 0;
|
||||
|
||||
int8_t SDscrool = 0;
|
||||
@ -235,7 +236,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);
|
||||
@ -332,14 +333,12 @@ volatile uint8_t slow_buttons;//Contains the bits of the currently pressed butto
|
||||
uint8_t currentMenuViewOffset; /* scroll offset in the current menu */
|
||||
uint8_t lastEncoderBits;
|
||||
uint16_t encoderPosition;
|
||||
uint16_t savedEncoderPosition;
|
||||
#if (SDCARDDETECT > 0)
|
||||
bool lcd_oldcardstatus;
|
||||
#endif
|
||||
#endif //ULTIPANEL
|
||||
|
||||
menuFunc_t currentMenu = lcd_status_screen; /* function pointer to the currently active menu */
|
||||
menuFunc_t savedMenu;
|
||||
uint32_t lcd_next_update_millis;
|
||||
uint8_t lcd_status_update_delay;
|
||||
bool ignore_click = false;
|
||||
@ -351,6 +350,25 @@ uint8_t lcdDrawUpdate = 2; /* Set to none-zero when the LCD nee
|
||||
// float raw_Ki, raw_Kd;
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Go to menu
|
||||
*
|
||||
* In MENU_ITEM(submenu,... ) use MENU_ITEM(back,...) or
|
||||
* menu_action_back() and menu_action_submenu() instead, otherwise menuStack will be broken.
|
||||
*
|
||||
* It is acceptable to call lcd_goto_menu(menu) directly from MENU_ITEM(function,...), if destination menu
|
||||
* is the same, from which function was called.
|
||||
*
|
||||
* @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");
|
||||
@ -522,8 +540,8 @@ static void lcd_status_screen()
|
||||
|
||||
if (current_click && (lcd_commands_type != LCD_COMMAND_STOP_PRINT)) //click is aborted unless stop print finishes
|
||||
{
|
||||
|
||||
lcd_goto_menu(lcd_main_menu);
|
||||
menuStack.reset(); //redundant, as already done in lcd_return_to_status(), just to be sure
|
||||
menu_action_submenu(lcd_main_menu);
|
||||
lcd_implementation_init( // to maybe revive the LCD if static electricity killed it.
|
||||
#if defined(LCD_PROGRESS_BAR) && defined(SDSUPPORT)
|
||||
currentMenu == lcd_status_screen
|
||||
@ -967,7 +985,8 @@ void lcd_commands()
|
||||
{
|
||||
|
||||
lcd_implementation_clear();
|
||||
lcd_goto_menu(lcd_babystep_z, 0, false);
|
||||
menuStack.reset();
|
||||
menu_action_submenu(lcd_babystep_z);
|
||||
enquecommand_P(PSTR("G1 X60.0 E9.0 F1000.0")); //intro line
|
||||
enquecommand_P(PSTR("G1 X100.0 E12.5 F1000.0")); //intro line
|
||||
enquecommand_P(PSTR("G92 E0.0"));
|
||||
@ -1377,6 +1396,7 @@ static void lcd_return_to_status() {
|
||||
);
|
||||
|
||||
lcd_goto_menu(lcd_status_screen, 0, false);
|
||||
menuStack.reset();
|
||||
}
|
||||
|
||||
|
||||
@ -1529,7 +1549,7 @@ static void lcd_menu_extruder_info()
|
||||
lcd.print(itostr3(pat9125_b));
|
||||
|
||||
// Display LASER shutter time from Filament sensor
|
||||
/* Shutter register is an index of LASER shutter time. It is automatically controlled by the chip’s internal
|
||||
/* Shutter register is an index of LASER shutter time. It is automatically controlled by the chip's internal
|
||||
auto-exposure algorithm. When the chip is tracking on a good reflection surface, the Shutter is small.
|
||||
When the chip is tracking on a poor reflection surface, the Shutter is large. Value ranges from 0 to
|
||||
46. */
|
||||
@ -1629,9 +1649,7 @@ static void lcd_menu_fails_stats()
|
||||
fprintf_P(lcdout, PSTR(ESC_H(0,0)"Last print failures"ESC_H(1,1)"Filam. runouts %-3d"ESC_H(0,2)"Total failures"ESC_H(1,3)"Filam. runouts %-3d"), filamentLast, filamentTotal);
|
||||
if (lcd_clicked())
|
||||
{
|
||||
lcd_quick_feedback();
|
||||
//lcd_return_to_status();
|
||||
lcd_goto_menu(lcd_main_menu, 8); //TODO: Remove hard coded encoder value.
|
||||
menu_action_back();
|
||||
}
|
||||
}
|
||||
#endif //TMC2130
|
||||
@ -1814,13 +1832,13 @@ static void lcd_support_menu()
|
||||
void lcd_set_fan_check() {
|
||||
fans_check_enabled = !fans_check_enabled;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_FAN_CHECK_ENABLED, fans_check_enabled);
|
||||
lcd_goto_menu(lcd_settings_menu, 8);
|
||||
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
}
|
||||
|
||||
void lcd_set_filament_autoload() {
|
||||
filament_autoload_enabled = !filament_autoload_enabled;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_FSENS_AUTOLOAD_ENABLED, filament_autoload_enabled);
|
||||
lcd_goto_menu(lcd_settings_menu, 8);
|
||||
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
}
|
||||
|
||||
void lcd_unLoadFilament()
|
||||
@ -2196,7 +2214,7 @@ static void _lcd_move(const char *name, int axis, int min, int max) {
|
||||
}
|
||||
}
|
||||
if (lcdDrawUpdate) lcd_implementation_drawedit(name, ftostr31(current_position[axis]));
|
||||
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis); {
|
||||
if (LCD_CLICKED) menu_action_back(); {
|
||||
}
|
||||
}
|
||||
|
||||
@ -2218,7 +2236,7 @@ static void lcd_move_e()
|
||||
{
|
||||
lcd_implementation_drawedit(PSTR("Extruder"), ftostr31(current_position[E_AXIS]));
|
||||
}
|
||||
if (LCD_CLICKED) lcd_goto_menu(lcd_move_menu_axis);
|
||||
if (LCD_CLICKED) menu_action_back();
|
||||
}
|
||||
else {
|
||||
lcd_implementation_clear();
|
||||
@ -2370,7 +2388,7 @@ static void _lcd_babystep(int axis, const char *msg)
|
||||
(axis == 0) ? EEPROM_BABYSTEP_X : ((axis == 1) ? EEPROM_BABYSTEP_Y : EEPROM_BABYSTEP_Z),
|
||||
&menuData.babyStep.babystepMem[axis]);
|
||||
}
|
||||
if (LCD_CLICKED) lcd_goto_menu(lcd_main_menu);
|
||||
if (LCD_CLICKED) menu_action_back();
|
||||
}
|
||||
|
||||
static void lcd_babystep_x() {
|
||||
@ -2385,6 +2403,14 @@ static void lcd_babystep_z() {
|
||||
|
||||
static void lcd_adjust_bed();
|
||||
|
||||
/**
|
||||
* @brief adjust bed reset menu item function
|
||||
*
|
||||
* To be used as MENU_ITEM(function,...) inside lcd_adjust_bed submenu. In such case lcd_goto_menu usage
|
||||
* is correct and doesn't break menuStack.
|
||||
* Because we did not leave the menu, the menuData did not reset.
|
||||
* Force refresh of the bed leveling data.
|
||||
*/
|
||||
static void lcd_adjust_bed_reset()
|
||||
{
|
||||
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_VALID, 1);
|
||||
@ -2392,9 +2418,7 @@ static void lcd_adjust_bed_reset()
|
||||
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_RIGHT, 0);
|
||||
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_FRONT, 0);
|
||||
eeprom_update_byte((unsigned char*)EEPROM_BED_CORRECTION_REAR , 0);
|
||||
lcd_goto_menu(lcd_adjust_bed, 0, false);
|
||||
// Because we did not leave the menu, the menuData did not reset.
|
||||
// Force refresh of the bed leveling data.
|
||||
lcd_goto_menu(lcd_adjust_bed, 0, false); //doesn't break menuStack
|
||||
menuData.adjustBed.status = 0;
|
||||
}
|
||||
|
||||
@ -3018,7 +3042,7 @@ static void lcd_show_end_stops() {
|
||||
|
||||
static void menu_show_end_stops() {
|
||||
lcd_show_end_stops();
|
||||
if (LCD_CLICKED) lcd_goto_menu(lcd_calibration_menu);
|
||||
if (LCD_CLICKED) lcd_goto_menu(lcd_calibration_menu); //doesn't break menuStack
|
||||
}
|
||||
|
||||
// Lets the user move the Z carriage up to the end stoppers.
|
||||
@ -3406,7 +3430,7 @@ static void lcd_sort_type_set() {
|
||||
}
|
||||
eeprom_update_byte((unsigned char *)EEPROM_SD_SORT, sdSort);
|
||||
presort_flag = true;
|
||||
lcd_goto_menu(lcd_settings_menu, 8);
|
||||
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
}
|
||||
#endif //SDCARD_SORT_ALPHA
|
||||
|
||||
@ -3530,8 +3554,8 @@ static void lcd_fsensor_state_set()
|
||||
lcd_fsensor_fail();
|
||||
}
|
||||
}
|
||||
if (IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) lcd_goto_menu(lcd_tune_menu, 7);
|
||||
else lcd_goto_menu(lcd_settings_menu, 7);
|
||||
if (IS_SD_PRINTING || is_usb_printing || (lcd_commands_type == LCD_COMMAND_V2_CAL)) lcd_goto_menu(lcd_tune_menu);
|
||||
else lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
|
||||
}
|
||||
#endif //PAT9125
|
||||
@ -3596,16 +3620,18 @@ void lcd_temp_calibration_set() {
|
||||
temp_cal_active = !temp_cal_active;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_TEMP_CAL_ACTIVE, temp_cal_active);
|
||||
digipot_init();
|
||||
lcd_goto_menu(lcd_settings_menu, 10);
|
||||
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
}
|
||||
|
||||
#ifdef HAS_SECOND_SERIAL_PORT
|
||||
void lcd_second_serial_set() {
|
||||
if(selectedSerialPort == 1) selectedSerialPort = 0;
|
||||
else selectedSerialPort = 1;
|
||||
eeprom_update_byte((unsigned char *)EEPROM_SECOND_SERIAL_ACTIVE, selectedSerialPort);
|
||||
MYSERIAL.begin(BAUDRATE);
|
||||
lcd_goto_menu(lcd_settings_menu, 11);
|
||||
lcd_goto_menu(lcd_settings_menu);//doesn't break menuStack
|
||||
}
|
||||
#endif //HAS_SECOND_SERIAL_PORT
|
||||
|
||||
void lcd_calibrate_pinda() {
|
||||
enquecommand_P(PSTR("G76"));
|
||||
@ -4619,7 +4645,7 @@ static void lcd_disable_farm_mode() {
|
||||
lcd_return_to_status();
|
||||
}
|
||||
else {
|
||||
lcd_goto_menu(lcd_settings_menu);
|
||||
lcd_goto_menu(lcd_settings_menu); //doesn't break menuStack
|
||||
}
|
||||
lcd_update_enable(true);
|
||||
lcdDrawUpdate = 2;
|
||||
@ -6669,32 +6695,24 @@ 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();
|
||||
|
||||
/**
|
||||
* @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) {
|
||||
@ -7115,10 +7133,6 @@ void lcd_buttons_update()
|
||||
if (millis() > button_blanking_time) {
|
||||
button_blanking_time = millis() + BUTTON_BLANKING_TIME;
|
||||
if (button_pressed == false && long_press_active == false) {
|
||||
if (currentMenu != lcd_move_z) {
|
||||
savedMenu = currentMenu;
|
||||
savedEncoderPosition = encoderPosition;
|
||||
}
|
||||
long_press_timer = millis();
|
||||
button_pressed = true;
|
||||
}
|
||||
@ -7127,7 +7141,7 @@ void lcd_buttons_update()
|
||||
|
||||
long_press_active = true;
|
||||
move_menu_scale = 1.0;
|
||||
lcd_goto_menu(lcd_move_z);
|
||||
menu_action_submenu(lcd_move_z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7137,14 +7151,8 @@ void lcd_buttons_update()
|
||||
button_blanking_time = millis() + BUTTON_BLANKING_TIME;
|
||||
|
||||
if (long_press_active == false) { //button released before long press gets activated
|
||||
if (currentMenu == lcd_move_z) {
|
||||
//return to previously active menu and previous encoder position
|
||||
lcd_goto_menu(savedMenu, savedEncoderPosition);
|
||||
}
|
||||
else {
|
||||
newbutton |= EN_C;
|
||||
}
|
||||
}
|
||||
else if (currentMenu == lcd_move_z) lcd_quick_feedback();
|
||||
//button_pressed is set back to false via lcd_quick_feedback function
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user