diff --git a/common/common.h b/common/common.h index 10757f6..5d14a73 100644 --- a/common/common.h +++ b/common/common.h @@ -47,6 +47,48 @@ typedef union { }; } color_t; +typedef enum +{ + ThemeLayoutId_Logo, + ThemeLayoutId_HbmenuVersion, + ThemeLayoutId_LoaderInfo, + ThemeLayoutId_AttentionText, + ThemeLayoutId_LogInfo, + ThemeLayoutId_InfoMsg, + ThemeLayoutId_MenuPath, + ThemeLayoutId_MenuTypeMsg, + ThemeLayoutId_MsgBoxSeparator, + ThemeLayoutId_MsgBoxBottomText, + ThemeLayoutId_BackWave, + ThemeLayoutId_MiddleWave, + ThemeLayoutId_FrontWave, + ThemeLayoutId_ButtonA, + ThemeLayoutId_ButtonAText, + ThemeLayoutId_ButtonB, + ThemeLayoutId_ButtonBText, + ThemeLayoutId_ButtonY, + ThemeLayoutId_ButtonYText, + ThemeLayoutId_ButtonM, + ThemeLayoutId_ButtonMText, + ThemeLayoutId_ButtonX, + ThemeLayoutId_ButtonXText, + ThemeLayoutId_NetworkIcon, + ThemeLayoutId_BatteryCharge, + ThemeLayoutId_BatteryIcon, + ThemeLayoutId_ChargingIcon, + ThemeLayoutId_Status, + ThemeLayoutId_Temperature, + ThemeLayoutId_MenuList, + ThemeLayoutId_MenuListTiles, + ThemeLayoutId_MenuListIcon, + ThemeLayoutId_MenuListName, + ThemeLayoutId_MenuActiveEntryIcon, + ThemeLayoutId_MenuActiveEntryName, + ThemeLayoutId_MenuActiveEntryAuthor, + ThemeLayoutId_MenuActiveEntryVersion, + ThemeLayoutId_Total, +} ThemeLayoutId; + // when building for pc we need to include these separately #ifndef __SWITCH__ #include "switch/nro.h" @@ -163,6 +205,8 @@ static inline color_t FetchPixelColor(uint32_t x, uint32_t y) void DrawPixel(uint32_t x, uint32_t y, color_t clr); void DrawText(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text); +void DrawTextFromLayout(ThemeLayoutId id, color_t clr, const char* text); +void DrawTextFromLayoutRelative(ThemeLayoutId id, int base_x, int base_y, int *inPos, int *outPos, color_t clr, const char* text, const char align); void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text); void GetTextDimensions(u32 font, const char* text, uint32_t* width_out, uint32_t* height_out); uint32_t GetTextXCoordinate(u32 font, uint32_t rX, const char* text, const char align); diff --git a/common/font.c b/common/font.c index c644458..a4c4e39 100644 --- a/common/font.c +++ b/common/font.c @@ -276,6 +276,38 @@ void DrawText(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text) DrawText_(font, x, y, clr, text, 0, NULL); } +void DrawTextFromLayout(ThemeLayoutId id, color_t clr, const char* text) +{ + ThemeLayoutObject *obj = &themeCurrent.layoutObjects[id]; + if (!obj->visible) return; + + DrawText(obj->font, obj->posStart[0], obj->posStart[1], clr, text); +} + +void DrawTextFromLayoutRelative(ThemeLayoutId id, int base_x, int base_y, int *inPos, int *outPos, color_t clr, const char* text, const char align) +{ + ThemeLayoutObject *obj = &themeCurrent.layoutObjects[id]; + + base_x = obj->posType ? base_x + inPos[0] : inPos[0]; + base_y = obj->posType ? base_y + inPos[1] : inPos[1]; + + base_x = GetTextXCoordinate(obj->font, base_x, text, align); + + if (outPos) { + outPos[0] = base_x; + outPos[1] = base_y; + } + + obj->posFinal[0] = base_x; + obj->posFinal[1] = base_y; + + if (!obj->visible) return; + + GetTextDimensions(obj->font, text, &obj->textSize[0], &obj->textSize[1]); + + DrawText(obj->font, base_x, base_y, clr, text); +} + void DrawTextTruncate(u32 font, uint32_t x, uint32_t y, color_t clr, const char* text, uint32_t max_width, const char* end_text) { DrawText_(font, x, y, clr, text, max_width, end_text); diff --git a/common/menu.c b/common/menu.c index c745e64..1a96164 100644 --- a/common/menu.c +++ b/common/menu.c @@ -150,6 +150,12 @@ static void drawImage(int x, int y, int width, int height, const uint8_t *image, } } +static void drawImageFromLayout(ThemeLayoutId id, const uint8_t *image, ImageMode mode) { + ThemeLayoutObject *obj = &themeCurrent.layoutObjects[id]; + if (!obj->visible) return; + drawImage(obj->posStart[0], obj->posStart[1], obj->imageSize[0], obj->imageSize[1], image, mode); +} + //Draws an RGBA8888 image masked by the passed color. static void drawIcon(int x, int y, int width, int height, const uint8_t *image, color_t color) { int tmpx, tmpy; @@ -170,11 +176,12 @@ uint8_t *invalid_icon_small; uint8_t *theme_icon_small; static void drawEntry(menuEntry_s* me, int off_x, int is_active) { + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; int x, y; - int start_y = 720 - 100 - 145;//*(n % 2); - int end_y = start_y + 140 + 32; + int start_y = layoutobj->posStart[1];//*(n % 2); + int end_y = start_y + layoutobj->size[1]; int start_x = off_x;//(n / 2); - int end_x = start_x + 140; + int end_x = start_x + layoutobj->size[0]; int j; const uint8_t *smallimg = NULL; @@ -287,15 +294,17 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) { } if (smallimg) { - drawImage(start_x, start_y + 32, 140, 140, smallimg, IMAGE_MODE_RGB24); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon]; + drawImage(start_x + layoutobj->posStart[0], start_y + layoutobj->posStart[1], layoutobj->imageSize[0], layoutobj->imageSize[1], smallimg, IMAGE_MODE_RGB24); } - if (is_active && largeimg) { - drawImage(117, 100+10, 256, 256, largeimg, IMAGE_MODE_RGB24); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon]; + if (is_active && largeimg && layoutobj->visible) { + drawImage(layoutobj->posStart[0], layoutobj->posStart[1], layoutobj->imageSize[0], layoutobj->imageSize[1], largeimg, IMAGE_MODE_RGB24); - shadow_start_y = 100+10+256; - border_start_x = 117; - border_end_x = 117+256; + shadow_start_y = layoutobj->posStart[1]+layoutobj->imageSize[1]; + border_start_x = layoutobj->posStart[0]; + border_end_x = layoutobj->posStart[0]+layoutobj->imageSize[0]; for (shadow_y=shadow_start_y; shadow_y name); - DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, themeCurrent.borderTextColor, tmpstr, 140 - 32, "..."); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListName]; + DrawTextTruncate(layoutobj->font, start_x + layoutobj->posStart[0], start_y + layoutobj->posStart[1], themeCurrent.borderTextColor, tmpstr, layoutobj->size[0], "..."); if (is_active) { - start_x = 1280 - 790; - start_y = 135+10; - - DrawTextTruncate(interuimedium30, start_x, start_y + 39, themeCurrent.textColor, tmpstr, 1280 - start_x - 120 ,"..."); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryName]; + if (layoutobj->visible) DrawTextTruncate(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr, layoutobj->size[0], "..."); if (me->type != ENTRY_TYPE_FOLDER) { memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Author), me->author); - DrawText(interuiregular14, start_x, start_y + 28 + 30 + 18, themeCurrent.textColor, tmpstr); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryAuthor]; + if (layoutobj->visible) DrawText(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr); + memset(tmpstr, 0, sizeof(tmpstr)); snprintf(tmpstr, sizeof(tmpstr)-1, "%s: %s", textGetString(StrId_AppInfo_Version), me->version); - DrawText(interuiregular14, start_x, start_y + 28 + 30 + 18 + 6 + 18, themeCurrent.textColor, tmpstr); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryVersion]; + if (layoutobj->visible) DrawText(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, tmpstr); } } } @@ -344,6 +355,8 @@ void computeFrontGradient(color_t baseColor, int height) { float dark_mult, dark_sub = 75; color_t color; + if (height < 0 || height > 720) return; + for (y=0; y<720; y++) { alpha = y - (720 - height); @@ -429,6 +442,7 @@ void drawWave(int id, float timer, color_t color, int height, float phase, float float wave_top_y, alpha, one_minus_alpha; color_t existing_color, new_color; + if (height < 0 || height > 720) return; height = 720 - height; for (x=0; x<1280; x++) { @@ -478,17 +492,25 @@ void drawCharge() { sprintf(chargeString, "%d%%", batteryCharge); - int tmpX = GetTextXCoordinate(interuiregular14, 1180 - 10, chargeString, 'r'); + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BatteryCharge]; - DrawText(interuiregular14, tmpX - 24 - 8, 0 + 47 + 10 + 21 + 4, themeCurrent.textColor, chargeString); - drawIcon(1180 - 8 - 24 - 8, 0 + 47 + 10 + 6, 24, 24, assetsGetDataBuffer(AssetId_battery_icon), themeCurrent.textColor); - if (isCharging) - drawIcon(1180 - 20, 0 + 47 + 10 + 6, 24, 24, assetsGetDataBuffer(AssetId_charging_icon), themeCurrent.textColor); + if (layoutobj->visible) { + int tmpX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], chargeString, 'r'); + DrawText(layoutobj->font, tmpX, layoutobj->posStart[1], themeCurrent.textColor, chargeString); + } + + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BatteryIcon]; + if (layoutobj->visible) drawIcon(layoutobj->posStart[0], layoutobj->posStart[1], layoutobj->imageSize[0], layoutobj->imageSize[1], assetsGetDataBuffer(AssetId_battery_icon), themeCurrent.textColor); + + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ChargingIcon]; + if (isCharging && layoutobj->visible) + drawIcon(layoutobj->posStart[0], layoutobj->posStart[1], layoutobj->imageSize[0], layoutobj->imageSize[1], assetsGetDataBuffer(AssetId_charging_icon), themeCurrent.textColor); } } void drawNetwork(int tmpX, AssetId id) { - drawIcon(tmpX, 0 + 47 + 10 + 3, 24, 24, assetsGetDataBuffer(id), themeCurrent.textColor); + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_NetworkIcon]; + if (layoutobj->visible) drawIcon(layoutobj->posType ? tmpX + layoutobj->posStart[0] : layoutobj->posStart[0], layoutobj->posStart[1], layoutobj->imageSize[0], layoutobj->imageSize[1], assetsGetDataBuffer(id), themeCurrent.textColor); } u32 drawStatus() { @@ -508,9 +530,11 @@ u32 drawStatus() { snprintf(tmpstr, sizeof(tmpstr)-1, "%02d:%02d:%02d", hours, minutes, seconds); - u32 tmpX = GetTextXCoordinate(interuimedium20, 1180, tmpstr, 'r'); + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_Status]; - DrawText(interuimedium20, tmpX, 0 + 47 + 10, themeCurrent.textColor, tmpstr); + u32 tmpX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], tmpstr, 'r'); + + if (layoutobj->visible) DrawText(layoutobj->font, tmpX, layoutobj->posStart[1], themeCurrent.textColor, tmpstr); drawCharge(); @@ -518,21 +542,19 @@ u32 drawStatus() { if (netstatusFlag) drawNetwork(tmpX, id); if (temperatureFlag) { snprintf(tmpstr, sizeof(tmpstr)-1, "%.1f°C", ((float)temperature) / 1000); - DrawText(interuiregular14, 1180 + 4, 0 + 47 + 10 + + 21 + 6, themeCurrent.textColor, tmpstr); + DrawTextFromLayout(ThemeLayoutId_Temperature, themeCurrent.textColor, tmpstr); } } return tmpX; } -void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) { - int x_image = 1280 - 252 - 30 - 32; - int x_text = 1280 - 216 - 30 - 32; +void drawButtons(menu_s* menu, bool emptyDir, int *out_basePos) { + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA]; + int basePos[2]={0}; - if(emptyDir) { - x_image = 1280 - 126 - 30 - 32; - x_text = 1280 - 90 - 30 - 32; - } + basePos[0] = layoutobj->posStart[0]; + basePos[1] = layoutobj->posStart[1]; #ifdef __SWITCH__ if (strcmp( menu->dirname, "sdmc:/") != 0) @@ -540,27 +562,26 @@ void drawButtons(menu_s* menu, bool emptyDir, int *x_image_out) { if (strcmp( menu->dirname, "/") != 0) #endif { - //drawImage(x_image, 720 - 48, 32, 32, themeCurrent.buttonBImage, IMAGE_MODE_RGBA32); - DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonBText);//Display the 'B' button from SharedFont. - DrawText(interuiregular18, x_text, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Back)); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonBText]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonBText, basePos[0], basePos[1], !emptyDir ? layoutobj->posStart : layoutobj->posEnd, basePos, themeCurrent.textColor, textGetString(StrId_Actions_Back), 'l'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonB]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonB, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonBText, 'l'); } if(hbmenu_state == HBMENU_DEFAULT) { - x_text = GetTextXCoordinate(interuiregular18, x_image - 32, textGetString(StrId_NetLoader), 'r'); - x_image = x_text - 36; - *x_image_out = x_image - 40; - - DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonYText); - DrawText(interuiregular18, x_text, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_NetLoader)); - - x_text = GetTextXCoordinate(interuiregular18, x_image - 32, textGetString(StrId_ThemeMenu), 'r'); - x_image = x_text - 36; - *x_image_out = x_image - 40; - - DrawText(fontscale7, x_image, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonMText); - DrawText(interuiregular18, x_text, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonYText]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonYText, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, textGetString(StrId_NetLoader), 'r'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonY]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonY, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonYText, 'l'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonMText]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonMText, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, textGetString(StrId_ThemeMenu), 'r'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonM]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonM, basePos[0], basePos[1], layoutobj->posStart, basePos, themeCurrent.textColor, themeCurrent.buttonMText, 'l'); } + + out_basePos[0] = basePos[0]; + out_basePos[1] = basePos[1]; } void menuUpdateNetloader(netloaderState *netloader_state) { @@ -595,44 +616,60 @@ void menuLoop(void) { menuEntry_s* me; menu_s* menu = NULL; int i; - int x, y; - int menupath_x_endpos = 918 + 40; + int x, y, endy = 720; + int curPos[2]={0}; netloaderState netloader_state; + ThemeLayoutObject *layoutobj = NULL; - for (y=0; y<450; y++) { + for (i=0; i<3; i++) { + if (i==2) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_BackWave]; + if (i==1) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave]; + if (i==0) layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave]; + if (layoutobj->visible && layoutobj->size[1] >= 0 && layoutobj->size[1] <= 720-10) { + endy = 720 - layoutobj->size[1] + 10; + break; + } + } + + for (y=0; yvisible) drawWave(0, menuTimer, themeCurrent.backWaveColor, layoutobj->size[1], 0.0, 3.0); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave]; + if (layoutobj->visible) drawWave(1, menuTimer, themeCurrent.middleWaveColor, layoutobj->size[1], 2.0, 3.5); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave]; + if (layoutobj->visible) drawWave(2, menuTimer, themeCurrent.frontWaveColor, layoutobj->size[1], 4.0, -2.5); menuTimer += 0.05; - drawImage(40, 20, 140, 60, themeCurrent.hbmenuLogoImage, IMAGE_MODE_RGBA32); - DrawText(interuiregular14, 184, 46 + 18, themeCurrent.textColor, VERSION); + drawImageFromLayout(ThemeLayoutId_Logo, themeCurrent.hbmenuLogoImage, IMAGE_MODE_RGBA32); + DrawTextFromLayout(ThemeLayoutId_HbmenuVersion, themeCurrent.textColor, VERSION); u32 statusXPos = drawStatus(); #ifdef __SWITCH__ AppletType at = appletGetAppletType(); - if (at != AppletType_Application && at != AppletType_SystemApplication) { + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_AttentionText]; + if (at != AppletType_Application && at != AppletType_SystemApplication && layoutobj->visible) { const char* appletMode = textGetString(StrId_AppletMode); - u32 x_pos = GetTextXCoordinate(interuimedium30, statusXPos, appletMode, 'r'); - DrawText(interuimedium30, x_pos - 32, 46 + 18, themeCurrent.attentionTextColor, appletMode); + u32 x_pos = GetTextXCoordinate(layoutobj->font, statusXPos, appletMode, 'r'); + DrawText(layoutobj->font, layoutobj->posType ? x_pos + layoutobj->posStart[0] : layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.attentionTextColor, appletMode); } const char* loaderInfo = envGetLoaderInfo(); - if (loaderInfo) { - u32 x_pos = 43; + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_LoaderInfo]; + if (loaderInfo && layoutobj->visible) { + u32 x_pos = layoutobj->posStart[0]; char* spacePos = strchr(loaderInfo, ' '); if (spacePos) { char tempbuf[64] = {0}; size_t tempsize = spacePos - loaderInfo + 1; if (tempsize > sizeof(tempbuf)-1) tempsize = sizeof(tempbuf)-1; memcpy(tempbuf, loaderInfo, tempsize); - x_pos = GetTextXCoordinate(interuiregular14, 184, tempbuf, 'r'); + x_pos = GetTextXCoordinate(layoutobj->font, layoutobj->posEnd[0], tempbuf, 'r'); } - DrawText(interuiregular14, x_pos, 46 + 18 + 20, themeCurrent.textColor, loaderInfo); + DrawText(layoutobj->font, x_pos, layoutobj->posStart[1], themeCurrent.textColor, loaderInfo); } #endif @@ -642,7 +679,7 @@ void menuLoop(void) { char tmpstr[64]; snprintf(tmpstr, sizeof(tmpstr)-1, "%lu", g_tickdiff_frame); - DrawText(interuiregular14, 180 + 256, 46 + 16 + 18, themeCurrent.textColor, tmpstr); + DrawTextFromLayout(ThemeLayoutId_LogInfo, themeCurrent.textColor, tmpstr); #endif memset(&netloader_state, 0, sizeof(netloader_state)); @@ -680,16 +717,19 @@ void menuLoop(void) { launchMenuEntryTask(netloader_state.me); } } else { - DrawText(interuiregular14, 64, 128 + 18, themeCurrent.textColor, textGetString(StrId_NoAppsFound_Msg)); + DrawTextFromLayout(ThemeLayoutId_InfoMsg, themeCurrent.textColor, textGetString(StrId_NoAppsFound_Msg)); } - drawButtons(menu, true, &menupath_x_endpos); + drawButtons(menu, true, curPos); } else { static int v = 0; + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; + int entries_count = layoutobj->posEnd[0]; + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; - if (menu->nEntries > 7) { - int wanted_x = clamp(-menu->curEntry * (140 + 30), -(menu->nEntries - 7) * (140 + 30), 0); + if (menu->nEntries > entries_count) { + int wanted_x = clamp(-menu->curEntry * layoutobj->posEnd[0], -(menu->nEntries - entries_count) * layoutobj->posEnd[0], 0); menu->xPos += v; v += (wanted_x - menu->xPos) / 3; v /= 2; @@ -702,7 +742,7 @@ void menuLoop(void) { // Draw menu entries for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) { - int entry_start_x = 29 + i * (140 + 30); + int entry_start_x = layoutobj->posStart[0] + i * layoutobj->posEnd[0]; int entry_draw_x = entry_start_x + menu->xPos; int screen_width = 1280; @@ -714,54 +754,61 @@ void menuLoop(void) { if (is_active) active_entry = me; - if (!is_active && entry_draw_x < -(29 + 140 + 30)) + if (!is_active && entry_draw_x < -(layoutobj->posStart[0] + layoutobj->posEnd[0])) continue; drawEntry(me, entry_draw_x, is_active); } - int getX = GetTextXCoordinate(interuiregular18, 1180, textGetString(StrId_ThemeMenu), 'r'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuTypeMsg]; + int getX=0; - if(hbmenu_state == HBMENU_THEME_MENU) { - DrawText(interuiregular18, getX, 30 + 26 + 32 + 20, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); - } else { - //DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); - //DrawText(fontscale7, getX - 40, 30 + 26 + 32 + 10, themeCurrent.textColor, themeCurrent.buttonMText); + if (layoutobj->visible) { + getX = GetTextXCoordinate(layoutobj->font, layoutobj->posStart[0], textGetString(StrId_ThemeMenu), 'r'); + + if(hbmenu_state == HBMENU_THEME_MENU) { + DrawText(layoutobj->font, getX, layoutobj->posStart[1], themeCurrent.textColor, textGetString(StrId_ThemeMenu)); + } else { + //DrawText(interuiregular18, getX, 30 + 26 + 32 + 10, themeCurrent.textColor, textGetString(StrId_ThemeMenu)); + //DrawText(fontscale7, getX - 40, 30 + 26 + 32 + 10, themeCurrent.textColor, themeCurrent.buttonMText); + } } if(active_entry != NULL) { - if (active_entry->type == ENTRY_TYPE_THEME) { - DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText); - DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Apply)); - } - else if (active_entry->type != ENTRY_TYPE_FOLDER) { - DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText);//Display the 'A' button from SharedFont. - DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Launch)); - } - else { - DrawText(fontscale7, 1280 - 126 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonAText); - DrawText(interuiregular18, 1280 - 90 - 30 - 32, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Open)); - } + const char *buttonstr = ""; + + if (active_entry->type == ENTRY_TYPE_THEME) + buttonstr = textGetString(StrId_Actions_Apply); + else if (active_entry->type != ENTRY_TYPE_FOLDER) + buttonstr = textGetString(StrId_Actions_Launch); + else + buttonstr = textGetString(StrId_Actions_Open); + + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonAText]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonAText, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, buttonstr, 'l'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonA, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, themeCurrent.buttonAText, 'l'); } - drawButtons(menu, false, &menupath_x_endpos); + drawButtons(menu, false, curPos); if (active_entry && active_entry->type != ENTRY_TYPE_THEME) { - if (active_entry->starred) { - getX = GetTextXCoordinate(interuiregular18, menupath_x_endpos + 8, textGetString(StrId_Actions_Unstar), 'r'); - DrawText(fontscale7, getX - 36, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonXText); - DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Unstar)); - } else { - getX = GetTextXCoordinate(interuiregular18, menupath_x_endpos + 8, textGetString(StrId_Actions_Star), 'r'); - DrawText(fontscale7, getX - 36, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonXText); - DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Star)); - } - menupath_x_endpos = getX - 36 - 40; + const char *buttonstr = ""; + if (active_entry->starred) + buttonstr = textGetString(StrId_Actions_Unstar); + else + buttonstr = textGetString(StrId_Actions_Star); + + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonXText]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonXText, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, buttonstr, 'r'); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_ButtonX]; + DrawTextFromLayoutRelative(ThemeLayoutId_ButtonX, curPos[0], curPos[1], layoutobj->posStart, curPos, themeCurrent.textColor, themeCurrent.buttonXText, 'l'); } } - DrawTextTruncate(interuiregular18, 40, 720 - 47 + 24, themeCurrent.textColor, menu->dirname, menupath_x_endpos - 40, "..."); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuPath]; + if (layoutobj->visible) DrawTextTruncate(layoutobj->font, layoutobj->posStart[0], layoutobj->posStart[1], themeCurrent.textColor, menu->dirname, layoutobj->size[0], "..."); menuDrawMsgBox(); } diff --git a/common/message-box.c b/common/message-box.c index 569f304..af66e3d 100644 --- a/common/message-box.c +++ b/common/message-box.c @@ -16,6 +16,7 @@ void drawMsgBoxBgToBuff(color_t *buff, int width, int height) { float rad, alpha; color_t base_color = themeCurrent.backgroundColor; color_t color; + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator]; for (y=0; yposStart[1]) { color = themeCurrent.separatorColor; } @@ -76,6 +77,7 @@ void menuDrawMsgBox() { if (!menuIsMsgBoxOpen()) return; + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator]; int off; int x, y; int start_x = 1280 / 2 - currMsgBox.width / 2; @@ -85,7 +87,7 @@ void menuDrawMsgBox() { color_t curr_color; color_t border_color; - int sep_start_y = currMsgBox.height - 80; + int sep_start_y = currMsgBox.height + layoutobj->posStart[1]; int border_thickness = 6; int shadow_start_y, shadow_y; @@ -121,7 +123,7 @@ void menuDrawMsgBox() { curr_color = border_color; } } - else if (msgboxNetloaderProgressEnabled && y > currMsgBox.height - 80 && x < progress_width) { + else if (msgboxNetloaderProgressEnabled && y > sep_start_y && x < progress_width) { curr_color = themeCurrent.progressBarColor; } @@ -135,10 +137,11 @@ void menuDrawMsgBox() { 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 + (currMsgBox.height - text_height - 80) / 2, themeCurrent.textColor, textptr); + DrawText(interuiregular18, x, start_y + (sep_start_y - text_height) / 2, themeCurrent.textColor, textptr); } - y = start_y + 245 + 26; + 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'); diff --git a/common/theme.c b/common/theme.c index 5381ba9..8538fdd 100644 --- a/common/theme.c +++ b/common/theme.c @@ -10,6 +10,58 @@ bool colorFromSetting(config_setting_t *rgba, color_t *col) { return true; } +bool intElemFromSetting(config_setting_t *setting, int *out, size_t count) { + if (!setting || config_setting_length(setting) < count) + return false; + + for (size_t i=0; iposStart, sizeof(obj->posStart)); + memcpy(tmpobj.posEnd, obj->posEnd, sizeof(obj->posEnd)); + memcpy(tmpobj.size, obj->size, sizeof(obj->size)); + + if (config_setting_lookup_bool(layout_setting, "visible", &tmp)==CONFIG_TRUE) + tmpobj.visible = tmp; + else + tmpobj.visible = obj->visible; + if (config_setting_lookup_bool(layout_setting, "posType", &tmp)==CONFIG_TRUE) + tmpobj.posType = tmp; + else + tmpobj.posType = obj->posType; + + intElemFromSetting(config_setting_lookup(layout_setting, "posStart"), tmpobj.posStart, 2); + intElemFromSetting(config_setting_lookup(layout_setting, "posEnd"), tmpobj.posEnd, 2); + intElemFromSetting(config_setting_lookup(layout_setting, "size"), tmpobj.size, 2); + + if (!tmpobj.posType && (tmpobj.posStart[0] < 0 || tmpobj.posStart[1] < 0 || tmpobj.posEnd[0] < 0 || tmpobj.posEnd[1] < 0)) + return false; + if (tmpobj.size[0] < 0 || tmpobj.size[1] < 0) + return false; + + obj->posStart[0] = tmpobj.posStart[0]; + obj->posStart[1] = tmpobj.posStart[1]; + obj->posEnd[0] = tmpobj.posEnd[0]; + obj->posEnd[1] = tmpobj.posEnd[1]; + + if (!ignore_cfg_visible) obj->visible = tmpobj.visible; + obj->posType = tmpobj.posType; + obj->size[0] = tmpobj.size[0]; + obj->size[1] = tmpobj.size[1]; + + return true; +} + void themeStartup(ThemePreset preset) { themeGlobalPreset = preset; theme_t themeLight = (theme_t) { @@ -60,13 +112,283 @@ void themeStartup(ThemePreset preset) { .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark), }; + theme_t themeCommon = { + .layoutObjects = { + [ThemeLayoutId_Logo] = { + .visible = true, + .posType = false, + .posStart = {40, 20}, + .imageSize = {140, 60}, + }, + + [ThemeLayoutId_HbmenuVersion] = { + .visible = true, + .posType = false, + .posStart = {184, 46 + 18}, + .font = interuiregular14, + }, + + [ThemeLayoutId_LoaderInfo] = { + .visible = true, + .posType = true, + .posStart = {43, 46 + 18 + 20}, + .posEnd = {184}, + .font = interuiregular14, + }, + + [ThemeLayoutId_AttentionText] = { + .visible = true, + .posType = true, + .posStart = {-32, 46 + 18}, + .font = interuimedium30, + }, + + [ThemeLayoutId_LogInfo] = { + .visible = true, + .posType = false, + .posStart = {180 + 256, 46 + 16 + 18}, + .font = interuiregular14, + }, + + [ThemeLayoutId_InfoMsg] = { + .visible = true, + .posType = false, + .posStart = {64, 128 + 18}, + .font = interuiregular14, + }, + + [ThemeLayoutId_MenuPath] = { + .visible = true, + .posType = false, + .posStart = {40, 720 - 47 + 24}, + .size = {380}, + .font = interuiregular18, + }, + + [ThemeLayoutId_MenuTypeMsg] = { + .visible = true, + .posType = false, + .posStart = {1180, 30 + 26 + 32 + 20}, + .font = interuiregular18, + }, + + [ThemeLayoutId_MsgBoxSeparator] = { + .visible = true, + .posType = true, + .posStart = {0, -80}, + }, + + [ThemeLayoutId_MsgBoxBottomText] = { + .visible = true, + .posType = true, + .posStart = {0, -29}, + }, + + [ThemeLayoutId_BackWave] = { + .visible = true, + .posType = true, + .size = {0, 295}, + }, + + [ThemeLayoutId_MiddleWave] = { + .visible = true, + .posType = true, + .size = {0, 290}, + }, + + [ThemeLayoutId_FrontWave] = { + .visible = true, + .posType = true, + .size = {0, 280}, + }, + + [ThemeLayoutId_ButtonA] = { + .visible = true, + .posType = false, + .posStart = {1280 - 126 - 30 - 32, 720 - 47 + 24}, + .touchSize = {36, 25}, + .font = fontscale7, + }, + + [ThemeLayoutId_ButtonAText] = { + .visible = true, + .posType = false, + .posStart = {1280 - 90 - 30 - 32, 720 - 47 + 24}, + .touchSize = {0, 25}, + .font = interuiregular18, + }, + + [ThemeLayoutId_ButtonB] = { + .visible = true, + .posType = true, + .posStart = {-36, 0}, + .posEnd = {0}, + .touchSize = {36, 25}, + .font = fontscale7, + }, + + [ThemeLayoutId_ButtonBText] = { + .visible = true, + .posType = true, + .posStart = {-90, 0}, + .touchSize = {0, 32}, + .font = interuiregular18, + }, + + [ThemeLayoutId_ButtonY] = { + .visible = true, + .posType = true, + .posStart = {-36, 0}, + .font = fontscale7, + }, + + [ThemeLayoutId_ButtonYText] = { + .visible = true, + .posType = true, + .posStart = {-32, 0}, + .font = interuiregular18, + }, + + [ThemeLayoutId_ButtonM] = { + .visible = true, + .posType = true, + .posStart = {-36, 0}, + .font = fontscale7, + }, + + [ThemeLayoutId_ButtonMText] = { + .visible = true, + .posType = true, + .posStart = {-32, 0}, + .font = interuiregular18, + }, + + [ThemeLayoutId_ButtonX] = { + .visible = true, + .posType = true, + .posStart = {-36, 0}, + .touchSize = {36, 25}, + .font = fontscale7, + }, + + [ThemeLayoutId_ButtonXText] = { + .visible = true, + .posType = true, + .posStart = {-40 + 8, 0}, + .touchSize = {0, 25}, + .font = interuiregular18, + }, + + [ThemeLayoutId_NetworkIcon] = { + .visible = true, + .posType = true, + .posStart = {0, 0 + 47 + 10 + 3}, + .imageSize = {24, 24}, + }, + + [ThemeLayoutId_BatteryCharge] = { + .visible = true, + .posType = false, + .posStart = {1180 - 10 - 24 - 8, 0 + 47 + 10 + 21 + 4}, + .font = interuiregular14, + }, + + [ThemeLayoutId_BatteryIcon] = { + .visible = true, + .posType = false, + .posStart = {1180 - 8 - 24 - 8, 0 + 47 + 10 + 6}, + .imageSize = {24, 24}, + }, + + [ThemeLayoutId_ChargingIcon] = { + .visible = true, + .posType = false, + .posStart = {1180 - 20, 0 + 47 + 10 + 6}, + .imageSize = {24, 24}, + }, + + [ThemeLayoutId_Status] = { + .visible = true, + .posType = false, + .posStart = {1180, 0 + 47 + 10}, + .font = interuimedium20, + }, + + [ThemeLayoutId_Temperature] = { + .visible = true, + .posType = false, + .posStart = {1180 + 4, 0 + 47 + 10 + + 21 + 6}, + .font = interuiregular14, + }, + + [ThemeLayoutId_MenuList] = { + .visible = true, + .posType = false, + .posStart = {29, 720 - 100 - 145}, + .posEnd = {140 + 30, 0}, + .size = {140, 140 + 32}, + }, + + [ThemeLayoutId_MenuListTiles] = { + .visible = true, + .posType = true, + .posEnd = {7, 0}, + .size = {0, 0}, + }, + + [ThemeLayoutId_MenuListIcon] = { + .visible = true, + .posType = true, + .posStart = {0, 32}, + .imageSize = {140, 140}, + }, + + [ThemeLayoutId_MenuListName] = { + .visible = true, + .posType = true, + .posStart = {4, 4 + 18}, + .size = {140 - 32, 0}, + .font = interuiregular14, + }, + + [ThemeLayoutId_MenuActiveEntryIcon] = { + .visible = true, + .posType = false, + .posStart = {117, 100+10}, + .imageSize = {256, 256}, + }, + + [ThemeLayoutId_MenuActiveEntryName] = { + .visible = true, + .posType = false, + .posStart = {1280 - 790, 135+10 + 39}, + .size = {790 - 120, 0}, + .font = interuimedium30, + }, + + [ThemeLayoutId_MenuActiveEntryAuthor] = { + .visible = true, + .posType = false, + .posStart = {1280 - 790, 135+10 + 28 + 30 + 18}, + .font = interuiregular14, + }, + + [ThemeLayoutId_MenuActiveEntryVersion] = { + .visible = true, + .posType = false, + .posStart = {1280 - 790, 135+10 + 28 + 30 + 18 + 6 + 18}, + .font = interuiregular14, + }, + }, + }; + char themePath[PATH_MAX] = {0}; GetThemePathFromConfig(themePath, PATH_MAX); theme_t *themeDefault; config_t cfg = {0}; config_init(&cfg); - config_setting_t *theme = NULL; + config_setting_t *theme = NULL, *layout = NULL; color_t text, attentionText, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor, progressBarColor; int waveBlending; const char *AText, *BText, *XText, *YText, *PText, *MText, *starOnText, *starOffText; @@ -166,9 +488,58 @@ void themeStartup(ThemePreset preset) { } else { themeCurrent = *themeDefault; } + + memcpy(themeCurrent.layoutObjects, themeCommon.layoutObjects, sizeof(themeCommon.layoutObjects)); + + layout = config_lookup(&cfg, "layout"); + + if (layout != NULL) { + layoutObjectFromSetting(config_setting_lookup(layout, "logo"), &themeCurrent.layoutObjects[ThemeLayoutId_Logo], true); + layoutObjectFromSetting(config_setting_lookup(layout, "hbmenuVersion"), &themeCurrent.layoutObjects[ThemeLayoutId_HbmenuVersion], true); + layoutObjectFromSetting(config_setting_lookup(layout, "loaderInfo"), &themeCurrent.layoutObjects[ThemeLayoutId_LoaderInfo], true); + layoutObjectFromSetting(config_setting_lookup(layout, "attentionText"), &themeCurrent.layoutObjects[ThemeLayoutId_AttentionText], true); + layoutObjectFromSetting(config_setting_lookup(layout, "logInfo"), &themeCurrent.layoutObjects[ThemeLayoutId_LogInfo], true); + layoutObjectFromSetting(config_setting_lookup(layout, "infoMsg"), &themeCurrent.layoutObjects[ThemeLayoutId_InfoMsg], true); + layoutObjectFromSetting(config_setting_lookup(layout, "menuPath"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuPath], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuTypeMsg"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuTypeMsg], false); + layoutObjectFromSetting(config_setting_lookup(layout, "msgBoxSeparator"), &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator], false); + layoutObjectFromSetting(config_setting_lookup(layout, "msgBoxBottomText"), &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxBottomText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "backWave"), &themeCurrent.layoutObjects[ThemeLayoutId_BackWave], false); + layoutObjectFromSetting(config_setting_lookup(layout, "middleWave"), &themeCurrent.layoutObjects[ThemeLayoutId_MiddleWave], false); + layoutObjectFromSetting(config_setting_lookup(layout, "frontWave"), &themeCurrent.layoutObjects[ThemeLayoutId_FrontWave], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonA"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonA], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonAText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonAText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonB"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonB], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonBText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonBText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonY"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonY], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonYText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonYText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonM"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonM], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonMText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonMText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonX"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonX], false); + layoutObjectFromSetting(config_setting_lookup(layout, "buttonXText"), &themeCurrent.layoutObjects[ThemeLayoutId_ButtonXText], false); + layoutObjectFromSetting(config_setting_lookup(layout, "networkIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_NetworkIcon], false); + layoutObjectFromSetting(config_setting_lookup(layout, "batteryCharge"), &themeCurrent.layoutObjects[ThemeLayoutId_BatteryCharge], false); + layoutObjectFromSetting(config_setting_lookup(layout, "batteryIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_BatteryIcon], false); + layoutObjectFromSetting(config_setting_lookup(layout, "chargingIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_ChargingIcon], false); + layoutObjectFromSetting(config_setting_lookup(layout, "status"), &themeCurrent.layoutObjects[ThemeLayoutId_Status], false); + layoutObjectFromSetting(config_setting_lookup(layout, "temperature"), &themeCurrent.layoutObjects[ThemeLayoutId_Temperature], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuList"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuList], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuListTiles"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuListIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListIcon], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuListName"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuListName], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryIcon"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryIcon], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryName"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryName], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryAuthor"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryAuthor], false); + layoutObjectFromSetting(config_setting_lookup(layout, "menuActiveEntryVersion"), &themeCurrent.layoutObjects[ThemeLayoutId_MenuActiveEntryVersion], false); + } } else { themeCurrent = *themeDefault; + memcpy(themeCurrent.layoutObjects, themeCommon.layoutObjects, sizeof(themeCommon.layoutObjects)); } + + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; + if (layoutobj->posEnd[0] < 1) layoutobj->posEnd[0] = 1; + config_destroy(&cfg); } diff --git a/common/theme.h b/common/theme.h index 2cc48b0..d34673c 100644 --- a/common/theme.h +++ b/common/theme.h @@ -3,6 +3,26 @@ #include "common.h" #include +typedef enum +{ + THEME_PRESET_LIGHT, + THEME_PRESET_DARK, +} ThemePreset; + +typedef struct +{ + bool visible; + bool posType; // false = absolute, true = relative + int posStart[2]; + int posEnd[2]; + int size[2]; // width/height + int imageSize[2]; // width/height for the actual image data + int touchSize[2]; + int posFinal[2]; + uint32_t textSize[2]; + u32 font; +} ThemeLayoutObject; + typedef struct { color_t textColor; @@ -26,13 +46,9 @@ typedef struct char labelStarOnText[32]; char labelStarOffText[32]; const uint8_t *hbmenuLogoImage; -} theme_t; -typedef enum -{ - THEME_PRESET_LIGHT, - THEME_PRESET_DARK, -} ThemePreset; + ThemeLayoutObject layoutObjects[ThemeLayoutId_Total]; +} theme_t; bool colorFromSetting(config_setting_t *rgba, color_t *col); void themeStartup(ThemePreset preset); diff --git a/nx_main/main.c b/nx_main/main.c index 9d74818..a9c6277 100644 --- a/nx_main/main.c +++ b/nx_main/main.c @@ -209,6 +209,8 @@ bool menuUpdate(void) { bool exitflag = 0; menu_s* menu = menuGetCurrent(); u64 down = menuGetKeysDown(); + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; + int entries_count = layoutobj->posEnd[0]; handleTouch(menu); @@ -241,8 +243,8 @@ bool menuUpdate(void) { if (down & KEY_LEFT) move--; if (down & KEY_RIGHT) move++; - if (down & KEY_DOWN) move-=7; - if (down & KEY_UP) move+=7; + if (down & KEY_DOWN) move-=entries_count; + if (down & KEY_UP) move+=entries_count; int newEntry = menu->curEntry + move; if (newEntry < 0) newEntry = 0; diff --git a/nx_main/nx_touch.c b/nx_main/nx_touch.c index 593997b..ec38810 100644 --- a/nx_main/nx_touch.c +++ b/nx_main/nx_touch.c @@ -5,19 +5,6 @@ #define VERTICAL_SWIPE_MINIMUM_DISTANCE 300 #define HORIZONTAL_SWIPE_VERTICAL_PLAY 250 #define HORIZONTAL_SWIPE_MINIMUM_DISTANCE 300 -#define LISTING_START_Y 475 -#define LISTING_END_Y 647 -#define BUTTON_START_Y 672 -#define BUTTON_END_Y 704 -#define BACK_BUTTON_START_X 966 -#define BACK_BUTTON_END_X 1048 -#define LAUNCH_BUTTON_START_X 1092 -#define LAUNCH_BUTTON_END_X 1200 -#define STAR_BUTTON_START_X 426 -#define STAR_BUTTON_END_X 490 -#define STAR_BUTTON_START_Y 100 -#define STAR_BUTTON_END_Y 161 - #define distance(x1, y1, x2, y2) (int) sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))) @@ -33,15 +20,16 @@ void touchInit() { void handleTappingOnApp(menu_s* menu, int px) { int i = 0; menuEntry_s *me = NULL; + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; for (me = menu->firstEntry, i = 0; me; me = me->next, i ++) { - int entry_start_x = 29 + i * (140 + 30); + int entry_start_x = layoutobj->posStart[0] + i * layoutobj->posEnd[0]; int screen_width = 1280; if (entry_start_x >= (screen_width - menu->xPos)) break; - if (px >= (entry_start_x + menu->xPos) && px <= (entry_start_x + menu->xPos) + 140 ) { + if (px >= (entry_start_x + menu->xPos) && px <= (entry_start_x + menu->xPos) + layoutobj->size[0]) { launchMenuEntryTask(me); break; } @@ -58,10 +46,22 @@ void handleTappingOnOpenLaunch(menu_s* menu) { } } +static inline bool checkInsideTextLayoutObject(ThemeLayoutId id, int x, int y) { + ThemeLayoutObject *layoutobj = &themeCurrent.layoutObjects[id]; + if (!layoutobj->visible) return false; + + return x > layoutobj->posFinal[0] && x < layoutobj->posFinal[0]+(layoutobj->touchSize[0] ? layoutobj->touchSize[0] : layoutobj->textSize[0]) && y > layoutobj->posFinal[1]-layoutobj->touchSize[1] && y < layoutobj->posFinal[1]; +} + void handleTouch(menu_s* menu) { + ThemeLayoutObject *layoutobj = NULL; touchPosition currentTouch; u32 touches = hidTouchCount(); + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuListTiles]; + int entries_count = layoutobj->posEnd[0]; + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MenuList]; + // On touch start. if (touches == 1 && !touchInfo.gestureInProgress) { hidTouchRead(¤tTouch, 0); @@ -82,15 +82,15 @@ void handleTouch(menu_s* menu) { if (touchInfo.isTap && (abs(touchInfo.firstTouch.px - currentTouch.px) > TAP_MOVEMENT_GAP || abs(touchInfo.firstTouch.py - currentTouch.py) > TAP_MOVEMENT_GAP)) { touchInfo.isTap = false; } - if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.py > LISTING_START_Y && touchInfo.firstTouch.py < LISTING_END_Y && !touchInfo.isTap && menu->nEntries > 7) { + if (!menuIsMsgBoxOpen() && touchInfo.firstTouch.py > layoutobj->posStart[1] && touchInfo.firstTouch.py < layoutobj->posStart[1]+layoutobj->size[1] && !touchInfo.isTap && menu->nEntries > entries_count) { menu->xPos = touchInfo.initMenuXPos + (currentTouch.px - touchInfo.firstTouch.px); - menu->curEntry = touchInfo.initMenuIndex + ((int) (touchInfo.firstTouch.px - currentTouch.px) / 170); + menu->curEntry = touchInfo.initMenuIndex + ((int) (touchInfo.firstTouch.px - currentTouch.px) / layoutobj->posEnd[0]); if (menu->curEntry < 0) menu->curEntry = 0; - if (menu->curEntry >= menu->nEntries - 6) - menu->curEntry = menu->nEntries - 7; + if (menu->curEntry >= menu->nEntries - entries_count - 1) + menu->curEntry = menu->nEntries - entries_count; } } // On touch end. @@ -103,43 +103,40 @@ void handleTouch(menu_s* menu) { bool netloader_active = menuIsNetloaderActive(); if (menuIsMsgBoxOpen() && !netloader_active) { + layoutobj = &themeCurrent.layoutObjects[ThemeLayoutId_MsgBoxSeparator]; MessageBox currMsgBox = menuGetCurrentMsgBox(); int start_x = 1280 / 2 - currMsgBox.width / 2; - int start_y = (720 / 2 - currMsgBox.height / 2) + (currMsgBox.height - 80); + int start_y = (720 / 2 - currMsgBox.height / 2) + currMsgBox.height; int end_x = start_x + currMsgBox.width; - int end_y = start_y + 80; + int end_y = start_y; + start_y+= layoutobj->posStart[1]; if (x1 > start_x && x1 < end_x && y1 > start_y && y1 < end_y && touchInfo.isTap) { menuCloseMsgBox(); } } else if (touchInfo.isTap && !netloader_active) { // App Icons - if (y1 > LISTING_START_Y && y1 < LISTING_END_Y) { + if (y1 > layoutobj->posStart[1] && y1 < layoutobj->posStart[1]+layoutobj->size[1]) { handleTappingOnApp(menu, touchInfo.prevTouch.px); } // Bottom Buttons - else if (y1 > BUTTON_START_Y && y1 < BUTTON_END_Y) { - // Back Button for non-empty directory - if (menu->nEntries != 0 && x1 > BACK_BUTTON_START_X && x1 < BACK_BUTTON_END_X) { + else { + // Back Button + if (checkInsideTextLayoutObject(ThemeLayoutId_ButtonB, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonBText, x1, y1)) { launchMenuBackTask(); } - // Open/Launch Button / Back Button for empty directories - else if (x1 > LAUNCH_BUTTON_START_X && x1 < LAUNCH_BUTTON_END_X) { - if (menu->nEntries == 0) { - launchMenuBackTask(); - } else { - handleTappingOnOpenLaunch(menu); - } + // Open/Launch Button + else if (menu->nEntries != 0 && (checkInsideTextLayoutObject(ThemeLayoutId_ButtonA, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonAText, x1, y1))) { + handleTappingOnOpenLaunch(menu); } - } - // Star - else { - int i; - menuEntry_s* me; - for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next); - if (me->type != ENTRY_TYPE_THEME && x1 > STAR_BUTTON_START_X && x1 < STAR_BUTTON_END_X - && y1 > STAR_BUTTON_START_Y && y1 < STAR_BUTTON_END_Y) { - menuHandleXButton(); + // Star Button + else if (menu->nEntries != 0) { + int i; + menuEntry_s* me; + for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next); + if (me->type != ENTRY_TYPE_THEME && (checkInsideTextLayoutObject(ThemeLayoutId_ButtonX, x1, y1) || checkInsideTextLayoutObject(ThemeLayoutId_ButtonXText, x1, y1))) { + menuHandleXButton(); + } } } } @@ -155,7 +152,7 @@ void handleTouch(menu_s* menu) { } } // Horizontal Swipe - else if (y1 < LISTING_START_Y && y2 < LISTING_START_Y) { + else if (y1 < layoutobj->posStart[1] && y2 < layoutobj->posStart[1]) { if (abs(y1 - y2) < HORIZONTAL_SWIPE_VERTICAL_PLAY && distance(x1, y1, x2, y2) > HORIZONTAL_SWIPE_MINIMUM_DISTANCE) { // Swipe left to go into theme-menu if (x1 - x2 > 0) {