Convert button on LCD into button for MMU

- Dependent on current MMU error being processed
- Includes rename of LEFT_BUTTON_CHOICE -> LCD_LEFT_BUTTON_CHOICE (and right, middle as well) to avoid confusion with MMU buttons' ordering
This commit is contained in:
D.R.racer 2022-05-27 07:07:48 +02:00
parent a0e9a302b8
commit 5082da78d2
9 changed files with 222 additions and 122 deletions

View File

@ -648,7 +648,7 @@ void crashdet_detected(uint8_t mask)
lcd_puts_P(_T(MSG_RESUME_PRINT)); lcd_puts_P(_T(MSG_RESUME_PRINT));
lcd_putc('?'); lcd_putc('?');
bool yesno = lcd_show_yes_no_and_wait(false); bool yesno = lcd_show_yes_no_and_wait(false);
if (yesno == LEFT_BUTTON_CHOICE) if (yesno == LCD_LEFT_BUTTON_CHOICE)
{ {
enquecommand_P(PSTR("CRASH_RECOVER")); enquecommand_P(PSTR("CRASH_RECOVER"));
} }
@ -1604,7 +1604,7 @@ void setup()
#ifdef DEBUG_UVLO_AUTOMATIC_RECOVER #ifdef DEBUG_UVLO_AUTOMATIC_RECOVER
puts_P(_N("Normal recovery!")); puts_P(_N("Normal recovery!"));
#endif #endif
if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) == LEFT_BUTTON_CHOICE) { if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) == LCD_LEFT_BUTTON_CHOICE) {
recover_print(0); recover_print(0);
} else { } else {
eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0); eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0);
@ -3289,7 +3289,7 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
KEEPALIVE_STATE(PAUSED_FOR_USER); KEEPALIVE_STATE(PAUSED_FOR_USER);
#ifdef STEEL_SHEET #ifdef STEEL_SHEET
bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false); bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
if(result == LEFT_BUTTON_CHOICE) { if(result == LCD_LEFT_BUTTON_CHOICE) {
lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET)); lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET));
} }
#endif //STEEL_SHEET #endif //STEEL_SHEET
@ -3586,8 +3586,8 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
if (!MMU2::mmu2.Enabled()) { if (!MMU2::mmu2.Enabled()) {
KEEPALIVE_STATE(PAUSED_FOR_USER); KEEPALIVE_STATE(PAUSED_FOR_USER);
lcd_change_fil_state = lcd_change_fil_state =
lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=2 lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LCD_LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=2
if (lcd_change_fil_state == MIDDLE_BUTTON_CHOICE) { if (lcd_change_fil_state == LCD_MIDDLE_BUTTON_CHOICE) {
lcd_clear(); lcd_clear();
lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT)); lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
current_position[X_AXIS] -= 100; current_position[X_AXIS] -= 100;
@ -4920,7 +4920,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
lcd_show_fullscreen_message_and_wait_P(_i("Stable ambient temperature 21-26C is needed a rigid stand is required."));////MSG_TEMP_CAL_WARNING c=20 r=4 lcd_show_fullscreen_message_and_wait_P(_i("Stable ambient temperature 21-26C is needed a rigid stand is required."));////MSG_TEMP_CAL_WARNING c=20 r=4
bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false); bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
if (result == LEFT_BUTTON_CHOICE) if (result == LCD_LEFT_BUTTON_CHOICE)
{ {
current_position[Z_AXIS] = MESH_HOME_Z_SEARCH; current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
plan_buffer_line_curposXYZE(3000 / 60); plan_buffer_line_curposXYZE(3000 / 60);

View File

@ -2,8 +2,8 @@
#include <stdint.h> #include <stdint.h>
// Helper macros to parse the operations from Btns() // Helper macros to parse the operations from Btns()
#define BUTTON_OP_HI_NIBBLE(X) ( ( X & 0xF0 ) >> 4 ) #define BUTTON_OP_RIGHT(X) ( ( X & 0xF0 ) >> 4 )
#define BUTTON_OP_LO_NIBBLE(X) ( X & 0x0F ) #define BUTTON_OP_MIDDLE(X) ( X & 0x0F )
namespace MMU2 { namespace MMU2 {
@ -19,4 +19,18 @@ enum class ButtonOperations : uint8_t {
DisableMMU = 6, DisableMMU = 6,
}; };
/// Button codes + extended actions performed on the printer's side
enum Buttons : uint8_t {
Left = 0,
Middle,
Right,
// performed on the printer's side
RestartMMU,
StopPrint,
NoButton = 0xff // shall be kept last
};
} // namespace MMU2 } // namespace MMU2

View File

@ -273,7 +273,8 @@ static const char * const errorDescs[] PROGMEM = {
// 01234567890123456789 // 01234567890123456789
// >bttxt >bttxt >MoreW // >bttxt >bttxt >MoreW
// Therefore at least some of the buttons, which can occur on the screen together, need to be 5-chars long max @@TODO. // Therefore at least some of the buttons, which can occur on the screen together, need to be 5-chars long max @@TODO.
// @@TODO beware - this doesn't correspond to the HW MMU buttons - needs to be discussed // Beware - we only have space for 2 buttons on the LCD while the MMU has 3 buttons
// -> the left button on the MMU is not used/rendered on the LCD (it is also almost unused on the MMU side)
static const char btnRetry[] PROGMEM_I1 = ISTR("Retry"); static const char btnRetry[] PROGMEM_I1 = ISTR("Retry");
static const char btnContinue[] PROGMEM_I1 = ISTR("Done"); static const char btnContinue[] PROGMEM_I1 = ISTR("Done");
static const char btnRestartMMU[] PROGMEM_I1 = ISTR("RstMMU"); static const char btnRestartMMU[] PROGMEM_I1 = ISTR("RstMMU");
@ -295,15 +296,15 @@ static const char * const btnOperation[] PROGMEM = {
// We have 8 different operations/buttons at this time, so we need at least 4 bits to encode each. // We have 8 different operations/buttons at this time, so we need at least 4 bits to encode each.
// Since one of the buttons is always "More", we can skip that one. // Since one of the buttons is always "More", we can skip that one.
// Therefore we need just 1 byte to describe the necessary buttons for each screen. // Therefore we need just 1 byte to describe the necessary buttons for each screen.
uint8_t constexpr Btns(ButtonOperations b0, ButtonOperations b1){ uint8_t constexpr Btns(ButtonOperations bMiddle, ButtonOperations bRight){
return ((uint8_t)b1) << 4 | ((uint8_t)b0); return ((uint8_t)bRight) << 4 | ((uint8_t)bMiddle);
} }
static const uint8_t errorButtons[] PROGMEM = { static const uint8_t errorButtons[] PROGMEM = {
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::Continue),
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::Continue),
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::Continue),
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::Continue),
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation), Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),

View File

@ -6,6 +6,8 @@
namespace MMU2 { namespace MMU2 {
static ButtonOperations buttonSelectedOperation = ButtonOperations::NoOperation;
// we don't have a constexpr find_if in C++17/STL yet // we don't have a constexpr find_if in C++17/STL yet
template <class InputIt, class UnaryPredicate> template <class InputIt, class UnaryPredicate>
constexpr InputIt find_if_cx(InputIt first, InputIt last, UnaryPredicate p) { constexpr InputIt find_if_cx(InputIt first, InputIt last, UnaryPredicate p) {
@ -151,4 +153,131 @@ const char * const PrusaErrorButtonMore(){
return btnMore; return btnMore;
} }
struct ResetOnExit {
ResetOnExit() = default;
~ResetOnExit(){
buttonSelectedOperation = ButtonOperations::NoOperation;
}
};
Buttons ButtonPressed(uint16_t ec) {
if (buttonSelectedOperation == ButtonOperations::NoOperation) {
return NoButton; // no button
}
ResetOnExit ros; // clear buttonSelectedOperation on exit from this call
uint8_t ei = PrusaErrorCodeIndex(ec);
// The list of responses which occur in mmu error dialogs
// Return button index or perform some action on the MK4 by itself (like restart MMU)
// Based on Prusa-Error-Codes errors_list.h
// So far hardcoded, but shall be generated in the future
switch ( PrusaErrorCode(ei) ) {
case ERR_MECHANICAL_FINDA_DIDNT_TRIGGER:
case ERR_MECHANICAL_FINDA_DIDNT_GO_OFF:
case ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER:
case ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF:
case ERR_MECHANICAL_FSENSOR_TOO_EARLY:
switch (buttonSelectedOperation) {
case ButtonOperations::Retry: // "Repeat action"
return Middle;
case ButtonOperations::Continue: // "Continue"
return Right;
default:
break;
}
break;
case ERR_MECHANICAL_SELECTOR_CANNOT_HOME:
case ERR_MECHANICAL_IDLER_CANNOT_HOME:
case ERR_MECHANICAL_PULLEY_CANNOT_MOVE:
switch (buttonSelectedOperation) {
// may be allow move selector right and left in the future
case ButtonOperations::Retry: // "Repeat action"
return Middle;
default:
break;
}
break;
case ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT:
case ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT:
case ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT:
switch (buttonSelectedOperation) {
case ButtonOperations::Continue: // "Continue"
return Left;
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
default:
break;
}
break;
case ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR:
case ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR:
case ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET:
case ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR:
case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED:
case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED:
case ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED:
case ERR_CONNECT_MMU_NOT_RESPONDING:
case ERR_CONNECT_COMMUNICATION_ERROR:
case ERR_SYSTEM_QUEUE_FULL:
case ERR_SYSTEM_FW_RUNTIME_ERROR:
switch (buttonSelectedOperation) {
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
default:
break;
}
break;
case ERR_SYSTEM_FILAMENT_ALREADY_LOADED:
switch (buttonSelectedOperation) {
case ButtonOperations::Unload: // "Unload"
return Left;
case ButtonOperations::Continue: // "Proceed/Continue"
return Right;
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
default:
break;
}
break;
case ERR_SYSTEM_INVALID_TOOL:
switch (buttonSelectedOperation) {
case ButtonOperations::StopPrint: // "Stop print"
return StopPrint;
case ButtonOperations::RestartMMU: // "Restart MMU"
return RestartMMU;
default:
break;
}
break;
default:
break;
}
return NoButton;
}
void SetButtonResponse(ButtonOperations rsp){
buttonSelectedOperation = rsp;
}
} // namespace MMU2 } // namespace MMU2

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "mmu2/buttons.h"
namespace MMU2 { namespace MMU2 {
@ -31,4 +32,11 @@ const char * const PrusaErrorButtonTitle(uint8_t bi);
/// @returns pointer to a PROGMEM string representing the "More" button /// @returns pointer to a PROGMEM string representing the "More" button
const char * const PrusaErrorButtonMore(); const char * const PrusaErrorButtonMore();
/// Sets the selected button for later pick-up by the MMU state machine.
/// Used to save the GUI selection/decoupling
void SetButtonResponse(ButtonOperations rsp);
/// @returns button index/code based on currently processed error/screen
Buttons ButtonPressed(uint16_t ec);
} // namespace MMU2 } // namespace MMU2

View File

@ -62,12 +62,11 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec) {
// Read and determine what operations should be shown on the menu // Read and determine what operations should be shown on the menu
// Note: uint16_t is used here to avoid compiler warning. uint8_t is only half the size of void* // Note: uint16_t is used here to avoid compiler warning. uint8_t is only half the size of void*
const uint8_t button_operation = PrusaErrorButtons(ei); const uint8_t button_operation = PrusaErrorButtons(ei);
const uint8_t button_high_nibble = BUTTON_OP_HI_NIBBLE(button_operation); const uint8_t button_op_right = BUTTON_OP_RIGHT(button_operation);
const uint8_t button_low_nibble = BUTTON_OP_LO_NIBBLE(button_operation); const uint8_t button_op_middle = BUTTON_OP_MIDDLE(button_operation);
// Check if the menu should have three or two choices // Check if the menu should have three or two choices
if (button_high_nibble == (uint8_t)ButtonOperations::NoOperation) if (button_op_right == (uint8_t)ButtonOperations::NoOperation){
{
// Two operations not specified, the error menu should only show two choices // Two operations not specified, the error menu should only show two choices
two_choices = true; two_choices = true;
} }
@ -75,69 +74,37 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec) {
back_to_choices: back_to_choices:
lcd_clear(); lcd_clear();
lcd_update_enable(false); lcd_update_enable(false);
// Print title and header // Print title and header
lcd_printf_P(PSTR("%.20S\nprusa3d.com/ERR04%hu"), _T(PrusaErrorTitle(ei)), PrusaErrorCode(ei) ); lcd_printf_P(PSTR("%.20S\nprusa3d.com/ERR04%hu"), _T(PrusaErrorTitle(ei)), PrusaErrorCode(ei) );
// Render static characters in third line
lcd_set_cursor(0, 2);
lcd_printf_P(PSTR("FI: FS: > %c %c"), LCD_STR_THERMOMETER[0], LCD_STR_DEGREE[0]);
// Render the choices and store selection in 'choice_selected' // Render the choices and store selection in 'choice_selected'
choice_selected = lcd_show_multiscreen_message_with_choices_and_wait_P( choice_selected = lcd_show_multiscreen_message_with_choices_and_wait_P(
NULL, // NULL, since title screen is not in PROGMEM NULL, // NULL, since title screen is not in PROGMEM
false, false,
two_choices ? LEFT_BUTTON_CHOICE : MIDDLE_BUTTON_CHOICE, two_choices ? LCD_LEFT_BUTTON_CHOICE : LCD_MIDDLE_BUTTON_CHOICE, // beware - LEFT button on the LCD matches the MIDDLE button on the MMU!
_T(PrusaErrorButtonTitle(button_low_nibble)), _T(PrusaErrorButtonTitle(button_op_middle)),
_T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_high_nibble)), _T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_op_right)),
two_choices ? nullptr : _T(PrusaErrorButtonMore()), two_choices ? nullptr : _T(PrusaErrorButtonMore()),
two_choices ? two_choices ? 10 : 7 // If two choices, allow the first choice to have more characters
10 // If two choices, allow the first choice to have more characters
: 7,
ReportErrorHook_cb
); );
if ((two_choices && choice_selected == MIDDLE_BUTTON_CHOICE) // Two choices and middle button selected if ((two_choices && choice_selected == LCD_MIDDLE_BUTTON_CHOICE) // Two choices and middle button selected
|| (!two_choices && choice_selected == RIGHT_BUTTON_CHOICE)) // Three choices and right most button selected || (!two_choices && choice_selected == LCD_RIGHT_BUTTON_CHOICE)) // Three choices and right most button selected
{ {
// 'More' show error description // 'More' show error description
lcd_show_fullscreen_message_and_wait_P(_T(PrusaErrorDesc(ei))); lcd_show_fullscreen_message_and_wait_P(_T(PrusaErrorDesc(ei)));
// Return back to the choice menu // Return back to the choice menu
goto back_to_choices; goto back_to_choices;
} else if(choice_selected == MIDDLE_BUTTON_CHOICE) { } else if(choice_selected == LCD_MIDDLE_BUTTON_CHOICE) {
// TODO: User selected middle choice, not sure what to do. SetButtonResponse((ButtonOperations)button_op_right);
// At the moment just return to the status screen
switch (button_high_nibble)
{
case (uint8_t)ButtonOperations::Retry:
case (uint8_t)ButtonOperations::Continue:
case (uint8_t)ButtonOperations::RestartMMU:
case (uint8_t)ButtonOperations::Unload:
case (uint8_t)ButtonOperations::StopPrint:
case (uint8_t)ButtonOperations::DisableMMU:
default:
lcd_update_enable(true);
lcd_return_to_status();
break;
}
} else { } else {
// TODO: User selected the left most choice, not sure what to do. SetButtonResponse((ButtonOperations)button_op_middle);
// At the moment just return to the status screen
switch (button_low_nibble)
{
case (uint8_t)ButtonOperations::Retry:
case (uint8_t)ButtonOperations::Continue:
case (uint8_t)ButtonOperations::RestartMMU:
case (uint8_t)ButtonOperations::Unload:
case (uint8_t)ButtonOperations::StopPrint:
case (uint8_t)ButtonOperations::DisableMMU:
default:
lcd_update_enable(true);
lcd_return_to_status();
break;
}
} }
// if any button/command selected, close the screen
lcd_update_enable(true);
lcd_return_to_status();
} }
void ReportProgressHook(CommandInProgress cip, uint16_t ec) { void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
@ -145,8 +112,4 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
lcd_setstatuspgm( _T(ProgressCodeToText(ec)) ); lcd_setstatuspgm( _T(ProgressCodeToText(ec)) );
} }
Buttons ButtonPressed(uint16_t ec) {
// query the MMU error screen if a button has been pressed/selected
}
} // namespace MMU2 } // namespace MMU2

View File

@ -28,21 +28,6 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec);
/// Called when the MMU sends operation progress update /// Called when the MMU sends operation progress update
void ReportProgressHook(CommandInProgress cip, uint16_t ec); void ReportProgressHook(CommandInProgress cip, uint16_t ec);
/// Button codes + extended actions performed on the printer's side
enum Buttons : uint8_t {
Left = 0,
Middle,
Right,
// performed on the printer's side
RestartMMU,
StopPrint,
NoButton = 0xff // shall be kept last
};
Buttons ButtonPressed(uint16_t ec);
/// @returns true if the MMU is communicating and available /// @returns true if the MMU is communicating and available
/// can change at runtime /// can change at runtime
bool MMUAvailable(); bool MMUAvailable();

View File

@ -2299,11 +2299,11 @@ void show_preheat_nozzle_warning()
void lcd_load_filament_color_check() void lcd_load_filament_color_check()
{ {
bool clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LEFT_BUTTON_CHOICE); bool clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LCD_LEFT_BUTTON_CHOICE);
while (clean == MIDDLE_BUTTON_CHOICE) { while (clean == LCD_MIDDLE_BUTTON_CHOICE) {
load_filament_final_feed(); load_filament_final_feed();
st_synchronize(); st_synchronize();
clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LEFT_BUTTON_CHOICE); clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LCD_LEFT_BUTTON_CHOICE);
} }
} }
@ -3193,23 +3193,25 @@ int8_t lcd_show_multiscreen_message_yes_no_and_wait_P(const char *msg, bool allo
void lcd_show_choices_prompt_P(uint8_t selected, const char *first_choice, const char *second_choice, uint8_t second_col, const char *third_choice = nullptr) void lcd_show_choices_prompt_P(uint8_t selected, const char *first_choice, const char *second_choice, uint8_t second_col, const char *third_choice = nullptr)
{ {
lcd_set_cursor(0, 3); lcd_set_cursor(0, 3);
lcd_print(selected == LEFT_BUTTON_CHOICE ? '>': ' '); lcd_print(selected == LCD_LEFT_BUTTON_CHOICE ? '>': ' ');
lcd_puts_P(first_choice); lcd_puts_P(first_choice);
if (third_choice) if (third_choice)
{ {
lcd_set_cursor(7, 3); lcd_set_cursor(7, 3);
lcd_print(selected == MIDDLE_BUTTON_CHOICE ? '>': ' '); lcd_print(selected == LCD_MIDDLE_BUTTON_CHOICE ? '>': ' ');
lcd_puts_P(second_choice); lcd_puts_P(second_choice);
lcd_set_cursor(13, 3); lcd_set_cursor(13, 3);
lcd_print(selected == RIGHT_BUTTON_CHOICE ? '>': ' '); lcd_print(selected == LCD_RIGHT_BUTTON_CHOICE ? '>': ' ');
lcd_puts_P(third_choice); lcd_puts_P(third_choice);
} else { } else {
lcd_set_cursor(second_col, 3); lcd_set_cursor(second_col, 3);
lcd_print(selected == MIDDLE_BUTTON_CHOICE ? '>': ' '); lcd_print(selected == LCD_MIDDLE_BUTTON_CHOICE ? '>': ' ');
lcd_puts_P(second_choice); lcd_puts_P(second_choice);
} }
} }
typedef ;
//! @brief Show single or multiple screen message with two possible choices and wait with possible timeout //! @brief Show single or multiple screen message with two possible choices and wait with possible timeout
//! @param msg Message to show. If NULL, do not clear the screen and handle choice selection only. //! @param msg Message to show. If NULL, do not clear the screen and handle choice selection only.
//! @param allow_timeouting bool, if true, allows time outing of the screen //! @param allow_timeouting bool, if true, allows time outing of the screen
@ -3231,25 +3233,24 @@ int8_t lcd_show_multiscreen_message_with_choices_and_wait_P(const char * const m
bool multi_screen = msg_next != NULL; bool multi_screen = msg_next != NULL;
lcd_set_custom_characters_nextpage(); lcd_set_custom_characters_nextpage();
// Initial status/prompt on single-screen messages // Initial status/prompt on single-screen messages
uint8_t current_selection = default_selection; uint8_t current_selection = default_selection;
if (!msg_next) { if (!msg_next) {
lcd_show_choices_prompt_P(current_selection, first_choice, second_choice, second_col, third_choice); lcd_show_choices_prompt_P(current_selection, first_choice, second_choice, second_col, third_choice);
} }
// Wait for user confirmation or a timeout. // Wait for user confirmation or a timeout.
unsigned long previous_millis_cmd = _millis(); unsigned long previous_millis_cmd = _millis();
int8_t enc_dif = lcd_encoder_diff; int8_t enc_dif = lcd_encoder_diff;
lcd_consume_click(); lcd_consume_click();
KEEPALIVE_STATE(PAUSED_FOR_USER); KEEPALIVE_STATE(PAUSED_FOR_USER);
for (;;) { for (;;) {
for (uint8_t i = 0; i < 100; ++i) { for (uint8_t i = 0; i < 100; ++i) {
delay_keep_alive(50); delay_keep_alive(50);
if (allow_timeouting && _millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS) if (allow_timeouting && _millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS) {
{ return -1;
return -1; }
} manage_heater();
manage_heater(); manage_inactivity(true);
manage_inactivity(true);
if (multiscreen_cb) if (multiscreen_cb)
{ {
@ -3848,7 +3849,7 @@ void lcd_v2_calibration()
} }
else else
{ {
loaded = !lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), false, LEFT_BUTTON_CHOICE); loaded = !lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), false, LCD_LEFT_BUTTON_CHOICE);
lcd_update_enabled = true; lcd_update_enabled = true;
} }
@ -4040,8 +4041,8 @@ void lcd_wizard(WizState state)
lcd_show_fullscreen_message_and_wait_P(_T(MSG_WIZARD_WELCOME_SHIPPING)); lcd_show_fullscreen_message_and_wait_P(_T(MSG_WIZARD_WELCOME_SHIPPING));
state = S::Restore; state = S::Restore;
} else { } else {
wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_T(MSG_WIZARD_WELCOME), false, LEFT_BUTTON_CHOICE); wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_T(MSG_WIZARD_WELCOME), false, LCD_LEFT_BUTTON_CHOICE);
if (wizard_event == LEFT_BUTTON_CHOICE) { if (wizard_event == LCD_LEFT_BUTTON_CHOICE) {
state = S::Restore; state = S::Restore;
eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1); eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
} else { // MIDDLE_BUTTON_CHOICE } else { // MIDDLE_BUTTON_CHOICE
@ -4080,7 +4081,7 @@ void lcd_wizard(WizState state)
lcd_show_fullscreen_message_and_wait_P(_i("Now remove the test print from steel sheet."));////MSG_REMOVE_TEST_PRINT c=20 r=4 lcd_show_fullscreen_message_and_wait_P(_i("Now remove the test print from steel sheet."));////MSG_REMOVE_TEST_PRINT c=20 r=4
lcd_show_fullscreen_message_and_wait_P(_i("I will run z calibration now."));////MSG_WIZARD_Z_CAL c=20 r=8 lcd_show_fullscreen_message_and_wait_P(_i("I will run z calibration now."));////MSG_WIZARD_Z_CAL c=20 r=8
wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false); wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
if (wizard_event == MIDDLE_BUTTON_CHOICE) { if (wizard_event == LCD_MIDDLE_BUTTON_CHOICE) {
lcd_show_fullscreen_message_and_wait_P(_T(MSG_PLACE_STEEL_SHEET)); lcd_show_fullscreen_message_and_wait_P(_T(MSG_PLACE_STEEL_SHEET));
} }
wizard_event = gcode_M45(true, 0); wizard_event = gcode_M45(true, 0);
@ -4104,7 +4105,7 @@ void lcd_wizard(WizState state)
setTargetHotend(PLA_PREHEAT_HOTEND_TEMP, 0); setTargetHotend(PLA_PREHEAT_HOTEND_TEMP, 0);
setTargetBed(PLA_PREHEAT_HPB_TEMP); setTargetBed(PLA_PREHEAT_HPB_TEMP);
wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), true); wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), true);
if (wizard_event == LEFT_BUTTON_CHOICE) { if (wizard_event == LCD_LEFT_BUTTON_CHOICE) {
state = S::Lay1CalCold; state = S::Lay1CalCold;
} else { // MIDDLE_BUTTON_CHOICE } else { // MIDDLE_BUTTON_CHOICE
if(MMU2::mmu2.Enabled()) state = S::LoadFilCold; if(MMU2::mmu2.Enabled()) state = S::LoadFilCold;
@ -4137,7 +4138,7 @@ void lcd_wizard(WizState state)
break; break;
case S::RepeatLay1Cal: case S::RepeatLay1Cal:
wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_i("Do you want to repeat last step to readjust distance between nozzle and heatbed?"), false);////MSG_WIZARD_REPEAT_V2_CAL c=20 r=7 wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_i("Do you want to repeat last step to readjust distance between nozzle and heatbed?"), false);////MSG_WIZARD_REPEAT_V2_CAL c=20 r=7
if (wizard_event == LEFT_BUTTON_CHOICE) if (wizard_event == LCD_LEFT_BUTTON_CHOICE)
{ {
lcd_show_fullscreen_message_and_wait_P(_i("Please clean heatbed and then press the knob."));////MSG_WIZARD_CLEAN_HEATBED c=20 r=8 lcd_show_fullscreen_message_and_wait_P(_i("Please clean heatbed and then press the knob."));////MSG_WIZARD_CLEAN_HEATBED c=20 r=8
state = S::Lay1CalCold; state = S::Lay1CalCold;
@ -5092,7 +5093,7 @@ char reset_menu() {
static void lcd_disable_farm_mode() static void lcd_disable_farm_mode()
{ {
int8_t disable = lcd_show_fullscreen_message_yes_no_and_wait_P(PSTR("Disable farm mode?"), true); //allow timeouting, default no int8_t disable = lcd_show_fullscreen_message_yes_no_and_wait_P(PSTR("Disable farm mode?"), true); //allow timeouting, default no
if (disable == LEFT_BUTTON_CHOICE) if (disable == LCD_LEFT_BUTTON_CHOICE)
{ {
enquecommand_P(PSTR("G99")); enquecommand_P(PSTR("G99"));
lcd_return_to_status(); lcd_return_to_status();

View File

@ -64,11 +64,10 @@ void lcd_crash_detect_enable();
void lcd_crash_detect_disable(); void lcd_crash_detect_disable();
#endif #endif
enum ButtonChoice enum LCDButtonChoice : uint_fast8_t {
{ LCD_LEFT_BUTTON_CHOICE = 0,
LEFT_BUTTON_CHOICE = 0, LCD_MIDDLE_BUTTON_CHOICE = 1,
MIDDLE_BUTTON_CHOICE = 1, LCD_RIGHT_BUTTON_CHOICE = 2,
RIGHT_BUTTON_CHOICE = 2,
}; };
extern const char* lcd_display_message_fullscreen_P(const char *msg); extern const char* lcd_display_message_fullscreen_P(const char *msg);
@ -78,7 +77,7 @@ extern void lcd_wait_for_click();
extern bool lcd_wait_for_click_delay(uint16_t nDelay); extern bool lcd_wait_for_click_delay(uint16_t nDelay);
extern void lcd_show_fullscreen_message_and_wait_P(const char *msg); extern void lcd_show_fullscreen_message_and_wait_P(const char *msg);
// 1: no, 0: yes, -1: timeouted // 1: no, 0: yes, -1: timeouted
extern int8_t lcd_show_yes_no_and_wait(bool allow_timeouting = true, uint8_t default_selection = MIDDLE_BUTTON_CHOICE); extern int8_t lcd_show_yes_no_and_wait(bool allow_timeouting = true, uint8_t default_selection = LCD_MIDDLE_BUTTON_CHOICE);
// 1: no, 0: yes, -1: timeouted // 1: no, 0: yes, -1: timeouted
extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, uint8_t default_selection = MIDDLE_BUTTON_CHOICE); extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, uint8_t default_selection = MIDDLE_BUTTON_CHOICE);
extern int8_t lcd_show_multiscreen_message_with_choices_and_wait_P(const char * const msg, bool allow_timeouting, uint8_t default_selection, extern int8_t lcd_show_multiscreen_message_with_choices_and_wait_P(const char * const msg, bool allow_timeouting, uint8_t default_selection,