diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h index 8561eb05a2..9a83e9ee09 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/command_processor.h @@ -209,11 +209,25 @@ class CommandProcessor : public CLCD::CommandFifo { inline CommandProcessor& rectangle(int16_t x, int16_t y, int16_t w, int16_t h) { using namespace FTDI; CLCD::CommandFifo::cmd(BEGIN(RECTS)); - CLCD::CommandFifo::cmd(VERTEX2F(x * 16, y * 16)); + CLCD::CommandFifo::cmd(VERTEX2F( x * 16, y * 16)); CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, (y + h) * 16)); return *this; } + inline CommandProcessor& border(int16_t x, int16_t y, int16_t w, int16_t h) { + using namespace FTDI; + CLCD::CommandFifo::cmd(BEGIN(LINES)); + CLCD::CommandFifo::cmd(VERTEX2F( x * 16, y * 16)); + CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, y * 16)); + CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, y * 16)); + CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, (y + h) * 16)); + CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, (y + h) * 16)); + CLCD::CommandFifo::cmd(VERTEX2F( x * 16, (y + h) * 16)); + CLCD::CommandFifo::cmd(VERTEX2F( x * 16, (y + h) * 16)); + CLCD::CommandFifo::cmd(VERTEX2F( x * 16, y * 16)); + return *this; + } + template FORCEDINLINE CommandProcessor& toggle(int16_t x, int16_t y, int16_t w, int16_t h, T text, bool state, uint16_t options = FTDI::OPT_3D) { CLCD::FontMetrics fm(_font); diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp index 9f73c7dfb8..f3f518359c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/ftdi_eve_lib/extended/text_box.cpp @@ -29,25 +29,30 @@ namespace FTDI { * be broken so that the display width is less than w. The line will also * be broken after a '\n'. Returns the display width of the line. */ - static uint16_t find_line_break(const FontMetrics &fm, uint16_t w, const char *str, const char *&end) { - w -= fm.get_char_width(' '); + static uint16_t find_line_break(const FontMetrics &utf8_fm, const CLCD::FontMetrics &clcd_fm, const uint16_t w, const char *str, const char *&end, bool use_utf8) { const char *p = str; end = str; uint16_t lw = 0, result = 0; for (;;) { - utf8_char_t c = get_utf8_char_and_inc(p); - if (c == ' ' || c == '\n' || c == '\0') { - if (lw < w || end == str) { - end = (c == '\0') ? p-1 : p; + const char *next = p; + utf8_char_t c = get_utf8_char_and_inc(next); + // Decide whether to break the string at this location + if (c == '\n' || c == '\0' || c == ' ') { + end = p; + result = lw; + } + if (c == '\n' || c == '\0') break; + // Now add the length of the current character to the tally. + lw += use_utf8 ? utf8_fm.get_char_width(c) : clcd_fm.char_widths[(uint8_t)c]; + // Stop processing once string exceeds the display width + if (lw >= w) { + if (end == str) { + end = p; result = lw; } - if (c == '\0' || c == '\n') break; + break; } - lw += fm.get_char_width(c); - } - if (end == str) { - end = p-1; - result = lw; + p = next; } return result; } @@ -55,17 +60,18 @@ namespace FTDI { /** * This function returns a measurements of the word-wrapped text box. */ - static void measure_text_box(const FontMetrics &fm, const char *str, uint16_t &width, uint16_t &height) { + static void measure_text_box(const FontMetrics &utf8_fm, const CLCD::FontMetrics &clcd_fm, const char *str, uint16_t &width, uint16_t &height, bool use_utf8) { const char *line_start = (const char*)str; const char *line_end; const uint16_t wrap_width = width; width = height = 0; for (;;) { - uint16_t line_width = find_line_break(fm, wrap_width, line_start, line_end); - if (line_end == line_start) break; + uint16_t line_width = find_line_break(utf8_fm, clcd_fm, wrap_width, line_start, line_end, use_utf8); width = max(width, line_width); - height += fm.get_height(); + height += utf8_fm.get_height(); line_start = line_end; + if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; + if (line_start[0] == '\0') break; } } @@ -73,41 +79,45 @@ namespace FTDI { * This function draws text inside a bounding box, doing word wrapping and using the largest font that will fit. */ void draw_text_box(CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options, uint8_t font) { + #if ENABLED(TOUCH_UI_USE_UTF8) + const bool use_utf8 = has_utf8_chars(str); + #else + constexpr bool use_utf8 = false; + #endif uint16_t box_width, box_height; - FontMetrics fm(font); + FontMetrics utf8_fm(font); + CLCD::FontMetrics clcd_fm; + clcd_fm.load(font); // Shrink the font until we find a font that fits for (;;) { box_width = w; - measure_text_box(fm, str, box_width, box_height); + measure_text_box(utf8_fm, clcd_fm, str, box_width, box_height, use_utf8); if (box_width <= (uint16_t)w && box_height <= (uint16_t)h) break; if (font == 26) break; - fm.load(--font); + utf8_fm.load(--font); + clcd_fm.load(font); } const uint16_t dx = (options & OPT_RIGHTX) ? w : - (options & OPT_CENTERX) ? w/2 : 0; - const uint16_t dy = (options & OPT_BOTTOMY) ? (h - box_height) : - (options & OPT_CENTERY) ? (h - box_height)/2 : 0; + (options & OPT_CENTERX) ? w / 2 : 0, + dy = (options & OPT_BOTTOMY) ? (h - box_height) : + (options & OPT_CENTERY) ? (h - box_height) / 2 : 0; - const char *line_start = str; - const char *line_end; + const char *line_start = str, *line_end; for (;;) { - find_line_break(fm, w, line_start, line_end); - if (line_end == line_start) break; + find_line_break(utf8_fm, clcd_fm, w, line_start, line_end, use_utf8); const size_t line_len = line_end - line_start; if (line_len) { char line[line_len + 1]; strncpy(line, line_start, line_len); line[line_len] = 0; - if (line[line_len - 1] == '\n' || line[line_len - 1] == ' ') - line[line_len - 1] = 0; #if ENABLED(TOUCH_UI_USE_UTF8) - if (has_utf8_chars(line)) { - draw_utf8_text(cmd, x + dx, y + dy, line, fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY)); + if (use_utf8) { + draw_utf8_text(cmd, x + dx, y + dy, line, utf8_fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY)); } else #endif { @@ -115,9 +125,11 @@ namespace FTDI { cmd.CLCD::CommandFifo::str(line); } } - y += fm.get_height(); + y += utf8_fm.get_height(); line_start = line_end; + if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; + if (line_start[0] == '\0') break; } } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp index 4e90e71e8a..68e50c90ac 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/about_screen.cpp @@ -44,16 +44,13 @@ void AboutScreen::onRedraw(draw_mode_t) { .cmd(COLOR_RGB(bg_text_enabled)) .tag(0); - #define HEADING_POS BTN_POS(1,2), BTN_SIZE(4,1) + #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) - #define _INSET_POS(x,y,w,h) x + w/10, y, w - w/5, h - #define INSET_POS(pos) _INSET_POS(pos) - char about_str[1 + strlen_P(GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)) #ifdef TOOLHEAD_NAME @@ -89,7 +86,7 @@ void AboutScreen::onRedraw(draw_mode_t) { , OPT_CENTER, font_medium); cmd.tag(0); draw_text_box(cmd, FW_INFO_POS, about_str, OPT_CENTER, font_medium); - draw_text_box(cmd, INSET_POS(LICENSE_POS), GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny); + draw_text_box(cmd, LICENSE_POS, GET_TEXT_F(MSG_LICENSE), OPT_CENTER, font_tiny); cmd.font(font_medium); #if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.cpp index 568da53524..a3febb39a2 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/interface_settings_screen.cpp @@ -58,11 +58,7 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { if (what & BACKGROUND) { #define GRID_COLS 4 - #if ENABLED(TOUCH_UI_PORTRAIT) - #define GRID_ROWS 7 - #else - #define GRID_ROWS 6 - #endif + #define GRID_ROWS TERN(TOUCH_UI_PORTRAIT, 7, 6) cmd.cmd(CLEAR_COLOR_RGB(bg_color)) .cmd(CLEAR(true,true,true)) @@ -77,21 +73,19 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { #if DISABLED(LCD_FYSETC_TFT81050) .text(BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_LCD_BRIGHTNESS), OPT_RIGHTX | OPT_CENTERY) #endif - .text(BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_SOUND_VOLUME), OPT_RIGHTX | OPT_CENTERY) - .text(BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_SCREEN_LOCK), OPT_RIGHTX | OPT_CENTERY); + .text(BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_SOUND_VOLUME), OPT_RIGHTX | OPT_CENTERY); + #if ENABLED(FTDI_LOCK_SCREEN) + cmd.text(BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_SCREEN_LOCK), OPT_RIGHTX | OPT_CENTERY); + #endif #if DISABLED(TOUCH_UI_NO_BOOTSCREEN) - cmd.text(BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_BOOT_SCREEN), OPT_RIGHTX | OPT_CENTERY); + cmd.text(BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_BOOT_SCREEN), OPT_RIGHTX | OPT_CENTERY); #endif #undef EDGE_R } if (what & FOREGROUND) { - #if defined(FTDI_LOCK_SCREEN) || DISABLED(TOUCH_UI_NO_BOOTSCREEN) - #if ENABLED(TOUCH_UI_PORTRAIT) - constexpr uint8_t w = 2; - #else - constexpr uint8_t w = 1; - #endif + #if ENABLED(FTDI_LOCK_SCREEN) || DISABLED(TOUCH_UI_NO_BOOTSCREEN) + constexpr uint8_t w = TERN(TOUCH_UI_PORTRAIT, 2, 1); #endif cmd.font(font_medium) @@ -101,7 +95,7 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { .tag(2).slider(BTN_POS(3,2), BTN_SIZE(2,1), mydata.brightness, 128) #endif .tag(3).slider(BTN_POS(3,3), BTN_SIZE(2,1), mydata.volume, 0xFF) - #ifdef FTDI_LOCK_SCREEN + #if ENABLED(FTDI_LOCK_SCREEN) .colors(ui_toggle) .tag(4).toggle2(BTN_POS(3,4), BTN_SIZE(w,1), GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), LockScreen::is_enabled()) #endif @@ -126,7 +120,7 @@ void InterfaceSettingsScreen::onRedraw(draw_mode_t what) { bool InterfaceSettingsScreen::onTouchEnd(uint8_t tag) { switch (tag) { case 1: GOTO_PREVIOUS(); return true; - #ifdef FTDI_LOCK_SCREEN + #if ENABLED(FTDI_LOCK_SCREEN) case 4: if (!LockScreen::is_enabled()) LockScreen::enable(); @@ -185,8 +179,7 @@ void InterfaceSettingsScreen::onIdle() { } void InterfaceSettingsScreen::failSafeSettings() { - // Reset settings that may make the printer interface - // unusable. + // Reset settings that may make the printer interface unusable. CLCD::mem_write_32(CLCD::REG::ROTATE, 0); CLCD::default_touch_transform(); CLCD::default_display_orientation(); @@ -197,9 +190,7 @@ void InterfaceSettingsScreen::failSafeSettings() { } void InterfaceSettingsScreen::defaultSettings() { - #ifdef FTDI_LOCK_SCREEN - LockScreen::passcode = 0; - #endif + TERN_(FTDI_LOCK_SCREEN, LockScreen::passcode = 0); SoundPlayer::set_volume(255); CLCD::set_brightness(255); UIData::reset_persistent_data(); @@ -218,11 +209,7 @@ void InterfaceSettingsScreen::saveSettings(char *buff) { persistent_data_t eeprom; - #ifdef FTDI_LOCK_SCREEN - eeprom.passcode = LockScreen::passcode; - #else - eeprom.passcode = 0; - #endif + eeprom.passcode = TERN0(FTDI_LOCK_SCREEN, LockScreen::passcode); eeprom.sound_volume = SoundPlayer::get_volume(); eeprom.display_brightness = CLCD::get_brightness(); eeprom.bit_flags = UIData::get_persistent_data(); @@ -251,7 +238,7 @@ void InterfaceSettingsScreen::loadSettings(const char *buff) { SERIAL_ECHOLNPGM("Loading setting from EEPROM"); - #ifdef FTDI_LOCK_SCREEN + #if ENABLED(FTDI_LOCK_SCREEN) LockScreen::passcode = eeprom.passcode; #endif SoundPlayer::set_volume(eeprom.sound_volume); @@ -282,10 +269,7 @@ void InterfaceSettingsScreen::loadSettings(const char *buff) { if (success) success = persistentStore.write_data(0, data, ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE) == PERSISTENT_STORE_SUCCESS; - if (success) - StatusScreen::setStatusMessage(GET_TEXT_F(MSG_EEPROM_RESTORED)); - else - StatusScreen::setStatusMessage(GET_TEXT_F(MSG_EEPROM_RESET)); + StatusScreen::setStatusMessage(success ? GET_TEXT_F(MSG_EEPROM_RESTORED) : GET_TEXT_F(MSG_EEPROM_RESET)); return success; } diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.cpp index 176630d11e..5d92052ace 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.cpp +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.cpp @@ -60,4 +60,8 @@ void SaveSettingsDialogBox::promptToSaveSettings() { GOTO_PREVIOUS(); // No save needed. } +void SaveSettingsDialogBox::promptToSaveAndStay() { + if (needs_save) GOTO_SCREEN(SaveSettingsDialogBox); +} + #endif // FTDI_SAVE_SETTINGS_DIALOG_BOX diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.h index 8985a974fe..0cbadfbbe6 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/save_settings_dialog_box.h @@ -34,5 +34,6 @@ class SaveSettingsDialogBox : public DialogBoxBaseClass, public UncachedScreen { static bool onTouchEnd(uint8_t tag); static void promptToSaveSettings(); + static void promptToSaveAndStay(); static void settingsChanged() {needs_save = true;} }; diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h index 7cc4e078ad..63ecdfcb3c 100644 --- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h +++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/theme/fonts.h @@ -55,7 +55,7 @@ namespace Theme { constexpr int16_t font_small = 27; constexpr int16_t font_medium = 28; constexpr int16_t font_large = 30; - constexpr int16_t font_xlarge = 31; + constexpr int16_t font_xlarge = 30; constexpr float icon_scale = 0.6; #endif #elif defined(TOUCH_UI_320x240)