Skip to content

Commit

Permalink
🚸 Fix MarlinUI expanded label alignment (#26339)
Browse files Browse the repository at this point in the history
Co-authored-by: ellensp <[email protected]>
Co-authored-by: Scott Lahteine <[email protected]>
  • Loading branch information
3 people authored Oct 22, 2023
1 parent 156e7c1 commit 797ea5e
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 82 deletions.
33 changes: 24 additions & 9 deletions Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1170,23 +1170,38 @@ void MarlinUI::draw_status_screen() {

int8_t n = LCD_WIDTH;
const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
int8_t pad = (center || full) ? n - plen - vlen : 0;

// Value length, if any
int8_t vlen = vstr ? utf8_strlen(vstr) : 0;

// Expanded label string and width in chars
char estr[calculateWidth(ftpl) + 3] = "\0";
int8_t llen = ftpl ? expand_u8str(estr, ftpl, itemIndex, itemStringC, itemStringF, n - vlen) : 0;

bool mv_colon = false;
if (vlen) {
// Move the leading colon from the value to the label below
mv_colon = (*vstr == ':');
// Shorter value, wider label
if (mv_colon) { vstr++; vlen--; llen++; }
// Remove leading spaces from the value and shorten
while (*vstr == ' ') { vstr++; vlen--; }
}

// Padding for center or full justification
int8_t pad = (center || full) ? n - llen - vlen : 0;

// SS_CENTER: Pad with half of the unused space first
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) { lcd_put_u8str(F(" ")); n--; }
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad, --pad, --n) lcd_put_u8str(F(" "));

// Draw as much of the label as fits
if (plen) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n - vlen);
// Draw as much of the label as fits (without the relocated colon, drawn below)
if (llen) n -= lcd_put_u8str_max(estr, n - vlen);

if (vlen && n > 0) {
// SS_FULL: Pad with enough space to justify the value
if (full && !center) {
// Move the leading colon from the value to the label
if (*vstr == ':') { n -= lcd_put_u8str(F(":")); vstr++; }
// Move spaces to the padding
while (*vstr == ' ') { vstr++; pad++; }
if (mv_colon) n -= lcd_put_u8str(F(":"));
// Pad in-between
for (; pad > 0; --pad) { lcd_put_u8str(F(" ")); n--; }
}
Expand Down
27 changes: 20 additions & 7 deletions Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,23 +975,36 @@ void MarlinUI::draw_status_screen() {

uint8_t n = LCD_WIDTH;
const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
int8_t pad = (center || full) ? n - plen - vlen : 0;

// Value length, if any
int8_t vlen = vstr ? utf8_strlen(vstr) : 0;

char estr[utf8_strlen(ftpl) + 3] = "\0";
int8_t llen = ftpl ? expand_u8str(estr, ftpl, itemIndex, itemStringC, itemStringF, n - vlen) : 0;

bool mv_colon = false;
if (vlen) {
// Move the leading colon from the value to the label below
mv_colon = (*vstr == ':');
// Shorter value, wider label
if (mv_colon) { vstr++; vlen--; llen++; }
// Remove leading spaces from the value and shorten
while (*vstr == ' ') { vstr++; vlen--; }
}

int8_t pad = (center || full) ? n - llen - vlen : 0;

// SS_CENTER: Pad with half of the unused space first
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) { lcd.write(' '); n--; }

// Draw as much of the label as fits
if (plen) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n - vlen);
if (llen) n -= lcd_put_u8str_max(estr, n - vlen);

if (vlen && n > 0) {
// SS_FULL: Pad with enough space to justify the value
if (full && !center) {
// Move the leading colon from the value to the label
if (*vstr == ':') { lcd.write(':'); vstr++; n--; }
// Move spaces to the padding
while (*vstr == ' ') { vstr++; pad++; }
if (mv_colon) { lcd.write(':'); n--; }
// Pad in-between
for (; pad > 0; --pad) { lcd.write(' '); n--; }
}
Expand Down
38 changes: 27 additions & 11 deletions Marlin/src/lcd/dogm/marlinui_DOGM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,30 +414,46 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
if (!mark_as_selected(row, style & SS_INVERT)) return;

pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed

const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
const int pwide = ftpl ? calculateWidth(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
int pad = (center || full) ? ((LCD_PIXEL_WIDTH) - pwide - vlen * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH) : 0;

char estr[calculateWidth(ftpl) + 3] = "\0";
pixel_len_t lwide = ftpl ? (MENU_FONT_WIDTH) * expand_u8str(estr, ftpl, itemIndex, itemStringC, itemStringF, (LCD_PIXEL_WIDTH) / (MENU_FONT_WIDTH)) : 0;

// Value length, if any
int8_t vlen = vstr ? utf8_strlen(vstr) : 0;

bool mv_colon = false;
if (vlen) {
// Move the leading colon from the value to the label below
mv_colon = (*vstr == ':');
// Shorter value, wider label
if (mv_colon) { vstr++; vlen--; lwide += MENU_FONT_WIDTH; }
// Remove leading spaces from the value and shorten
while (*vstr == ' ') { vstr++; vlen--; }
}

// Padding for center or full justification
int8_t pad = (center || full) ? ((LCD_PIXEL_WIDTH) - lwide - vlen * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH) : 0;

// SS_CENTER: Pad with half of the unused space first
if (center) for (int lpad = pad / 2; lpad > 0; --lpad) n -= lcd_put_u8str(F(" "));
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) n -= lcd_put_u8str(F(" "));

// Draw as much of the label as fits
if (pwide) n -= lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH);
// Draw as much of the label as fits (without the relocated colon, drawn below)
if (lwide) lcd_put_u8str_max(estr, n);

// Value string?
if (vlen) {
// SS_FULL: Pad with enough space to justify the value
if (full && !center && n > MENU_FONT_WIDTH) {
// Move the leading colon from the value to the label
if (*vstr == ':') { n -= lcd_put_u8str(F(":")); vstr++; }
// Move spaces to the padding
while (*vstr == ' ') { vstr++; pad++; }
// Draw the leading colon moved from the value to the label
if (mv_colon) n -= lcd_put_u8str(F(":"));
// Pad in-between
for (; pad > 0; --pad) n -= lcd_put_u8str(F(" "));
}
// Draw the value string
n -= lcd_put_u8str_max(vstr, n);
}
// Always fill out the rest with spaces
while (n > MENU_FONT_WIDTH) n -= lcd_put_u8str(F(" "));
}

Expand Down
33 changes: 23 additions & 10 deletions Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,26 +317,39 @@ void MarlinUI::draw_status_message(const bool blink) {
dwin_string.set();

const bool center = bool(style & SS_CENTER), full = bool(style & SS_FULL);
const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
int8_t plen = ftpl ? utf8_strlen(ftpl) : 0;
const int8_t olen = plen;

// Value length, if any
int8_t vlen = vstr ? utf8_strlen(vstr) : 0;

bool mv_colon = false;
if (vlen) {
// Move the leading colon from the value to the label below
mv_colon = (*vstr == ':');
// Shorter value, wider label
if (mv_colon) { vstr++; vlen--; plen++; }
// Remove leading spaces from the value and shorten
while (*vstr == ' ') { vstr++; vlen--; }
}

int8_t pad = (center || full) ? (LCD_WIDTH) - 1 - plen - vlen : 0;

// SS_CENTER: Pad with half of the unused space first
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad) dwin_string.add(' ');
if (center) for (int8_t lpad = pad / 2; lpad > 0; --lpad, --pad) dwin_string.add(' ');

// Append the templated label string
if (plen) {
// Append the templated label string
dwin_string.add(ftpl, itemIndex, itemStringC, itemStringF);
pad -= dwin_string.length - plen;
// Remove padding if the string was expanded
pad -= dwin_string.length - olen;
}

// SS_FULL: Pad with enough space to justify the value
if (vlen) {
if (full && !center) {
// Move the leading colon from the value to the label
if (*vstr == ':') { dwin_string.add(':'); vstr++; }
// Move spaces to the padding
while (*vstr == ' ') { vstr++; pad++; }
// Append the leading colon moved from the value to the label
if (mv_colon) dwin_string.add(':');
// Pad in-between
for (; pad > 0; --pad) dwin_string.add(' ');
}
Expand All @@ -345,7 +358,7 @@ void MarlinUI::draw_status_message(const bool blink) {
}

// SS_CENTER: Pad the rest of the string
if (center) for (int8_t rpad = pad - (pad / 2); rpad > 0; --rpad) dwin_string.add(' ');
if (center) while (pad--) dwin_string.add(' ');

lcd_moveto(1, row);
lcd_put_dwin_string();
Expand Down
48 changes: 4 additions & 44 deletions Marlin/src/lcd/lcdprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,50 +123,10 @@ lcd_uint_t expand_u8str_P(char * const outstr, PGM_P const ptpl, const int8_t in
* Return the number of characters emitted
*/
lcd_uint_t lcd_put_u8str_P(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;
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 == '*') { lcd_put_u8str(F("E")); n--; }
if (n) {
int8_t inum = ind + ((wc == '{') ? 0 : LCD_FIRST_TOOL);
if (inum >= 10) {
lcd_put_lchar('0' + (inum / 10)); n--;
inum %= 10;
}
if (n) { lcd_put_lchar('0' + inum); n--; }
}
}
else {
PGM_P const b = ind == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED);
n -= lcd_put_u8str_max_P(b, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
}
if (n) {
n -= lcd_put_u8str_max_P((PGM_P)p, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
break;
}
}
else if (wc == '$' && fstr) {
n -= lcd_put_u8str_max_P(FTOP(fstr), n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
}
else if (wc == '$' && cstr) {
n -= lcd_put_u8str_max(cstr, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
}
else if (wc == '@') {
lcd_put_lchar(AXIS_CHAR(ind));
n--;
}
else {
lcd_put_lchar(wc);
n -= wc > 255 ? prop : 1;
}
}
return maxlen - n;
char estr[maxlen + 2];
const lcd_uint_t outlen = expand_u8str_P(estr, ptpl, ind, cstr, fstr, maxlen);
lcd_put_u8str_max(estr, maxlen * (MENU_FONT_WIDTH));
return outlen;
}

// Calculate UTF8 width with a simple check
Expand Down
9 changes: 8 additions & 1 deletion Marlin/src/lcd/menu/menu_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ void menu_advanced_settings();

#define __STOP_ITEM(F,S) PSTRING_ITEM_F_P(F, TEST(stops, S) ? PSTR(STR_ENDSTOP_HIT) : PSTR(STR_ENDSTOP_OPEN), SS_FULL);
#define _STOP_ITEM(L,S) __STOP_ITEM(F(L), S)
#define STOP_ITEM(A,I,M,L) TERN(HAS_##A##I##_##M##_STATE, _STOP_ITEM, _IF_1_ELSE)(STRINGIFY(A) STRINGIFY(I) " " STRINGIFY(L), A##I##_##M)
#if HAS_X2_STATE || HAS_Y2_STATE || HAS_Z2_STATE
#define _S1_EXP_ ~,
#define _S1_SP_(I) THIRD(I, " ", "")
#define S1_SPACE(I) _S1_SP_(_CAT(_S1_EXP_,I))
#else
#define S1_SPACE(I)
#endif
#define STOP_ITEM(A,I,M,L) TERN(HAS_##A##I##_##M##_STATE, _STOP_ITEM, _IF_1_ELSE)(STRINGIFY(A) STRINGIFY(I) S1_SPACE(I) " " L, A##I##_##M)
#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);

Expand Down

0 comments on commit 797ea5e

Please sign in to comment.