🧑‍💻 MarlinUI menu tweaks

Changes in prep for #26339
This commit is contained in:
Scott Lahteine 2023-10-20 17:21:30 -05:00
parent 4b0b00c8da
commit b0ece8f8df
9 changed files with 245 additions and 145 deletions

View file

@ -1165,12 +1165,12 @@ void MarlinUI::draw_status_screen() {
#endif // ADVANCED_PAUSE_FEATURE
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
lcd_moveto(0, row);
int8_t n = LCD_WIDTH;
const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
const int8_t plen = fstr ? utf8_strlen(fstr) : 0,
const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
int8_t pad = (center || full) ? n - plen - vlen : 0;
@ -1178,7 +1178,7 @@ void MarlinUI::draw_status_screen() {
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) { lcd_put_u8str(F(" ")); n--; }
// Draw as much of the label as fits
if (plen) n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n - vlen);
if (plen) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n - vlen);
if (vlen && n > 0) {
// SS_FULL: Pad with enough space to justify the value

View file

@ -969,7 +969,7 @@ void MarlinUI::draw_status_screen() {
#endif
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
if (!PanelDetected) return;
lcd_moveto(0, row);
@ -1004,25 +1004,25 @@ void MarlinUI::draw_status_screen() {
}
// Draw a generic menu item with pre_char (if selected) and post_char
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) {
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char pre_char, const char post_char) {
if (!PanelDetected) return;
lcd_moveto(0, row);
lcd.write(sel ? pre_char : ' ');
uint8_t n = LCD_WIDTH - 2;
n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n);
for (; n; --n) lcd.write(' ');
lcd.write(post_char);
lcd.print_line();
}
// Draw a menu item with a (potentially) editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
if (!PanelDetected) return;
const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
lcd_moveto(0, row);
lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = LCD_WIDTH - 2 - vlen;
n -= lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n);
if (vlen) {
lcd.write(':');
for (; n; --n) lcd.write(' ');

View file

@ -411,8 +411,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
// Draw a static line of text in the same idiom as a menu item
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
if (!mark_as_selected(row, style & SS_INVERT)) return;
if (mark_as_selected(row, style & SS_INVERT)) {
pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
@ -440,22 +440,22 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
}
while (n > MENU_FONT_WIDTH) n -= lcd_put_u8str(F(" "));
}
}
// Draw a generic menu item
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
uint8_t n = LCD_WIDTH - 1;
n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n);
for (; n; --n) lcd_put_u8str(F(" "));
lcd_put_lchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char);
lcd_put_u8str(F(" "));
}
}
// Draw a menu item with an editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)),
pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr));
const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
@ -469,7 +469,6 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
}
}
}
void MenuEditItemBase::draw_edit_screen(FSTR_P const ftpl, const char * const value/*=nullptr*/) {
ui.encoder_direction_normal();
@ -545,14 +544,14 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
#if HAS_MEDIA
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
const uint8_t maxlen = LCD_WIDTH - isDir;
if (isDir) lcd_put_lchar(LCD_STR_FOLDER[0]);
const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH);
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
for (; n > MENU_FONT_WIDTH; n -= MENU_FONT_WIDTH) lcd_put_u8str(F(" "));
}
}
#endif // HAS_MEDIA

View file

@ -308,7 +308,8 @@ void MarlinUI::draw_status_message(const bool blink) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
// Call mark_as_selected to draw a bigger selection box
// and draw the text without a background
if (mark_as_selected(row, (bool)(style & SS_INVERT), true)) {
if (!mark_as_selected(row, (bool)(style & SS_INVERT), true)) return;
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
dwin_font.fg = COLOR_WHITE;
@ -349,11 +350,11 @@ void MarlinUI::draw_status_message(const bool blink) {
lcd_moveto(1, row);
lcd_put_dwin_string();
}
}
// Draw a generic menu item
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
dwin_font.fg = COLOR_WHITE;
@ -368,13 +369,13 @@ void MarlinUI::draw_status_message(const bool blink) {
lcd_moveto(1, row);
lcd_put_dwin_string();
}
}
//
// Draw a menu item with an editable value
//
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
dwin_font.fg = COLOR_WHITE;
@ -394,7 +395,6 @@ void MarlinUI::draw_status_message(const bool blink) {
lcd_put_dwin_string();
}
}
}
//
// Draw an edit screen with label and current value
@ -464,7 +464,8 @@ void MarlinUI::draw_status_message(const bool blink) {
#if HAS_MEDIA
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
if (mark_as_selected(row, sel)) {
if (!mark_as_selected(row, sel)) return;
dwin_string.set();
uint8_t maxlen = LCD_WIDTH - 1;
@ -479,7 +480,6 @@ void MarlinUI::draw_status_message(const bool blink) {
lcd_moveto(1, row);
lcd_put_dwin_string();
}
}
#endif // HAS_MEDIA

View file

@ -31,6 +31,84 @@
#include "marlinui.h"
#include "lcdprint.h"
/**
* expand_u8str_P
*
* Expand a string with optional substitutions:
*
* $ displays the clipped string given by fstr or cstr
* { displays '0'....'10' for indexes 0 - 10
* ~ displays '1'....'11' for indexes 0 - 10
* * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
* @ displays an axis name such as XYZUVW, or E for an extruder
*
* Return the number of characters emitted
*/
lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t ind, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
const uint8_t prop = USE_WIDE_GLYPH ? 2 : 1;
const uint8_t *p = (uint8_t*)ptpl;
char *o = outstr;
int8_t n = maxlen;
while (n > 0) {
lchar_t wc;
p = get_utf8_value_cb(p, read_byte_rom, wc);
if (!wc) break;
if (wc == '{' || wc == '~' || wc == '*') {
if (ind >= 0) {
if (wc == '*') { *o++ = 'E'; n--; }
if (n) {
int8_t inum = ind + ((wc == '{') ? 0 : LCD_FIRST_TOOL);
if (inum >= 10) {
*o++ = ('0' + (inum / 10)); n--;
inum %= 10;
}
if (n) { *o++ = '0' + inum; n--; }
}
}
else {
PGM_P const b = ind == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED);
strncpy_P(o, b, n);
n -= utf8_strlen_P(b);
o += strlen(o);
}
if (n > 0) {
strncpy_P(o, (PGM_P)p, n);
n -= utf8_strlen(o);
o += strlen(o);
break;
}
}
else if (wc == '$' && fstr) {
strncpy_P(o, FTOP(fstr), n);
n -= utf8_strlen_P(FTOP(fstr));
o += strlen(o);
}
else if (wc == '$' && cstr) {
strncpy(o, cstr, n);
n -= utf8_strlen(o);
o += strlen(o);
}
else if (wc == '@') {
*o++ = AXIS_CHAR(ind);
*o = '\0';
n--;
}
else if (wc > 255 && prop == 2) {
// Wide glyph support incomplete
*((uint16_t*)o) = wc;
o += 2;
*o = '\0';
n--;
}
else {
*o++ = wc;
*o = '\0';
n--;
}
}
return maxlen - n;
}
/**
* lcd_put_u8str_P
*

View file

@ -205,14 +205,37 @@ inline int lcd_put_u8str(const lcd_uint_t col, const lcd_uint_t row, FSTR_P cons
return lcd_put_u8str_P(col, row, FTOP(fstr));
}
/**
* @brief Expand a string with optional substitution
* @details Expand a string with optional substitutions:
* $ : the clipped string given by fstr or cstr
* { : '0'....'10' for indexes 0 - 10
* ~ : '1'....'11' for indexes 0 - 10
* * : 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
* @ : an axis name such as XYZUVW, or E for an extruder
*
* @param *outstr The output destination buffer
* @param ptpl A ROM string (template)
* @param ind An index value to use for = ~ * substitution
* @param cstr An SRAM C-string to use for $ substitution
* @param fstr A ROM F-string to use for $ substitution
* @param maxlen The maximum size of the string (in pixels on GLCD)
* @return the output width (in pixels on GLCD)
*/
lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH);
inline lcd_uint_t expand_u8str(char * const outstr, FSTR_P const ftpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
return expand_u8str_P(outstr, FTOP(ftpl), ind, cstr, fstr, maxlen);
}
/**
* @brief Draw a string with optional substitution
* @details Print a string with optional substitutions:
* $ displays the clipped string given by fstr or cstr
* { displays '0'....'10' for indexes 0 - 10
* ~ displays '1'....'11' for indexes 0 - 10
* * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
* @ displays an axis name such as XYZUVW, or E for an extruder
* $ : the clipped string given by fstr or cstr
* { : '0'....'10' for indexes 0 - 10
* ~ : '1'....'11' for indexes 0 - 10
* * : 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
* @ : an axis name such as XYZUVW, or E for an extruder
*
* @param ptpl A ROM string (template)
* @param ind An index value to use for = ~ * substitution

View file

@ -76,7 +76,7 @@ class MenuItemBase {
// STATIC_ITEM(LABEL,...)
class MenuItem_static : public MenuItemBase {
public:
static void draw(const uint8_t row, FSTR_P const fstr, const uint8_t style=SS_DEFAULT, const char *vstr=nullptr);
static void draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style=SS_DEFAULT, const char *vstr=nullptr);
};
// BACK_ITEM(LABEL)

View file

@ -78,7 +78,7 @@ void menu_advanced_settings();
#if ENABLED(LCD_PROGRESS_BAR_TEST)
static void progress_bar_test() {
static void screen_progress_bar_test() {
static int8_t bar_percent = 0;
if (ui.use_click()) {
ui.goto_previous_screen();
@ -93,8 +93,8 @@ void menu_advanced_settings();
lcd_moveto(0, LCD_HEIGHT - 1); ui.draw_progress_bar(bar_percent);
}
void _progress_bar_test() {
ui.goto_screen(progress_bar_test);
void _goto_progress_bar_test() {
ui.goto_screen(screen_progress_bar_test);
TERN_(HAS_MARLINUI_HD44780, ui.set_custom_characters(CHARSET_INFO));
}
@ -108,7 +108,7 @@ void menu_advanced_settings();
#define STOP_MINMAX(A,I) STOP_ITEM(A,I,MIN,"Min") STOP_ITEM(A,I,MAX,"Max")
#define FIL_ITEM(N) PSTRING_ITEM_N_P(N-1, MSG_FILAMENT_EN, (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) ? PSTR("PRESENT") : PSTR("out"), SS_FULL);
static void endstop_test() {
static void screen_endstop_test() {
if (ui.use_click()) {
ui.goto_previous_screen();
//endstops.enable_globally(false);
@ -148,11 +148,11 @@ void menu_advanced_settings();
BACK_ITEM(MSG_CONFIGURATION);
#if ENABLED(LCD_PROGRESS_BAR_TEST)
SUBMENU(MSG_PROGRESS_BAR_TEST, _progress_bar_test);
SUBMENU(MSG_PROGRESS_BAR_TEST, _goto_progress_bar_test);
#endif
#if ENABLED(LCD_ENDSTOP_TEST)
SUBMENU(MSG_ENDSTOP_TEST, endstop_test);
SUBMENU(MSG_ENDSTOP_TEST, screen_endstop_test);
#endif
END_MENU();

View file

@ -339,10 +339,10 @@ void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, c
}
// Draw a menu item with a (potentially) editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
menu_item(row, sel);
tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
tft_string.set(ftpl, itemIndex, itemStringC, itemStringF);
tft.add_text(MENU_TEXT_X, MENU_TEXT_Y, COLOR_MENU_TEXT, tft_string);
if (inStr) {
tft_string.set(inStr);
@ -351,10 +351,10 @@ void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr
}
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char *vstr/*=nullptr*/) {
menu_item(row);
tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
tft_string.set(ftpl, itemIndex, itemStringC, itemStringF);
const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
if (!full || !vstr) {