🎨 Improve LulzBot FTDI Eve Touch UI (#27275)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Bkahl 2024-08-06 14:52:17 -05:00 committed by GitHub
parent c509603530
commit ab6e68c312
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 1346 additions and 667 deletions

View file

@ -111,20 +111,17 @@ void FilesScreen::drawFileButton(int x, int y, int w, int h, const char *filenam
cmd.cmd(COLOR_RGB(is_highlighted ? fg_action : bg_color));
cmd.font(font_medium).rectangle(bx, by, bw, bh);
cmd.cmd(COLOR_RGB(is_highlighted ? normal_btn.rgb : bg_text_enabled));
#if ENABLED(SCROLL_LONG_FILENAMES)
if (is_highlighted) {
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x,y));
cmd.cmd(SCISSOR_SIZE(w,h));
cmd.cmd(MACRO(0));
cmd.text(bx, by, bw, bh, filename, OPT_CENTERY | OPT_NOFIT);
} else
#endif
draw_text_with_ellipsis(cmd, bx,by, bw - (is_dir ? 20 : 0), bh, filename, OPT_CENTERY, font_medium);
if (is_dir && !is_highlighted) cmd.text(bx, by, bw, bh, F("> "), OPT_CENTERY | OPT_RIGHTX);
#if ENABLED(SCROLL_LONG_FILENAMES)
if (is_highlighted) cmd.cmd(RESTORE_CONTEXT());
#endif
if (TERN0(SCROLL_LONG_FILENAMES, is_highlighted)) {
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x,y));
cmd.cmd(SCISSOR_SIZE(w,h));
cmd.cmd(MACRO(0));
cmd.text(bx, by, bw, bh, filename, OPT_CENTERY | OPT_NOFIT);
}
else
draw_text_with_ellipsis(cmd, bx, by, bw - (is_dir ? 20 : 0), bh, filename, OPT_CENTERY, font_medium);
if (is_dir && !is_highlighted) cmd.text(bx, by, bw, bh, F("> "), OPT_CENTERY | OPT_RIGHTX);
if (TERN0(SCROLL_LONG_FILENAMES, is_highlighted)) cmd.cmd(RESTORE_CONTEXT());
}
void FilesScreen::drawFileList() {
@ -136,11 +133,9 @@ void FilesScreen::drawFileList() {
uint16_t fileIndex = mydata.cur_page * FILES_PER_PAGE;
for (uint8_t i = 0; i < FILES_PER_PAGE; i++, fileIndex++) {
if (files.seek(fileIndex)) {
drawFileButton(files.filename(), getTagForLine(i), files.isDir(), false);
mydata.flags.is_empty = false;
} else
break;
if (!files.seek(fileIndex)) break;
drawFileButton(files.filename(), getTagForLine(i), files.isDir(), false);
mydata.flags.is_empty = false;
}
}

View file

@ -78,6 +78,8 @@ namespace ExtUI {
void onPrintTimerStarted() {
InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_STARTED);
current_screen.forget();
PUSH_SCREEN(StatusScreen);
}
void onPrintTimerStopped() {
InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FINISHED);
@ -118,9 +120,18 @@ namespace ExtUI {
if (msg)
ConfirmUserRequestAlertBox::show(msg);
else
ConfirmUserRequestAlertBox::hide();
ConfirmUserRequestAlertBox::show("Press Resume to Continue");
}
#if ENABLED(ADVANCED_PAUSE_FEATURE)
void filament_load_prompt(const char * const msg) {
if (msg)
FilamentPromptBox::show();
else
FilamentPromptBox::hide();
}
#endif
// For fancy LCDs include an icon ID, message, and translated button title
void onUserConfirmRequired(const int icon, const char * const cstr, FSTR_P const fBtn) {
onUserConfirmRequired(cstr);

View file

@ -21,6 +21,7 @@
****************************************************************************/
#include "ftdi_extended.h"
#include "../../screens.h"
#if ENABLED(FTDI_EXTENDED)
using namespace FTDI;
@ -32,6 +33,7 @@ enum {
tiny_timer_t touch_timer;
UIData::flags_t UIData::flags;
uint8_t pressed_tag = UNPRESSED;
uint8_t lastPauseMsgState = 0;
uint8_t UIData::get_persistent_data_mask() {
// A bit mask for flags that should be stored to the EEPROM.
@ -117,6 +119,31 @@ namespace FTDI {
return;
}
#if ENABLED(ADVANCED_PAUSE_FEATURE)
if (ExtUI::awaitingUserConfirm() && (lastPauseMsgState != ExtUI::pauseModeStatus)) {
//SERIAL_ECHOLNPGM("Calling Pause Screen : ", lastPauseMsgState);
switch (ExtUI::pauseModeStatus) {
case PAUSE_MESSAGE_PARKING: ExtUI::onStatusChanged(GET_TEXT_F(MSG_PAUSE_PRINT_PARKING)); break;
case PAUSE_MESSAGE_CHANGING: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_INIT)); break;
case PAUSE_MESSAGE_UNLOAD: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_UNLOAD)); break;
case PAUSE_MESSAGE_WAITING: ExtUI::onStatusChanged(GET_TEXT_F(MSG_ADVANCED_PAUSE_WAITING)); break;
case PAUSE_MESSAGE_INSERT: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_INSERT)); break;
case PAUSE_MESSAGE_LOAD: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_LOAD)); break;
case PAUSE_MESSAGE_PURGE: ExtUI::onStatusChanged(GET_TEXT_F(TERN(ADVANCED_PAUSE_CONTINUOUS_PURGE, MSG_FILAMENT_CHANGE_CONT_PURGE, MSG_FILAMENT_CHANGE_PURGE))); break;
case PAUSE_MESSAGE_RESUME: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_RESUME)); break;
case PAUSE_MESSAGE_HEAT: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEAT)); break;
case PAUSE_MESSAGE_HEATING: ExtUI::onStatusChanged(GET_TEXT_F(MSG_FILAMENT_CHANGE_HEATING)); break;
case PAUSE_MESSAGE_OPTION: FilamentPromptBox::show(); break;
case PAUSE_MESSAGE_STATUS: break;
default: ExtUI::onUserConfirmRequired(PSTR("Confirm Continue")); break;
}
}
else if (!ExtUI::awaitingUserConfirm() && !ExtUI::isPrintingPaused() && !ExtUI::getHostKeepaliveIsPaused()) {
ConfirmUserRequestAlertBox::hide();
FilamentPromptBox::hide();
}
#endif // ADVANCED_PAUSE_FEATURE
const uint8_t tag = CLCD::get_tag();
switch (pressed_tag) {

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D *
* *
* 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 *
@ -22,11 +23,12 @@
#include "../config.h"
#include "../screens.h"
#include "../../ui_api.h"
#ifdef FTDI_ABOUT_SCREEN
#define GRID_COLS 4
#define GRID_ROWS 8
#define GRID_ROWS 30
using namespace FTDI;
using namespace Theme;
@ -43,74 +45,63 @@ void AboutScreen::onRedraw(draw_mode_t) {
.cmd(CLEAR(true,true,true))
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0);
#define HEADING_POS BTN_POS(1,1), BTN_SIZE(4,2)
#define FW_VERS_POS BTN_POS(1,3), BTN_SIZE(4,1)
#define FW_INFO_POS BTN_POS(1,4), BTN_SIZE(4,1)
#define LICENSE_POS BTN_POS(1,5), BTN_SIZE(4,3)
#define STATS_POS BTN_POS(1,8), BTN_SIZE(2,1)
#define BACK_POS BTN_POS(3,8), BTN_SIZE(2,1)
char about_str[1
+ strlen_P(GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2))
#ifdef TOOLHEAD_NAME
+ strlen_P(TOOLHEAD_NAME)
#endif
];
#ifdef TOOLHEAD_NAME
// If MSG_ABOUT_TOUCH_PANEL_2 has %s, substitute in the toolhead name.
// But this is optional, so squelch the compiler warning here.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-extra-args"
sprintf_P(about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2), TOOLHEAD_NAME);
#pragma GCC diagnostic pop
#else
strcpy_P(about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2));
#ifdef LULZBOT_LCD_MACHINE_NAME
draw_text_box(cmd, BTN_POS(1,1), BTN_SIZE(4,6), F(
#if ENABLED(LULZBOT_LONG_BED)
"" LULZBOT_LCD_MACHINE_NAME " \nWith Long Bed"
#elif ENABLED(LULZBOT_LONG_BED_V2)
"" LULZBOT_LCD_MACHINE_NAME " \nWith Long Bed V2"
#elif ENABLED(LULZBOT_BLTouch) && NONE(LULZBOT_LONG_BED_V2, TAZProV2)
"" LULZBOT_LCD_MACHINE_NAME " \nWith BLTouch"
#else
"" LULZBOT_LCD_MACHINE_NAME "\n"
#endif
), OPT_CENTER, font_xxlarge);
#endif
draw_text_box(cmd, HEADING_POS,
#ifdef MACHINE_NAME
F(MACHINE_NAME)
#else
GET_TEXT_F(MSG_ABOUT_TOUCH_PANEL_1)
#endif
, OPT_CENTER, font_xlarge
);
#if ALL(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU)
#ifdef LULZBOT_LCD_MACHINE_NAME
cmd.tag(3);
#endif
draw_text_box(cmd, FW_VERS_POS,
#ifdef TOUCH_UI_VERSION
F(TOUCH_UI_VERSION)
#else
FPSTR(getFirmwareName_str())
#endif
, OPT_CENTER, font_medium);
cmd.tag(0);
draw_text_box(cmd, FW_INFO_POS, about_str, OPT_CENTER, font_medium);
draw_text_box(cmd, LICENSE_POS, GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny);
draw_text_box(cmd, BTN_POS(1,7), BTN_SIZE(4,3), F(
"Firmware:"
), OPT_CENTER, font_xlarge);
cmd.font(font_medium);
#if ALL(PRINTCOUNTER, FTDI_STATISTICS_SCREEN)
cmd.colors(normal_btn)
.tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU));
draw_text_box(cmd, BTN_POS(1,10), BTN_SIZE(4,2), F(
"" LULZBOT_M115_EXTRUDER_TYPE ""
), OPT_CENTER, font_xlarge);
#endif
cmd.colors(action_btn)
.tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
#if ENABLED(SHOW_TOOL_HEAD_ID)
draw_text_box(cmd, BTN_POS(1,13), BTN_SIZE(4,3), F(
"Tool Head:"
), OPT_CENTER, font_xlarge);
#endif
draw_text_box(cmd, BTN_POS(1,19), BTN_SIZE(4,3), F(
"Version:"
), OPT_CENTER, font_xlarge);
draw_text_box(cmd, BTN_POS(1,22), BTN_SIZE(4,2), F(
"Marlin " SHORT_BUILD_VERSION ""
), OPT_CENTER, font_xlarge);
cmd.font(font_medium).colors(normal_btn).tag(1).button(BTN_POS(1,24), BTN_SIZE(4,3), GET_TEXT_F(MSG_INFO_PRINTER_STATS_MENU));
cmd.font(font_medium).colors(action_btn).tag(2).button(BTN_POS(1,27), BTN_SIZE(4,3), GET_TEXT_F(MSG_BUTTON_DONE));
}
bool AboutScreen::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); break;
switch(tag) {
default: return false;
#if ALL(PRINTCOUNTER, FTDI_STATISTICS_SCREEN)
case 2: GOTO_SCREEN(StatisticsScreen); break;
case 1: GOTO_SCREEN(StatisticsScreen); break;
#endif
case 2: GOTO_PREVIOUS(); return true;
#if ALL(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU)
case 3: GOTO_SCREEN(DeveloperMenu); break;
#endif
default: return false;
}
return true;
}
#endif // FTDI_ABOUT_SCREEN
#endif // EXTENSIBLE_UI

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -43,21 +44,21 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
#define GRID_ROWS 8
#endif
#define GRID_COLS 2
#define RESTORE_DEFAULTS_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define DISPLAY_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define INTERFACE_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define ZPROBE_ZOFFSET_POS BTN_POS(1,3), BTN_SIZE(1,1)
#define STEPS_PER_MM_POS BTN_POS(2,3), BTN_SIZE(1,1)
#define FILAMENT_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define VELOCITY_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define TMC_CURRENT_POS BTN_POS(1,5), BTN_SIZE(1,1)
#define ACCELERATION_POS BTN_POS(2,5), BTN_SIZE(1,1)
#define ENDSTOPS_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define JERK_POS BTN_POS(2,6), BTN_SIZE(1,1)
#define CASE_LIGHT_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define BACKLASH_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define OFFSETS_POS BTN_POS(1,8), BTN_SIZE(1,1)
#define TMC_HOMING_THRS_POS BTN_POS(2,8), BTN_SIZE(1,1)
#define RESTORE_DEFAULTS_POS BTN_POS(1,8), BTN_SIZE(2,1)
#define DISPLAY_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define INTERFACE_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define ZPROBE_ZOFFSET_POS BTN_POS(1,1), BTN_SIZE(1,1)
#define STEPS_PER_MM_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define FILAMENT_POS BTN_POS(1,3), BTN_SIZE(1,1)
#define VELOCITY_POS BTN_POS(2,1), BTN_SIZE(1,1)
#define TMC_CURRENT_POS BTN_POS(2,5), BTN_SIZE(1,1)
#define ACCELERATION_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define ENDSTOPS_POS BTN_POS(1,5), BTN_SIZE(1,1)
#define JERK_POS BTN_POS(2,3), BTN_SIZE(1,1)
#define FLOW_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define BACKLASH_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define OFFSETS_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define TMC_HOMING_THRS_POS BTN_POS(2,6), BTN_SIZE(1,1)
#if ANY(HAS_MULTI_HOTEND, SENSORLESS_HOMING)
#define BACK_POS BTN_POS(1,9), BTN_SIZE(2,1)
#else
@ -67,7 +68,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
#define GRID_COLS 3
#define GRID_ROWS 6
#define ZPROBE_ZOFFSET_POS BTN_POS(1,1), BTN_SIZE(1,1)
#define CASE_LIGHT_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define FLOW_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define STEPS_PER_MM_POS BTN_POS(2,1), BTN_SIZE(1,1)
#define TMC_CURRENT_POS BTN_POS(3,1), BTN_SIZE(1,1)
#define TMC_HOMING_THRS_POS BTN_POS(3,2), BTN_SIZE(1,1)
@ -89,14 +90,16 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
cmd.colors(normal_btn)
.font(Theme::font_medium)
.enabled(ENABLED(HAS_BED_PROBE))
.tag(2) .button(ZPROBE_ZOFFSET_POS, GET_TEXT_F(MSG_ZPROBE_ZOFFSET))
.enabled(ENABLED(CASE_LIGHT_ENABLE))
.tag(16).button(CASE_LIGHT_POS, GET_TEXT_F(MSG_CASE_LIGHT))
.tag(2) .button(ZPROBE_ZOFFSET_POS, GET_TEXT_F(MSG_ZOFFSET))
.tag(16).button(FLOW_POS, GET_TEXT_F(MSG_FLOW))
.tag(3) .button(STEPS_PER_MM_POS, GET_TEXT_F(MSG_STEPS_PER_MM))
.enabled(ENABLED(HAS_TRINAMIC_CONFIG))
.tag(13).button(TMC_CURRENT_POS, GET_TEXT_F(MSG_TMC_CURRENT))
.enabled(ENABLED(SENSORLESS_HOMING))
.tag(14).button(TMC_HOMING_THRS_POS, GET_TEXT_F(MSG_TMC_HOMING_THRS))
#if ENABLED(SENSORLESS_HOMING)
.tag(14).button(TMC_HOMING_THRS_POS, GET_TEXT_F(MSG_TMC_HOMING_THRS))
#else
.tag(17).button(TMC_HOMING_THRS_POS, GET_TEXT_F(MSG_CLEAN_NOZZLE))
#endif
.enabled(ENABLED(HAS_MULTI_HOTEND))
.tag(4) .button(OFFSETS_POS, GET_TEXT_F(MSG_OFFSETS_MENU))
.enabled(ANY(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR))
@ -119,14 +122,14 @@ bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
#if HAS_BED_PROBE
case 2: GOTO_SCREEN(ZOffsetScreen); break;
case 2: GOTO_SCREEN(ZOffsetScreen); break;
#endif
case 3: GOTO_SCREEN(StepsScreen); break;
case 3: GOTO_SCREEN(StepsScreen); break;
#if HAS_MULTI_HOTEND
case 4: GOTO_SCREEN(NozzleOffsetScreen); break;
case 4: GOTO_SCREEN(NozzleOffsetScreen); break;
#endif
case 5: GOTO_SCREEN(MaxVelocityScreen); break;
case 6: GOTO_SCREEN(DefaultAccelerationScreen); break;
case 5: GOTO_SCREEN(MaxVelocityScreen); break;
case 6: GOTO_SCREEN(DefaultAccelerationScreen); break;
case 7: GOTO_SCREEN(TERN(HAS_JUNCTION_DEVIATION, JunctionDeviationScreen, JerkScreen)); break;
#if ENABLED(BACKLASH_GCODE)
case 8: GOTO_SCREEN(BacklashCompensationScreen); break;
@ -144,9 +147,14 @@ bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) {
case 14: GOTO_SCREEN(StepperBumpSensitivityScreen); break;
#endif
case 15: GOTO_SCREEN(DisplayTuningScreen); break;
#if ENABLED(CASE_LIGHT_ENABLE)
case 16: GOTO_SCREEN(CaseLightScreen); break;
#endif
case 16: GOTO_SCREEN(FlowPercentScreen); break;
case 17:
GOTO_SCREEN(StatusScreen);
#ifndef CLEAN_SCRIPT
#define CLEAN_SCRIPT "G12"
#endif
injectCommands(F(CLEAN_SCRIPT));
break;
default: return false;
}
return true;

View file

@ -38,7 +38,7 @@ void AlertDialogBox::onEntry() {
void AlertDialogBox::onRedraw(draw_mode_t what) {
if (what & FOREGROUND) {
drawOkayButton();
drawDoneButton();
}
}

View file

@ -33,7 +33,7 @@ constexpr static BaseNumericAdjustmentScreenData &mydata = screen_data.BaseNumer
#if ENABLED(TOUCH_UI_PORTRAIT)
#define GRID_COLS 13
#define GRID_ROWS 10
#define GRID_ROWS (8+EXTRUDERS)
#define LAYOUT_FONT font_small
#else
#define GRID_COLS 18
@ -57,7 +57,7 @@ BaseNumericAdjustmentScreen::widgets_t::widgets_t(draw_mode_t what) : _what(what
cmd.font(font_medium);
_button(cmd, 1,
#if ENABLED(TOUCH_UI_PORTRAIT)
BTN_POS(1,10), BTN_SIZE(13,1),
BTN_POS(1,GRID_ROWS), BTN_SIZE(13,1),
#else
BTN_POS(15,7), BTN_SIZE(4,1),
#endif

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -33,22 +34,20 @@ using namespace Theme;
constexpr static ChangeFilamentScreenData &mydata = screen_data.ChangeFilamentScreen;
#ifdef TOUCH_UI_PORTRAIT
#define GRID_COLS 2
#define GRID_ROWS 11
#define E_TEMP_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define E_TEMP_LBL_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define UNLD_LABL_POS BTN_POS(1,8), BTN_SIZE(1,1)
#define LOAD_LABL_POS BTN_POS(2,8), BTN_SIZE(1,1)
#define UNLD_MOMN_POS BTN_POS(1,9), BTN_SIZE(1,1)
#define LOAD_MOMN_POS BTN_POS(2,9), BTN_SIZE(1,1)
#define UNLD_CONT_POS BTN_POS(1,10), BTN_SIZE(1,1)
#define LOAD_CONT_POS BTN_POS(2,10), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,11), BTN_SIZE(2,1)
#define GRID_COLS 4
#define GRID_ROWS 10
#define E0_TEMP_POS BTN_POS(1,2), BTN_SIZE(2,1)
#define E1_TEMP_POS BTN_POS(3,2), BTN_SIZE(2,1)
#define UNLD_LABL_POS BTN_POS(3,7), BTN_SIZE(2,2)
#define LOAD_LABL_POS BTN_POS(1,7), BTN_SIZE(2,2)
#define FILAMENT_SWAP_POS BTN_POS(1,9), BTN_SIZE(4,1)
#define BACK_POS BTN_POS(1,10), BTN_SIZE(4,1)
#else
#define GRID_COLS 4
#define GRID_ROWS 6
#define E_TEMP_POS BTN_POS(3,2), BTN_SIZE(2,1)
#define E_TEMP_LBL_POS BTN_POS(3,1), BTN_SIZE(2,1)
#define E0_TEMP_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define E1_TEMP_POS BTN_POS(3,2), BTN_SIZE(1,1)
#define FILAMENT_SWAP_POS BTN_POS(1,9), BTN_SIZE(4,1)
#define UNLD_LABL_POS BTN_POS(3,3), BTN_SIZE(1,1)
#define LOAD_LABL_POS BTN_POS(4,3), BTN_SIZE(1,1)
#define UNLD_MOMN_POS BTN_POS(3,4), BTN_SIZE(1,1)
@ -57,22 +56,34 @@ constexpr static ChangeFilamentScreenData &mydata = screen_data.ChangeFilamentSc
#define LOAD_CONT_POS BTN_POS(4,5), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(3,6), BTN_SIZE(2,1)
#endif
#define REMOVAL_TEMP_LBL_POS BTN_POS(1,3), BTN_SIZE(2,1)
#define GRADIENT_POS BTN_POS(1,4), BTN_SIZE(1,3)
#define LOW_TEMP_POS BTN_POS(2,6), BTN_SIZE(1,1)
#define MED_TEMP_POS BTN_POS(2,5), BTN_SIZE(1,1)
#define HIG_TEMP_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define HEATING_LBL_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define CAUTION_LBL_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define HOT_LBL_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define E_SEL_LBL_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define E1_SEL_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define E2_SEL_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define GROUP_1_POS BTN_POS(1,3), BTN_SIZE(4,1)
#define GROUP_1_LABL_POS BTN_POS(1,3), BTN_SIZE(3,1)
#define GROUP_1_TEMP_POS BTN_POS(4,3), BTN_SIZE(1,1)
#define GROUP_2_POS BTN_POS(1,4), BTN_SIZE(4,1)
#define GROUP_2_LABL_POS BTN_POS(1,4), BTN_SIZE(3,1)
#define GROUP_2_TEMP_POS BTN_POS(4,4), BTN_SIZE(1,1)
#define GROUP_3_POS BTN_POS(1,5), BTN_SIZE(4,1)
#define GROUP_3_LABL_POS BTN_POS(1,5), BTN_SIZE(3,1)
#define GROUP_3_TEMP_POS BTN_POS(4,5), BTN_SIZE(1,1)
#define GROUP_4_POS BTN_POS(1,6), BTN_SIZE(4,1)
#define GROUP_4_LABL_POS BTN_POS(1,6), BTN_SIZE(3,1)
#define GROUP_4_TEMP_POS BTN_POS(4,6), BTN_SIZE(1,1)
#define E1_SEL_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define E2_SEL_POS BTN_POS(3,1), BTN_SIZE(2,1)
#define COOL_TEMP 40
#define LOW_TEMP 180
#define MED_TEMP 200
#define HIGH_TEMP 220
#define MED_TEMP 220
#define HIGH_TEMP 240
#define GROUP_1_TEMP 180
#define GROUP_2_TEMP 200
#define GROUP_3_TEMP 220
#define GROUP_4_TEMP 240
#define _ICON_POS(x,y,w,h) x, y, w/3, h
#define _TEXT_POS(x,y,w,h) x + w/3, y, w - w/3, h
#define ICON_POS(pos) _ICON_POS(pos)
#define TEXT_POS(pos) _TEXT_POS(pos)
/****************** COLOR SCALE ***********************/
@ -144,95 +155,161 @@ void ChangeFilamentScreen::onRedraw(draw_mode_t what) {
.cmd(CLEAR(true,true,true))
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0)
.font(TERN(TOUCH_UI_PORTRAIT, font_large, font_medium))
.text(E_SEL_LBL_POS, GET_TEXT_F(MSG_EXTRUDER_SELECTION))
.text(E_TEMP_LBL_POS, GET_TEXT_F(MSG_CURRENT_TEMPERATURE))
.text(REMOVAL_TEMP_LBL_POS, GET_TEXT_F(MSG_REMOVAL_TEMPERATURE));
drawTempGradient(GRADIENT_POS);
.font(TERN(TOUCH_UI_PORTRAIT, font_large, font_medium));
}
if (what & FOREGROUND) {
char str[15];
char e0_str[20], e1_str[20];
const extruder_t e = getExtruder();
if (isHeaterIdle(e))
format_temp_and_idle(str, getActualTemp_celsius(e));
if (isHeaterIdle(H0))
format_temp_and_idle(e0_str, getActualTemp_celsius(H0));
else
format_temp_and_temp(str, getActualTemp_celsius(e), getTargetTemp_celsius(e));
format_temp_and_temp(e0_str, getActualTemp_celsius(H0), getTargetTemp_celsius(H0));
const rgb_t tcol = getWarmColor(getActualTemp_celsius(e), COOL_TEMP, LOW_TEMP, MED_TEMP, HIGH_TEMP);
cmd.cmd(COLOR_RGB(tcol))
.tag(15)
.rectangle(E_TEMP_POS)
.cmd(COLOR_RGB(tcol.luminance() > 128 ? 0x000000 : 0xFFFFFF))
#if HAS_MULTI_EXTRUDER
if (isHeaterIdle(H1))
format_temp_and_idle(e1_str, getActualTemp_celsius(H1));
else
format_temp_and_temp(e1_str, getActualTemp_celsius(H1), getTargetTemp_celsius(H1));
#else
strcpy_P(e1_str, PSTR("N/A"));
#endif
if (getTargetTemp_celsius(H0) > 0) {
cmd.cmd(COLOR_RGB(temp_button));
}
else {
cmd.cmd(COLOR_RGB(gray_color_1));
}
cmd.tag(15)
.rectangle(E0_TEMP_POS)
.font(font_medium)
.text(E_TEMP_POS, str)
.colors(normal_btn)
.text(TEXT_POS(E0_TEMP_POS), e0_str)
.colors(normal_btn);
const bool t_ok = getActualTemp_celsius(e) > getSoftenTemp() - 10;
if (mydata.t_tag && !t_ok)
cmd.text(HEATING_LBL_POS, GET_TEXT_F(MSG_HEATING));
else if (getActualTemp_celsius(e) > 100) {
cmd.cmd(COLOR_RGB(0xFF0000))
.text(CAUTION_LBL_POS, GET_TEXT_F(MSG_CAUTION))
.colors(normal_btn)
.text(HOT_LBL_POS, GET_TEXT_F(MSG_HOT));
if DISABLED(HAS_MULTI_HOTEND) {
cmd.font(font_small).cmd(COLOR_RGB(gray_color_1));
}
else if (getTargetTemp_celsius(H1) > 0) {
cmd.font(font_medium).cmd(COLOR_RGB(temp_button));
}
else {
cmd.font(font_medium).cmd(COLOR_RGB(gray_color_1));
}
cmd.tag(15)
.rectangle(E1_TEMP_POS)
.colors(normal_btn)
.text(TEXT_POS(E1_TEMP_POS), e1_str)
.colors(normal_btn);
cmd.tag(5)
.cmd (BITMAP_SOURCE(Extruder_Icon_Info))
.cmd (BITMAP_LAYOUT(Extruder_Icon_Info))
.cmd (BITMAP_SIZE (Extruder_Icon_Info))
.icon(ICON_POS(E0_TEMP_POS), Extruder_Icon_Info, icon_scale)
.icon(ICON_POS(E1_TEMP_POS), Extruder_Icon_Info, icon_scale);
const bool t_ok = getActualTemp_celsius(e) > getSoftenTemp() - 30;
#define TOG_STYLE(A) colors(A ? action_btn : normal_btn)
const bool tog2 = mydata.t_tag == 2;
const bool tog3 = mydata.t_tag == 3;
const bool tog4 = mydata.t_tag == 4;
const bool tog5 = mydata.t_tag == 5;
const bool tog10 = mydata.e_tag == 10;
#if HAS_MULTI_HOTEND
const bool tog11 = mydata.e_tag == 11;
#endif
cmd.TOG_STYLE(tog10)
.tag(10).button (E1_SEL_POS, F("1"))
.tag(10).font(font_large).button (E1_SEL_POS, F("Extruder 1"))
#if HOTENDS < 2
.enabled(false)
.tag(0).fgcolor(gray_color_1)
#else
.TOG_STYLE(tog11)
.TOG_STYLE(tog11).tag(11)
#endif
.tag(11).button (E2_SEL_POS, F("2"));
.button (E2_SEL_POS, F("Extruder 2"));
if (!t_ok) reset_menu_timeout();
const bool tog7 = mydata.repeat_tag == 7;
const bool tog8 = mydata.repeat_tag == 8;
cmd.colors(normal_btn)
.font(font_medium)
.tag(0)
.button(GROUP_1_POS, F(""), OPT_FLAT)
.button(GROUP_2_POS, F(""), OPT_FLAT)
.button(GROUP_3_POS, F(""), OPT_FLAT)
.button(GROUP_4_POS, F(""), OPT_FLAT);
{
char str[30];
format_temp(str, LOW_TEMP);
cmd.tag(2) .TOG_STYLE(tog2).button (LOW_TEMP_POS, str);
format_temp(str, GROUP_1_TEMP);
cmd.tag(2) .TOG_STYLE(tog2).button (GROUP_1_TEMP_POS, F( STRINGIFY(GROUP_1_TEMP)));
format_temp(str, MED_TEMP);
cmd.tag(3) .TOG_STYLE(tog3).button (MED_TEMP_POS, str);
format_temp(str, GROUP_2_TEMP);
cmd.tag(3) .TOG_STYLE(tog3).button (GROUP_2_TEMP_POS, F( STRINGIFY(GROUP_2_TEMP)));
format_temp(str, HIGH_TEMP);
cmd.tag(4) .TOG_STYLE(tog4).button (HIG_TEMP_POS, str);
format_temp(str, GROUP_3_TEMP);
cmd.tag(4) .TOG_STYLE(tog4).button (GROUP_3_TEMP_POS, F( STRINGIFY(GROUP_3_TEMP)));
format_temp(str, GROUP_4_TEMP);
cmd.tag(5) .TOG_STYLE(tog5).button (GROUP_4_TEMP_POS, F( STRINGIFY(GROUP_4_TEMP)));
}
cmd.colors(normal_btn)
.font(font_medium)
.tag(0)
.text(GROUP_1_LABL_POS, F("PLA, PVA, PVB"))
.text(GROUP_2_LABL_POS, F("TPU, Flexibles"))
.text(GROUP_3_LABL_POS, F("ABS, PETg, ASA"))
.text(GROUP_4_LABL_POS, F("Nylon, PC"));
cmd.cmd(COLOR_RGB(t_ok ? bg_text_enabled : bg_text_disabled))
.tag(0) .text (UNLD_LABL_POS, GET_TEXT_F(MSG_UNLOAD_FILAMENT))
.text (LOAD_LABL_POS, GET_TEXT_F(MSG_LOAD_FILAMENT))
.colors(normal_btn)
.tag(5) .enabled(t_ok).button (UNLD_MOMN_POS, GET_TEXT_F(MSG_MOMENTARY))
.tag(6) .enabled(t_ok).button (LOAD_MOMN_POS, GET_TEXT_F(MSG_MOMENTARY))
.tag(7).TOG_STYLE(tog7).enabled(t_ok).button (UNLD_CONT_POS, GET_TEXT_F(MSG_CONTINUOUS))
.tag(8).TOG_STYLE(tog8).enabled(t_ok).button (LOAD_CONT_POS, GET_TEXT_F(MSG_CONTINUOUS))
.tag(1).colors(action_btn) .button (BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
.font(font_xlarge)
.tag(7).TOG_STYLE(tog7).enabled(t_ok).button (UNLD_LABL_POS, GET_TEXT_F(MSG_UNLOAD))
.tag(8).TOG_STYLE(tog8).enabled(t_ok).button (LOAD_LABL_POS, GET_TEXT_F(MSG_LOAD))
.font(font_medium)
.tag(1).colors(action_btn).button (BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
if (ExtUI::isPrintingPaused()) {
cmd.colors(normal_btn)
.font(font_medium)
.tag(16).colors(normal_btn).button(FILAMENT_SWAP_POS, GET_TEXT_F(MSG_RESUME_PRINT));
}
else {
#ifdef PARKING_COMMAND_GCODE
cmd.colors(normal_btn)
.font(font_medium)
.tag(17).colors(normal_btn).button(FILAMENT_SWAP_POS, GET_TEXT_F(MSG_FILAMENT_SWAP));
#endif
}
}
}
void ChangeFilamentScreen::loadBitmaps() {
// Load the bitmaps for the status screen
using namespace Theme;
constexpr uint32_t base = ftdi_memory_map::RAM_G;
CLCD::mem_write_xbm(base + Extruder_Icon_Info.RAMG_offset, Extruder_Icon, sizeof(Extruder_Icon));
// Load fonts for internationalization
#if ENABLED(TOUCH_UI_USE_UTF8)
load_utf8_data(base + UTF8_FONT_OFFSET);
#endif
}
uint8_t ChangeFilamentScreen::getSoftenTemp() {
switch (mydata.t_tag) {
case 2: return LOW_TEMP;
case 3: return MED_TEMP;
case 4: return HIGH_TEMP;
case 2: return GROUP_1_TEMP;
case 3: return GROUP_2_TEMP;
case 4: return GROUP_3_TEMP;
case 5: return GROUP_4_TEMP;
default: return EXTRUDE_MINTEMP;
}
}
@ -257,19 +334,6 @@ void ChangeFilamentScreen::doPurge() {
#endif
}
bool ChangeFilamentScreen::onTouchStart(uint8_t tag) {
// Make the Momentary and Continuous buttons slightly more responsive
switch (tag) {
case 5: case 6: case 7: case 8:
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
if (tag == 5 || tag == 7) doPurge();
#endif
return ChangeFilamentScreen::onTouchHeld(tag);
default:
return false;
}
}
bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) {
using namespace ExtUI;
switch (tag) {
@ -277,6 +341,7 @@ bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) {
case 2:
case 3:
case 4:
case 5:
// Change temperature
mydata.t_tag = tag;
setTargetTemp_celsius(getSoftenTemp(), getExtruder());
@ -290,8 +355,8 @@ bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) {
case 10:
case 11:
// Change extruder
mydata.e_tag = tag;
mydata.t_tag = 0;
mydata.e_tag = tag;
mydata.t_tag = 0;
mydata.repeat_tag = 0;
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
mydata.need_purge = true;
@ -299,6 +364,14 @@ bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) {
setActiveTool(getExtruder(), true);
break;
case 15: GOTO_SCREEN(TemperatureScreen); break;
case 16:
if (ExtUI::isPrintingPaused()) {
injectCommands(F("M117 Print Resumed")); resumePrint(); GOTO_SCREEN(StatusScreen);
}
break;
#ifdef PARKING_COMMAND_GCODE
case 17: injectCommands(F(PARKING_COMMAND_GCODE)); break;
#endif
}
return true;
}
@ -309,7 +382,7 @@ bool ChangeFilamentScreen::onTouchHeld(uint8_t tag) {
#define UI_INCREMENT_AXIS(axis) UI_INCREMENT(AxisPosition_mm, axis);
#define UI_DECREMENT_AXIS(axis) UI_DECREMENT(AxisPosition_mm, axis);
switch (tag) {
case 5: case 7: UI_DECREMENT_AXIS(getExtruder()); break;
case 7: UI_DECREMENT_AXIS(getExtruder()); break;
case 6: case 8: UI_INCREMENT_AXIS(getExtruder()); break;
default: return false;
}

View file

@ -40,11 +40,12 @@ class ChangeFilamentScreen : public BaseScreen, public CachedScreen<CHANGE_FILAM
static void drawTempGradient(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
static void doPurge();
public:
static void loadBitmaps();
static uint32_t getWarmColor(uint16_t temp, uint16_t cool, uint16_t low, uint16_t med, uint16_t high);
static void onEntry();
static void onExit();
static void onRedraw(draw_mode_t);
static bool onTouchStart(uint8_t tag);
//static bool onTouchStart(uint8_t tag);
static bool onTouchEnd(uint8_t tag);
static bool onTouchHeld(uint8_t tag);
static void onIdle();

View file

@ -35,18 +35,23 @@ void ConfirmUserRequestAlertBox::onRedraw(draw_mode_t mode) {
bool ConfirmUserRequestAlertBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
#ifdef FTDI_TUNE_MENU
if (ExtUI::isPrintingPaused()) {
// The TuneMenu will call ExtUI::setUserConfirmed()
GOTO_SCREEN(TuneMenu);
current_screen.forget();
}
else
#if ENABLED(ADVANCED_PAUSE_FEATURE)
if (ExtUI::pauseModeStatus == PAUSE_MESSAGE_PURGE || ExtUI::pauseModeStatus == PAUSE_MESSAGE_OPTION)
ExtUI::setPauseMenuResponse(PAUSE_RESPONSE_RESUME_PRINT);
#endif
{
ExtUI::setUserConfirmed();
GOTO_PREVIOUS();
}
ExtUI::setUserConfirmed();
#ifdef FTDI_TUNE_MENU
if (ExtUI::awaitingUserConfirm()) {
// The TuneMenu will call ExtUI::setUserConfirmed()
if (ExtUI::isOngoingPrintJob())
GOTO_SCREEN(TuneMenu);
else
GOTO_SCREEN(StatusScreen);
current_screen.forget();
return true;
}
#endif
GOTO_PREVIOUS();
return true;
case 2: GOTO_PREVIOUS(); return true;
default: return false;

View file

@ -1,24 +1,23 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* 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
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/*****************************
* custom_user_menu.cpp *
*****************************/
/****************************************************************************
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#include "../screens.h"
@ -33,7 +32,7 @@ using namespace Theme;
#define _USER_DESC(N) MAIN_MENU_ITEM_##N##_DESC
#define _USER_GCODE(N) MAIN_MENU_ITEM_##N##_GCODE
#define _USER_ITEM(N) .tag(_ITEM_TAG(N)).button(USER_ITEM_POS(N), _USER_DESC(N))
#define _USER_ACTION(N) case _ITEM_TAG(N): injectCommands(F(_USER_GCODE(N))); TERN_(USER_SCRIPT_RETURN, GOTO_SCREEN(StatusScreen)); break;
#define _USER_ACTION(N) case _ITEM_TAG(N): injectCommands(F(_USER_GCODE(N))); TERN_(CUSTOM_MENU_MAIN_SCRIPT_RETURN, GOTO_SCREEN(StatusScreen)); break;
void CustomUserMenus::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
@ -42,167 +41,127 @@ void CustomUserMenus::onRedraw(draw_mode_t what) {
.cmd(CLEAR(true, true, true));
}
#if HAS_USER_ITEM(16, 17, 18, 19, 20)
#define _MORE_THAN_FIFTEEN 1
#else
#define _MORE_THAN_FIFTEEN 0
#endif
#if _MORE_THAN_FIFTEEN || HAS_USER_ITEM(11, 12, 13, 14, 15)
#define _MORE_THAN_TEN 1
#else
#define _MORE_THAN_TEN 0
#endif
#if ENABLED(TOUCH_UI_PORTRAIT)
#define GRID_COLS (1 + _MORE_THAN_TEN)
#define GRID_ROWS 11
#define USER_ITEM_POS(N) BTN_POS((1+((N-1)/10)), ((N-1) % 10 + 1)), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,11), BTN_SIZE(1,1)
#else
#if _MORE_THAN_TEN || HAS_USER_ITEM(6, 7, 8, 9, 10)
#define _MORE_THAN_FIVE 1
#if defined(TOOLHEAD_Legacy_Universal)
#define GRID_ROWS 10
#else
#define _MORE_THAN_FIVE 0
#define GRID_ROWS 7
#endif
#define GRID_COLS (1 + _MORE_THAN_FIVE + _MORE_THAN_TEN + _MORE_THAN_FIFTEEN)
#define GRID_ROWS 6
#define USER_ITEM_POS(N) BTN_POS((1+((N-1)/5)), ((N-1) % 5 + 1)), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,6), BTN_SIZE(GRID_COLS,1)
#define GRID_COLS 1
#define TOOLHEAD_LABL_POS BTN_POS(1, 1), BTN_SIZE(GRID_COLS,1)
#define USER_ITEM_POS(N) BTN_POS(1, N), BTN_SIZE(GRID_COLS,1)
#define TOOLHEAD_SWAP_POS BTN_POS(1,GRID_ROWS-1), BTN_SIZE(GRID_COLS,1)
#define BACK_POS BTN_POS(1,GRID_ROWS), BTN_SIZE(GRID_COLS,1)
#else
#define GRID_ROWS 9
#define GRID_COLS 1
#define TOOLHEAD_LABL_POS BTN_POS(1, 1), BTN_SIZE(GRID_COLS,1)
#define USER_ITEM_POS(N) BTN_POS(1, N), BTN_SIZE(GRID_COLS,1)
#define TOOLHEAD_SWAP_POS BTN_POS(1,GRID_ROWS-1), BTN_SIZE(GRID_COLS,1)
#define BACK_POS BTN_POS(1,GRID_ROWS), BTN_SIZE(GRID_COLS,1)
#endif
btn_colors thcolor[8] = {normal_btn};
//.color(TH_color[1])
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(Theme::font_medium)
#if HAS_USER_ITEM(1)
_USER_ITEM(1)
.tag(0).text(TOOLHEAD_LABL_POS, GET_TEXT_F(MSG_CUSTOM_MENU_MAIN_TITLE));
cmd.colors(accent_btn)
.font(Theme::font_medium)
#if defined(MAIN_MENU_ITEM_1_DESC)
//_USER_ITEM(1)
.tag(_ITEM_TAG(11)).button(USER_ITEM_POS(1), MAIN_MENU_ITEM_1_DESC)
#endif
#if HAS_USER_ITEM(2)
_USER_ITEM(2)
.colors(thcolor[1])
#if defined(MAIN_MENU_ITEM_2_DESC)
//_USER_ITEM(2)
.tag(_ITEM_TAG(12)).button(USER_ITEM_POS(2), MAIN_MENU_ITEM_2_DESC)
#endif
#if HAS_USER_ITEM(3)
_USER_ITEM(3)
.colors(thcolor[2])
#if defined(MAIN_MENU_ITEM_3_DESC)
//_USER_ITEM(3)
.tag(_ITEM_TAG(13)).button(USER_ITEM_POS(3), MAIN_MENU_ITEM_3_DESC)
#endif
#if HAS_USER_ITEM(4)
_USER_ITEM(4)
.colors(thcolor[3])
#if defined(MAIN_MENU_ITEM_4_DESC)
//_USER_ITEM(4)
.tag(_ITEM_TAG(14)).button(USER_ITEM_POS(4), MAIN_MENU_ITEM_4_DESC)
#endif
#if HAS_USER_ITEM(5)
_USER_ITEM(5)
.colors(thcolor[4])
#if defined(MAIN_MENU_ITEM_5_DESC)
//_USER_ITEM(5)
.tag(_ITEM_TAG(15)).button(USER_ITEM_POS(5), MAIN_MENU_ITEM_5_DESC)
#endif
#if HAS_USER_ITEM(6)
_USER_ITEM(6)
.colors(thcolor[5])
#if defined(MAIN_MENU_ITEM_6_DESC)
//_USER_ITEM(6)
.tag(_ITEM_TAG(16)).button(USER_ITEM_POS(6), MAIN_MENU_ITEM_6_DESC)
#endif
#if HAS_USER_ITEM(7)
_USER_ITEM(7)
.colors(thcolor[6])
#if defined(MAIN_MENU_ITEM_7_DESC)
//_USER_ITEM(7)
.tag(_ITEM_TAG(17)).button(USER_ITEM_POS(7), MAIN_MENU_ITEM_7_DESC)
#endif
#if HAS_USER_ITEM(8)
_USER_ITEM(8)
.colors(thcolor[7])
#if defined(MAIN_MENU_ITEM_8_DESC)
//_USER_ITEM(8)
.tag(_ITEM_TAG(18)).button(USER_ITEM_POS(8), MAIN_MENU_ITEM_8_DESC)
#endif
#if HAS_USER_ITEM(9)
_USER_ITEM(9)
#if DISABLED(TOOLHEAD_Legacy_Universal)
#undef GRID_ROWS
#define GRID_ROWS 8
#endif
#if HAS_USER_ITEM(10)
_USER_ITEM(10)
#endif
#if HAS_USER_ITEM(11)
_USER_ITEM(11)
#endif
#if HAS_USER_ITEM(12)
_USER_ITEM(12)
#endif
#if HAS_USER_ITEM(13)
_USER_ITEM(13)
#endif
#if HAS_USER_ITEM(14)
_USER_ITEM(14)
#endif
#if HAS_USER_ITEM(15)
_USER_ITEM(15)
#endif
#if HAS_USER_ITEM(16)
_USER_ITEM(16)
#endif
#if HAS_USER_ITEM(17)
_USER_ITEM(17)
#endif
#if HAS_USER_ITEM(18)
_USER_ITEM(18)
#endif
#if HAS_USER_ITEM(19)
_USER_ITEM(19)
#endif
#if HAS_USER_ITEM(20)
_USER_ITEM(20)
#endif
.colors(action_btn)
.tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
#ifdef PARKING_COMMAND_GCODE
.tag(20).colors(normal_btn).button(TOOLHEAD_SWAP_POS, GET_TEXT_F(MSG_TOOL_HEAD_SWAP))
#endif
.tag(1).colors(action_btn).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
}
}
bool CustomUserMenus::onTouchEnd(uint8_t tag) {
switch (tag) {
#if HAS_USER_ITEM(1)
_USER_ACTION(1)
#if defined(MAIN_MENU_ITEM_1_DESC)
//_USER_ACTION(1)
case _ITEM_TAG(11): injectCommands_P(PSTR(MAIN_MENU_ITEM_1_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(2)
_USER_ACTION(2)
#if defined(MAIN_MENU_ITEM_2_DESC)
//_USER_ACTION(2)
case _ITEM_TAG(12): injectCommands_P(PSTR(MAIN_MENU_ITEM_2_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(3)
_USER_ACTION(3)
#if defined(MAIN_MENU_ITEM_3_DESC)
//_USER_ACTION(3)
case _ITEM_TAG(13): injectCommands_P(PSTR(MAIN_MENU_ITEM_3_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(4)
_USER_ACTION(4)
#if defined(MAIN_MENU_ITEM_4_DESC)
//_USER_ACTION(4)
case _ITEM_TAG(14): injectCommands_P(PSTR(MAIN_MENU_ITEM_4_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(5)
_USER_ACTION(5)
#if defined(MAIN_MENU_ITEM_5_DESC)
//_USER_ACTION(5)
case _ITEM_TAG(15): injectCommands_P(PSTR(MAIN_MENU_ITEM_5_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(6)
_USER_ACTION(6)
#if defined(MAIN_MENU_ITEM_6_DESC)
//_USER_ACTION(6)
case _ITEM_TAG(16): injectCommands_P(PSTR(MAIN_MENU_ITEM_6_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen); break;
#endif
#if HAS_USER_ITEM(7)
_USER_ACTION(7)
#if defined(MAIN_MENU_ITEM_7_DESC)
//_USER_ACTION(7)
case _ITEM_TAG(17): injectCommands_P(PSTR(MAIN_MENU_ITEM_7_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen);break;
#endif
#if HAS_USER_ITEM(8)
_USER_ACTION(8)
#endif
#if HAS_USER_ITEM(9)
_USER_ACTION(9)
#endif
#if HAS_USER_ITEM(10)
_USER_ACTION(10)
#endif
#if HAS_USER_ITEM(11)
_USER_ACTION(11)
#endif
#if HAS_USER_ITEM(12)
_USER_ACTION(12)
#endif
#if HAS_USER_ITEM(13)
_USER_ACTION(13)
#endif
#if HAS_USER_ITEM(14)
_USER_ACTION(14)
#endif
#if HAS_USER_ITEM(15)
_USER_ACTION(15)
#endif
#if HAS_USER_ITEM(16)
_USER_ACTION(16)
#endif
#if HAS_USER_ITEM(17)
_USER_ACTION(17)
#endif
#if HAS_USER_ITEM(18)
_USER_ACTION(18)
#endif
#if HAS_USER_ITEM(19)
_USER_ACTION(19)
#endif
#if HAS_USER_ITEM(20)
_USER_ACTION(20)
#if defined(MAIN_MENU_ITEM_8_DESC)
//_USER_ACTION(8)
case _ITEM_TAG(18): injectCommands_P(PSTR(MAIN_MENU_ITEM_8_GCODE));sound.play(chimes, PLAY_ASYNCHRONOUS); GOTO_SCREEN(StatusScreen);break;
#endif
case 1: GOTO_PREVIOUS(); break;
#ifdef PARKING_COMMAND_GCODE
case 20: injectCommands(F(PARKING_COMMAND_GCODE)); break;
#endif
default: return false;
}
return true;

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -48,8 +49,33 @@ template void DialogBoxBaseClass::drawMessage(PGM_P const, const int16_t);
void DialogBoxBaseClass::drawYesNoButtons(uint8_t default_btn) {
CommandProcessor cmd;
cmd.font(font_medium)
.colors(default_btn == 1 ? action_btn : normal_btn).tag(1).button(BTN_POS(1,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_YES))
.colors(default_btn == 2 ? action_btn : normal_btn).tag(2).button(BTN_POS(2,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_NO));
.colors(default_btn == 1 ? action_btn : action_btn).tag(1).button(BTN_POS(2,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_YES))
.colors(default_btn == 2 ? action_btn : normal_btn).tag(2).button(BTN_POS(1,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_NO));
}
void DialogBoxBaseClass::drawStartPrintButtons(uint8_t default_btn) {
#undef GRID_COLS
#undef GRID_ROWS
#define GRID_COLS 1
#define GRID_ROWS 13
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART)
.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0);
draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(1,3), GET_TEXT_F(MSG_PRINT_COMPLETE), OPT_CENTER, font_xlarge);
draw_text_box(cmd, BTN_POS(1,5), BTN_SIZE(1,3), GET_TEXT_F(MSG_PRINT_AREA_CLEAR), OPT_CENTER, font_large);
cmd.font(font_large)
.colors(normal_btn).tag(1).button(BTN_POS(1,9), BTN_SIZE(1,2), GET_TEXT_F(MSG_START_NEXT_PRINT))
.colors(action_btn).tag(2).button(BTN_POS(1,11), BTN_SIZE(1,2), GET_TEXT_F(MSG_MAIN_MENU));
#undef GRID_COLS
#undef GRID_ROWS
#define GRID_COLS 2
#define GRID_ROWS 8
}
void DialogBoxBaseClass::drawOkayButton() {
@ -58,6 +84,12 @@ void DialogBoxBaseClass::drawOkayButton() {
.tag(1).button(BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BUTTON_OKAY));
}
void DialogBoxBaseClass::drawDoneButton() {
CommandProcessor cmd;
cmd.font(font_medium)
.tag(1).colors(action_btn).button(BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BUTTON_DONE));
}
template<typename T>
void DialogBoxBaseClass::drawButton(T label) {
CommandProcessor cmd;
@ -68,10 +100,17 @@ void DialogBoxBaseClass::drawButton(T label) {
template void DialogBoxBaseClass::drawButton(const char *);
template void DialogBoxBaseClass::drawButton(FSTR_P);
void DialogBoxBaseClass::drawFilamentButtons() {
CommandProcessor cmd;
cmd.font(font_medium)
.tag(1).button(BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_FILAMENT_CHANGE_OPTION_PURGE))
.tag(2).button(BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_FILAMENT_CHANGE_OPTION_RESUME));
}
bool DialogBoxBaseClass::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); return true;
case 2: GOTO_PREVIOUS(); return true;
case 1: GOTO_SCREEN(StatusScreen); return true;
case 2: GOTO_SCREEN(StatusScreen); return true;
default: return false;
}
}

View file

@ -32,7 +32,10 @@ class DialogBoxBaseClass : public BaseScreen {
template<typename T> static void drawButton(T);
static void drawYesNoButtons(uint8_t default_btn = 0);
static void drawStartPrintButtons(uint8_t default_btn = 0);
static void drawOkayButton();
static void drawDoneButton();
static void drawFilamentButtons();
static void onRedraw(draw_mode_t) {}

View file

@ -27,11 +27,13 @@
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
void FeedratePercentScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
w.precision(0).units(GET_TEXT_F(MSG_UNITS_PERCENT));
w.color(feedrate);
w.heading(GET_TEXT_F(MSG_PRINT_SPEED));
w.adjuster(4, GET_TEXT_F(MSG_SPEED), getFeedrate_percent());
w.increments();

View file

@ -0,0 +1,72 @@
/**************************************
* filament_prompt_box.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#include "../screens.h"
#include "../screen_data.h"
#ifdef FTDI_FILAMENT_PROMPT_BOX
using namespace FTDI;
// Need to be renamed to Filament Purge prompt?
void FilamentPromptBox::onRedraw(draw_mode_t mode) {
AlertDialogBox::onRedraw(mode); // Required for the GOTO_SCREEN function to work
//GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE),GET_TEXT_F(MSG_FILAMENT_CHANGE_OPTION_PURGE), GET_TEXT_F(MSG_FILAMENT_CHANGE_OPTION_RESUME))
drawMessage(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE));
drawFilamentButtons();
}
bool FilamentPromptBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
#if ENABLED(ADVANCED_PAUSE_FEATURE)
pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE;
#endif
return true;
case 2:
#if ENABLED(ADVANCED_PAUSE_FEATURE)
pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT;
#endif
GOTO_SCREEN(StatusScreen);
return true;
default:
return false;
}
}
void FilamentPromptBox::show() {
drawMessage(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE));
drawFilamentButtons();
storeBackground();
screen_data.AlertDialogBox.isError = false;
if (!AT_SCREEN(FilamentPromptBox))
GOTO_SCREEN(FilamentPromptBox);
}
void FilamentPromptBox::hide() {
if (AT_SCREEN(FilamentPromptBox))
GOTO_PREVIOUS();
}
#endif // FTDI_FILAMENT_PROMPT_BOX

View file

@ -0,0 +1,35 @@
/************************************
* filament_prompt_box.h *
************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#define FTDI_FILAMENT_PROMPT_BOX
#define FTDI_FILAMENT_PROMPT_BOX_CLASS FilamentPromptBox
class FilamentPromptBox : public AlertDialogBox {
public:
static void onRedraw(draw_mode_t);
static bool onTouchEnd(uint8_t);
static void hide();
static void show();
};

View file

@ -0,0 +1,67 @@
/************************
* filament_prompt_dialog_box.cpp *
************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#include "../screens.h"
#include "../screen_data.h"
#ifdef FTDI_FILAMENT_PROMPT_DIALOG_BOX
constexpr static FilamentPromptDialogBoxData &mydata = screen_data.FilamentPromptDialogBox;
using namespace FTDI;
using namespace Theme;
void FilamentPromptDialogBox::onEntry() {
BaseScreen::onEntry();
sound.play(mydata.isError ? sad_trombone : twinkle, PLAY_ASYNCHRONOUS);
}
void FilamentPromptDialogBox::onRedraw(draw_mode_t what) {
if (what & FOREGROUND) {
drawMessage(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE));
drawFilamentButtons();
}
}
void FilamentPromptDialogBox::show() {
drawMessage(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE));
drawFilamentButtons();
storeBackground();
mydata.isError = false;
GOTO_SCREEN(FilamentPromptDialogBox);
}
void FilamentPromptDialogBox::showError() {
drawMessage(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE_CONTINUE));
storeBackground();
mydata.isError = true;
GOTO_SCREEN(FilamentPromptDialogBox);
}
void FilamentPromptDialogBox::hide() {
if (AT_SCREEN(FilamentPromptDialogBox))
GOTO_PREVIOUS();
}
#endif // FTDI_ALERT_DIALOG_BOX

View file

@ -0,0 +1,40 @@
/**********************
* filament_prompt_dialog_box.h *
**********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <https://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#define FTDI_FILAMENT_PROMPT_DIALOG_BOX
#define FTDI_FILAMENT_PROMPT_DIALOG_BOX_CLASS FilamentPromptDialogBox
struct FilamentPromptDialogBoxData {
bool isError;
};
class FilamentPromptDialogBox : public DialogBoxBaseClass, public CachedScreen<FILAMENT_PROMPT_BOX_CACHE,FILAMENT_PROMPT_BOX_DL_SIZE> {
public:
static void onEntry();
static void onRedraw(draw_mode_t);
static void show();
static void showError();
static void hide();
};

View file

@ -112,20 +112,16 @@ void FilesScreen::drawFileButton(int x, int y, int w, int h, const char *filenam
cmd.font(font_medium).rectangle(bx, by, bw, bh);
cmd.cmd(COLOR_RGB(is_highlighted ? normal_btn.rgb : bg_text_enabled));
if (TERN0(SCROLL_LONG_FILENAMES, is_highlighted)) {
#if ENABLED(SCROLL_LONG_FILENAMES)
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x,y));
cmd.cmd(SCISSOR_SIZE(w,h));
cmd.cmd(MACRO(0));
cmd.text(bx, by, bw, bh, filename, OPT_CENTERY | OPT_NOFIT);
#endif
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x,y));
cmd.cmd(SCISSOR_SIZE(w,h));
cmd.cmd(MACRO(0));
cmd.text(bx, by, bw, bh, filename, OPT_CENTERY | OPT_NOFIT);
}
else
draw_text_with_ellipsis(cmd, bx,by, bw - (is_dir ? 20 : 0), bh, filename, OPT_CENTERY, font_medium);
draw_text_with_ellipsis(cmd, bx, by, bw - (is_dir ? 20 : 0), bh, filename, OPT_CENTERY, font_medium);
if (is_dir && !is_highlighted) cmd.text(bx, by, bw, bh, F("> "), OPT_CENTERY | OPT_RIGHTX);
#if ENABLED(SCROLL_LONG_FILENAMES)
if (is_highlighted) cmd.cmd(RESTORE_CONTEXT());
#endif
if (TERN0(SCROLL_LONG_FILENAMES, is_highlighted)) cmd.cmd(RESTORE_CONTEXT());
}
void FilesScreen::drawFileList() {
@ -174,7 +170,7 @@ void FilesScreen::drawFooter() {
if (mydata.flags.is_root)
cmd.tag(240).button(BTN2_POS, GET_TEXT_F(MSG_BUTTON_DONE));
else
cmd.tag(245).button(BTN2_POS, F("Up Dir"));
cmd.tag(245).button(BTN2_POS, F("Back"));
cmd.enabled(has_selection)
.colors(has_selection ? action_btn : normal_btn);
@ -220,7 +216,8 @@ bool FilesScreen::onTouchEnd(uint8_t tag) {
GOTO_PREVIOUS();
return true;
case 241: // Print highlighted file
ConfirmStartPrintDialogBox::show(getSelectedFileIndex());
printFile(getSelectedShortFilename());
GOTO_SCREEN(StatusScreen);
return true;
case 242: // Previous page
if (mydata.cur_page > 0) {

View file

@ -31,7 +31,7 @@ void FlowPercentScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
w.precision(0).units(GET_TEXT_F(MSG_UNITS_PERCENT));
w.heading(GET_TEXT_F(MSG_FLOW));
w.heading(GET_TEXT_F(MSG_FLOW_PERCENTAGE));
w.adjuster(4, GET_TEXT_F(MSG_FLOW), getFlow_percent(E0));
w.increments();
}

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -40,12 +41,15 @@ using namespace Theme;
#define LEVEL_AXIS_POS BTN_POS(1,2), BTN_SIZE(2,1)
#define BED_MESH_TITLE_POS BTN_POS(1,3), BTN_SIZE(2,1)
#define PROBE_BED_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define ZOFFSET_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define TEST_MESH_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define SHOW_MESH_POS BTN_POS(1,5), BTN_SIZE(1,1)
#define EDIT_MESH_POS BTN_POS(2,5), BTN_SIZE(1,1)
#define BLTOUCH_TITLE_POS BTN_POS(1,6), BTN_SIZE(2,1)
#define BLTOUCH_RESET_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define BLTOUCH_TEST_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define EDIT_MESH_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define BLTOUCH_TITLE_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define BLTOUCH_RESET_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define BLTOUCH_TEST_POS BTN_POS(2,6), BTN_SIZE(1,1)
#define BLTOUCH_DEPLOY_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define BLTOUCH_STOW_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,8), BTN_SIZE(2,1)
#else
#define GRID_COLS 3
@ -54,12 +58,15 @@ using namespace Theme;
#define LEVEL_AXIS_POS BTN_POS(1,2), BTN_SIZE(3,1)
#define BED_MESH_TITLE_POS BTN_POS(1,3), BTN_SIZE(2,1)
#define PROBE_BED_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define ZOFFSET_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define TEST_MESH_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define SHOW_MESH_POS BTN_POS(1,5), BTN_SIZE(1,1)
#define EDIT_MESH_POS BTN_POS(2,5), BTN_SIZE(1,1)
#define BLTOUCH_TITLE_POS BTN_POS(3,3), BTN_SIZE(1,1)
#define BLTOUCH_RESET_POS BTN_POS(3,4), BTN_SIZE(1,1)
#define BLTOUCH_TEST_POS BTN_POS(3,5), BTN_SIZE(1,1)
#define BLTOUCH_DEPLOY_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define BLTOUCH_STOW_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,6), BTN_SIZE(3,1)
#endif
@ -81,19 +88,24 @@ void LevelingMenu::onRedraw(draw_mode_t what) {
.text(BLTOUCH_TITLE_POS, GET_TEXT_F(MSG_BLTOUCH))
#endif
.font(font_medium).colors(normal_btn)
.enabled(ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION))
.enabled(ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION,X_LEVEL_SEQUENCE))
.tag(2).button(LEVEL_AXIS_POS, GET_TEXT_F(MSG_LEVEL_X_AXIS))
.enabled(ENABLED(HAS_BED_PROBE))
.tag(3).button(PROBE_BED_POS, GET_TEXT_F(MSG_PROBE_BED))
.tag(4).button(ZOFFSET_POS, GET_TEXT_F(MSG_ZOFFSET))
#if DISABLED (AUTO_BED_LEVELING_BILINEAR)
.enabled(ENABLED(HAS_MESH))
.tag(4).button(SHOW_MESH_POS, GET_TEXT_F(MSG_MESH_VIEW))
.tag(5).button(SHOW_MESH_POS, GET_TEXT_F(MSG_MESH_VIEW))
.enabled(ENABLED(HAS_MESH))
.tag(5).button(EDIT_MESH_POS, GET_TEXT_F(MSG_EDIT_MESH))
.tag(6).button(EDIT_MESH_POS, GET_TEXT_F(MSG_EDIT_MESH))
.enabled(ENABLED(G26_MESH_VALIDATION))
.tag(6).button(TEST_MESH_POS, GET_TEXT_F(MSG_PRINT_TEST))
.tag(7).button(TEST_MESH_POS, GET_TEXT_F(MSG_PRINT_TEST))
#endif
#if ENABLED(BLTOUCH)
.tag(7).button(BLTOUCH_RESET_POS, GET_TEXT_F(MSG_BLTOUCH_RESET))
.tag(8).button(BLTOUCH_TEST_POS, GET_TEXT_F(MSG_BLTOUCH_SELFTEST))
.tag(8).button(BLTOUCH_RESET_POS, GET_TEXT_F(MSG_BLTOUCH_RESET))
.tag(9).button(BLTOUCH_TEST_POS, GET_TEXT_F(MSG_BLTOUCH_SELFTEST))
.tag(10).button(BLTOUCH_DEPLOY_POS, GET_TEXT_F(MSG_BLTOUCH_DEPLOY))
.tag(11).button(BLTOUCH_STOW_POS, GET_TEXT_F(MSG_BLTOUCH_STOW))
#endif
.colors(action_btn)
.tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
@ -103,13 +115,13 @@ void LevelingMenu::onRedraw(draw_mode_t what) {
bool LevelingMenu::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); break;
#if ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION)
case 2: SpinnerDialogBox::enqueueAndWait(F("G34")); break;
#if ANY(Z_STEPPER_AUTO_ALIGN, MECHANICAL_GANTRY_CALIBRATION, X_LEVEL_SEQUENCE)
case 2: SpinnerDialogBox::enqueueAndWait(F(LEVELING_COMMANDS)); break;
#endif
#if HAS_BED_PROBE
case 3:
#ifndef BED_LEVELING_COMMANDS
#define BED_LEVELING_COMMANDS "G29"
#define BED_LEVELING_COMMANDS "G28\nG29"
#endif
#if ENABLED(AUTO_BED_LEVELING_UBL)
BedMeshViewScreen::doProbe();
@ -118,19 +130,22 @@ bool LevelingMenu::onTouchEnd(uint8_t tag) {
#endif
break;
#endif
case 4: GOTO_SCREEN(ZOffsetScreen); break;
#if ENABLED(AUTO_BED_LEVELING_UBL)
case 4: BedMeshViewScreen::show(); break;
case 5: BedMeshEditScreen::show(); break;
case 5: BedMeshViewScreen::show(); break;
case 6: BedMeshEditScreen::show(); break;
#endif
#if ENABLED(G26_MESH_VALIDATION)
case 6:
case 7:
GOTO_SCREEN(StatusScreen);
injectCommands(F("G28\nM117 Heating...\nG26 R X0 Y0\nG27"));
break;
#endif
#if ENABLED(BLTOUCH)
case 7: injectCommands(F("M280 P0 S60")); break;
case 8: SpinnerDialogBox::enqueueAndWait(F("M280 P0 S90\nG4 P100\nM280 P0 S120")); break;
case 8: injectCommands(F("M280 P0 S60")); break;
case 9: SpinnerDialogBox::enqueueAndWait(F("M280 P0 S90\nG4 P100\nM280 P0 S120")); break;
case 10: injectCommands(F("M401\nM140 S0")); break;
case 11: injectCommands(F("M402")); break;
#endif
default: return false;
}

View file

@ -6,6 +6,7 @@
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Cocoa Press *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -38,39 +39,29 @@ void MainMenu::onRedraw(draw_mode_t what) {
#if ENABLED(TOUCH_UI_PORTRAIT)
#define GRID_COLS 2
#define GRID_ROWS 8
#define ABOUT_PRINTER_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define ADVANCED_SETTINGS_POS BTN_POS(1,2), BTN_SIZE(2,1)
#if ENABLED(CUSTOM_MENU_MAIN)
#define FILAMENTCHANGE_POS BTN_POS(1,3), BTN_SIZE(1,1)
#define CUSTOM_MENU_POS BTN_POS(2,3), BTN_SIZE(1,1)
#else
#define FILAMENTCHANGE_POS BTN_POS(1,3), BTN_SIZE(2,1)
#endif
#define GRID_ROWS 7
#define MOVE_AXIS_POS BTN_POS(1,1), BTN_SIZE(1,1)
#define DISABLE_STEPPERS_POS BTN_POS(2,1), BTN_SIZE(1,1)
#define BACKLASH_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define CLEAN_NOZZLE_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define LEVELING_POS BTN_POS(1,3), BTN_SIZE(1,1)
#define Z_OFFSET_POS BTN_POS(2,3), BTN_SIZE(1,1)
#define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(2,1)
#define DISABLE_STEPPERS_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define MOVE_AXIS_POS BTN_POS(1,6), BTN_SIZE(1,1)
#define LEVELING_POS BTN_POS(2,6), BTN_SIZE(1,1)
#define AUTO_HOME_POS BTN_POS(1,7), BTN_SIZE(1,1)
#define CLEAN_NOZZLE_POS BTN_POS(2,7), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(1,8), BTN_SIZE(2,1)
#define ABOUT_PRINTER_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define ADVANCED_SETTINGS_POS BTN_POS(1,6), BTN_SIZE(2,1)
#define BACK_POS BTN_POS(1,7), BTN_SIZE(2,1)
#else
#define GRID_COLS 6
#define GRID_ROWS 5
#define ADVANCED_SETTINGS_POS BTN_POS(1,1), BTN_SIZE(3,1)
#define ABOUT_PRINTER_POS BTN_POS(4,1), BTN_SIZE(3,1)
#define AUTO_HOME_POS BTN_POS(1,2), BTN_SIZE(3,1)
#define CLEAN_NOZZLE_POS BTN_POS(4,2), BTN_SIZE(3,1)
#define BACKLASH_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define CLEAN_NOZZLE_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define MOVE_AXIS_POS BTN_POS(1,3), BTN_SIZE(3,1)
#define Z_OFFSET_POS BTN_POS(2,3), BTN_SIZE(1,1)
#define DISABLE_STEPPERS_POS BTN_POS(4,3), BTN_SIZE(3,1)
#if ENABLED(CUSTOM_MENU_MAIN)
#define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(2,1)
#define FILAMENTCHANGE_POS BTN_POS(3,4), BTN_SIZE(2,1)
#define CUSTOM_MENU_POS BTN_POS(5,4), BTN_SIZE(2,1)
#else
#define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(3,1)
#define FILAMENTCHANGE_POS BTN_POS(4,4), BTN_SIZE(3,1)
#endif
#define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(2,1)
#define LEVELING_POS BTN_POS(1,5), BTN_SIZE(3,1)
#define BACK_POS BTN_POS(4,5), BTN_SIZE(3,1)
#endif
@ -79,23 +70,20 @@ void MainMenu::onRedraw(draw_mode_t what) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(Theme::font_medium)
.tag( 2).button(AUTO_HOME_POS, GET_TEXT_F(MSG_AUTO_HOME))
.enabled(ENABLED(NOZZLE_CLEAN_FEATURE))
.tag( 3).button(CLEAN_NOZZLE_POS, GET_TEXT_F(MSG_CLEAN_NOZZLE))
.tag( 4).button(MOVE_AXIS_POS, GET_TEXT_F(MSG_MOVE_AXIS))
.tag( 5).button(DISABLE_STEPPERS_POS,GET_TEXT_F(MSG_DISABLE_STEPPERS))
.tag( 6).button(TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE))
.enabled(DISABLED(TOUCH_UI_LULZBOT_BIO))
.tag( 7).button(FILAMENTCHANGE_POS, GET_TEXT_F(MSG_FILAMENTCHANGE))
.tag( 8).button(ADVANCED_SETTINGS_POS, GET_TEXT_F(MSG_ADVANCED_SETTINGS))
.enabled(ENABLED(HAS_LEVELING))
.tag( 9).button(LEVELING_POS, GET_TEXT_F(MSG_LEVELING))
.tag(10).button(ABOUT_PRINTER_POS, GET_TEXT_F(MSG_INFO_MENU))
#if ENABLED(CUSTOM_MENU_MAIN)
.tag(11).button(CUSTOM_MENU_POS, GET_TEXT_F(MSG_CUSTOM_COMMANDS))
#endif
.tag(2).button(MOVE_AXIS_POS, GET_TEXT_F(MSG_MOVE_AXIS))
.tag(3).button(DISABLE_STEPPERS_POS, F(""));
draw_text_box(cmd, DISABLE_STEPPERS_POS, F("Disable\nMotors"), OPT_CENTER, font_medium);
cmd.tag(4).button(BACKLASH_POS, GET_TEXT_F(MSG_BACKLASH))
.tag(5).button(CLEAN_NOZZLE_POS, GET_TEXT_F(MSG_CLEAN_NOZZLE))
.tag(6).button(TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE))
.enabled(DISABLED(TOUCH_UI_LULZBOT_BIO))
.tag(7).button(ADVANCED_SETTINGS_POS, GET_TEXT_F(MSG_ADVANCED_SETTINGS))
.enabled(ENABLED(HAS_LEVELING))
.tag(8).button(LEVELING_POS, GET_TEXT_F(MSG_LEVELING))
.tag(9).button(Z_OFFSET_POS, GET_TEXT_F(MSG_ZOFFSET))
.tag(10).button(ABOUT_PRINTER_POS, GET_TEXT_F(MSG_INFO_MENU))
.colors(action_btn)
.tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
.tag(1).button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
}
}
@ -104,31 +92,33 @@ bool MainMenu::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
case 2: SpinnerDialogBox::enqueueAndWait(F("G28")); break;
#if ENABLED(NOZZLE_CLEAN_FEATURE)
case 3:
injectCommands(F("G12"));
GOTO_SCREEN(StatusScreen); break;
case 2: GOTO_SCREEN(MoveAxisScreen); break;
case 3: injectCommands(F("M84")); break;
#if ENABLED(BACKLASH_COMPENSATION)
case 4: GOTO_SCREEN(BacklashCompensationScreen); break;
#endif
case 4: GOTO_SCREEN(MoveAxisScreen); break;
case 5:
injectCommands(F("M84 E"
TERN_(DISABLE_IDLE_X, " X")
TERN_(DISABLE_IDLE_Y, " Y")
TERN_(DISABLE_IDLE_Z, " Z")
));
GOTO_SCREEN(StatusScreen);
#ifndef CLEAN_SCRIPT
#define CLEAN_SCRIPT "G12"
#endif
injectCommands(F(CLEAN_SCRIPT));
break;
case 6: GOTO_SCREEN(TemperatureScreen); break;
case 7: GOTO_SCREEN(ChangeFilamentScreen); break;
case 8: GOTO_SCREEN(AdvancedSettingsMenu); break;
case 6: GOTO_SCREEN(TemperatureScreen); break;
case 7: GOTO_SCREEN(AdvancedSettingsMenu); break;
#if HAS_LEVELING
case 9: GOTO_SCREEN(LevelingMenu); break;
case 8: GOTO_SCREEN(LevelingMenu); break;
#endif
case 10: GOTO_SCREEN(AboutScreen); break;
#if ENABLED(CUSTOM_MENU_MAIN)
case 11: GOTO_SCREEN(CustomUserMenus); break;
#if ALL(HAS_LEVELING, HAS_BED_PROBE)
case 9:
#if EXTRUDERS > 1
GOTO_SCREEN(NudgeNozzleScreen);
#else
GOTO_SCREEN(ZOffsetScreen);
#endif
break;
#endif
case 10: GOTO_SCREEN(AboutScreen); break;
default:
return false;
}

View file

@ -28,6 +28,7 @@
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
constexpr static MoveAxisScreenData &mydata = screen_data.MoveAxisScreen;
@ -42,9 +43,12 @@ void BaseMoveAxisScreen::onEntry() {
}
BaseNumericAdjustmentScreen::onEntry();
}
#define GRID_COLS 13
#define GRID_ROWS (8+EXTRUDERS)
void MoveAxisScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
CommandProcessor cmd;
w.precision(1);
w.units(GET_TEXT_F(MSG_UNITS_MM));
w.heading( GET_TEXT_F(MSG_MOVE_AXIS));
@ -70,6 +74,13 @@ void MoveAxisScreen::onRedraw(draw_mode_t what) {
w.button(24, GET_TEXT_F(MSG_MOVE_Z_TO_TOP), !axis_should_home(Z_AXIS));
#endif
w.increments();
#ifdef PARKING_COMMAND_GCODE
if (!ExtUI::isPrinting()) { // making sure the Tool Head Swap Position is not avalible while printing
cmd.font(font_medium)
.colors(normal_btn)
.tag(25).button(BTN_POS(1,(7+EXTRUDERS)), BTN_SIZE(13,1), GET_TEXT_F(MSG_TOOL_HEAD_SWAP));
}
#endif
}
bool BaseMoveAxisScreen::onTouchHeld(const uint8_t tag) {
@ -111,6 +122,9 @@ bool BaseMoveAxisScreen::onTouchHeld(const uint8_t tag) {
#endif
#endif
case 23: SpinnerDialogBox::enqueueAndWait(F("G28")); break;
#ifdef PARKING_COMMAND_GCODE
case 25: injectCommands(F(PARKING_COMMAND_GCODE)); break;
#endif
default:
return false;
}

View file

@ -32,6 +32,9 @@ using namespace ExtUI;
constexpr static NudgeNozzleScreenData &mydata = screen_data.NudgeNozzleScreen;
#define GRID_COLS 13
#define GRID_ROWS (9+EXTRUDERS)
void NudgeNozzleScreen::onEntry() {
mydata.show_offsets = false;
#if HAS_MULTI_EXTRUDER
@ -44,9 +47,10 @@ void NudgeNozzleScreen::onEntry() {
void NudgeNozzleScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
CommandProcessor cmd;
w.precision(2, BaseNumericAdjustmentScreen::DEFAULT_MIDRANGE).units(GET_TEXT_F(MSG_UNITS_MM));
w.heading(GET_TEXT_F(MSG_NUDGE_NOZZLE));
w.heading(GET_TEXT_F(MSG_ZOFFSET));
#if ENABLED(BABYSTEP_XY)
w.color(x_axis).adjuster(2, GET_TEXT_F(MSG_AXIS_X), mydata.rel.x / getAxisSteps_per_mm(X));
w.color(y_axis).adjuster(4, GET_TEXT_F(MSG_AXIS_Y), mydata.rel.y / getAxisSteps_per_mm(Y));
@ -70,7 +74,7 @@ void NudgeNozzleScreen::onRedraw(draw_mode_t what) {
dtostrf(getZOffset_mm(), 4, 2, str);
strcat(str, " ");
strcat_P(str, GET_TEXT(MSG_UNITS_MM));
w.text_field(0, GET_TEXT_F(MSG_ZPROBE_ZOFFSET), str);
w.text_field(0, GET_TEXT_F(MSG_ZOFFSET), str);
#endif
#if HAS_MULTI_HOTEND
@ -79,6 +83,11 @@ void NudgeNozzleScreen::onRedraw(draw_mode_t what) {
#endif
}
#endif
if (what & FOREGROUND) {
cmd.colors(normal_btn)
.font(font_medium)
.tag(10).colors(action_btn).button(BTN_POS(1,GRID_ROWS), BTN_SIZE(GRID_COLS,1), GET_TEXT_F(MSG_BUTTON_DONE));
}
}
bool NudgeNozzleScreen::onTouchHeld(uint8_t tag) {
@ -100,6 +109,7 @@ bool NudgeNozzleScreen::onTouchHeld(uint8_t tag) {
case 8: mydata.link_nozzles = !link; break;
#endif
case 9: mydata.show_offsets = !mydata.show_offsets; break;
case 10: GOTO_SCREEN(SaveSettingsDialogBox); break;
default: return false;
}
#if HAS_MULTI_EXTRUDER || HAS_BED_PROBE

View file

@ -27,6 +27,8 @@
using namespace ExtUI;
using namespace Theme;
bool SaveSettingsDialogBox::needs_save = false;
void SaveSettingsDialogBox::onRedraw(draw_mode_t) {
@ -39,7 +41,9 @@ bool SaveSettingsDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
injectCommands(F("M500"));
AlertDialogBox::show(GET_TEXT_F(MSG_EEPROM_SAVED));
sound.play(twinkle, PLAY_ASYNCHRONOUS);
GOTO_SCREEN(StatusScreen);
//AlertDialogBox::show(GET_TEXT_F(MSG_EEPROM_SAVED));
// Remove SaveSettingsDialogBox from the stack
// so the alert box doesn't return to me.
current_screen.forget();

View file

@ -33,6 +33,7 @@ enum {
MENU_SCREEN_CACHE,
TUNE_SCREEN_CACHE,
ALERT_BOX_CACHE,
FILAMENT_PROMPT_BOX_CACHE,
SPINNER_CACHE,
ADVANCED_SETTINGS_SCREEN_CACHE,
MOVE_AXIS_SCREEN_CACHE,
@ -101,6 +102,7 @@ enum {
#define STATUS_SCREEN_DL_SIZE 4096
#define ALERT_BOX_DL_SIZE 3072
#define FILAMENT_PROMPT_BOX_DL_SIZE 3072
#define SPINNER_DL_SIZE 3072
#define FILE_SCREEN_DL_SIZE 4160
#define PRINTING_SCREEN_DL_SIZE 2048
@ -118,12 +120,14 @@ enum {
#include "about_screen.h"
#include "kill_screen.h"
#include "alert_dialog_box.h"
#include "filament_prompt_dialog_box.h"
#include "spinner_dialog_box.h"
#include "restore_failsafe_dialog_box.h"
#include "save_settings_dialog_box.h"
#include "confirm_start_print_dialog_box.h"
#include "confirm_abort_print_dialog_box.h"
#include "confirm_user_request_alert_box.h"
#include "filament_prompt_box.h"
#include "touch_calibration_screen.h"
#include "touch_registers_screen.h"
#include "change_filament_screen.h"
@ -140,6 +144,7 @@ enum {
#include "endstop_state_screen.h"
#include "display_tuning_screen.h"
#include "media_player_screen.h"
#include "flow_percent_screen.h"
#if ENABLED(PRINTCOUNTER)
#include "statistics_screen.h"

View file

@ -44,7 +44,7 @@ void StatisticsScreen::onRedraw(draw_mode_t what) {
.tag(0)
.font(Theme::font_medium)
.text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_INFO_STATS_MENU))
.text(BTN_POS(1,1), BTN_SIZE(4,1), GET_TEXT_F(MSG_INFO_PRINTER_STATS_MENU))
.font(Theme::font_small)
.tag(0)
.text(BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_INFO_PRINT_COUNT), OPT_RIGHTX | OPT_CENTERY)

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -30,48 +31,50 @@
using namespace FTDI;
using namespace Theme;
using namespace ExtUI;
#define GRID_COLS 3
#define GRID_COLS 9
#define GRID_ROWS 16
void StatusScreen::draw_axis_position(draw_mode_t what) {
CommandProcessor cmd;
#if ENABLED(TOUCH_UI_PORTRAIT)
#define X_LBL_POS BTN_POS(1, 9), BTN_SIZE(1,2)
#define Y_LBL_POS BTN_POS(1,11), BTN_SIZE(1,2)
#define Z_LBL_POS BTN_POS(1,13), BTN_SIZE(1,2)
#define X_VAL_POS BTN_POS(2, 9), BTN_SIZE(2,2)
#define Y_VAL_POS BTN_POS(2,11), BTN_SIZE(2,2)
#define Z_VAL_POS BTN_POS(2,13), BTN_SIZE(2,2)
#define X_LBL_POS BTN_POS(1,7), BTN_SIZE(2,2)
#define Y_LBL_POS BTN_POS(4,7), BTN_SIZE(2,2)
#define Z_LBL_POS BTN_POS(7,7), BTN_SIZE(2,2)
#define X_VAL_POS BTN_POS(2,7), BTN_SIZE(2,2)
#define Y_VAL_POS BTN_POS(5,7), BTN_SIZE(2,2)
#define Z_VAL_POS BTN_POS(8,7), BTN_SIZE(2,2)
#define ALL_VAL_POS BTN_POS(1,7), BTN_SIZE(9,2)
#else
#define X_LBL_POS BTN_POS(1, 9), BTN_SIZE(1,2)
#define Y_LBL_POS BTN_POS(2, 9), BTN_SIZE(1,2)
#define Z_LBL_POS BTN_POS(3, 9), BTN_SIZE(1,2)
#define X_VAL_POS BTN_POS(1,11), BTN_SIZE(1,2)
#define Y_VAL_POS BTN_POS(2,11), BTN_SIZE(1,2)
#define Z_VAL_POS BTN_POS(3,11), BTN_SIZE(1,2)
#define X_LBL_POS BTN_POS(1, 9), BTN_SIZE(1, 2)
#define Y_LBL_POS BTN_POS(2, 9), BTN_SIZE(1, 2)
#define Z_LBL_POS BTN_POS(3, 9), BTN_SIZE(1, 2)
#define X_VAL_POS BTN_POS(1,11), BTN_SIZE(1, 2)
#define Y_VAL_POS BTN_POS(2,11), BTN_SIZE(1, 2)
#define Z_VAL_POS BTN_POS(3,11), BTN_SIZE(1, 2)
#define ALL_VAL_POS BTN_POS(1, 9), BTN_SIZE(3,11)
#endif
#define _UNION_POS(x1,y1,w1,h1,x2,y2,w2,h2) x1,y1,max(x1+w1,x2+w2)-x1,max(y1+h1,y2+h2)-y1
#define UNION_POS(p1, p2) _UNION_POS(p1, p2)
if (what & BACKGROUND) {
cmd.tag(6)
.fgcolor(Theme::axis_label)
.font(Theme::font_large)
.button(UNION_POS(X_LBL_POS, X_VAL_POS), F(""), OPT_FLAT)
.button(UNION_POS(Y_LBL_POS, Y_VAL_POS), F(""), OPT_FLAT)
.button(UNION_POS(Z_LBL_POS, Z_VAL_POS), F(""), OPT_FLAT)
cmd.tag(0)
.colors(normal_btn)
.font(Theme::font_medium)
.fgcolor(Theme::x_axis) .button(X_VAL_POS, F(""), OPT_FLAT)
.fgcolor(Theme::y_axis) .button(Y_VAL_POS, F(""), OPT_FLAT)
.fgcolor(Theme::z_axis) .button(Z_VAL_POS, F(""), OPT_FLAT)
.font(Theme::font_small)
.text ( X_LBL_POS, GET_TEXT_F(MSG_AXIS_X))
.text ( Y_LBL_POS, GET_TEXT_F(MSG_AXIS_Y))
.text ( Z_LBL_POS, GET_TEXT_F(MSG_AXIS_Z))
.colors(normal_btn);
.text ( X_LBL_POS, GET_TEXT_F(MSG_AXIS_X))
.text ( Y_LBL_POS, GET_TEXT_F(MSG_AXIS_Y))
.text ( Z_LBL_POS, GET_TEXT_F(MSG_AXIS_Z));
if (!ExtUI::isOngoingPrintJob()) {
cmd.tag(6)
.button(X_VAL_POS, F(""), OPT_FLAT)
.button(Y_VAL_POS, F(""), OPT_FLAT)
.button(Z_VAL_POS, F(""), OPT_FLAT)
.button(ALL_VAL_POS, F(""));
}
}
if (what & FOREGROUND) {
@ -81,59 +84,72 @@ void StatusScreen::draw_axis_position(draw_mode_t what) {
char z_str[15];
if (isAxisPositionKnown(X))
format_position(x_str, getAxisPosition_mm(X));
format_position(x_str, getAxisPosition_mm(X), 0);
else
strcpy_P(x_str, PSTR("?"));
if (isAxisPositionKnown(Y))
format_position(y_str, getAxisPosition_mm(Y));
format_position(y_str, getAxisPosition_mm(Y), 0);
else
strcpy_P(y_str, PSTR("?"));
if (isAxisPositionKnown(Z))
format_position(z_str, getAxisPosition_mm(Z), 2);
format_position(z_str, getAxisPosition_mm(Z), 1);
else
strcpy_P(z_str, PSTR("?"));
cmd.tag(6)
.font(Theme::font_medium)
.text(X_VAL_POS, x_str)
.text(Y_VAL_POS, y_str)
.text(Z_VAL_POS, z_str);
if (!ExtUI::isOngoingPrintJob()) {
cmd.tag(6)
.colors(normal_text)
.font(Theme::font_medium)
.text(X_VAL_POS, x_str)
.text(Y_VAL_POS, y_str)
.text(Z_VAL_POS, z_str)
.text(X_LBL_POS, GET_TEXT_F(MSG_AXIS_X))
.text(Y_LBL_POS, GET_TEXT_F(MSG_AXIS_Y))
.text(Z_LBL_POS, GET_TEXT_F(MSG_AXIS_Z));
}
else {
cmd.tag(0)
.colors(temp_btn)
.font(Theme::font_medium)
.text(X_VAL_POS, x_str)
.text(Y_VAL_POS, y_str)
.text(Z_VAL_POS, z_str)
.text(X_LBL_POS, GET_TEXT_F(MSG_AXIS_X))
.text(Y_LBL_POS, GET_TEXT_F(MSG_AXIS_Y))
.text(Z_LBL_POS, GET_TEXT_F(MSG_AXIS_Z));
}
}
}
#undef GRID_COLS
#define GRID_COLS TERN(TOUCH_UI_PORTRAIT, 8, 12)
#define GRID_COLS 6
void StatusScreen::draw_temperature(draw_mode_t what) {
using namespace Theme;
#define TEMP_RECT_1 BTN_POS(1,1), BTN_SIZE(4,4)
#define TEMP_RECT_2 BTN_POS(1,1), BTN_SIZE(8,2)
#define NOZ_1_POS BTN_POS(1,1), BTN_SIZE(4,2)
#define NOZ_2_POS BTN_POS(5,1), BTN_SIZE(4,2)
#define BED_POS BTN_POS(1,3), BTN_SIZE(4,2)
#define FAN_POS BTN_POS(5,3), BTN_SIZE(4,2)
#define BACKGROUND_POS BTN_POS(1,1), BTN_SIZE(6,4)
#define TEMP_RECT_E0 BTN_POS(1,1), BTN_SIZE(3,2)
#define TEMP_RECT_E1 BTN_POS(4,1), BTN_SIZE(3,2)
#define TEMP_RECT_BED BTN_POS(1,3), BTN_SIZE(3,2)
#define NOZ_1_POS BTN_POS(1,1), BTN_SIZE(3,2)
#define NOZ_2_POS BTN_POS(4,1), BTN_SIZE(3,2)
#define BED_POS BTN_POS(1,3), BTN_SIZE(3,2)
#define FAN_POS BTN_POS(4,3), BTN_SIZE(3,2)
#define ALL_TEMP_POS BTN_POS(1,1), BTN_SIZE(6,4)
#define _ICON_POS(x,y,w,h) x, y, w/4, h
#define _TEXT_POS(x,y,w,h) x + w/4, y, w - w/4, h
#define _ICON_POS(x,y,w,h) x, y, w/3, h
#define _TEXT_POS(x,y,w,h) x + w/3, y, w - w/3, h
#define ICON_POS(pos) _ICON_POS(pos)
#define TEXT_POS(pos) _TEXT_POS(pos)
CommandProcessor cmd;
if (what & BACKGROUND) {
cmd.font(Theme::font_small)
.tag(5)
.fgcolor(temp) .button(TEMP_RECT_1, F(""), OPT_FLAT)
.button(TEMP_RECT_2, F(""), OPT_FLAT)
.fgcolor(fan_speed).button(FAN_POS, F(""), OPT_FLAT)
.tag(0);
// Draw Extruder Bitmap on Extruder Temperature Button
cmd.tag(5)
cmd.font(Theme::font_small).tag(5)
.cmd (BITMAP_SOURCE(Extruder_Icon_Info))
.cmd (BITMAP_LAYOUT(Extruder_Icon_Info))
.cmd (BITMAP_SIZE (Extruder_Icon_Info))
@ -147,7 +163,6 @@ void StatusScreen::draw_temperature(draw_mode_t what) {
.icon(ICON_POS(BED_POS), Bed_Heat_Icon_Info, icon_scale);
// Draw Fan Percent Bitmap on Bed Heat Button
cmd.cmd (BITMAP_SOURCE(Fan_Icon_Info))
.cmd (BITMAP_LAYOUT(Fan_Icon_Info))
.cmd (BITMAP_SIZE (Fan_Icon_Info))
@ -178,15 +193,43 @@ void StatusScreen::draw_temperature(draw_mode_t what) {
else
format_temp_and_temp(e1_str, getActualTemp_celsius(H1), getTargetTemp_celsius(H1));
#else
strcpy_P(e1_str, PSTR("-"));
strcpy_P(e1_str, PSTR("N/A"));
#endif
cmd.tag(5)
.font(font_medium)
.text(TEXT_POS(NOZ_1_POS), e0_str)
.text(TEXT_POS(NOZ_2_POS), e1_str)
.text(TEXT_POS(BED_POS), bed_str)
.text(TEXT_POS(FAN_POS), fan_str);
if (getTargetTemp_celsius(H0) > 0) {
cmd.fgcolor(temp_button);
}
else {
cmd.colors(normal_btn);
}
cmd.tag(5).font(font_medium).button(TEXT_POS(NOZ_1_POS), e0_str);
if (getTargetTemp_celsius(BED) > 0) {
cmd.fgcolor(temp_button);
}
else {
cmd.colors(normal_btn);
}
cmd.tag(5).font(font_medium).button(TEXT_POS(BED_POS), bed_str);
if (getActualFan_percent(FAN0) > 0) {
cmd.fgcolor(temp_button);
}
else {
cmd.colors(normal_btn);
}
cmd.tag(5).font(font_medium).button(TEXT_POS(FAN_POS), fan_str);
if DISABLED(HAS_MULTI_HOTEND) {
cmd.font(font_xsmall).fgcolor(gray_color_1);
}
else if (getTargetTemp_celsius(H1) > 0) {
cmd.font(font_medium).fgcolor(temp_button);
}
else {
cmd.font(font_medium).colors(normal_btn);
}
cmd.tag(5).button(TEXT_POS(NOZ_2_POS), e1_str);
}
}
@ -206,21 +249,28 @@ void StatusScreen::draw_progress(draw_mode_t what) {
CommandProcessor cmd;
#undef GRID_COLS
#undef GRID_COLS
#if ENABLED(TOUCH_UI_PORTRAIT)
#define GRID_COLS 3
#define PROGRESSZONE_POS BTN_POS(1,5), BTN_SIZE(3,2)
#define TIME_POS_X BTN_X(1)
#define TIME_POS_W BTN_W(1)
#define REMAINING_POS_X BTN_X(2)
#define REMAINING_POS_W BTN_W(1)
#define PROGRESS_POS_X BTN_X(3)
#define PROGRESS_POS_W BTN_W(1)
#define PROGRESSZONE_FIRSTLINE_Y BTN_Y(5)
#define PROGRESSBAR_POS BTN_POS(1,6), BTN_SIZE(3,1)
#define GRID_COLS 2
#define PROGRESSZONE_POS BTN_POS(1,9), BTN_SIZE(2,2)
#define PROGRESSZONE_POS_1 BTN_POS(1,9), BTN_SIZE(1,2)
#define PROGRESSZONE_POS_2 BTN_POS(2,9), BTN_SIZE(1,2)
#define TIME_POS_X BTN_X(1)
#define TIME_POS_W BTN_W(1)
//#define REMAINING_POS_X BTN_X(2)
//#define REMAINING_POS_W BTN_W(1)
#define PROGRESS_POS_X BTN_X(2)
#define PROGRESS_POS_W BTN_W(1)
#define PROGRESSZONE_FIRSTLINE_Y BTN_Y(9)
#define PROGRESSBAR_POS BTN_POS(1,8), BTN_SIZE(2,2)
#define CLEAR_PROGRESS_POS BTN_POS(0,6.75), BTN_SIZE(4,5)
#else
#define GRID_COLS 6
#define PROGRESSZONE_POS BTN_POS(5,1), BTN_SIZE(2,4)
#define PROGRESSZONE_POS_1 BTN_POS(1,9), BTN_SIZE(1,2)
#define PROGRESSZONE_POS_2 BTN_POS(2,9), BTN_SIZE(1,2)
#define CLEAR_PROGRESS_POS BTN_POS(0,6.75), BTN_SIZE(4,5)
#if ENABLED(SHOW_REMAINING_TIME)
#define TIME_POS BTN_POS(5,1), BTN_SIZE(1,2)
#define REMAINING_POS BTN_POS(6,1), BTN_SIZE(1,2)
@ -231,82 +281,123 @@ void StatusScreen::draw_progress(draw_mode_t what) {
#define PROGRESSBAR_POS BTN_POS(5,2), BTN_SIZE(2,2)
#endif
if (what & BACKGROUND) {
cmd.tag(0).font(font_medium)
.fgcolor(progress).button(PROGRESSZONE_POS, F(""), OPT_FLAT);
}
if (ExtUI::isOngoingPrintJob()|| ExtUI::isPrintingPaused()) {
if (what & FOREGROUND) {
const uint32_t elapsed = getProgress_seconds_elapsed();
char elapsed_str[10];
_format_time(elapsed_str, elapsed);
if (what & FOREGROUND) {
cmd.colors(temp_btn)
.tag(0).button(CLEAR_PROGRESS_POS, F(""), OPT_FLAT);
#if ENABLED(SHOW_REMAINING_TIME)
const uint32_t remaining = getProgress_seconds_remaining();
char remaining_str[10];
_format_time(remaining_str, remaining);
#endif
const uint32_t elapsed = getProgress_seconds_elapsed();
char elapsed_str[10];
_format_time(elapsed_str, elapsed);
const uint16_t current_progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, getProgress_permyriad(), getProgress_percent() * 100);
constexpr uint16_t progress_range = 10000U;
const bool show_progress_bar = current_progress > 0 && current_progress < progress_range + 1;
if (show_progress_bar) {
cmd.tag(0).font(font_medium)
.bgcolor(progress)
.progress(PROGRESSBAR_POS, current_progress, progress_range, OPT_FLAT);
}
char progress_str[10];
sprintf_P(progress_str,
#if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS)
PSTR("%3d.%02d%%"), uint8_t(current_progress / 100), current_progress % 100
#else
PSTR("%3d%%"), uint8_t(current_progress / 100)
#if ENABLED(SHOW_REMAINING_TIME)
const uint32_t remaining = getProgress_seconds_remaining();
char remaining_str[10];
_format_time(remaining_str, remaining);
#endif
);
#if ENABLED(TOUCH_UI_PORTRAIT)
const uint16_t texts_pos_h = show_progress_bar ? (BTN_H(1)) : (BTN_H(2));
cmd.font(font_medium)
.tag(7).text(TIME_POS_X, PROGRESSZONE_FIRSTLINE_Y, TIME_POS_W, texts_pos_h, elapsed_str)
#if ENABLED(SHOW_REMAINING_TIME)
.text(REMAINING_POS_X, PROGRESSZONE_FIRSTLINE_Y, REMAINING_POS_W, texts_pos_h, remaining_str)
#endif
.text(PROGRESS_POS_X, PROGRESSZONE_FIRSTLINE_Y, PROGRESS_POS_W, texts_pos_h, progress_str);
#else
cmd.font(font_medium)
.tag(7).text(TIME_POS, elapsed_str)
#if ENABLED(SHOW_REMAINING_TIME)
.text(REMAINING_POS, remaining_str)
#endif
.text(PROGRESS_POS, progress_str);
#endif
const uint16_t current_progress = TERN(HAS_PRINT_PROGRESS_PERMYRIAD, getProgress_permyriad(), getProgress_percent() * 100);
constexpr uint16_t progress_range = 10000U;
const bool show_progress_bar = current_progress < progress_range + 1;
if (show_progress_bar) {
cmd.tag(0).font(font_medium)
.bgcolor(progress)
.progress(PROGRESSBAR_POS, current_progress, progress_range, OPT_FLAT);
}
char progress_str[10];
sprintf_P(progress_str,
#if ENABLED(PRINT_PROGRESS_SHOW_DECIMALS)
PSTR("%3d.%02d%%"), uint8_t(current_progress / 100), current_progress % 100
#else
PSTR("%3d%%"), uint8_t(current_progress / 100)
#endif
);
#if ENABLED(TOUCH_UI_PORTRAIT)
const uint16_t texts_pos_h = show_progress_bar ? (BTN_H(2)) : (BTN_H(2));
cmd.font(font_medium)
.tag(0).text(TIME_POS_X, PROGRESSZONE_FIRSTLINE_Y, TIME_POS_W, texts_pos_h, elapsed_str)
#if ENABLED(SHOW_REMAINING_TIME)
.text(REMAINING_POS_X, PROGRESSZONE_FIRSTLINE_Y, REMAINING_POS_W, texts_pos_h, remaining_str)
#endif
.text(PROGRESS_POS_X, PROGRESSZONE_FIRSTLINE_Y, PROGRESS_POS_W, texts_pos_h, progress_str);
#else
cmd.font(font_medium)
.tag(0).text(TIME_POS, elapsed_str)
#if ENABLED(SHOW_REMAINING_TIME)
.text(REMAINING_POS, remaining_str)
#endif
.text(PROGRESS_POS, progress_str);
#endif
}
}
else {
cmd.colors(normal_btn)
.font(font_medium)
.tag(9).button(PROGRESSZONE_POS_1, GET_TEXT_F(MSG_HOME_ALL))
.tag(16).button(PROGRESSZONE_POS_2, GET_TEXT_F(MSG_PRESENT_BED));
}
}
void StatusScreen::draw_interaction_buttons(draw_mode_t what) {
#undef GRID_COLS
#define GRID_COLS 4
#define GRID_COLS 2
if (what & FOREGROUND) {
using namespace ExtUI;
#if ENABLED(TOUCH_UI_PORTRAIT)
#define MEDIA_BTN_POS BTN_POS(1,15), BTN_SIZE(2,2)
#define MENU_BTN_POS BTN_POS(3,15), BTN_SIZE(2,2)
#define TOOL_HEAD_POS BTN_POS(1,11), BTN_SIZE(1,2)
#define CHANGE_FILAMENT_POS BTN_POS(2,11), BTN_SIZE(1,2)
#define PREHEAT_POS BTN_POS(1,13), BTN_SIZE(1,2)
#define COOLDOWN_OFFSET_POS BTN_POS(2,13), BTN_SIZE(1,2)
#define MEDIA_BTN_POS BTN_POS(1,15), BTN_SIZE(1,2)
#define MENU_BTN_POS BTN_POS(2,15), BTN_SIZE(1,2)
#else
#define MEDIA_BTN_POS BTN_POS(1,13), BTN_SIZE(2,4)
#define MENU_BTN_POS BTN_POS(3,13), BTN_SIZE(2,4)
#define TOOL_HEAD_POS BTN_POS(1,11), BTN_SIZE(1,2)
#define CHANGE_FILAMENT_POS BTN_POS(2,11), BTN_SIZE(1,2)
#define PREHEAT_POS BTN_POS(1,13), BTN_SIZE(1,2)
#define COOLDOWN_OFFSET_POS BTN_POS(2,13), BTN_SIZE(1,2)
#define MEDIA_BTN_POS BTN_POS(1,13), BTN_SIZE(1,4)
#define MENU_BTN_POS BTN_POS(2,13), BTN_SIZE(1,4)
#endif
const bool has_media = isMediaMounted() && !isPrintingFromMedia();
CommandProcessor cmd;
if (ExtUI::isOngoingPrintJob() || ExtUI::isPrintingPaused()) {
cmd.colors(normal_btn)
.font(font_medium)
.tag(!ExtUI::isPrintingPaused() ? 17 : 18)
.button(TOOL_HEAD_POS, !ExtUI::isPrintingPaused() ? GET_TEXT_F(MSG_BUTTON_PAUSE) : GET_TEXT_F(MSG_BUTTON_RESUME))
.tag(!ExtUI::isPrintingPaused() ? 7 : 14)
.button(CHANGE_FILAMENT_POS, !ExtUI::isPrintingPaused() ? GET_TEXT_F(MSG_SPEED) : F(""));
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
cmd.tag(8).button(PREHEAT_POS, GET_TEXT_F(MSG_SENSOR));
#endif
if (ExtUI::isPrintingPaused())
draw_text_box(cmd, CHANGE_FILAMENT_POS, F("Change\nFilament"), OPT_CENTER, font_medium);
}
else {
cmd.colors(normal_btn)
.font(font_medium)
.tag(14).button(CHANGE_FILAMENT_POS, F(""));
draw_text_box(cmd, CHANGE_FILAMENT_POS, F("Change\nFilament"), OPT_CENTER, font_medium);
cmd.colors(normal_btn)
.font(font_medium)
.tag(20).button(PREHEAT_POS, GET_TEXT_F(MSG_PREHEAT));
cmd.enabled(ENABLED(CUSTOM_MENU_MAIN)).tag(10).button(TOOL_HEAD_POS, F(""));
draw_text_box(cmd, TOOL_HEAD_POS, F("" CUSTOM_MENU_MAIN_TITLE "\n "), OPT_CENTER, font_medium);
}
cmd.colors(normal_btn)
.font(Theme::font_medium)
.tag(15).button(COOLDOWN_OFFSET_POS, isOngoingPrintJob() ? GET_TEXT_F(MSG_ZOFFSET) : GET_TEXT_F(MSG_COOLDOWN))
.colors(has_media ? action_btn : normal_btn)
.enabled(has_media && !isPrinting())
.tag(3).button(MEDIA_BTN_POS, isPrinting() ? GET_TEXT_F(MSG_PRINTING) : GET_TEXT_F(MSG_BUTTON_MEDIA))
.enabled(has_media || isOngoingPrintJob())
.tag(isOngoingPrintJob() ? 19 : 3).button(MEDIA_BTN_POS, isOngoingPrintJob() ? GET_TEXT_F(MSG_BUTTON_CANCEL) : GET_TEXT_F(MSG_BUTTON_PRINT))
.colors(!has_media ? action_btn : normal_btn)
.tag(4).button(MENU_BTN_POS, GET_TEXT_F(MSG_BUTTON_MENU));
}
@ -317,14 +408,14 @@ void StatusScreen::draw_status_message(draw_mode_t what, const char *message) {
#define GRID_COLS 1
#if ENABLED(TOUCH_UI_PORTRAIT)
#define STATUS_POS BTN_POS(1,7), BTN_SIZE(1,2)
#define STATUS_POS BTN_POS(1,5), BTN_SIZE(1,2)
#else
#define STATUS_POS BTN_POS(1,5), BTN_SIZE(1,4)
#endif
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.fgcolor(Theme::status_msg)
cmd.colors(temp_btn)
.tag(0)
.button(STATUS_POS, F(""), OPT_FLAT);
@ -380,6 +471,7 @@ void StatusScreen::loadBitmaps() {
CLCD::mem_write_xbm(base + Extruder_Icon_Info.RAMG_offset, Extruder_Icon, sizeof(Extruder_Icon));
CLCD::mem_write_xbm(base + Bed_Heat_Icon_Info.RAMG_offset, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
CLCD::mem_write_xbm(base + Fan_Icon_Info.RAMG_offset, Fan_Icon, sizeof(Fan_Icon));
CLCD::mem_write_pgm(base + Home_icon_Info.RAMG_offset, Home_icon, sizeof(Home_icon));
// Load fonts for internationalization
#if ENABLED(TOUCH_UI_USE_UTF8)
@ -444,6 +536,48 @@ bool StatusScreen::onTouchEnd(uint8_t tag) {
}
break;
case 7: GOTO_SCREEN(FeedratePercentScreen); break;
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
case 8: GOTO_SCREEN(FilamentRunoutScreen); break;
#endif
case 9: injectCommands(F("G28")); break;
#if ENABLED(CUSTOM_MENU_MAIN)
case 10: GOTO_SCREEN(CustomUserMenus); break;
#endif
if (!ExtUI::isOngoingPrintJob()) {
case 11: injectCommands(F("G28X")); break;
case 12: injectCommands(F("G28Y")); break;
case 13: injectCommands(F("G28Z")); break;
}
case 14: GOTO_SCREEN(ChangeFilamentScreen); break;
#if ALL(HAS_LEVELING, HAS_BED_PROBE)
case 15:
if (ExtUI::isOngoingPrintJob()|| ExtUI::isPrintingPaused()) {
#if EXTRUDERS > 1
GOTO_SCREEN(NudgeNozzleScreen); break;
#else
GOTO_SCREEN(ZOffsetScreen); break;
#endif
}
else {
coolDown();
TERN_(HAS_HEATED_CHAMBER, setTargetTemp_celsius(0, CHAMBER));
GOTO_SCREEN(StatusScreen);
break;
}
#endif
#ifdef PRESENT_BED_GCODE
case 16: injectCommands(F(PRESENT_BED_GCODE)); break;
#endif
case 17: injectCommands(F("M117 Print Paused")); pausePrint(); break;
case 18: injectCommands(F("M117 Print Resumed")); resumePrint(); break;
case 19:
GOTO_SCREEN(ConfirmAbortPrintDialogBox);
current_screen.forget();
PUSH_SCREEN(StatusScreen);
break;
#ifdef PREHEAT_1_COMMAND
case 20: injectCommands_P(PSTR(PREHEAT_1_COMMAND)); break;
#endif
default:
return true;
}

View file

@ -91,7 +91,7 @@ void format_temp_and_material(char *str, const_celsius_float_t t1, const char *m
void format_position(char *str, float p, uint8_t decimals) {
dtostrf(p, 4 + decimals, decimals, str);
strcat_P(str, PSTR(" "));
strcat_P(str, GET_TEXT(MSG_UNITS_MM));
//strcat_P(str, GET_TEXT(MSG_UNITS_MM));
}
/**

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -30,15 +31,16 @@ using namespace Theme;
using namespace ExtUI;
void TemperatureScreen::onRedraw(draw_mode_t what) {
CommandProcessor cmd;
widgets_t w(what);
#if TOUCH_UI_LCD_TEMP_SCALING == 10
w.precision(1, DEFAULT_MIDRANGE)
#else
w.precision(0, getTargetTemp_celsius(E0) == 0 ? DEFAULT_HIGHEST : DEFAULT_MIDRANGE)
#endif
.color(temp).units(GET_TEXT_F(MSG_UNITS_C));
.color(temp_button).units(GET_TEXT_F(MSG_UNITS_C));
w.heading(GET_TEXT_F(MSG_TEMPERATURE));
w.button(30, GET_TEXT_F(MSG_COOLDOWN));
//w.button(30, GET_TEXT_F(MSG_COOLDOWN));
#ifndef NO_TOOLHEAD_HEATER_GCODE
#if ENABLED(TOUCH_UI_COCOA_PRESS)
w.adjuster( 2, GET_TEXT_F(MSG_NOZZLE), getTargetTemp_celsius(E0));
@ -67,10 +69,39 @@ void TemperatureScreen::onRedraw(draw_mode_t what) {
w.adjuster( 22, GET_TEXT_F(MSG_CHAMBER), getTargetTemp_celsius(CHAMBER));
#endif
#if HAS_FAN0
w.color(fan_speed).units(GET_TEXT_F(MSG_UNITS_PERCENT));
w.units(GET_TEXT_F(MSG_UNITS_PERCENT));
w.adjuster( 10, GET_TEXT_F(MSG_FAN_SPEED), getTargetFan_percent(FAN0));
#endif
w.increments();
#define PREHEAT_1_POS BTN_POS(1,(5+EXTRUDERS)), BTN_SIZE(1,1)
#define PREHEAT_2_POS BTN_POS(2,(5+EXTRUDERS)), BTN_SIZE(1,1)
#define PREHEAT_3_POS BTN_POS(1,(6+EXTRUDERS)), BTN_SIZE(1,1)
#define COOLDOWN_POS BTN_POS(2,(6+EXTRUDERS)), BTN_SIZE(1,1)
#define TOOLHEAD_SWAP_POS BTN_POS(1,(7+EXTRUDERS)), BTN_SIZE(2,1)
if (what & FOREGROUND) {
#define GRID_COLS 2
#define GRID_ROWS (8+EXTRUDERS)
if (!ExtUI::isOngoingPrintJob()) {
cmd.font(Theme::font_medium)
.colors(normal_btn);
#ifdef PREHEAT_1_COMMAND
cmd.tag(31).button(PREHEAT_1_POS, GET_TEXT_F(MSG_PREHEAT_1));
#endif
#ifdef PREHEAT_2_COMMAND
cmd.tag(32).button(PREHEAT_2_POS, GET_TEXT_F(MSG_PREHEAT_2));
#endif
#ifdef PREHEAT_3_COMMAND
cmd.tag(33).button(PREHEAT_3_POS, GET_TEXT_F(MSG_PREHEAT_3));
#endif
cmd.colors(cold_pull_btn)
.tag(30).button(COOLDOWN_POS, GET_TEXT_F(MSG_COOLDOWN));
#ifdef PARKING_COMMAND_GCODE
cmd.colors(normal_btn).tag(35).button(TOOLHEAD_SWAP_POS, GET_TEXT_F(MSG_TOOL_HEAD_SWAP));
#endif
}
}
}
bool TemperatureScreen::onTouchHeld(uint8_t tag) {
@ -103,7 +134,20 @@ bool TemperatureScreen::onTouchHeld(uint8_t tag) {
case 30:
coolDown();
TERN_(HAS_HEATED_CHAMBER, setTargetTemp_celsius(0, CHAMBER));
GOTO_SCREEN(StatusScreen);
break;
#ifdef PREHEAT_1_COMMAND
case 31: injectCommands_P(PSTR(PREHEAT_1_COMMAND)); GOTO_SCREEN(StatusScreen); break;
#endif
#ifdef PREHEAT_2_COMMAND
case 32: injectCommands_P(PSTR(PREHEAT_2_COMMAND)); GOTO_SCREEN(StatusScreen); break;
#endif
#ifdef PREHEAT_3COMMAND
case 33: injectCommands_P(PSTR(PREHEAT_3_COMMAND)); GOTO_SCREEN(StatusScreen); break;
#endif
#ifdef PARKING_COMMAND_GCODE
case 35: injectCommands(F(PARKING_COMMAND_GCODE)); break;
#endif
default:
return false;
}

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -31,7 +32,7 @@ using namespace FTDI;
using namespace Theme;
#define GRID_COLS 2
#define GRID_ROWS TERN(TOUCH_UI_PORTRAIT, 9, 5)
#define GRID_ROWS TERN(TOUCH_UI_PORTRAIT, 7, 5)
void TuneMenu::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
@ -41,55 +42,37 @@ void TuneMenu::onRedraw(draw_mode_t what) {
}
#if ENABLED(TOUCH_UI_PORTRAIT)
#define TEMPERATURE_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define FIL_CHANGE_POS BTN_POS(1,2), BTN_SIZE(2,1)
#define FILAMENT_POS BTN_POS(1,3), BTN_SIZE(2,1)
#define NUDGE_NOZ_POS BTN_POS(1,4), BTN_SIZE(2,1)
#define SPEED_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define PAUSE_POS BTN_POS(1,6), BTN_SIZE(2,1)
#define STOP_POS BTN_POS(1,7), BTN_SIZE(2,1)
#define CASE_LIGHT_POS BTN_POS(1,8), BTN_SIZE(2,1)
#define ADVANCED_SETTINGS_POS BTN_POS(1,9), BTN_SIZE(1,1)
#define BACK_POS BTN_POS(2,9), BTN_SIZE(1,1)
#define STOP_POS BTN_POS(1,1), BTN_SIZE(2,1)
#define PAUSE_POS BTN_POS(1,2), BTN_SIZE(2,1)
#define FLOW_POS BTN_POS(1,3), BTN_SIZE(2,1)
#define TEMPERATURE_POS BTN_POS(1,4), BTN_SIZE(2,1)
#define ABOUT_PRINTER_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define ADVANCED_SETTINGS_POS BTN_POS(1,6), BTN_SIZE(2,1)
#define BACK_POS BTN_POS(1,7), BTN_SIZE(2,1)
#else
#define TEMPERATURE_POS BTN_POS(1,1), BTN_SIZE(1,1)
#define NUDGE_NOZ_POS BTN_POS(2,1), BTN_SIZE(1,1)
#define FIL_CHANGE_POS BTN_POS(1,2), BTN_SIZE(1,1)
#define SPEED_POS BTN_POS(2,2), BTN_SIZE(1,1)
#define PAUSE_POS BTN_POS(1,3), BTN_SIZE(1,1)
#define STOP_POS BTN_POS(2,3), BTN_SIZE(1,1)
#define FILAMENT_POS BTN_POS(1,4), BTN_SIZE(1,1)
#define CASE_LIGHT_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define FLOW_POS BTN_POS(2,4), BTN_SIZE(1,1)
#define ADVANCED_SETTINGS_POS BTN_POS(1,5), BTN_SIZE(1,1)
#define ABOUT_PRINTER_POS BTN_POS(1,5), BTN_SIZE(2,1)
#define BACK_POS BTN_POS(2,5), BTN_SIZE(1,1)
#endif
if (what & FOREGROUND) {
const bool sdOrHostPrinting = ExtUI::isPrinting();
const bool sdOrHostPaused = ExtUI::isPrintingPaused();
CommandProcessor cmd;
cmd.colors(normal_btn)
cmd.colors(cancel_btn)
.font(font_medium)
.tag(2).button(TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE))
.enabled(!sdOrHostPrinting || sdOrHostPaused)
.tag(3).button(FIL_CHANGE_POS, GET_TEXT_F(MSG_FILAMENTCHANGE))
.enabled(ANY(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR))
.tag(9).button(FILAMENT_POS, GET_TEXT_F(MSG_FILAMENT))
#if ENABLED(BABYSTEPPING) && HAS_MULTI_HOTEND
.tag(4).button(NUDGE_NOZ_POS, GET_TEXT_F(MSG_NUDGE_NOZZLE))
#elif ALL(HAS_LEVELING, HAS_BED_PROBE)
.tag(4).button(NUDGE_NOZ_POS, GET_TEXT_F(MSG_ZPROBE_ZOFFSET))
#endif
.tag(5).button(SPEED_POS, GET_TEXT_F(MSG_PRINT_SPEED))
.enabled(sdOrHostPrinting)
.tag(sdOrHostPaused ? 7 : 6)
.tag(2).button(STOP_POS, GET_TEXT_F(MSG_CANCEL_PRINT))
.colors(normal_btn)
.tag(sdOrHostPaused ? 4 : 3)
.button(PAUSE_POS, sdOrHostPaused ? GET_TEXT_F(MSG_RESUME_PRINT) : GET_TEXT_F(MSG_PAUSE_PRINT))
.enabled(sdOrHostPrinting)
.tag(8).button(STOP_POS, GET_TEXT_F(MSG_STOP_PRINT))
.enabled(ENABLED(CASE_LIGHT_ENABLE))
.tag(10).button(CASE_LIGHT_POS, GET_TEXT_F(MSG_CASE_LIGHT))
.tag(11).button(ADVANCED_SETTINGS_POS, GET_TEXT_F(MSG_ADVANCED_SETTINGS))
.tag(5).button(FLOW_POS, GET_TEXT_F(MSG_FLOW))
.tag(6).button(TEMPERATURE_POS, GET_TEXT_F(MSG_TEMPERATURE))
.tag(7).button(ABOUT_PRINTER_POS, GET_TEXT_F(MSG_INFO_MENU))
.tag(8).button(ADVANCED_SETTINGS_POS, GET_TEXT_F(MSG_ADVANCED_SETTINGS))
.tag(1).colors(action_btn)
.button(BACK_POS, GET_TEXT_F(MSG_BUTTON_DONE));
}
@ -99,31 +82,18 @@ bool TuneMenu::onTouchEnd(uint8_t tag) {
using namespace Theme;
using namespace ExtUI;
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
case 2: GOTO_SCREEN(TemperatureScreen); break;
case 3: GOTO_SCREEN(ChangeFilamentScreen); break;
case 4:
#if ENABLED(BABYSTEPPING) && HAS_MULTI_HOTEND
GOTO_SCREEN(NudgeNozzleScreen);
#elif ALL(HAS_LEVELING, HAS_BED_PROBE)
GOTO_SCREEN(ZOffsetScreen);
#endif
break;
case 5: GOTO_SCREEN(FeedratePercentScreen); break;
case 6: pausePrint(); break;
case 7: resumePrint(); break;
case 8:
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
case 2:
GOTO_SCREEN(ConfirmAbortPrintDialogBox);
current_screen.forget();
PUSH_SCREEN(StatusScreen);
break;
#if ANY(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR)
case 9: GOTO_SCREEN(FilamentMenu); break;
#endif
#if ENABLED(CASE_LIGHT_ENABLE)
case 10: GOTO_SCREEN(CaseLightScreen); break;
#endif
case 11: GOTO_SCREEN(AdvancedSettingsMenu); break;
case 3: injectCommands(F("M117 Print Paused")); pausePrint(); break;
case 4: injectCommands(F("M117 Print Resumed")); resumePrint(); break;
case 5: GOTO_SCREEN(FlowPercentScreen); break;
case 6: GOTO_SCREEN(TemperatureScreen); break;
case 7: GOTO_SCREEN(AboutScreen); break;
case 8: GOTO_SCREEN(AdvancedSettingsMenu); break;
default:
return false;
}
@ -131,24 +101,61 @@ bool TuneMenu::onTouchEnd(uint8_t tag) {
}
void TuneMenu::pausePrint() {
// sound.play(twinkle, PLAY_ASYNCHRONOUS);
// if (ExtUI::isPrintingFromMedia())
// ExtUI::pausePrint();
// #ifdef ACTION_ON_PAUSE
// else hostui.pause();
// #endif
// This
sound.play(twinkle, PLAY_ASYNCHRONOUS);
if (ExtUI::isPrintingFromMedia())
{
SERIAL_ECHOLNPGM("Pause: isPrintingFromMedia");
ExtUI::pausePrint();
}
#ifdef ACTION_ON_PAUSE
else hostui.pause();
else
{
SERIAL_ECHOLNPGM("Pause: hostui.pause");
hostui.pause();
}
#endif
GOTO_SCREEN(StatusScreen);
}
void TuneMenu::resumePrint() {
// This
sound.play(twinkle, PLAY_ASYNCHRONOUS);
if (ExtUI::awaitingUserConfirm())
// Something is wrong with this
if (ExtUI::awaitingUserConfirm() && ExtUI::isPrintingPaused())
{
SERIAL_ECHOLNPGM("Resume: Awaiting User Confirm");
#if ENABLED(ADVANCED_PAUSE_FEATURE)
ExtUI::setPauseMenuResponse(PAUSE_RESPONSE_RESUME_PRINT);
#endif
ExtUI::setUserConfirmed();
}
if (ExtUI::isPrintingFromMedia())
{
ExtUI::setUserConfirmed();
else if (ExtUI::isPrintingFromMedia())
SERIAL_ECHOLNPGM("Resume: isPrintingFromMedia");
ExtUI::resumePrint();
}
#ifdef ACTION_ON_RESUME
else hostui.resume();
else
{
SERIAL_ECHOLNPGM("Resume: hostui.resume");
hostui.resume();
}
#endif
// This works
GOTO_SCREEN(StatusScreen);
}

View file

@ -5,6 +5,7 @@
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Brian Kahl 2023 - FAME3D. *
* *
* 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 *
@ -31,6 +32,8 @@ using namespace ExtUI;
using namespace Theme;
#define SHEET_THICKNESS 0.1
#define GRID_COLS 13
#define GRID_ROWS (9+EXTRUDERS)
constexpr static ZOffsetScreenData &mydata = screen_data.ZOffsetScreen;
@ -48,12 +51,19 @@ void ZOffsetScreen::onExit() {
void ZOffsetScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
CommandProcessor cmd;
w.precision(2, BaseNumericAdjustmentScreen::DEFAULT_MIDRANGE).units(GET_TEXT_F(MSG_UNITS_MM));
w.heading( GET_TEXT_F(MSG_ZPROBE_ZOFFSET));
w.color(z_axis).adjuster(4, GET_TEXT_F(MSG_ZPROBE_ZOFFSET), getZOffset_mm());
w.heading( GET_TEXT_F(MSG_ZOFFSET));
w.color(z_axis).adjuster(4, GET_TEXT_F(MSG_ZOFFSET), getZOffset_mm());
w.increments();
w.button(2, GET_TEXT_F(MSG_PROBE_WIZARD), !isPrinting() && !wizardRunning());
//w.button(2, GET_TEXT_F(MSG_PROBE_WIZARD), !isPrinting() && !wizardRunning());
if (what & FOREGROUND) {
cmd.colors(normal_btn)
.font(font_medium)
.tag(6).colors(action_btn).button(BTN_POS(1,GRID_ROWS), BTN_SIZE(GRID_COLS,1), GET_TEXT_F(MSG_BUTTON_DONE));
}
}
void ZOffsetScreen::move(float mm, int16_t steps) {
@ -73,11 +83,11 @@ void ZOffsetScreen::runWizard() {
setZOffset_mm(offset[Z_AXIS]);
// Move above probe point
char cmd[64], str[10];
strcpy_P(cmd, PSTR("G28 Z\nG0 F1000 X"));
dtostrf(TERN(Z_SAFE_HOMING,Z_SAFE_HOMING_X_POINT,X_CENTER), 3, 1, str);
strcpy_P(cmd, PSTR("G28O\nG0 F1000 X"));
dtostrf(TERN(Z_SAFE_HOMING, Z_SAFE_HOMING_X_POINT, X_CENTER), 3, 1, str);
strcat(cmd, str);
strcat_P(cmd, PSTR("Y"));
dtostrf(TERN(Z_SAFE_HOMING,Z_SAFE_HOMING_Y_POINT,Y_CENTER), 3, 1, str);
dtostrf(TERN(Z_SAFE_HOMING, Z_SAFE_HOMING_Y_POINT, Y_CENTER), 3, 1, str);
strcat(cmd, str);
strcat_P(cmd, PSTR("Z"));
dtostrf(SHEET_THICKNESS, 3, 1, str);
@ -101,6 +111,7 @@ bool ZOffsetScreen::onTouchHeld(uint8_t tag) {
case 2: runWizard(); break;
case 4: UI_DECREMENT(ZOffset_mm); move(-increment, -steps); break;
case 5: UI_INCREMENT(ZOffset_mm); move( increment, steps); break;
case 6: GOTO_SCREEN(SaveSettingsDialogBox); break;
default:
return false;
}

View file

@ -39,6 +39,7 @@ namespace Language_en {
LSTR MSG_BUTTON_OKAY = u8"Okay";
LSTR MSG_BUTTON_MENU = u8"Menu";
LSTR MSG_BUTTON_MEDIA = u8"Media";
LSTR MSG_BUTTON_USB = u8"USB";
LSTR MSG_BUTTON_OPEN = u8"Open";
LSTR MSG_CLEAN_NOZZLE = u8"Clean Nozzle";
LSTR MSG_VMAX_X = u8"Max X Speed";
@ -65,7 +66,9 @@ namespace Language_en {
LSTR MSG_HOME = u8"Home";
LSTR MSG_PRINT_STARTING = u8"Print starting";
LSTR MSG_PRINT_FINISHED = u8"Print finished";
LSTR MSG_PRINT_COMPLETE = u8"Print Complete!";
LSTR MSG_PRINT_ERROR = u8"Print error";
LSTR MSG_PRINT_AREA_CLEAR = u8"Please ensure print area is\nclear and ready to print.";
LSTR MSG_ABOUT_TOUCH_PANEL_1 = u8"Color Touch Panel";
LSTR MSG_ABOUT_TOUCH_PANEL_2 = WEBSITE_URL;
LSTR MSG_LICENSE = u8"This program is free software: you can redistribute it and/or modify it under the terms of "
@ -91,6 +94,7 @@ namespace Language_en {
LSTR MSG_IDLE = u8"idle";
LSTR MSG_SET_MAXIMUM = u8"Set Maximum";
LSTR MSG_PRINT_SPEED = u8"Print Speed";
LSTR MSG_SPEED = u8"Speed";
LSTR MSG_LINEAR_ADVANCE_K = u8"K";
LSTR MSG_LINEAR_ADVANCE_K1 = u8"K E1";
LSTR MSG_LINEAR_ADVANCE_K2 = u8"K E2";
@ -106,6 +110,7 @@ namespace Language_en {
LSTR MSG_CALIBRATION_WARNING = u8"For best results, unload the filament and clean the hotend prior to starting calibration. Continue?";
LSTR MSG_START_PRINT_CONFIRMATION = u8"Start printing %s?";
LSTR MSG_ABORT_WARNING = u8"Are you sure you want to cancel the print?";
LSTR MSG_START_NEXT_PRINT = u8"Start Next Print";
LSTR MSG_EXTRUDER_SELECTION = u8"Extruder Selection";
LSTR MSG_CURRENT_TEMPERATURE = u8"Current Temp";
LSTR MSG_REMOVAL_TEMPERATURE = u8"Removal Temp";
@ -113,6 +118,8 @@ namespace Language_en {
LSTR MSG_HOT = u8"Hot!";
LSTR MSG_UNLOAD_FILAMENT = u8"Unload/Retract";
LSTR MSG_LOAD_FILAMENT = u8"Load/Extrude";
LSTR MSG_LOAD = u8"Load";
LSTR MSG_UNLOAD = u8"Unload";
LSTR MSG_MOMENTARY = u8"Momentary";
LSTR MSG_CONTINUOUS = u8"Continuous";
LSTR MSG_PRINT_MENU = u8"Print Menu";

View file

@ -62,6 +62,7 @@ union screen_data_t {
DECL_DATA_IF_INCLUDED(FTDI_Z_OFFSET_SCREEN)
DECL_DATA_IF_INCLUDED(FTDI_BASE_NUMERIC_ADJ_SCREEN)
DECL_DATA_IF_INCLUDED(FTDI_ALERT_DIALOG_BOX)
DECL_DATA_IF_INCLUDED(FTDI_FILAMENT_PROMPT_DIALOG_BOX)
DECL_DATA_IF_INCLUDED(COCOA_STATUS_SCREEN)
DECL_DATA_IF_INCLUDED(COCOA_PREHEAT_SCREEN)
DECL_DATA_IF_INCLUDED(COCOA_LOAD_CHOCOLATE_SCREEN)

View file

@ -57,12 +57,14 @@ SCREEN_TABLE {
DECL_SCREEN_IF_INCLUDED(FTDI_TUNE_MENU)
DECL_SCREEN_IF_INCLUDED(FTDI_ADVANCED_SETTINGS_MENU)
DECL_SCREEN_IF_INCLUDED(FTDI_ALERT_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_FILAMENT_PROMPT_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_CONFIRM_USER_REQUEST_ALERT_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_RESTORE_FAILSAFE_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_SAVE_SETTINGS_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_CONFIRM_START_PRINT_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_CONFIRM_ABORT_PRINT_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_CONFIRM_AUTO_CALIBRATION_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_FILAMENT_PROMPT_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_CUSTOM_USER_MENUS)
DECL_SCREEN_IF_INCLUDED(FTDI_SPINNER_DIALOG_BOX)
DECL_SCREEN_IF_INCLUDED(FTDI_ABOUT_SCREEN)

View file

@ -279,6 +279,52 @@ namespace Theme {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
constexpr PROGMEM bitmap_info_t Home_icon_Info = {
.format = L1,
.linestride = 4,
.filter = BILINEAR,
.wrapx = BORDER,
.wrapy = BORDER,
.RAMG_offset = 8941,
.width = 32,
.height = 32,
};
constexpr PROGMEM unsigned char Home_icon[128] = {
0x00, 0x7B, 0xF0, 0x00,
0x00, 0x4F, 0xF8, 0x00,
0x00, 0x4E, 0x1C, 0x00,
0x00, 0x5C, 0x0E, 0x00,
0x00, 0x78, 0x07, 0x00,
0x00, 0x70, 0x03, 0x80,
0x00, 0xE0, 0x01, 0xC0,
0x01, 0xC0, 0x00, 0xE0,
0x03, 0x80, 0x00, 0x70,
0x07, 0x00, 0x00, 0x38,
0x0E, 0x00, 0x00, 0x1C,
0x1C, 0x00, 0x00, 0x0E,
0x3C, 0x00, 0x00, 0x0F,
0x3C, 0x00, 0x00, 0x0F,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x04, 0x00, 0x00, 0x08,
0x07, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
constexpr PROGMEM uint32_t UTF8_FONT_OFFSET = 10000;
constexpr PROGMEM uint32_t BACKGROUND_OFFSET = 40000;
} // namespace Theme

View file

@ -60,7 +60,7 @@ namespace Theme {
// Shades of gray
constexpr float gray_sat = 0.14;
constexpr uint32_t gray_color_0 = hsl_to_rgb(accent_hue, gray_sat, 0.15); // Darkest
constexpr uint32_t gray_color_0 = hsl_to_rgb(accent_hue, gray_sat, 0.10); // Darkest
constexpr uint32_t gray_color_1 = hsl_to_rgb(accent_hue, gray_sat, 0.26);
constexpr uint32_t gray_color_2 = hsl_to_rgb(accent_hue, gray_sat, 0.39);
constexpr uint32_t gray_color_3 = hsl_to_rgb(accent_hue, gray_sat, 0.52);
@ -113,8 +113,10 @@ namespace Theme {
constexpr uint32_t theme_darkest = gray_color_1;
constexpr uint32_t theme_dark = gray_color_2;
constexpr uint32_t bg_dark_color = gray_color_0;
constexpr uint32_t bg_color = gray_color_1;
constexpr uint32_t axis_label = gray_color_2;
constexpr uint32_t bg_light_color = gray_color_3;
constexpr uint32_t bg_text_enabled = 0xFFFFFF;
constexpr uint32_t bg_text_disabled = gray_color_2;
@ -126,6 +128,7 @@ namespace Theme {
constexpr uint32_t logo_bg_rgb = accent_color_4;
constexpr uint32_t logo_fill_rgb = accent_color_3;
constexpr uint32_t logo_stroke_rgb = 0x000000;
constexpr uint32_t lulzbot_accent = 0xA8A845;
constexpr uint32_t bed_mesh_lines_rgb = 0xFFFFFF;
constexpr uint32_t bed_mesh_shadow_rgb = 0x444444;
@ -154,6 +157,8 @@ namespace Theme {
constexpr uint32_t e_axis = axis_label;
constexpr uint32_t feedrate = axis_label;
constexpr uint32_t other = axis_label;
constexpr uint32_t cold_pull = hsl_to_rgb(190, 0.5, 0.50);
constexpr uint32_t cancel = hsl_to_rgb( 25, 0.7, 0.50);
// Status screen
constexpr uint32_t progress = axis_label;
@ -162,8 +167,10 @@ namespace Theme {
constexpr uint32_t fan_speed = hsl_to_rgb(240, 0.5, 0.13);
constexpr uint32_t temp = hsl_to_rgb(343, 1.0, 0.23);
#else
constexpr uint32_t fan_speed = hsl_to_rgb(204, 0.47, 0.41);
constexpr uint32_t temp = hsl_to_rgb(311, 0.51, 0.35);
constexpr uint32_t fan_speed = hsl_to_rgb(30, 0.85, 0.50);
constexpr uint32_t fan_speed_button = hsl_to_rgb(30, 0.85, 0.50);
constexpr uint32_t temp = hsl_to_rgb(accent_hue, accent_sat, 0.30);
constexpr uint32_t temp_button = hsl_to_rgb(accent_hue, accent_sat, 0.39);
#endif
constexpr uint32_t disabled_icon = gray_color_1;
@ -177,17 +184,29 @@ namespace Theme {
constexpr uint32_t transformF = 0x8010D0;
constexpr uint32_t transformVal = 0x104010;
constexpr btn_colors disabled_btn = {.bg = bg_color, .grad = fg_disabled, .fg = fg_disabled, .rgb = fg_disabled };
constexpr btn_colors normal_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = 0xFFFFFF };
constexpr btn_colors action_btn = {.bg = bg_color, .grad = 0xFFFFFF, .fg = fg_action, .rgb = 0xFFFFFF };
constexpr btn_colors red_btn = {.bg = 0xFF5555, .grad = 0xFFFFFF, .fg = 0xFF0000, .rgb = 0xFFFFFF };
constexpr btn_colors ui_slider = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = accent_color_3 };
constexpr btn_colors ui_toggle = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = 0xFFFFFF };
constexpr btn_colors disabled_btn = {.bg = bg_color, .grad = fg_disabled, .fg = fg_disabled, .rgb = fg_disabled };
constexpr btn_colors normal_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = 0xFFFFFF };
constexpr btn_colors accent_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = lulzbot_accent, .rgb = 0xFFFFFF };
constexpr btn_colors action_btn = {.bg = bg_color, .grad = 0xFFFFFF, .fg = fg_action, .rgb = 0xFFFFFF };
constexpr btn_colors red_btn = {.bg = 0xFF5555, .grad = 0xFFFFFF, .fg = 0xFF0000, .rgb = 0xFFFFFF };
constexpr btn_colors ui_slider = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = accent_color_3 };
constexpr btn_colors ui_toggle = {.bg = theme_darkest, .grad = 0xFFFFFF, .fg = theme_dark, .rgb = 0xFFFFFF };
constexpr btn_colors text_x_axis_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = x_axis };
constexpr btn_colors text_y_axis_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = y_axis };
constexpr btn_colors text_z_axis_btn = {.bg = fg_action, .grad = 0xFFFFFF, .fg = fg_normal, .rgb = z_axis };
constexpr btn_colors normal_text = {.bg = fg_action, .grad = fg_normal, .fg = fg_normal, .rgb = 0xFFFFFF };
constexpr btn_colors text_x_axis = {.bg = fg_action, .grad = fg_normal, .fg = fg_normal, .rgb = x_axis };
constexpr btn_colors text_y_axis = {.bg = fg_action, .grad = fg_normal, .fg = fg_normal, .rgb = y_axis };
constexpr btn_colors text_z_axis = {.bg = fg_action, .grad = fg_normal, .fg = fg_normal, .rgb = z_axis };
constexpr btn_colors cold_pull_btn = {.bg = fg_action, .grad = fg_normal, .fg = cold_pull, .rgb = 0xFFFFFF };
constexpr btn_colors cancel_btn = {.bg = fg_action, .grad = fg_normal, .fg = cancel, .rgb = 0xFFFFFF };
constexpr btn_colors temp_btn = {.bg = bg_color, .grad = fg_disabled, .fg = fg_disabled, .rgb = 0xFFFFFF };
constexpr btn_colors temp_disabled_btn = {.bg = bg_color, .grad = bg_dark_color, .fg = bg_dark_color, .rgb = bg_light_color };
// Temperature color scale
const rgb_t cool_rgb ( 0, 0, 0);
const rgb_t low_rgb (128, 0, 0);
const rgb_t med_rgb (255, 128, 0);
const rgb_t high_rgb (255, 255, 128);
const rgb_t cool_rgb (100, 100, 80);
const rgb_t low_rgb (128, 50, 0);
const rgb_t med_rgb (200, 85, 0);
const rgb_t high_rgb (255, 85, 0);
};

View file

@ -31,6 +31,7 @@ namespace Theme {
constexpr int16_t font_medium = 30;
constexpr int16_t font_large = 30;
constexpr int16_t font_xlarge = 31;
constexpr int16_t font_xxlarge = 31.5;
#else
constexpr int16_t font_tiny = 27;
constexpr int16_t font_xsmall = 29;
@ -38,8 +39,10 @@ namespace Theme {
constexpr int16_t font_medium = 30;
constexpr int16_t font_large = 31;
constexpr int16_t font_xlarge = 31;
constexpr int16_t font_xxlarge = 32;
#endif
constexpr float icon_scale = 1.0;
constexpr float icon_scale_lg = 2.0;
#elif defined(TOUCH_UI_480x272)
#if ENABLED(TOUCH_UI_PORTRAIT)
constexpr int16_t font_tiny = 26;
@ -48,6 +51,7 @@ namespace Theme {
constexpr int16_t font_medium = 27;
constexpr int16_t font_large = 28;
constexpr int16_t font_xlarge = 29;
constexpr int16_t font_xxlarge = 30;
constexpr float icon_scale = 0.7;
#else
constexpr int16_t font_tiny = 26;
@ -56,6 +60,7 @@ namespace Theme {
constexpr int16_t font_medium = 28;
constexpr int16_t font_large = 30;
constexpr int16_t font_xlarge = 30;
constexpr int16_t font_xxlarge = 31;
constexpr float icon_scale = 0.6;
#endif
#elif defined(TOUCH_UI_320x240)
@ -66,6 +71,7 @@ namespace Theme {
constexpr int16_t font_medium = 27;
constexpr int16_t font_large = 27;
constexpr int16_t font_xlarge = 28;
constexpr int16_t font_xxlarge = 29;
constexpr float icon_scale = 0.6;
#else
constexpr int16_t font_tiny = 26;
@ -74,6 +80,7 @@ namespace Theme {
constexpr int16_t font_medium = 27;
constexpr int16_t font_large = 29;
constexpr int16_t font_xlarge = 30;
constexpr int16_t font_xxlarge = 31;
constexpr float icon_scale = 0.5;
#endif
#endif

View file

@ -1188,6 +1188,10 @@ namespace ExtUI {
return isPrinting() && (isPrintingFromMediaPaused() || print_job_timer.isPaused());
}
bool isOngoingPrintJob() {
return isPrintingFromMedia() || printJobOngoing();
}
bool isMediaMounted() { return TERN0(HAS_MEDIA, card.isMounted()); }
// Pause/Resume/Stop are implemented in MarlinUI

View file

@ -465,6 +465,7 @@ namespace ExtUI {
bool isPrintingFromMedia();
bool isPrinting();
bool isPrintingPaused();
bool isOngoingPrintJob();
void printFile(const char *filename);
void stopPrint();

View file

@ -48,6 +48,22 @@
#define PREHEAT_1_LABEL ""
#endif
#ifndef PREHEAT_2_LABEL
#define PREHEAT_2_LABEL ""
#endif
#ifndef PREHEAT_3_LABEL
#define PREHEAT_3_LABEL ""
#endif
#ifndef PREHEAT_4_LABEL
#define PREHEAT_4_LABEL ""
#endif
#ifndef CUSTOM_MENU_MAIN_TITLE
#define CUSTOM_MENU_MAIN_TITLE ""
#endif
namespace LanguageNarrow_en {
constexpr uint8_t CHARSIZE = 2;
LSTR LANGUAGE = _UxGT("English");
@ -84,6 +100,7 @@ namespace LanguageNarrow_en {
LSTR MSG_Z_PROBE = _UxGT("Z Probe");
LSTR MSG_HOMING = _UxGT("Homing");
LSTR MSG_AUTO_HOME = _UxGT("Auto Home");
LSTR MSG_HOME_ALL = _UxGT("Home All");
LSTR MSG_AUTO_HOME_A = _UxGT("Home @");
LSTR MSG_AUTO_HOME_X = _UxGT("Home X");
LSTR MSG_AUTO_HOME_Y = _UxGT("Home Y");
@ -126,6 +143,10 @@ namespace LanguageNarrow_en {
LSTR MSG_PREHEAT_1_BEDONLY = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Bed");
LSTR MSG_PREHEAT_1_SETTINGS = _UxGT("Preheat ") PREHEAT_1_LABEL _UxGT(" Conf");
LSTR MSG_PREHEAT_2 = _UxGT("Preheat ") PREHEAT_2_LABEL;
LSTR MSG_PREHEAT_3 = _UxGT("Preheat ") PREHEAT_3_LABEL;
LSTR MSG_PREHEAT_4 = PREHEAT_4_LABEL;
LSTR MSG_PREHEAT_M = _UxGT("Preheat $");
LSTR MSG_PREHEAT_M_H = _UxGT("Preheat $ ~");
LSTR MSG_PREHEAT_M_END = _UxGT("Preheat $ End");
@ -136,6 +157,7 @@ namespace LanguageNarrow_en {
LSTR MSG_PREHEAT_HOTEND = _UxGT("Preheat Hotend");
LSTR MSG_PREHEAT_CUSTOM = _UxGT("Preheat Custom");
LSTR MSG_PREHEAT = _UxGT("Preheat");
LSTR MSG_COOLDOWN = _UxGT("Cooldown");
LSTR MSG_CUTTER_FREQUENCY = _UxGT("Frequency");
@ -189,6 +211,9 @@ namespace LanguageNarrow_en {
LSTR MSG_MESH_CANCEL = _UxGT("Mesh cancelled");
LSTR MSG_MESH_RESET = _UxGT("Mesh reset");
LSTR MSG_CUSTOM_COMMANDS = _UxGT("Custom Commands");
LSTR MSG_CUSTOM_MENU_MAIN_TITLE = _UxGT(CUSTOM_MENU_MAIN_TITLE);
LSTR MSG_TOOL_HEAD_TH = _UxGT(CUSTOM_MENU_MAIN_TITLE" (TH)");
LSTR MSG_PRESENT_BED = _UxGT("Present Bed");
LSTR MSG_M48_TEST = _UxGT("M48 Probe Test");
LSTR MSG_M48_POINT = _UxGT("M48 Point");
LSTR MSG_M48_OUT_OF_BOUNDS = _UxGT("Probe out of bounds");
@ -343,6 +368,7 @@ namespace LanguageNarrow_en {
LSTR MSG_CONTROLLER_FAN_AUTO_ON = _UxGT("Auto Mode");
LSTR MSG_CONTROLLER_FAN_SPEED = _UxGT("Active Speed");
LSTR MSG_CONTROLLER_FAN_DURATION = _UxGT("Idle Period");
LSTR MSG_FLOW_PERCENTAGE = _UxGT("Set Flowrate Percentage");
LSTR MSG_FLOW = _UxGT("Flow");
LSTR MSG_FLOW_N = _UxGT("Flow ~");
LSTR MSG_CONTROL = _UxGT("Control");
@ -515,6 +541,7 @@ namespace LanguageNarrow_en {
LSTR MSG_ADVANCED_PAUSE = _UxGT("Advanced Pause");
LSTR MSG_RESUME_PRINT = _UxGT("Resume Print");
LSTR MSG_STOP_PRINT = _UxGT("Stop Print");
LSTR MSG_CANCEL_PRINT = _UxGT("Cancel Print");
LSTR MSG_OUTAGE_RECOVERY = _UxGT("Power Outage");
LSTR MSG_RESUME_BED_TEMP = _UxGT("Resume Bed Temp");
LSTR MSG_HOST_START_PRINT = _UxGT("Host Start");
@ -552,6 +579,8 @@ namespace LanguageNarrow_en {
LSTR MSG_FILAMENT_SWAP_EXTRA = _UxGT("Swap Extra");
LSTR MSG_FILAMENT_PURGE_LENGTH = _UxGT("Purge Length");
LSTR MSG_TOOL_CHANGE = _UxGT("Tool Change");
LSTR MSG_TOOL_HEAD_SWAP = _UxGT("Park For Tool Head Swap");
LSTR MSG_FILAMENT_SWAP = _UxGT("Park For Filament Change");
LSTR MSG_TOOL_CHANGE_ZLIFT = _UxGT("Z Raise");
LSTR MSG_SINGLENOZZLE_PRIME_SPEED = _UxGT("Prime Speed");
LSTR MSG_SINGLENOZZLE_WIPE_RETRACT = _UxGT("Wipe Retract");
@ -611,6 +640,7 @@ namespace LanguageNarrow_en {
LSTR MSG_ZPROBE_YOFFSET = _UxGT("Probe Y Offset");
LSTR MSG_ZPROBE_ZOFFSET = _UxGT("Probe Z Offset");
LSTR MSG_ZPROBE_MARGIN = _UxGT("Probe Margin");
LSTR MSG_ZOFFSET = _UxGT("Z Offset");
LSTR MSG_Z_FEED_RATE = _UxGT("Z Feed Rate");
LSTR MSG_ENABLE_HS_MODE = _UxGT("Enable HS mode");
LSTR MSG_MOVE_NOZZLE_TO_BED = _UxGT("Move Nozzle to Bed");
@ -660,7 +690,8 @@ namespace LanguageNarrow_en {
LSTR MSG_UBL_LEVELING = _UxGT("Unified Bed Leveling");
LSTR MSG_MESH_LEVELING = _UxGT("Mesh Leveling");
LSTR MSG_MESH_DONE = _UxGT("Mesh probing done");
LSTR MSG_INFO_STATS_MENU = _UxGT("Printer Stats");
LSTR MSG_INFO_PRINTER_STATS_MENU = _UxGT("Printer Stats");
LSTR MSG_INFO_STATS_MENU = _UxGT("Stats");
LSTR MSG_RESET_STATS = _UxGT("Reset Print Stats?");
LSTR MSG_INFO_BOARD_MENU = _UxGT("Board Info");
LSTR MSG_INFO_THERMISTOR_MENU = _UxGT("Thermistors");
@ -670,6 +701,7 @@ namespace LanguageNarrow_en {
LSTR MSG_INFO_RUNAWAY_OFF = _UxGT("Runaway Watch: OFF");
LSTR MSG_INFO_RUNAWAY_ON = _UxGT("Runaway Watch: ON");
LSTR MSG_HOTEND_IDLE_TIMEOUT = _UxGT("Hotend Idle Timeout");
LSTR MSG_BED_IDLE_TIMEOUT = _UxGT("Bed Idle Timeout");
LSTR MSG_HOTEND_IDLE_DISABLE = _UxGT("Disable Timeout");
LSTR MSG_HOTEND_IDLE_NOZZLE_TARGET = _UxGT("Nozzle Idle Temp");
LSTR MSG_HOTEND_IDLE_BED_TARGET = _UxGT("Bed Idle Temp");
@ -718,6 +750,7 @@ namespace LanguageNarrow_en {
LSTR MSG_FILAMENT_CHANGE_PURGE_CONTINUE = _UxGT("Purge or Continue?"); // ProUI
LSTR MSG_FILAMENT_CHANGE_NOZZLE = _UxGT(" Nozzle: ");
LSTR MSG_RUNOUT_SENSOR = _UxGT("Runout Sensor");
LSTR MSG_SENSOR = _UxGT("Sensor");
LSTR MSG_RUNOUT_DISTANCE_MM = _UxGT("Runout Dist mm");
LSTR MSG_EXTRUDER_MIN_TEMP = _UxGT("Extruder Min Temp."); // ProUI
LSTR MSG_FANCHECK = _UxGT("Fan Tacho Check");