Skip to content

Commit

Permalink
Implemented a theme switcher feature (switchbrew#62)
Browse files Browse the repository at this point in the history
* 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).
  • Loading branch information
NightlyFox authored and yellows8 committed Sep 29, 2018
1 parent 985dc94 commit 992c4c4
Show file tree
Hide file tree
Showing 18 changed files with 377 additions and 42 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ build
*.pfs0
*.nacp
*.nro
test.*
switch
12 changes: 11 additions & 1 deletion Makefile.pc
Original file line number Diff line number Diff line change
Expand Up @@ -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 $@

Expand Down Expand Up @@ -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.*
3 changes: 3 additions & 0 deletions common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
48 changes: 48 additions & 0 deletions common/font.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
27 changes: 27 additions & 0 deletions common/language.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions common/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef enum
StrId_Actions_Launch,
StrId_Actions_Open,
StrId_Actions_Back,
StrId_Actions_Apply,

StrId_MsgBox_OK,

Expand All @@ -42,6 +43,9 @@ typedef enum
StrId_NetLoaderActive,
StrId_NetLoaderTransferring,

StrId_ThemeMenu,
StrId_ThemeNotApplied,

StrId_Max,
} StrId;

Expand Down
26 changes: 25 additions & 1 deletion common/menu-entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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;
}
Expand Down
67 changes: 67 additions & 0 deletions common/menu-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Loading

0 comments on commit 992c4c4

Please sign in to comment.