diff options
Diffstat (limited to 'screen_ui.cpp')
-rw-r--r-- | screen_ui.cpp | 121 |
1 files changed, 98 insertions, 23 deletions
diff --git a/screen_ui.cpp b/screen_ui.cpp index 3c6c3ae25..e36fa3d8f 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -52,6 +52,7 @@ static double now() { ScreenRecoveryUI::ScreenRecoveryUI() : currentIcon(NONE), installingFrame(0), + rtl_locale(false), progressBarType(EMPTY), progressScopeStart(0), progressScopeSize(0), @@ -78,7 +79,9 @@ ScreenRecoveryUI::ScreenRecoveryUI() : indeterminate_frames(6), installing_frames(7), install_overlay_offset_x(13), - install_overlay_offset_y(190) { + install_overlay_offset_y(190), + overlay_offset_x(-1), + overlay_offset_y(-1) { pthread_mutex_init(&updateMutex, NULL); self = this; } @@ -89,12 +92,12 @@ ScreenRecoveryUI::ScreenRecoveryUI() : // animation. Does nothing if no overlay animation is defined. // Should only be called with updateMutex locked. void ScreenRecoveryUI::draw_install_overlay_locked(int frame) { - if (installationOverlay == NULL) return; + if (installationOverlay == NULL || overlay_offset_x < 0) return; gr_surface surface = installationOverlay[frame]; int iconWidth = gr_get_width(surface); int iconHeight = gr_get_height(surface); gr_blit(surface, 0, 0, iconWidth, iconHeight, - install_overlay_offset_x, install_overlay_offset_y); + overlay_offset_x, overlay_offset_y); } // Clear the screen and draw the currently selected background icon (if any). @@ -107,14 +110,26 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) if (icon) { gr_surface surface = backgroundIcon[icon]; + gr_surface text_surface = backgroundText[icon]; + int iconWidth = gr_get_width(surface); int iconHeight = gr_get_height(surface); + int textWidth = gr_get_width(text_surface); + int textHeight = gr_get_height(text_surface); + int iconX = (gr_fb_width() - iconWidth) / 2; - int iconY = (gr_fb_height() - iconHeight) / 2; + int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; + + int textX = (gr_fb_width() - textWidth) / 2; + int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40; + gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); - if (icon == INSTALLING) { + if (icon == INSTALLING_UPDATE || icon == ERASING) { draw_install_overlay_locked(installingFrame); } + + gr_color(255, 255, 255, 255); + gr_texticon(textX, textY, text_surface); } } @@ -124,12 +139,12 @@ void ScreenRecoveryUI::draw_progress_locked() { if (currentIcon == ERROR) return; - if (currentIcon == INSTALLING) { + if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { draw_install_overlay_locked(installingFrame); } if (progressBarType != EMPTY) { - int iconHeight = gr_get_height(backgroundIcon[INSTALLING]); + int iconHeight = gr_get_height(backgroundIcon[INSTALLING_UPDATE]); int width = gr_get_width(progressBarEmpty); int height = gr_get_height(progressBarEmpty); @@ -144,18 +159,35 @@ void ScreenRecoveryUI::draw_progress_locked() float p = progressScopeStart + progress * progressScopeSize; int pos = (int) (p * width); - if (pos > 0) { - gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); - } - if (pos < width-1) { - gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); + if (rtl_locale) { + // Fill the progress bar from right to left. + if (pos > 0) { + gr_blit(progressBarFill, width-pos, 0, pos, height, dx+width-pos, dy); + } + if (pos < width-1) { + gr_blit(progressBarEmpty, 0, 0, width-pos, height, dx, dy); + } + } else { + // Fill the progress bar from left to right. + if (pos > 0) { + gr_blit(progressBarFill, 0, 0, pos, height, dx, dy); + } + if (pos < width-1) { + gr_blit(progressBarEmpty, pos, 0, width-pos, height, dx+pos, dy); + } } } if (progressBarType == INDETERMINATE) { static int frame = 0; gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); - frame = (frame + 1) % indeterminate_frames; + // in RTL locales, we run the animation backwards, which + // makes the spinner spin the other way. + if (rtl_locale) { + frame = (frame + indeterminate_frames - 1) % indeterminate_frames; + } else { + frame = (frame + 1) % indeterminate_frames; + } } } } @@ -242,7 +274,8 @@ void ScreenRecoveryUI::progress_loop() { // update the installation animation, if active // skip this if we have a text overlay (too expensive to update) - if (currentIcon == INSTALLING && installing_frames > 0 && !show_text) { + if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && + installing_frames > 0 && !show_text) { installingFrame = (installingFrame + 1) % installing_frames; redraw = 1; } @@ -283,6 +316,13 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) { } } +void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) { + int result = res_create_localized_surface(filename, surface); + if (result < 0) { + LOGE("missing bitmap %s\n(Code %d)\n", filename, result); + } +} + void ScreenRecoveryUI::Init() { gr_init(); @@ -295,11 +335,19 @@ void ScreenRecoveryUI::Init() text_cols = gr_fb_width() / CHAR_WIDTH; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; - LoadBitmap("icon_installing", &backgroundIcon[INSTALLING]); + LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); + backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); + backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; + LoadBitmap("progress_empty", &progressBarEmpty); LoadBitmap("progress_fill", &progressBarFill); + LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); + LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); + LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); + LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); + int i; progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames * @@ -321,14 +369,6 @@ void ScreenRecoveryUI::Init() sprintf(filename, "icon_installing_overlay%02d", i+1); LoadBitmap(filename, installationOverlay+i); } - - // Adjust the offset to account for the positioning of the - // base image on the screen. - if (backgroundIcon[INSTALLING] != NULL) { - gr_surface bg = backgroundIcon[INSTALLING]; - install_overlay_offset_x += (gr_fb_width() - gr_get_width(bg)) / 2; - install_overlay_offset_y += (gr_fb_height() - gr_get_height(bg)) / 2; - } } else { installationOverlay = NULL; } @@ -338,11 +378,46 @@ void ScreenRecoveryUI::Init() RecoveryUI::Init(); } +void ScreenRecoveryUI::SetLocale(const char* locale) { + if (locale) { + char* lang = strdup(locale); + for (char* p = lang; *p; ++p) { + if (*p == '_') { + *p = '\0'; + break; + } + } + + // A bit cheesy: keep an explicit list of supported languages + // that are RTL. + if (strcmp(lang, "ar") == 0 || // Arabic + strcmp(lang, "fa") == 0 || // Persian (Farsi) + strcmp(lang, "he") == 0 || // Hebrew (new language code) + strcmp(lang, "iw") == 0 || // Hebrew (old language code) + strcmp(lang, "ur") == 0) { // Urdu + rtl_locale = true; + } + free(lang); + } +} + void ScreenRecoveryUI::SetBackground(Icon icon) { pthread_mutex_lock(&updateMutex); + + // Adjust the offset to account for the positioning of the + // base image on the screen. + if (backgroundIcon[icon] != NULL) { + gr_surface bg = backgroundIcon[icon]; + gr_surface text = backgroundText[icon]; + overlay_offset_x = install_overlay_offset_x + (gr_fb_width() - gr_get_width(bg)) / 2; + overlay_offset_y = install_overlay_offset_y + + (gr_fb_height() - (gr_get_height(bg) + gr_get_height(text) + 40)) / 2; + } + currentIcon = icon; update_screen_locked(); + pthread_mutex_unlock(&updateMutex); } |