screen_ui: Word-wrap menu headers.
This CL adds ScreenRecoveryUI::DrawWrappedTextLines() to better handle
long menu header texts. It does a word wrap at spaces, if available.
This avoids fixed-length menu headers being truncated on small screens.
Bug: 64293520
Test: On bullhead, boot into recovery with --prompt_and_wipe_data, and
check the prompt texts.
Change-Id: Ia22746583516dd230567a267584aca558429395e
diff --git a/recovery.cpp b/recovery.cpp
index 233e562..c5ead45 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -757,12 +757,13 @@
}
static bool prompt_and_wipe_data(Device* device) {
+ // Use a single string and let ScreenRecoveryUI handles the wrapping.
const char* const headers[] = {
- "Can't load Android system. Your data may be corrupt.",
- "If you continue to get this message, you may need to",
- "perform a factory data reset and erase all user data",
+ "Can't load Android system. Your data may be corrupt. "
+ "If you continue to get this message, you may need to "
+ "perform a factory data reset and erase all user data "
"stored on this device.",
- NULL
+ nullptr
};
const char* const items[] = {
"Try again",
diff --git a/screen_ui.cpp b/screen_ui.cpp
index 8f792f1..e056512 100644
--- a/screen_ui.cpp
+++ b/screen_ui.cpp
@@ -278,6 +278,34 @@
return offset;
}
+int ScreenRecoveryUI::DrawWrappedTextLines(int x, int y, const char* const* lines) const {
+ int offset = 0;
+ for (size_t i = 0; lines != nullptr && lines[i] != nullptr; ++i) {
+ // The line will be wrapped if it exceeds text_cols_.
+ std::string line(lines[i]);
+ size_t next_start = 0;
+ while (next_start < line.size()) {
+ std::string sub = line.substr(next_start, text_cols_ + 1);
+ if (sub.size() <= text_cols_) {
+ next_start += sub.size();
+ } else {
+ // Line too long and must be wrapped to text_cols_ columns.
+ size_t last_space = sub.find_last_of(" \t\n");
+ if (last_space == std::string::npos) {
+ // No space found, just draw as much as we can
+ sub.resize(text_cols_);
+ next_start += text_cols_;
+ } else {
+ sub.resize(last_space);
+ next_start += last_space + 1;
+ }
+ }
+ offset += DrawTextLine(x, y + offset, sub.c_str(), false);
+ }
+ }
+ return offset;
+}
+
static const char* REGULAR_HELP[] = {
"Use volume up/down and power.",
NULL
@@ -316,7 +344,7 @@
y += DrawTextLines(x, y, HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP);
SetColor(HEADER);
- y += DrawTextLines(x, y, menu_headers_);
+ y += DrawWrappedTextLines(x, y, menu_headers_);
SetColor(MENU);
y += DrawHorizontalRule(y) + 4;
diff --git a/screen_ui.h b/screen_ui.h
index 8402fac..df7cc25 100644
--- a/screen_ui.h
+++ b/screen_ui.h
@@ -187,6 +187,9 @@
virtual int DrawTextLine(int x, int y, const char* line, bool bold) const;
// Draws multiple text lines. Returns the offset it should be moving along Y-axis.
int DrawTextLines(int x, int y, const char* const* lines) const;
+ // Similar to DrawTextLines() to draw multiple text lines, but additionally wraps long lines.
+ // Returns the offset it should be moving along Y-axis.
+ int DrawWrappedTextLines(int x, int y, const char* const* lines) const;
};
#endif // RECOVERY_UI_H