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:
Scott Lahteine
2018-11-11 12:16:24 -06:00
committed by GitHub
parent 9da6809ac3
commit a0c795b097
65 changed files with 1881 additions and 1997 deletions

View File

@ -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))