📺 Fix and optimize FTDI Eve Touch Interface (#22427)

This commit is contained in:
Marcio T 2021-07-23 16:02:39 -06:00 committed by Scott Lahteine
parent 99f917c022
commit eb8649ba42
8 changed files with 66 additions and 52 deletions

View file

@ -902,6 +902,7 @@ bool CLCD::CommandFifo::has_fault() {
} }
#if FTDI_API_LEVEL == 800 #if FTDI_API_LEVEL == 800
void CLCD::CommandFifo::start() { void CLCD::CommandFifo::start() {
if (command_write_ptr == 0xFFFFFFFFul) { if (command_write_ptr == 0xFFFFFFFFul) {
command_write_ptr = mem_read_32(REG::CMD_WRITE) & 0x0FFF; command_write_ptr = mem_read_32(REG::CMD_WRITE) & 0x0FFF;
@ -979,12 +980,13 @@ template <class T> bool CLCD::CommandFifo::_write_unaligned(T data, uint16_t len
template <class T> bool CLCD::CommandFifo::write(T data, uint16_t len) { template <class T> bool CLCD::CommandFifo::write(T data, uint16_t len) {
const uint8_t padding = MULTIPLE_OF_4(len) - len; const uint8_t padding = MULTIPLE_OF_4(len) - len;
const uint8_t pad_bytes[] = { 0, 0, 0, 0 };
uint8_t pad_bytes[] = {0, 0, 0, 0};
return _write_unaligned(data, len) && return _write_unaligned(data, len) &&
_write_unaligned(pad_bytes, padding); _write_unaligned(pad_bytes, padding);
} }
#else
#else // FTDI_API_LEVEL != 800 ...
void CLCD::CommandFifo::start() { void CLCD::CommandFifo::start() {
} }
@ -1042,13 +1044,29 @@ template <class T> bool CLCD::CommandFifo::write(T data, uint16_t len) {
mem_write_bulk(REG::CMDB_WRITE, data, len, padding); mem_write_bulk(REG::CMDB_WRITE, data, len, padding);
return true; return true;
} }
#endif
#endif // ... FTDI_API_LEVEL != 800
template bool CLCD::CommandFifo::write(const void*, uint16_t); template bool CLCD::CommandFifo::write(const void*, uint16_t);
template bool CLCD::CommandFifo::write(progmem_str, uint16_t); template bool CLCD::CommandFifo::write(progmem_str, uint16_t);
// CO_PROCESSOR COMMANDS // CO_PROCESSOR COMMANDS
void CLCD::CommandFifo::str(const char * data, size_t maxlen) {
// Write the string without the terminating '\0'
const size_t len = strnlen(data, maxlen);
write(data, len);
// If padding was added by the previous write, then
// the string is terminated. Otherwise write four
// more zeros.
const uint8_t padding = MULTIPLE_OF_4(len) - len;
if (padding == 0) {
const uint8_t pad_bytes[] = {0, 0, 0, 0};
write(pad_bytes, 4);
}
}
void CLCD::CommandFifo::str(const char * data) { void CLCD::CommandFifo::str(const char * data) {
write(data, strlen(data)+1); write(data, strlen(data)+1);
} }

View file

@ -248,6 +248,7 @@ class CLCD::CommandFifo {
void keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options); void keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options);
// Sends the string portion of text, button, toggle and keys. // Sends the string portion of text, button, toggle and keys.
void str (const char * data, size_t maxlen);
void str (const char * data); void str (const char * data);
void str (progmem_str data); void str (progmem_str data);

View file

@ -29,31 +29,31 @@ namespace FTDI {
* be broken so that the display width is less than w. The line will also * 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. * be broken after a '\n'. Returns the display width of the line.
*/ */
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) { static uint16_t find_line_break(const FontMetrics &utf8_fm, const CLCD::FontMetrics &clcd_fm, const uint16_t w, const char *start, const char *&end, bool use_utf8) {
const char *p = str; const char *p = start;
end = str; end = start;
uint16_t lw = 0, result = 0; uint16_t lw = 0, result = 0;
for (;;) { for (;;) {
const char *next = p; const char *next = p;
utf8_char_t c = get_utf8_char_and_inc(next); const utf8_char_t c = get_utf8_char_and_inc(next);
// Decide whether to break the string at this location // Decide whether to break the string at this location
if (c == '\n' || c == '\0' || c == ' ') { if (c == '\n' || c == '\0' || c == ' ') {
end = p; end = p;
result = lw; result = lw;
} }
if (c == '\n' || c == '\0') break; if (c == '\n' || c == '\0') break;
// Now add the length of the current character to the tally. // Measure the next character
lw += use_utf8 ? utf8_fm.get_char_width(c) : clcd_fm.char_widths[(uint8_t)c]; const uint16_t cw = use_utf8 ? utf8_fm.get_char_width(c) : clcd_fm.char_widths[(uint8_t)c];
// Stop processing once string exceeds the display width // Stop processing once string exceeds the display width
if (lw >= w) { if (lw + cw > w) break;
if (end == str) { // Now add the length of the current character to the tally.
end = p; lw += cw;
result = lw;
}
break;
}
p = next; p = next;
} }
if (end == start) {
end = p;
result = lw;
}
return result; return result;
} }
@ -66,12 +66,13 @@ namespace FTDI {
const uint16_t wrap_width = width; const uint16_t wrap_width = width;
width = height = 0; width = height = 0;
for (;;) { for (;;) {
uint16_t line_width = find_line_break(utf8_fm, clcd_fm, wrap_width, line_start, line_end, use_utf8); const uint16_t line_width = find_line_break(utf8_fm, clcd_fm, wrap_width, line_start, line_end, use_utf8);
if (line_end == line_start) break;
width = max(width, line_width); width = max(width, line_width);
height += utf8_fm.get_height(); height += utf8_fm.get_height();
line_start = line_end; line_start = line_end;
if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; if (*line_start == '\n' || *line_start == ' ') line_start++;
if (line_start[0] == '\0') break; if (*line_start == '\0') break;
} }
} }
@ -108,28 +109,25 @@ namespace FTDI {
const char *line_start = str, *line_end; const char *line_start = str, *line_end;
for (;;) { for (;;) {
find_line_break(utf8_fm, clcd_fm, w, line_start, line_end, use_utf8); find_line_break(utf8_fm, clcd_fm, w, line_start, line_end, use_utf8);
if (line_end == line_start) break;
const size_t line_len = line_end - line_start; const size_t line_len = line_end - line_start;
if (line_len) { if (line_len) {
char line[line_len + 1];
strncpy(line, line_start, line_len);
line[line_len] = 0;
#if ENABLED(TOUCH_UI_USE_UTF8) #if ENABLED(TOUCH_UI_USE_UTF8)
if (use_utf8) { if (use_utf8)
draw_utf8_text(cmd, x + dx, y + dy, line, utf8_fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY)); draw_utf8_text(cmd, x + dx, y + dy, line_start, utf8_fm.fs, options & ~(OPT_CENTERY | OPT_BOTTOMY), line_len);
} else else
#endif #endif
{ {
cmd.CLCD::CommandFifo::text(x + dx, y + dy, font, options & ~(OPT_CENTERY | OPT_BOTTOMY)); cmd.CLCD::CommandFifo::text(x + dx, y + dy, font, options & ~(OPT_CENTERY | OPT_BOTTOMY));
cmd.CLCD::CommandFifo::str(line); cmd.CLCD::CommandFifo::str(line_start, line_len);
} }
} }
y += utf8_fm.get_height(); y += utf8_fm.get_height();
line_start = line_end; line_start = line_end;
if (line_start[0] == '\n' || line_start[0] == ' ') line_start++; if (*line_start == '\n' || *line_start == ' ') line_start++;
if (line_start[0] == '\0') break; if (*line_start == '\0') break;
} }
} }

View file

@ -95,9 +95,9 @@
* fs - A scaling object used to specify the font size. * fs - A scaling object used to specify the font size.
*/ */
static uint16_t render_utf8_text(CommandProcessor* cmd, int x, int y, const char *str, font_size_t fs) { static uint16_t render_utf8_text(CommandProcessor* cmd, int x, int y, const char *str, font_size_t fs, size_t maxlen=SIZE_MAX) {
const int start_x = x; const int start_x = x;
while (*str) { while (*str && maxlen--) {
const utf8_char_t c = get_utf8_char_and_inc(str); const utf8_char_t c = get_utf8_char_and_inc(str);
#ifdef TOUCH_UI_UTF8_CYRILLIC_CHARSET #ifdef TOUCH_UI_UTF8_CYRILLIC_CHARSET
CyrillicCharSet::render_glyph(cmd, x, y, fs, c) || CyrillicCharSet::render_glyph(cmd, x, y, fs, c) ||
@ -185,8 +185,8 @@
* Returns: A width in pixels * Returns: A width in pixels
*/ */
uint16_t FTDI::get_utf8_text_width(const char *str, font_size_t fs) { uint16_t FTDI::get_utf8_text_width(const char *str, font_size_t fs, size_t maxlen) {
return render_utf8_text(nullptr, 0, 0, str, fs); return render_utf8_text(nullptr, 0, 0, str, fs, maxlen);
} }
uint16_t FTDI::get_utf8_text_width(progmem_str pstr, font_size_t fs) { uint16_t FTDI::get_utf8_text_width(progmem_str pstr, font_size_t fs) {
@ -210,9 +210,10 @@
* *
* options - Text alignment options (i.e. OPT_CENTERX, OPT_CENTERY, OPT_CENTER or OPT_RIGHTX) * options - Text alignment options (i.e. OPT_CENTERX, OPT_CENTERY, OPT_CENTER or OPT_RIGHTX)
* *
* maxlen - Maximum characters to draw
*/ */
void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, const char *str, font_size_t fs, uint16_t options) { void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, const char *str, font_size_t fs, uint16_t options, size_t maxlen) {
cmd.cmd(SAVE_CONTEXT()); cmd.cmd(SAVE_CONTEXT());
cmd.cmd(BITMAP_TRANSFORM_A(fs.get_coefficient())); cmd.cmd(BITMAP_TRANSFORM_A(fs.get_coefficient()));
cmd.cmd(BITMAP_TRANSFORM_E(fs.get_coefficient())); cmd.cmd(BITMAP_TRANSFORM_E(fs.get_coefficient()));
@ -220,14 +221,14 @@
// Apply alignment options // Apply alignment options
if (options & OPT_CENTERX) if (options & OPT_CENTERX)
x -= get_utf8_text_width(str, fs) / 2; x -= get_utf8_text_width(str, fs, maxlen) / 2;
else if (options & OPT_RIGHTX) else if (options & OPT_RIGHTX)
x -= get_utf8_text_width(str, fs); x -= get_utf8_text_width(str, fs, maxlen);
if (options & OPT_CENTERY) if (options & OPT_CENTERY)
y -= fs.get_height()/2; y -= fs.get_height()/2;
// Render the text // Render the text
render_utf8_text(&cmd, x, y, str, fs); render_utf8_text(&cmd, x, y, str, fs, maxlen);
cmd.cmd(RESTORE_CONTEXT()); cmd.cmd(RESTORE_CONTEXT());
} }

View file

@ -67,10 +67,10 @@ namespace FTDI {
uint16_t get_utf8_char_width(utf8_char_t, font_size_t); uint16_t get_utf8_char_width(utf8_char_t, font_size_t);
uint16_t get_utf8_text_width(progmem_str, font_size_t); uint16_t get_utf8_text_width(progmem_str, font_size_t);
uint16_t get_utf8_text_width(const char *, font_size_t); uint16_t get_utf8_text_width(const char *, font_size_t, size_t maxlen=SIZE_MAX);
void draw_utf8_text(CommandProcessor&, int x, int y, progmem_str, font_size_t, uint16_t options = 0); void draw_utf8_text(CommandProcessor&, int x, int y, progmem_str, font_size_t, uint16_t options = 0);
void draw_utf8_text(CommandProcessor&, int x, int y, const char *, font_size_t, uint16_t options = 0); void draw_utf8_text(CommandProcessor&, int x, int y, const char *, font_size_t, uint16_t options = 0, size_t maxlen=SIZE_MAX);
// Similar to CLCD::FontMetrics, but can be used with UTF8 encoded strings. // Similar to CLCD::FontMetrics, but can be used with UTF8 encoded strings.

View file

@ -76,7 +76,9 @@ void AboutScreen::onRedraw(draw_mode_t) {
#endif #endif
, OPT_CENTER, font_xlarge , OPT_CENTER, font_xlarge
); );
cmd.tag(3); #if BOTH(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU)
cmd.tag(3);
#endif
draw_text_box(cmd, FW_VERS_POS, draw_text_box(cmd, FW_VERS_POS,
#ifdef TOUCH_UI_VERSION #ifdef TOUCH_UI_VERSION
F(TOUCH_UI_VERSION) F(TOUCH_UI_VERSION)
@ -89,7 +91,7 @@ void AboutScreen::onRedraw(draw_mode_t) {
draw_text_box(cmd, 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); cmd.font(font_medium);
#if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) #if BOTH(PRINTCOUNTER, FTDI_STATISTICS_SCREEN)
cmd.colors(normal_btn) cmd.colors(normal_btn)
.tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU)); .tag(2).button(STATS_POS, GET_TEXT_F(MSG_INFO_STATS_MENU));
#endif #endif
@ -100,10 +102,10 @@ void AboutScreen::onRedraw(draw_mode_t) {
bool AboutScreen::onTouchEnd(uint8_t tag) { bool AboutScreen::onTouchEnd(uint8_t tag) {
switch (tag) { switch (tag) {
case 1: GOTO_PREVIOUS(); break; case 1: GOTO_PREVIOUS(); break;
#if ENABLED(PRINTCOUNTER) && defined(FTDI_STATISTICS_SCREEN) #if BOTH(PRINTCOUNTER, FTDI_STATISTICS_SCREEN)
case 2: GOTO_SCREEN(StatisticsScreen); break; case 2: GOTO_SCREEN(StatisticsScreen); break;
#endif #endif
#if ENABLED(TOUCH_UI_DEVELOPER_MENU) && defined(FTDI_DEVELOPER_MENU) #if BOTH(TOUCH_UI_DEVELOPER_MENU, FTDI_DEVELOPER_MENU)
case 3: GOTO_SCREEN(DeveloperMenu); break; case 3: GOTO_SCREEN(DeveloperMenu); break;
#endif #endif
default: return false; default: return false;

View file

@ -53,17 +53,12 @@ bool ConfirmUserRequestAlertBox::onTouchEnd(uint8_t tag) {
} }
} }
void ConfirmUserRequestAlertBox::onIdle() {
if (!ExtUI::awaitingUserConfirm()) {
hide();
}
}
void ConfirmUserRequestAlertBox::show(const char *msg) { void ConfirmUserRequestAlertBox::show(const char *msg) {
drawMessage(msg); drawMessage(msg);
storeBackground(); storeBackground();
screen_data.AlertDialogBox.isError = false; screen_data.AlertDialogBox.isError = false;
GOTO_SCREEN(ConfirmUserRequestAlertBox); if (!AT_SCREEN(ConfirmUserRequestAlertBox))
GOTO_SCREEN(ConfirmUserRequestAlertBox);
} }
void ConfirmUserRequestAlertBox::hide() { void ConfirmUserRequestAlertBox::hide() {

View file

@ -31,5 +31,4 @@ class ConfirmUserRequestAlertBox : public AlertDialogBox {
static bool onTouchEnd(uint8_t); static bool onTouchEnd(uint8_t);
static void hide(); static void hide();
static void show(const char*); static void show(const char*);
static void onIdle();
}; };