Implemented a theme switcher feature (#62)

* Implemented Theme Menu.

* Minor adjustments.

* added two new theming attributes, borderColor, borderTextcolor, allows users to modify the boxes that surrounds the menu entries

* added theme info to config file, users can now add theme author, theme name, and theme version to a theme config file.

* tested building on mac osx, added to .gitignore and make clean for files generated on osx

* The path for the theme is now stored in a config string in settings.cfg, instead of a hard-coded theme.cfg path.

* added functions to create/modify settings config for hbmenu theme

* added Default theme entry that will always insert itself at the front of the list of themes

* added code for + and - button, using - button for theme menu now (button display for this is disabled).
This commit is contained in:
NightlyFox 2018-09-28 22:20:24 -05:00 committed by yellows8
parent 985dc946fe
commit 992c4c482b
18 changed files with 377 additions and 42 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ build
*.pfs0
*.nacp
*.nro
test.*
switch

View File

@ -25,6 +25,7 @@ test : pc_main/main.cpp pc_main/pc_launch.c \
common/netloader.c \
build_pc/invalid_icon.bin.o build_pc/folder_icon.bin.o \
build_pc/hbmenu_logo_light.bin.o build_pc/hbmenu_logo_dark.bin.o \
build_pc/theme_icon_dark.bin.o build_pc/theme_icon_light.bin.o \
#build_pc/tahoma24.o build_pc/tahoma12.o build_pc/interuimedium20.o build_pc/interuimedium30.o build_pc/interuiregular14.o build_pc/interuiregular18.o
gcc -Wall -O2 -g -DVERSION=\"v$(APP_VERSION)\" $(EXTRA_CFLAGS) `pkg-config freetype2 --cflags` $^ -lsfml-graphics -lsfml-window -lsfml-system -lstdc++ `pkg-config freetype2 --libs` -lm -lz -lconfig $(EXTRA_LDFLAGS) -I. -iquote $(DEVKITPRO)/libnx/include -Ibuild_pc -g -o $@
@ -78,7 +79,16 @@ build_pc/hbmenu_logo_dark.bin.o : data/hbmenu_logo_dark.bin
@echo $(notdir $<)
@$(bin2o)
build_pc/theme_icon_light.bin.o : data/theme_icon_light.bin
mkdir -p $(dir $@)
@echo $(notdir $<)
@$(bin2o)
build_pc/theme_icon_dark.bin.o : data/theme_icon_dark.bin
mkdir -p $(dir $@)
@echo $(notdir $<)
@$(bin2o)
clean:
rm -rf build_pc/ test
rm -rf build_pc/ test test.*

View File

@ -60,6 +60,7 @@ typedef union {
#include "message-box.h"
void menuStartup();
void themeMenuStartup();
void menuLoop();
static inline uint8_t BlendColor(uint32_t src, uint32_t dst, uint8_t alpha)
@ -152,6 +153,8 @@ 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 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);
uint32_t GetTextYCoordinate(u32 font, uint32_t rY, const char* text, const char align);
bool fontInitialize(void);
void fontExit();

View File

@ -376,3 +376,51 @@ void fontExit()
if (s_font_libret==0) FT_Done_FreeType(s_font_library);
}
/*Automatically gives you the desired x-coordinate
*based on the string length and desired alignment
*rY=reference point... where to align around
*align='t','b','c' translates to (top,bottom,center)
*'t' aligned, top of text aligns with rY,
*you get the rest....
*/
uint32_t GetTextYCoordinate(u32 font, uint32_t rY, const char* text, const char align) {
uint32_t height_o,width;
GetTextDimensions(font,text,&width,&height_o);
uint32_t height = (uint32_t)height_o;
uint32_t fC = (rY-height);
switch(align){
case 't':
default:
return rY;
case 'c':
return (rY+(height>>1));//>>1 is a bitwise shift for dividing by 2
case 'b':
if(fC<=0) return 0;
else return fC;
}
}
/*Automatically gives you the desired x-coordinate
*based on the string length and desired alignment
*rX=reference point... where to align around
*text=string you want to display
*align='r','l','c' translates to (right,left,center)
*'r' aligned, rX location = end of string, you get the rest...
*/
uint32_t GetTextXCoordinate(u32 font, uint32_t rX, const char* text, const char align) {
uint32_t height,width_o;
GetTextDimensions(font,text,&width_o,&height);
uint32_t fC = (rX-width_o);
switch(align){
case 'r':
if(fC<0) return 0;
else return fC;
case 'c':
return (rX+(width_o>>1));//>>1 is a bitwise shift for dividing by 2
case 'l':
default:
return rX;
}
}

View File

@ -310,6 +310,33 @@ const char* const g_strings[StrId_Max][16] =
STR_TW("確認"),
},
[StrId_Actions_Apply] =
{
STR_EN("Apply"),
STR_ES("Aplicar"),
STR_JP("適用"),
STR_KO("대다"),
STR_TW("应用"),
},
[StrId_ThemeMenu] =
{
STR_EN("Theme Menu"),
STR_ES("Menú temático"),
STR_JP("テーマメニュー"),
STR_KO("테마 메뉴"),
STR_TW("主题菜单"),
},
[StrId_ThemeNotApplied] =
{
STR_EN("Theme cannot be applied because an error occurred."),
STR_ES("El tema no se pudo aplicar porque se ha producido un error."),
STR_JP("エラーが発生したため、テーマを適用できませんでした。"),
STR_KO("오류가 발생 했기 때문에 테마를 적용할 수 없습니다."),
STR_TW("由于发生错误, 无法应用主题。"),
},
/*[StrId_Reboot] =
{
STR_EN(

View File

@ -21,6 +21,7 @@ typedef enum
StrId_Actions_Launch,
StrId_Actions_Open,
StrId_Actions_Back,
StrId_Actions_Apply,
StrId_MsgBox_OK,
@ -42,6 +43,9 @@ typedef enum
StrId_NetLoaderActive,
StrId_NetLoaderTransferring,
StrId_ThemeMenu,
StrId_ThemeNotApplied,
StrId_Max,
} StrId;

View File

@ -137,6 +137,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) {
tempbuf[PATH_MAX] = 0;
strcpy(me->name, name);
if (me->type == ENTRY_TYPE_FOLDER)
{
//Check for <dirpath>/<dirname>.nro
@ -182,7 +183,7 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) {
if (me->type == ENTRY_TYPE_FILE)
{
strcpy(me->name, name);
//strcpy(me->name, name);//This is already done before both if statements
strcpy(me->author, textGetString(StrId_DefaultPublisher));
strcpy(me->version, "1.0.0");
@ -293,6 +294,29 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) {
/*if (shortcut)
shortcutFree(&sc);*/
}
if (me->type == ENTRY_TYPE_THEME) {
config_t cfg = {0};
config_init(&cfg);
config_setting_t *themeInfo;
const char *name,
*author = textGetString(StrId_DefaultPublisher),
*version = "1.0.0";
if(config_read_file(&cfg, me->path)) {
themeInfo = config_lookup(&cfg, "themeInfo");
if (themeInfo != NULL) {
if(config_setting_lookup_string(themeInfo, "name", &name))
strncpy(me->name, name, sizeof(me->name)-1);
config_setting_lookup_string(themeInfo, "author", &author);
config_setting_lookup_string(themeInfo, "version", &version);
}
}
strncpy(me->author, author, sizeof(me->author)-1);
strncpy(me->version, version, sizeof(me->version)-1);
config_destroy(&cfg);
}
return true;
}

View File

@ -34,6 +34,22 @@ static void menuAddEntry(menuEntry_s* me) {
m->nEntries ++;
}
static void menuAddEntryToFront(menuEntry_s* me) {
menu_s* m = &s_menu[!s_curMenu];
me->menu = m;
if (m->lastEntry)
{
me->next = m->firstEntry;
m->firstEntry = me;
} else
{
m->firstEntry = me;
m->lastEntry = me;
}
m->xPos = 0;
m->nEntries ++;
}
static void menuClear(void) {
menu_s* m = &s_menu[!s_curMenu];
menuEntry_s *cur, *next;
@ -150,3 +166,54 @@ int menuScan(const char* target) {
return 0;
}
int themeMenuScan(const char* target) {
menuClear();
if (chdir(target) < 0) return 1;
if (getcwd(s_menu[!s_curMenu].dirname, PATH_MAX+1) == NULL)
return 1;
DIR* dir;
struct dirent* dp;
char tmp_path[PATH_MAX+1];
dir = opendir(s_menu[!s_curMenu].dirname);
if (!dir) return 2;
while ((dp = readdir(dir)))
{
menuEntry_s* me = NULL;
bool shortcut = false;
if (dp->d_name[0]=='.')
continue;
memset(tmp_path, 0, sizeof(tmp_path));
snprintf(tmp_path, sizeof(tmp_path)-1, "%s/%s", s_menu[!s_curMenu].dirname, dp->d_name);
const char* ext = getExtension(dp->d_name);
if (strcasecmp(ext, ".cfg")==0)
me = menuCreateEntry(ENTRY_TYPE_THEME);
if (!me)
continue;
strncpy(me->path, tmp_path, sizeof(me->path)-1);
me->path[sizeof(me->path)-1] = 0;
if (menuEntryLoad(me, dp->d_name, shortcut))
menuAddEntry(me);
else
menuDeleteEntry(me);
}
closedir(dir);
menuSort();
menuEntry_s* me = menuCreateEntry(ENTRY_TYPE_THEME);
if(me) {
if(menuEntryLoad(me, "Default Theme", false));//Create Default theme Menu Entry
menuAddEntryToFront(me);
}
// Swap the menu and clear the previous menu
s_curMenu = !s_curMenu;
menuClear();
return 0;
}

View File

@ -4,19 +4,23 @@
#include "invalid_icon_bin.h"
#include "folder_icon_bin.h"
#include "theme_icon_dark_bin.h"
#include "theme_icon_light_bin.h"
char rootPath[PATH_MAX+8];
void computeFrontGradient(color_t baseColor, int height);
char *menuGetRootPath() {
return rootPath;
}
void launchMenuEntryTask(menuEntry_s* arg)
{
void launchMenuEntryTask(menuEntry_s* arg) {
menuEntry_s* me = arg;
if (me->type == ENTRY_TYPE_FOLDER)
menuScan(me->path);
//changeDirTask(me->path);
else if(me->type == ENTRY_TYPE_THEME)
launchApplyThemeTask(me);
else
launchMenuEntry(me);
}
@ -27,6 +31,7 @@ static enum
HBMENU_NETLOADER_ACTIVE,
HBMENU_NETLOADER_ERROR,
HBMENU_NETLOADER_SUCCESS,
HBMENU_THEME_MENU,
} hbmenu_state = HBMENU_DEFAULT;
void launchMenuNetloaderTask() {
@ -34,17 +39,28 @@ void launchMenuNetloaderTask() {
if(netloader_activate() == 0) hbmenu_state = HBMENU_NETLOADER_ACTIVE;
}
void launchMenuBackTask()
{
void launchMenuBackTask() {
if(hbmenu_state == HBMENU_NETLOADER_ACTIVE) {
netloader_deactivate();
hbmenu_state = HBMENU_DEFAULT;
} else {
}
else if(hbmenu_state == HBMENU_THEME_MENU) {
hbmenu_state = HBMENU_DEFAULT;
menuScan(rootPath);
}
else {
menuScan("..");
}
}
void launchApplyThemeTask(menuEntry_s* arg) {
const char* themePath = removeDriveFromPath(arg->path);
SetThemePathToConfig(themePath);
themeStartup(themeGlobalPreset);
computeFrontGradient(themeCurrent.frontWaveColor, 280);
}
//Draws an RGB888 or RGBA8888 image.
static void drawImage(int x, int y, int width, int height, const uint8_t *image, ImageMode mode) {
int tmpx, tmpy;
@ -72,6 +88,7 @@ static void drawImage(int x, int y, int width, int height, const uint8_t *image,
uint8_t *folder_icon_small;
uint8_t *invalid_icon_small;
uint8_t *theme_icon_small;
static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
int x, y;
@ -87,7 +104,7 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
int border_start_x, border_end_x;
int border_start_y, border_end_y;
color_t border_color = MakeColor(255, 255, 255, 255);
color_t border_color = themeCurrent.borderColor;
int shadow_start_y, shadow_y;
int shadow_inset;
@ -166,7 +183,7 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
for (y=start_y; y<end_y; y++) {
for (x=start_x; x<end_x; x+=4) {
Draw4PixelsRaw(x, y, MakeColor(255, 255, 255, 255));
Draw4PixelsRaw(x, y, themeCurrent.borderColor);
}
}
@ -178,6 +195,12 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
smallimg = folder_icon_small;
largeimg = folder_icon_bin;
}
else if (me->type == ENTRY_TYPE_THEME){
smallimg = theme_icon_small;
if(themeGlobalPreset == THEME_PRESET_DARK)
largeimg = theme_icon_dark_bin;
else largeimg = theme_icon_light_bin;
}
else {
smallimg = invalid_icon_small;
largeimg = invalid_icon_bin;
@ -206,7 +229,7 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) {
}
}
DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, MakeColor(64, 64, 64, 255), me->name, 140 - 32, "...");
DrawTextTruncate(interuiregular14, start_x + 4, start_y + 4 + 18, themeCurrent.borderTextColor, me->name, 140 - 32, "...");
if (is_active) {
start_x = 1280 - 790;
@ -267,10 +290,24 @@ void menuStartup() {
folder_icon_small = downscaleImg(folder_icon_bin, 256, 256, 140, 140, IMAGE_MODE_RGB24);
invalid_icon_small = downscaleImg(invalid_icon_bin, 256, 256, 140, 140, IMAGE_MODE_RGB24);
if(themeGlobalPreset == THEME_PRESET_DARK)
theme_icon_small = downscaleImg(theme_icon_dark_bin, 256, 256, 140, 140, IMAGE_MODE_RGB24);
else
theme_icon_small = downscaleImg(theme_icon_light_bin, 256, 256, 140, 140, IMAGE_MODE_RGB24);
computeFrontGradient(themeCurrent.frontWaveColor, 280);
//menuCreateMsgBox(780, 300, "This is a test");
}
void themeMenuStartup() {
if(hbmenu_state != HBMENU_DEFAULT) return;
hbmenu_state = HBMENU_THEME_MENU;
char tmp_path[PATH_MAX];
snprintf(tmp_path, sizeof(tmp_path)-1, "%s%s%s%s%s%s",DIRECTORY_SEPARATOR, "config", DIRECTORY_SEPARATOR, "nx-hbmenu" , DIRECTORY_SEPARATOR, "themes");
themeMenuScan(tmp_path);
}
color_t waveBlendAdd(color_t a, color_t b, float alpha) {
return MakeColor(a.r+(b.r*alpha), a.g+b.g*alpha, a.b + b.b*alpha, 255);
}
@ -440,14 +477,25 @@ void menuLoop() {
drawEntry(me, entry_start_x + menu->xPos, is_active);
}
int getX = GetTextXCoordinate(interuiregular18, 1180, textGetString(StrId_ThemeMenu), 'r');
if(hbmenu_state == HBMENU_THEME_MENU) {
DrawText(interuiregular18, getX, 0 + 47, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
} else {
//DrawText(interuiregular18, getX, 0 + 47, themeCurrent.textColor, textGetString(StrId_ThemeMenu));
//DrawText(fontscale7, getX - 40, 0 + 47, themeCurrent.textColor, themeCurrent.buttonMText);
}
if(active_entry != NULL) {
if (active_entry->type != ENTRY_TYPE_FOLDER) {
//drawImage(1280 - 126 - 30 - 32, 720 - 48, 32, 32, themeCurrent.buttonAImage, IMAGE_MODE_RGBA32);
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 {
//drawImage(1280 - 126 - 30 - 32, 720 - 48, 32, 32, themeCurrent.buttonAImage, IMAGE_MODE_RGBA32);
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));
}

View File

@ -19,6 +19,7 @@ typedef enum
{
ENTRY_TYPE_FILE,
ENTRY_TYPE_FOLDER,
ENTRY_TYPE_THEME,
} MenuEntryType;
typedef struct menuEntry_s_tag menuEntry_s;
@ -84,8 +85,10 @@ void menuEntryParseNacp(menuEntry_s* me);
menu_s* menuGetCurrent(void);
int menuScan(const char* target);
int themeMenuScan(const char* target);
void launchMenuEntryTask(menuEntry_s* arg);
void launchApplyThemeTask(menuEntry_s* arg);
void launchMenuBackTask();
void launchMenuNetloaderTask();
char *menuGetRootPath();
@ -109,3 +112,9 @@ static inline char* getSlash(const char* str)
return (char*)p;
}
static inline char* removeDriveFromPath(const char* str) {
const char* p;
for (p = str; p <= (str+strlen(str)) && *p != ':'; p++);
p++;//iterate one more time past ':'
return (char*)p;
}

View File

@ -6,6 +6,9 @@
#include "hbmenu_logo_light_bin.h"
#include "hbmenu_logo_dark_bin.h"
theme_t themeCurrent;
ThemePreset themeGlobalPreset;
bool colorFromSetting(config_setting_t *rgba, color_t *col) {
if(rgba == NULL)
return false;
@ -14,6 +17,7 @@ bool colorFromSetting(config_setting_t *rgba, color_t *col) {
}
void themeStartup(ThemePreset preset) {
themeGlobalPreset = preset;
theme_t themeLight = (theme_t) {
.textColor = MakeColor(0, 0, 0, 255),
.frontWaveColor = MakeColor(100, 212, 250, 255),
@ -22,11 +26,13 @@ void themeStartup(ThemePreset preset) {
.backgroundColor = MakeColor(233, 236, 241, 255),
.highlightColor = MakeColor(91, 237, 224, 255),
.separatorColor = MakeColor(219, 218, 219, 255),
.borderColor = MakeColor(255,255,255,255),
.borderTextColor = MakeColor(64,64,64,255),
.enableWaveBlending = 0,
.buttonAText = "\uE0E0",
.buttonBText = "\uE0E1",
//.buttonAImage = button_a_light_bin,
//.buttonBImage = button_b_light_bin,
.buttonPText = "\uE0EF",
.buttonMText = "\uE0F0",
.hbmenuLogoImage = hbmenu_logo_light_bin
};
@ -38,31 +44,31 @@ void themeStartup(ThemePreset preset) {
.backgroundColor = MakeColor(45, 45, 50, 255),
.highlightColor = MakeColor(91, 237, 224, 255),
.separatorColor = MakeColor(219, 218, 219, 255),
.borderColor = MakeColor(255,255,255,255),
.borderTextColor = MakeColor(64,64,64,255),
.enableWaveBlending = 0,
.buttonAText = "\uE0A0",
.buttonBText = "\uE0A1",
//.buttonAImage = button_a_dark_bin,
//.buttonBImage = button_b_dark_bin,
.buttonPText = "\uE0B3",
.buttonMText = "\uE0B4",
.hbmenuLogoImage = hbmenu_logo_dark_bin
};
char tmp_path[PATH_MAX] = {0};
#ifdef __SWITCH__
tmp_path[0] = '/';
#endif
char themePath[PATH_MAX] = {0};
GetThemePathFromConfig(themePath, PATH_MAX);
strncat(tmp_path, "config/nx-hbmenu/themes/theme.cfg", sizeof(tmp_path)-2);
theme_t *themeDefault;
config_t cfg = {0};
config_init(&cfg);
config_setting_t *theme;
color_t text, frontWave, middleWave, backWave, background, highlight, separator;
config_setting_t *theme = NULL;
color_t text, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor;
int waveBlending;
const char *AText, *BText;
bool good_cfg = config_read_file(&cfg, tmp_path);
const char *AText, *BText, *PText, *MText;
bool good_cfg = false;
if(themePath[0]!=0)
good_cfg = config_read_file(&cfg, themePath);
switch (preset) {
case THEME_PRESET_LIGHT:
default:
@ -77,7 +83,7 @@ void themeStartup(ThemePreset preset) {
theme = config_lookup(&cfg, "darkTheme");
break;
}
if (good_cfg) {
if (theme != NULL) {
if (!colorFromSetting(config_setting_lookup(theme, "textColor"), &text))
@ -94,12 +100,20 @@ void themeStartup(ThemePreset preset) {
highlight = themeDefault->highlightColor;
if (!colorFromSetting(config_setting_lookup(theme, "separatorColor"), &separator))
separator = themeDefault->separatorColor;
if (!colorFromSetting(config_setting_lookup(theme, "borderColor"), &borderColor))
borderColor = themeDefault->borderColor;
if (!colorFromSetting(config_setting_lookup(theme, "borderTextColor"), &borderTextColor))
borderTextColor = themeDefault->borderTextColor;
if (!config_setting_lookup_int(theme, "enableWaveBlending", &waveBlending))
waveBlending = themeDefault->enableWaveBlending;
if (!config_setting_lookup_string(theme, "buttonAText", &AText))
AText = themeDefault->buttonAText;
if (!config_setting_lookup_string(theme, "buttonBText", &BText))
BText = themeDefault->buttonBText;
if (!config_setting_lookup_string(theme, "buttonPText", &PText))
PText = themeDefault->buttonPText;
if (!config_setting_lookup_string(theme, "buttonMText", &MText))
MText = themeDefault->buttonMText;
themeCurrent = (theme_t) {
.textColor = text,
.frontWaveColor = frontWave,
@ -108,13 +122,15 @@ void themeStartup(ThemePreset preset) {
.backgroundColor = background,
.highlightColor = highlight,
.separatorColor = separator,
.borderColor = borderColor,
.borderTextColor = borderTextColor,
.enableWaveBlending = waveBlending,
.buttonAText = AText,
.buttonBText = BText,
//.buttonAImage = button_a_dark_bin,
//.buttonBImage = button_b_dark_bin,
.hbmenuLogoImage = hbmenu_logo_dark_bin
.hbmenuLogoImage = themeDefault->hbmenuLogoImage
};
strncpy(themeCurrent.buttonAText, AText, sizeof(themeCurrent.buttonAText)-1);
strncpy(themeCurrent.buttonBText, BText, sizeof(themeCurrent.buttonBText)-1);
strncpy(themeCurrent.buttonPText, PText, sizeof(themeCurrent.buttonPText)-1);
strncpy(themeCurrent.buttonMText, MText, sizeof(themeCurrent.buttonMText)-1);
} else {
themeCurrent = *themeDefault;
}
@ -123,3 +139,66 @@ void themeStartup(ThemePreset preset) {
}
config_destroy(&cfg);
}
void GetThemePathFromConfig(char* themePath, size_t size) {
const char* tmpThemePath = "";
config_t cfg = {0};
config_setting_t *settings = NULL;
char tmp_path[PATH_MAX] = {0};
#ifdef __SWITCH__
tmp_path[0] = '/';
#endif
strncat(tmp_path, "config/nx-hbmenu/settings.cfg", sizeof(tmp_path)-2);
bool good_cfg = config_read_file(&cfg, tmp_path);
if(good_cfg) {
settings = config_lookup(&cfg, "settings");
if(settings != NULL) {
if(config_setting_lookup_string(settings, "themePath", &tmpThemePath))
strncpy(themePath, tmpThemePath, size-1);
}
}
config_destroy(&cfg);
}
void SetThemePathToConfig(const char* themePath) {
config_t cfg = {0};
config_init(&cfg);
char settingPath[PATH_MAX] = {0};
config_setting_t *root = NULL,
*group = NULL,
*settings = NULL;
#ifdef __SWITCH__
settingPath[0] = '/';
#endif
strncat(settingPath, "config/nx-hbmenu/settings.cfg", sizeof(settingPath)-2);
bool good_cfg = config_read_file(&cfg, settingPath);
if(good_cfg) {
group = config_lookup(&cfg, "settings");
if(group != NULL)
settings = config_setting_lookup(group, "themePath");
if(settings != NULL)
config_setting_set_string(settings, themePath);
} else {
root = config_root_setting(&cfg);
if(root != NULL)
group = config_setting_add(root, "settings", CONFIG_TYPE_GROUP);
if(group != NULL)
settings = config_setting_add(group, "themePath", CONFIG_TYPE_STRING);
if(settings != NULL)
config_setting_set_string(settings, themePath);
}
if(!config_write_file(&cfg, settingPath)) {
menuCreateMsgBox(780, 300, textGetString(StrId_ThemeNotApplied));
}
config_destroy(&cfg);
}

View File

@ -12,12 +12,13 @@ typedef struct
color_t backgroundColor;
color_t highlightColor;
color_t separatorColor;
color_t activeColor;
color_t borderColor;
color_t borderTextColor;
bool enableWaveBlending;
const char *buttonAText;
const char *buttonBText;
//const uint8_t *buttonAImage;
//const uint8_t *buttonBImage;
char buttonAText[32];
char buttonBText[32];
char buttonPText[32];
char buttonMText[32];
const uint8_t *hbmenuLogoImage;
} theme_t;
@ -28,7 +29,10 @@ typedef enum
} ThemePreset;
bool colorFromSetting(config_setting_t *rgba, color_t *col);
void themeStartup(ThemePreset preset);
void GetThemePathFromConfig(char* themePath, size_t size);
void SetThemePathToConfig(const char* themePath);
theme_t themeCurrent;
extern theme_t themeCurrent;
extern ThemePreset themeGlobalPreset;

1
data/theme_icon_dark.bin Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -135,6 +135,9 @@ bool menuUpdate(void) {
{
launchMenuBackTask();
}
else if(down & KEY_MINUS){
themeMenuStartup();
}
else if (down & KEY_PLUS)
{
exitflag = 1;

View File

@ -66,6 +66,8 @@ extern "C" bool menuUpdate(void) {
int new_return_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Return);
static int y_state = 0;
int new_y_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Y);
static int t_state = 0;
int new_t_state = sf::Keyboard::isKeyPressed(sf::Keyboard::T);
if(!new_y_state && y_state)
{
@ -77,6 +79,9 @@ extern "C" bool menuUpdate(void) {
{
launchMenuBackTask();
}
else if(!new_t_state && t_state){
themeMenuStartup();
}
else if (!new_return_state && return_state)
{
if (menuIsMsgBoxOpen()) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB