Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee6fefd2 authored by Tao Bao's avatar Tao Bao
Browse files

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
(cherry picked from commit 2bbc6d642d1fbfb007905d95b629fe5f833b2a1b)
parent 20fa1a92
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -758,12 +758,13 @@ static bool wipe_data(Device* device) {
}

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",
+29 −1
Original line number Diff line number Diff line
@@ -278,6 +278,34 @@ int ScreenRecoveryUI::DrawTextLines(int x, int y, const char* const* lines) cons
  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 @@ void ScreenRecoveryUI::draw_screen_locked() {
    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;
+3 −0
Original line number Diff line number Diff line
@@ -187,6 +187,9 @@ class ScreenRecoveryUI : public RecoveryUI {
  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