#include "common.h" #include "message-box.h" MessageBox currMsgBox; static bool msgboxNetloaderEnabled; static char msgboxNetloaderText[256]; static bool msgboxNetloaderProgressEnabled; static float msgboxNetloaderProgress; void drawMsgBoxBgToBuff(color_t *buff, int width, int height) { int x, y; int off; int circle_center_x, circle_center_y; int corner_size = 0; float rad, alpha; color_t base_color = themeCurrent.backgroundColor; color_t color; ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator]; for (y=0; y 0) { if (xwidth-corner_size && yheight-corner_size) { // bottom left corner circle_center_x = corner_size-1; circle_center_y = height-corner_size; } else if (x>width-corner_size && y>height-corner_size) { // bottom right corner circle_center_x = width-corner_size; circle_center_y = height-corner_size; } else { circle_center_x = -1; circle_center_y = -1; } if (circle_center_x == -1 && circle_center_y == -1) { color = base_color; } else { rad = sqrt(pow(circle_center_x - x, 2) + pow(circle_center_y - y, 2)); alpha = (float)corner_size - rad; if (rad < corner_size) { if (alpha < 1.0) { color = MakeColor(base_color.r, base_color.g, base_color.b, base_color.a * alpha); } else color = base_color; } else color = MakeColor(0, 0, 0, 0); } } else color = base_color; if (y == height + layoutobj->posStart[1]) { color = themeCurrent.separatorColor; } off = (y * width + x); *((uint32_t *)&buff[off]) = color.r | (color.g<<8) | (color.b<<16) | (color.a<<24); } } } void menuDrawMsgBox() { if (!menuIsMsgBoxOpen()) return; ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator]; int off; int x, y; int start_x = 1280 / 2 - currMsgBox.width / 2; int start_y = 720 / 2 - currMsgBox.height / 2; int end_x = start_x + currMsgBox.width; uint32_t text_width, text_height; color_t curr_color; color_t border_color; int sep_start_y = currMsgBox.height + layoutobj->posStart[1]; int border_thickness = 6; int shadow_start_y, shadow_y; int shadow_inset; int shadow_size = 4; float highlight_multiplier = highlight_multiplier = fmax(0.0, fabs(fmod(menuTimer, 1.0) - 0.5) / 0.5); color_t shadow_color; uint8_t shadow_alpha_base = 80; const char* textptr = currMsgBox.text; int progress_width = (int)(msgboxNetloaderProgress*currMsgBox.width); char progress_text[32]; border_color = MakeColor(themeCurrent.highlightColor.r + (255 - themeCurrent.highlightColor.r) * highlight_multiplier, themeCurrent.highlightColor.g + (255 - themeCurrent.highlightColor.g) * highlight_multiplier, themeCurrent.highlightColor.b + (255 - themeCurrent.highlightColor.b) * highlight_multiplier, 255); // Darken the background for (y=0; y<720; y++) { for (x=0; x<1280; x++) { DrawPixel(x, y, MakeColor(0, 0, 0, 100)); } } // Draw the message box background for (y=0; y=currMsgBox.width-border_thickness) && y>sep_start_y) || (y>sep_start_y && y<=sep_start_y+border_thickness) || (y>=currMsgBox.height-border_thickness)) { curr_color = border_color; } } else if (msgboxNetloaderProgressEnabled && y > sep_start_y && x < progress_width) { curr_color = themeCurrent.progressBarColor; } DrawPixel(start_x+x, start_y+y, curr_color); } } if (msgboxNetloaderEnabled) textptr = msgboxNetloaderText; GetTextDimensions(interuiregular18, textptr, &text_width, &text_height); x = GetTextXCoordinate(interuiregular18, start_x + (currMsgBox.width / 2), textptr, 'c'); if (text_width < currMsgBox.width && text_height < sep_start_y) { DrawText(interuiregular18, x, start_y + (sep_start_y - text_height) / 2, themeCurrent.textColor, textptr); } layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxBottomText]; y = start_y + currMsgBox.height + layoutobj->posStart[1]; if (!msgboxNetloaderEnabled) { x = GetTextXCoordinate(interuimedium20, start_x + (currMsgBox.width / 2), textGetString(StrId_MsgBox_OK), 'c'); DrawText(interuimedium20, x, y, themeCurrent.textColor, textGetString(StrId_MsgBox_OK)); } if (msgboxNetloaderEnabled && msgboxNetloaderProgressEnabled) { memset(progress_text, 0, sizeof(progress_text)); snprintf(progress_text, sizeof(progress_text)-1, "%.02f%%", msgboxNetloaderProgress*100); x = GetTextXCoordinate(interuiregular18, start_x + (currMsgBox.width / 2), progress_text, 'c'); DrawText(interuiregular18, x, y, themeCurrent.textColor, progress_text); } shadow_start_y = start_y + currMsgBox.height; for (shadow_y=shadow_start_y; shadow_y = start_x + shadow_inset && x <= end_x - shadow_inset) { DrawPixel(x, shadow_y, shadow_color); } } } } void menuCreateMsgBox(int width, int height, const char *text) { if (menuIsMsgBoxOpen()) return; char *new_text = strdup(text); if (new_text==NULL) return; currMsgBox = (MessageBox) { width, height, NULL, new_text }; currMsgBox.bg = malloc(currMsgBox.width*currMsgBox.height*4); if (currMsgBox.bg) { drawMsgBoxBgToBuff(currMsgBox.bg, currMsgBox.width, currMsgBox.height); } } bool menuIsMsgBoxOpen() { return currMsgBox.width != 0 || currMsgBox.height != 0 || currMsgBox.bg || currMsgBox.text; } void menuCloseMsgBox() { if (currMsgBox.bg) { free(currMsgBox.bg); currMsgBox.bg = NULL; } currMsgBox.width = currMsgBox.height = 0; if (currMsgBox.text) { free(currMsgBox.text); currMsgBox.text = NULL; } } MessageBox menuGetCurrentMsgBox() { return currMsgBox; } void menuMsgBoxSetNetloaderState(bool enabled, const char *text, bool enable_progress, float progress) { msgboxNetloaderEnabled = enabled; memset(msgboxNetloaderText, 0, sizeof(msgboxNetloaderText)); if (text) strncpy(msgboxNetloaderText, text, sizeof(msgboxNetloaderText)-1); msgboxNetloaderProgressEnabled = enable_progress; msgboxNetloaderProgress = progress; }