2018-10-23 23:00:34 +02:00
|
|
|
/**
|
|
|
|
* Marlin 3D Printer Firmware
|
2020-02-03 15:00:57 +01:00
|
|
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
2018-10-23 23:00:34 +02:00
|
|
|
*
|
|
|
|
* Based on Sprinter and grbl.
|
2019-06-28 06:57:50 +02:00
|
|
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
2018-10-23 23:00:34 +02:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2020-07-23 05:20:14 +02:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2018-10-23 23:00:34 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
2020-10-17 02:36:25 +02:00
|
|
|
#include "../marlinui.h"
|
2019-06-11 12:58:43 +02:00
|
|
|
#include "../../libs/numtostr.h"
|
2018-10-23 23:00:34 +02:00
|
|
|
#include "../../inc/MarlinConfig.h"
|
|
|
|
|
2019-04-16 22:45:31 +02:00
|
|
|
#include "limits.h"
|
|
|
|
|
2018-10-23 23:00:34 +02:00
|
|
|
extern int8_t encoderLine, encoderTopLine, screen_items;
|
|
|
|
|
|
|
|
void scroll_screen(const uint8_t limit, const bool is_menu);
|
|
|
|
bool printer_busy();
|
2018-11-06 05:51:10 +01:00
|
|
|
|
2019-04-24 17:13:44 +02:00
|
|
|
typedef void (*selectFunc_t)();
|
|
|
|
|
2019-10-10 02:46:10 +02:00
|
|
|
#define SS_LEFT 0x00
|
|
|
|
#define SS_CENTER 0x01
|
|
|
|
#define SS_INVERT 0x02
|
|
|
|
#define SS_DEFAULT SS_CENTER
|
2019-09-27 10:06:23 +02:00
|
|
|
|
2020-09-28 08:13:27 +02:00
|
|
|
#if HAS_MARLINUI_U8GLIB && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY)
|
2018-11-14 20:13:51 +01:00
|
|
|
void _lcd_zoffset_overlay_gfx(const float zvalue);
|
2018-10-23 23:00:34 +02:00
|
|
|
#endif
|
|
|
|
|
2020-03-17 21:12:52 +01:00
|
|
|
#if ENABLED(BABYSTEP_ZPROBE_OFFSET) && Z_PROBE_OFFSET_RANGE_MIN >= -9 && Z_PROBE_OFFSET_RANGE_MAX <= 9
|
|
|
|
#define BABYSTEP_TO_STR(N) ftostr43sign(N)
|
|
|
|
#elif ENABLED(BABYSTEPPING)
|
|
|
|
#define BABYSTEP_TO_STR(N) ftostr53sign(N)
|
2020-01-03 03:40:40 +01:00
|
|
|
#endif
|
|
|
|
|
2018-10-23 23:00:34 +02:00
|
|
|
////////////////////////////////////////////
|
2019-11-02 13:28:20 +01:00
|
|
|
///////////// Base Menu Items //////////////
|
2018-10-23 23:00:34 +02:00
|
|
|
////////////////////////////////////////////
|
|
|
|
|
2019-11-02 13:28:20 +01:00
|
|
|
class MenuItemBase {
|
|
|
|
public:
|
2020-07-09 10:11:57 +02:00
|
|
|
// Index to interject in the item label and/or for use by its action.
|
2020-06-11 01:35:56 +02:00
|
|
|
static int8_t itemIndex;
|
2019-11-15 03:30:30 +01:00
|
|
|
|
2020-07-09 10:11:57 +02:00
|
|
|
// An optional pointer for use in display or by the action
|
|
|
|
static PGM_P itemString;
|
|
|
|
|
2019-11-15 03:30:30 +01:00
|
|
|
// Store the index of the item ahead of use by indexed items
|
2020-07-09 10:11:57 +02:00
|
|
|
FORCE_INLINE static void init(const int8_t ind=0, PGM_P const pstr=nullptr) { itemIndex = ind; itemString = pstr; }
|
2019-11-15 03:30:30 +01:00
|
|
|
|
2019-11-02 13:28:20 +01:00
|
|
|
// Draw an item either selected (pre_char) or not (space) with post_char
|
|
|
|
static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char);
|
|
|
|
|
|
|
|
// Draw an item either selected ('>') or not (space) with post_char
|
2019-11-15 03:30:30 +01:00
|
|
|
FORCE_INLINE static void _draw(const bool sel, const uint8_t row, PGM_P const pstr, const char post_char) {
|
2019-11-02 13:28:20 +01:00
|
|
|
_draw(sel, row, pstr, '>', post_char);
|
|
|
|
}
|
|
|
|
};
|
2018-10-23 23:00:34 +02:00
|
|
|
|
2020-08-21 12:21:34 +02:00
|
|
|
// STATIC_ITEM(LABEL,...)
|
2019-11-15 03:30:30 +01:00
|
|
|
class MenuItem_static : public MenuItemBase {
|
|
|
|
public:
|
2020-08-09 01:21:44 +02:00
|
|
|
static void draw(const uint8_t row, PGM_P const pstr, const uint8_t style=SS_DEFAULT, const char * const vstr=nullptr);
|
2019-11-15 03:30:30 +01:00
|
|
|
};
|
|
|
|
|
2020-08-22 04:59:59 +02:00
|
|
|
// BACK_ITEM(LABEL)
|
|
|
|
class MenuItem_back : public MenuItemBase {
|
|
|
|
public:
|
|
|
|
FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr) {
|
|
|
|
_draw(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0]);
|
|
|
|
}
|
|
|
|
// Back Item action goes back one step in history
|
|
|
|
FORCE_INLINE static void action(PGM_P const=nullptr) { ui.go_back(); }
|
|
|
|
};
|
|
|
|
|
2020-08-21 12:21:34 +02:00
|
|
|
// CONFIRM_ITEM(LABEL,Y,N,FY,FN,...),
|
|
|
|
// YESNO_ITEM(LABEL,FY,FN,...)
|
2019-11-15 03:30:30 +01:00
|
|
|
class MenuItem_confirm : public MenuItemBase {
|
2018-11-06 05:51:10 +01:00
|
|
|
public:
|
2019-11-02 13:28:20 +01:00
|
|
|
FORCE_INLINE static void draw(const bool sel, const uint8_t row, PGM_P const pstr, ...) {
|
|
|
|
_draw(sel, row, pstr, '>', LCD_STR_ARROW_RIGHT[0]);
|
|
|
|
}
|
|
|
|
// Implemented for HD44780 and DOGM
|
|
|
|
// Draw the prompt, buttons, and state
|
|
|
|
static void draw_select_screen(
|
|
|
|
PGM_P const yes, // Right option label
|
|
|
|
PGM_P const no, // Left option label
|
|
|
|
const bool yesno, // Is "yes" selected?
|
|
|
|
PGM_P const pref, // Prompt prefix
|
|
|
|
const char * const string, // Prompt runtime string
|
|
|
|
PGM_P const suff // Prompt suffix
|
|
|
|
);
|
|
|
|
static void select_screen(
|
|
|
|
PGM_P const yes, PGM_P const no,
|
|
|
|
selectFunc_t yesFunc, selectFunc_t noFunc,
|
|
|
|
PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr
|
|
|
|
);
|
|
|
|
static inline void select_screen(
|
|
|
|
PGM_P const yes, PGM_P const no,
|
|
|
|
selectFunc_t yesFunc, selectFunc_t noFunc,
|
|
|
|
PGM_P const pref, const progmem_str string, PGM_P const suff=nullptr
|
|
|
|
) {
|
|
|
|
char str[strlen_P((PGM_P)string) + 1];
|
|
|
|
strcpy_P(str, (PGM_P)string);
|
|
|
|
select_screen(yes, no, yesFunc, noFunc, pref, str, suff);
|
|
|
|
}
|
|
|
|
// Shortcut for prompt with "NO"/ "YES" labels
|
|
|
|
FORCE_INLINE static void confirm_screen(selectFunc_t yesFunc, selectFunc_t noFunc, PGM_P const pref, const char * const string=nullptr, PGM_P const suff=nullptr) {
|
|
|
|
select_screen(GET_TEXT(MSG_YES), GET_TEXT(MSG_NO), yesFunc, noFunc, pref, string, suff);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-10-23 23:00:34 +02:00
|
|
|
////////////////////////////////////////////
|
2019-11-02 13:28:20 +01:00
|
|
|
///////////// Edit Menu Items //////////////
|
2018-10-23 23:00:34 +02:00
|
|
|
////////////////////////////////////////////
|
|
|
|
|
2019-10-08 02:44:33 +02:00
|
|
|
// The Menu Edit shadow value
|
|
|
|
typedef union {
|
|
|
|
bool state;
|
|
|
|
float decimal;
|
|
|
|
int8_t int8;
|
|
|
|
int16_t int16;
|
|
|
|
int32_t int32;
|
|
|
|
uint8_t uint8;
|
|
|
|
uint16_t uint16;
|
|
|
|
uint32_t uint32;
|
|
|
|
} chimera_t;
|
|
|
|
extern chimera_t editable;
|
|
|
|
|
2019-11-15 03:30:30 +01:00
|
|
|
// Base class for Menu Edit Items
|
2019-11-02 13:28:20 +01:00
|
|
|
class MenuEditItemBase : public MenuItemBase {
|
2019-04-09 04:10:41 +02:00
|
|
|
private:
|
2019-11-15 03:30:30 +01:00
|
|
|
// These values are statically constructed by init() via action()
|
|
|
|
// The action() method acts like the instantiator. The entire lifespan
|
|
|
|
// of a menu item is within its declaration, so all these values decompose
|
|
|
|
// into behavior and unused items get optimized out.
|
2019-04-09 04:10:41 +02:00
|
|
|
static PGM_P editLabel;
|
|
|
|
static void *editValue;
|
2019-10-03 02:04:16 +02:00
|
|
|
static int32_t minEditValue, maxEditValue; // Encoder value range
|
2019-04-09 04:10:41 +02:00
|
|
|
static screenFunc_t callbackFunc;
|
|
|
|
static bool liveEdit;
|
2018-11-06 05:51:10 +01:00
|
|
|
protected:
|
2019-10-11 04:03:33 +02:00
|
|
|
typedef const char* (*strfunc_t)(const int32_t);
|
2019-05-12 01:44:35 +02:00
|
|
|
typedef void (*loadfunc_t)(void *, const int32_t);
|
2019-11-15 03:30:30 +01:00
|
|
|
static void goto_edit_screen(
|
|
|
|
PGM_P const el, // Edit label
|
|
|
|
void * const ev, // Edit value pointer
|
|
|
|
const int32_t minv, // Encoder minimum
|
|
|
|
const int32_t maxv, // Encoder maximum
|
|
|
|
const uint16_t ep, // Initial encoder value
|
|
|
|
const screenFunc_t cs, // MenuItem_type::draw_edit_screen => MenuEditItemBase::edit()
|
|
|
|
const screenFunc_t cb, // Callback after edit
|
|
|
|
const bool le // Flag to call cb() during editing
|
|
|
|
);
|
|
|
|
static void edit_screen(strfunc_t, loadfunc_t); // Edit value handler
|
2019-11-02 13:28:20 +01:00
|
|
|
public:
|
|
|
|
// Implemented for HD44780 and DOGM
|
|
|
|
// Draw the current item at specified row with edit data
|
2020-07-09 10:11:57 +02:00
|
|
|
static void draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const inStr, const bool pgm=false);
|
2019-11-02 13:28:20 +01:00
|
|
|
|
|
|
|
// Implemented for HD44780 and DOGM
|
|
|
|
// This low-level method is good to draw from anywhere
|
2019-11-15 03:30:30 +01:00
|
|
|
static void draw_edit_screen(PGM_P const pstr, const char* const value);
|
|
|
|
|
|
|
|
// This method is for the current menu item
|
|
|
|
static inline void draw_edit_screen(const char* const value) { draw_edit_screen(editLabel, value); }
|
2018-11-06 05:51:10 +01:00
|
|
|
};
|
|
|
|
|
2020-08-21 12:21:34 +02:00
|
|
|
#if ENABLED(SDSUPPORT)
|
|
|
|
class CardReader;
|
|
|
|
class MenuItem_sdbase {
|
|
|
|
public:
|
|
|
|
// Implemented for HD44780 and DOGM
|
|
|
|
static void draw(const bool sel, const uint8_t row, PGM_P const pstr, CardReader &theCard, const bool isDir);
|
|
|
|
};
|
2018-11-11 19:16:24 +01:00
|
|
|
#endif
|
2018-10-23 23:00:34 +02:00
|
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
|
/////////////// Menu Screens ///////////////
|
|
|
|
////////////////////////////////////////////
|
|
|
|
|
|
|
|
void menu_main();
|
|
|
|
void menu_move();
|
|
|
|
|
|
|
|
#if ENABLED(SDSUPPORT)
|
2019-08-15 00:52:14 +02:00
|
|
|
void menu_media();
|
2018-10-23 23:00:34 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
////////////////////////////////////////////
|
|
|
|
//////// Menu Item Helper Functions ////////
|
|
|
|
////////////////////////////////////////////
|
|
|
|
|
2020-08-22 03:26:16 +02:00
|
|
|
void lcd_move_z();
|
2018-10-23 23:00:34 +02:00
|
|
|
void _lcd_draw_homing();
|
|
|
|
|
2019-03-17 05:43:06 +01:00
|
|
|
#define HAS_LINE_TO_Z ANY(DELTA, PROBE_MANUALLY, MESH_BED_LEVELING, LEVEL_BED_CORNERS)
|
2018-10-28 08:59:21 +01:00
|
|
|
|
|
|
|
#if HAS_LINE_TO_Z
|
|
|
|
void line_to_z(const float &z);
|
|
|
|
#endif
|
|
|
|
|
2020-09-28 08:13:27 +02:00
|
|
|
#if HAS_MARLINUI_U8GLIB && EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY)
|
2019-10-29 22:38:17 +01:00
|
|
|
void _lcd_zoffset_overlay_gfx(const float zvalue);
|
|
|
|
#endif
|
|
|
|
|
2020-10-05 07:31:20 +02:00
|
|
|
#if ENABLED(PROBE_OFFSET_WIZARD)
|
2020-11-26 04:38:00 +01:00
|
|
|
void goto_probe_offset_wizard();
|
2020-10-05 07:31:20 +02:00
|
|
|
#endif
|
|
|
|
|
2018-10-23 23:00:34 +02:00
|
|
|
#if ENABLED(LCD_BED_LEVELING) || (HAS_LEVELING && DISABLED(SLIM_LCD_MENUS))
|
|
|
|
void _lcd_toggle_bed_leveling();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if ENABLED(BABYSTEPPING)
|
|
|
|
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
|
|
|
void lcd_babystep_zoffset();
|
|
|
|
#else
|
|
|
|
void lcd_babystep_z();
|
|
|
|
#endif
|
2020-07-03 16:24:41 +02:00
|
|
|
|
|
|
|
#if ENABLED(BABYSTEP_MILLIMETER_UNITS)
|
|
|
|
#define BABYSTEP_SIZE_X int32_t((BABYSTEP_MULTIPLICATOR_XY) * planner.settings.axis_steps_per_mm[X_AXIS])
|
|
|
|
#define BABYSTEP_SIZE_Y int32_t((BABYSTEP_MULTIPLICATOR_XY) * planner.settings.axis_steps_per_mm[Y_AXIS])
|
|
|
|
#define BABYSTEP_SIZE_Z int32_t((BABYSTEP_MULTIPLICATOR_Z) * planner.settings.axis_steps_per_mm[Z_AXIS])
|
|
|
|
#else
|
|
|
|
#define BABYSTEP_SIZE_X BABYSTEP_MULTIPLICATOR_XY
|
|
|
|
#define BABYSTEP_SIZE_Y BABYSTEP_MULTIPLICATOR_XY
|
|
|
|
#define BABYSTEP_SIZE_Z BABYSTEP_MULTIPLICATOR_Z
|
|
|
|
#endif
|
|
|
|
|
2018-10-23 23:00:34 +02:00
|
|
|
#endif
|
2020-08-22 03:26:16 +02:00
|
|
|
|
|
|
|
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
|
|
|
|
void touch_screen_calibration();
|
|
|
|
#endif
|
2020-11-22 01:21:43 +01:00
|
|
|
|
|
|
|
extern uint8_t screen_history_depth;
|
|
|
|
inline void clear_menu_history() { screen_history_depth = 0; }
|
2020-12-09 11:29:33 +01:00
|
|
|
|
|
|
|
#define STICKY_SCREEN(S) []{ ui.defer_status_screen(); ui.goto_screen(S); }
|