Encapsulate common display code in a singleton (#12395)
* Encapsulate common LCD code in a singleton * Depend more UBL code on UBL_DEVEL_DEBUGGING - Since most users don't need the debugging on at all times, this helps reduce the default build size for UBL by over 2K, a little closer to fitting on 128K boards.
This commit is contained in:
@ -30,6 +30,7 @@
|
||||
#include "../../module/motion.h"
|
||||
#include "../../gcode/queue.h"
|
||||
#include "../../sd/cardreader.h"
|
||||
#include "../../libs/buzzer.h"
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
#include "../../module/configuration_store.h"
|
||||
@ -61,10 +62,6 @@ menuPosition screen_history[6];
|
||||
uint8_t screen_history_depth = 0;
|
||||
bool screen_changed;
|
||||
|
||||
#if LCD_TIMEOUT_TO_STATUS
|
||||
bool defer_return_to_status;
|
||||
#endif
|
||||
|
||||
// Value Editing
|
||||
PGM_P editLabel;
|
||||
void *editValue;
|
||||
@ -79,9 +76,9 @@ bool no_reentry = false;
|
||||
//////// Menu Navigation & History /////////
|
||||
////////////////////////////////////////////
|
||||
|
||||
void lcd_return_to_status() { lcd_goto_screen(lcd_status_screen); }
|
||||
void MarlinUI::return_to_status() { goto_screen(status_screen); }
|
||||
|
||||
void lcd_save_previous_screen() {
|
||||
void MarlinUI::save_previous_screen() {
|
||||
if (screen_history_depth < COUNT(screen_history)) {
|
||||
screen_history[screen_history_depth].menu_function = currentScreen;
|
||||
screen_history[screen_history_depth].encoder_position = encoderPosition;
|
||||
@ -89,25 +86,18 @@ void lcd_save_previous_screen() {
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_goto_previous_menu() {
|
||||
void MarlinUI::goto_previous_screen() {
|
||||
if (screen_history_depth > 0) {
|
||||
--screen_history_depth;
|
||||
lcd_goto_screen(
|
||||
goto_screen(
|
||||
screen_history[screen_history_depth].menu_function,
|
||||
screen_history[screen_history_depth].encoder_position
|
||||
);
|
||||
}
|
||||
else
|
||||
lcd_return_to_status();
|
||||
return_to_status();
|
||||
}
|
||||
|
||||
#if LCD_TIMEOUT_TO_STATUS
|
||||
void lcd_goto_previous_menu_no_defer() {
|
||||
set_defer_return_to_status(false);
|
||||
lcd_goto_previous_menu();
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////
|
||||
/////////// Common Menu Actions ////////////
|
||||
////////////////////////////////////////////
|
||||
@ -142,34 +132,33 @@ void menu_item_gcode::action(PGM_P pgcode) { enqueue_and_echo_commands_P(pgcode)
|
||||
* ...which calls:
|
||||
* menu_item_int3::action_setting_edit(PSTR(MSG_SPEED), &feedrate_percentage, 10, 999)
|
||||
*/
|
||||
void menu_item_invariants::edit(strfunc_t strfunc, loadfunc_t loadfunc) {
|
||||
ENCODER_DIRECTION_NORMAL();
|
||||
if ((int32_t)encoderPosition < 0) encoderPosition = 0;
|
||||
if ((int32_t)encoderPosition > maxEditValue) encoderPosition = maxEditValue;
|
||||
if (lcdDrawUpdate)
|
||||
lcd_implementation_drawedit(editLabel, strfunc(encoderPosition + minEditValue));
|
||||
if (lcd_clicked || (liveEdit && lcdDrawUpdate)) {
|
||||
if (editValue != NULL) loadfunc(editValue, encoderPosition + minEditValue);
|
||||
if (callbackFunc && (liveEdit || lcd_clicked)) (*callbackFunc)();
|
||||
if (lcd_clicked) lcd_goto_previous_menu();
|
||||
lcd_clicked = false;
|
||||
void MenuItemBase::edit(strfunc_t strfunc, loadfunc_t loadfunc) {
|
||||
ui.encoder_direction_normal();
|
||||
if ((int32_t)ui.encoderPosition < 0) ui.encoderPosition = 0;
|
||||
if ((int32_t)ui.encoderPosition > maxEditValue) ui.encoderPosition = maxEditValue;
|
||||
if (ui.should_draw())
|
||||
draw_edit_screen(editLabel, strfunc(ui.encoderPosition + minEditValue));
|
||||
if (ui.lcd_clicked || (liveEdit && ui.should_draw())) {
|
||||
if (editValue != NULL) loadfunc(editValue, ui.encoderPosition + minEditValue);
|
||||
if (callbackFunc && (liveEdit || ui.lcd_clicked)) (*callbackFunc)();
|
||||
if (ui.use_click()) ui.goto_previous_screen();
|
||||
}
|
||||
}
|
||||
|
||||
void menu_item_invariants::init(PGM_P const el, void * const ev, const int32_t minv, const int32_t maxv, const uint32_t ep, const screenFunc_t cs, const screenFunc_t cb, const bool le) {
|
||||
lcd_save_previous_screen();
|
||||
lcd_refresh();
|
||||
void MenuItemBase::init(PGM_P const el, void * const ev, const int32_t minv, const int32_t maxv, const uint32_t ep, const screenFunc_t cs, const screenFunc_t cb, const bool le) {
|
||||
ui.save_previous_screen();
|
||||
ui.refresh();
|
||||
editLabel = el;
|
||||
editValue = ev;
|
||||
minEditValue = minv;
|
||||
maxEditValue = maxv;
|
||||
encoderPosition = ep;
|
||||
currentScreen = cs;
|
||||
ui.encoderPosition = ep;
|
||||
ui.currentScreen = cs;
|
||||
callbackFunc = cb;
|
||||
liveEdit = le;
|
||||
}
|
||||
|
||||
#define DEFINE_MENU_EDIT_ITEM(NAME) template class menu_item_template<NAME ## _item_info>;
|
||||
#define DEFINE_MENU_EDIT_ITEM(NAME) template class TMenuItem<NAME ## _item_info>;
|
||||
|
||||
DEFINE_MENU_EDIT_ITEM(int3);
|
||||
DEFINE_MENU_EDIT_ITEM(int4);
|
||||
@ -184,7 +173,7 @@ DEFINE_MENU_EDIT_ITEM(float62);
|
||||
DEFINE_MENU_EDIT_ITEM(long5);
|
||||
|
||||
void menu_item_bool::action_setting_edit(PGM_P pstr, bool *ptr, screenFunc_t callback) {
|
||||
UNUSED(pstr); *ptr ^= true; lcd_refresh();
|
||||
UNUSED(pstr); *ptr ^= true; ui.refresh();
|
||||
if (callback) (*callback)();
|
||||
}
|
||||
|
||||
@ -202,7 +191,7 @@ bool printer_busy() { return planner.movesplanned() || IS_SD_PRINTING(); }
|
||||
/**
|
||||
* General function to go directly to a screen
|
||||
*/
|
||||
void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder/*=0*/) {
|
||||
void MarlinUI::goto_screen(screenFunc_t screen, const uint32_t encoder/*=0*/) {
|
||||
if (currentScreen != screen) {
|
||||
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
@ -215,10 +204,10 @@ void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder/*=0*/) {
|
||||
// Going to menu_main from status screen? Remember first click time.
|
||||
// Going back to status screen within a very short time? Go to Z babystepping.
|
||||
if (screen == menu_main) {
|
||||
if (currentScreen == lcd_status_screen)
|
||||
if (on_status_screen())
|
||||
doubleclick_expire_ms = millis() + DOUBLECLICK_MAX_INTERVAL;
|
||||
}
|
||||
else if (screen == lcd_status_screen && currentScreen == menu_main && PENDING(millis(), doubleclick_expire_ms)) {
|
||||
else if (screen == status_screen && currentScreen == menu_main && PENDING(millis(), doubleclick_expire_ms)) {
|
||||
if (printer_busy()) {
|
||||
screen =
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
@ -239,25 +228,25 @@ void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder/*=0*/) {
|
||||
|
||||
currentScreen = screen;
|
||||
encoderPosition = encoder;
|
||||
if (screen == lcd_status_screen) {
|
||||
set_defer_return_to_status(false);
|
||||
if (screen == status_screen) {
|
||||
ui.defer_status_screen(false);
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
ubl.lcd_map_control = false;
|
||||
#endif
|
||||
screen_history_depth = 0;
|
||||
}
|
||||
|
||||
lcd_implementation_clear();
|
||||
clear_lcd();
|
||||
|
||||
// Re-initialize custom characters that may be re-used
|
||||
#if HAS_CHARACTER_LCD
|
||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||
if (!ubl.lcd_map_control)
|
||||
#endif
|
||||
LCD_SET_CHARSET(screen == lcd_status_screen ? CHARSET_INFO : CHARSET_MENU);
|
||||
LCD_SET_CHARSET(screen == status_screen ? CHARSET_INFO : CHARSET_MENU);
|
||||
#endif
|
||||
|
||||
lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT;
|
||||
refresh(LCDVIEW_CALL_REDRAW_NEXT);
|
||||
screen_changed = true;
|
||||
#if HAS_GRAPHICAL_LCD
|
||||
drawing_screen = false;
|
||||
@ -276,24 +265,24 @@ void lcd_goto_screen(screenFunc_t screen, const uint32_t encoder/*=0*/) {
|
||||
//
|
||||
static PGM_P sync_message;
|
||||
|
||||
void _lcd_synchronize() {
|
||||
if (lcdDrawUpdate) lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, sync_message);
|
||||
void MarlinUI::_synchronize() {
|
||||
if (should_draw()) draw_menu_item_static(LCD_HEIGHT >= 4 ? 1 : 0, sync_message);
|
||||
if (no_reentry) return;
|
||||
// Make this the current handler till all moves are done
|
||||
no_reentry = true;
|
||||
const screenFunc_t old_screen = currentScreen;
|
||||
lcd_goto_screen(_lcd_synchronize);
|
||||
goto_screen(_synchronize);
|
||||
planner.synchronize(); // idle() is called until moves complete
|
||||
no_reentry = false;
|
||||
lcd_goto_screen(old_screen);
|
||||
goto_screen(old_screen);
|
||||
}
|
||||
|
||||
// Display the synchronize screen with a custom message
|
||||
// ** This blocks the command queue! **
|
||||
void lcd_synchronize(PGM_P const msg/*=NULL*/) {
|
||||
void MarlinUI::synchronize(PGM_P const msg/*=NULL*/) {
|
||||
static const char moving[] PROGMEM = MSG_MOVING;
|
||||
sync_message = msg ? msg : moving;
|
||||
_lcd_synchronize();
|
||||
_synchronize();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,16 +297,16 @@ void lcd_synchronize(PGM_P const msg/*=NULL*/) {
|
||||
*/
|
||||
int8_t encoderLine, screen_items;
|
||||
void scroll_screen(const uint8_t limit, const bool is_menu) {
|
||||
ENCODER_DIRECTION_MENUS();
|
||||
ui.encoder_direction_menus();
|
||||
ENCODER_RATE_MULTIPLY(false);
|
||||
if (encoderPosition > 0x8000) encoderPosition = 0;
|
||||
if (first_page) {
|
||||
encoderLine = encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM);
|
||||
if (ui.encoderPosition > 0x8000) ui.encoderPosition = 0;
|
||||
if (ui.first_page) {
|
||||
encoderLine = ui.encoderPosition / (ENCODER_STEPS_PER_MENU_ITEM);
|
||||
screen_changed = false;
|
||||
}
|
||||
if (screen_items > 0 && encoderLine >= screen_items - limit) {
|
||||
encoderLine = MAX(0, screen_items - limit);
|
||||
encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM);
|
||||
ui.encoderPosition = encoderLine * (ENCODER_STEPS_PER_MENU_ITEM);
|
||||
}
|
||||
if (is_menu) {
|
||||
NOMORE(encoderTopLine, encoderLine);
|
||||
@ -328,12 +317,12 @@ void scroll_screen(const uint8_t limit, const bool is_menu) {
|
||||
encoderTopLine = encoderLine;
|
||||
}
|
||||
|
||||
void lcd_completion_feedback(const bool good/*=true*/) {
|
||||
void MarlinUI::completion_feedback(const bool good/*=true*/) {
|
||||
if (good) {
|
||||
lcd_buzz(100, 659);
|
||||
lcd_buzz(100, 698);
|
||||
BUZZ(100, 659);
|
||||
BUZZ(100, 698);
|
||||
}
|
||||
else lcd_buzz(20, 440);
|
||||
else BUZZ(20, 440);
|
||||
}
|
||||
|
||||
#if HAS_LINE_TO_Z
|
||||
@ -348,17 +337,17 @@ void lcd_completion_feedback(const bool good/*=true*/) {
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
|
||||
void lcd_babystep_zoffset() {
|
||||
if (use_click()) { return lcd_goto_previous_menu_no_defer(); }
|
||||
set_defer_return_to_status(true);
|
||||
if (ui.use_click()) return ui.goto_previous_screen_no_defer();
|
||||
ui.defer_status_screen(true);
|
||||
#if ENABLED(BABYSTEP_HOTEND_Z_OFFSET)
|
||||
const bool do_probe = (active_extruder == 0);
|
||||
#else
|
||||
constexpr bool do_probe = true;
|
||||
#endif
|
||||
ENCODER_DIRECTION_NORMAL();
|
||||
if (encoderPosition) {
|
||||
const int16_t babystep_increment = (int32_t)encoderPosition * (BABYSTEP_MULTIPLICATOR);
|
||||
encoderPosition = 0;
|
||||
ui.encoder_direction_normal();
|
||||
if (ui.encoderPosition) {
|
||||
const int16_t babystep_increment = (int32_t)ui.encoderPosition * (BABYSTEP_MULTIPLICATOR);
|
||||
ui.encoderPosition = 0;
|
||||
|
||||
const float diff = planner.steps_to_mm[Z_AXIS] * babystep_increment,
|
||||
new_probe_offset = zprobe_zoffset + diff,
|
||||
@ -378,16 +367,16 @@ void lcd_completion_feedback(const bool good/*=true*/) {
|
||||
else hotend_offset[Z_AXIS][active_extruder] = new_offs;
|
||||
#endif
|
||||
|
||||
lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT;
|
||||
ui.refresh(LCDVIEW_CALL_REDRAW_NEXT);
|
||||
}
|
||||
}
|
||||
if (lcdDrawUpdate) {
|
||||
if (ui.should_draw()) {
|
||||
#if ENABLED(BABYSTEP_HOTEND_Z_OFFSET)
|
||||
if (!do_probe)
|
||||
lcd_implementation_drawedit(PSTR(MSG_IDEX_Z_OFFSET), ftostr43sign(hotend_offset[Z_AXIS][active_extruder]));
|
||||
draw_edit_screen(PSTR(MSG_IDEX_Z_OFFSET), ftostr43sign(hotend_offset[Z_AXIS][active_extruder]));
|
||||
else
|
||||
#endif
|
||||
lcd_implementation_drawedit(PSTR(MSG_ZPROBE_ZOFFSET), ftostr43sign(zprobe_zoffset));
|
||||
draw_edit_screen(PSTR(MSG_ZPROBE_ZOFFSET), ftostr43sign(zprobe_zoffset));
|
||||
|
||||
#if ENABLED(BABYSTEP_ZPROBE_GFX_OVERLAY)
|
||||
if (do_probe) _lcd_zoffset_overlay_gfx(zprobe_zoffset);
|
||||
@ -447,14 +436,14 @@ void watch_temp_callback_bed() {
|
||||
#endif
|
||||
|
||||
#if ENABLED(EEPROM_SETTINGS)
|
||||
void lcd_store_settings() { lcd_completion_feedback(settings.save()); }
|
||||
void lcd_load_settings() { lcd_completion_feedback(settings.load()); }
|
||||
void lcd_store_settings() { ui.completion_feedback(settings.save()); }
|
||||
void lcd_load_settings() { ui.completion_feedback(settings.load()); }
|
||||
#endif
|
||||
|
||||
void _lcd_draw_homing() {
|
||||
constexpr uint8_t line = (LCD_HEIGHT - 1) / 2;
|
||||
if (lcdDrawUpdate) lcd_implementation_drawmenu_static(line, PSTR(MSG_LEVEL_BED_HOMING));
|
||||
lcdDrawUpdate = LCDVIEW_CALL_NO_REDRAW;
|
||||
if (ui.should_draw()) draw_menu_item_static(line, PSTR(MSG_LEVEL_BED_HOMING));
|
||||
ui.refresh(LCDVIEW_CALL_NO_REDRAW);
|
||||
}
|
||||
|
||||
#if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS))
|
||||
|
Reference in New Issue
Block a user