From 30961e9991e8bbe7c307d82f4c12640ef180db9c Mon Sep 17 00:00:00 2001 From: hippydave Date: Sun, 7 Jul 2019 22:45:28 +0100 Subject: [PATCH] Add starred favourites at start of list --- assets/star_off.bin | Bin 0 -> 15616 bytes assets/star_on.bin | Bin 0 -> 15616 bytes assets/star_small.bin | Bin 0 -> 4620 bytes common/assets.c | 3 ++ common/assets.h | 3 ++ common/language.c | 24 +++++++++++++- common/language.h | 2 ++ common/menu-entry.c | 7 ++++ common/menu-list.c | 26 +++++++++++++-- common/menu.c | 69 +++++++++++++++++++++++++++++++++++++++ common/menu.h | 6 ++++ common/theme.c | 17 ++++++++-- common/theme.h | 4 +++ nx_main/main.c | 4 +++ nx_main/nx_touch.c | 15 +++++++++ pc_main/main.cpp | 8 +++++ resources/star_off.png | Bin 0 -> 4496 bytes resources/star_on.png | Bin 0 -> 5122 bytes resources/star_small.png | Bin 0 -> 2500 bytes 19 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 assets/star_off.bin create mode 100644 assets/star_on.bin create mode 100644 assets/star_small.bin create mode 100644 resources/star_off.png create mode 100644 resources/star_on.png create mode 100644 resources/star_small.png diff --git a/assets/star_off.bin b/assets/star_off.bin new file mode 100644 index 0000000000000000000000000000000000000000..20b455cb0610401faa51e8121733d58ed0443266 GIT binary patch literal 15616 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 literal 0 HcmV?d00001 diff --git a/assets/star_small.bin b/assets/star_small.bin new file mode 100644 index 0000000000000000000000000000000000000000..dbec7330f61551f88d022dd674758223ed5a354a GIT binary patch literal 4620 zcmcJSTWlOx8OP7eoUx75KmfH(X-QkBPH9BbCN-$gCInK^3J8ry5qk?%H0jz25a@ec73F`S^clXY94>+^Te? zvu9>@&iQ`lyRQ)M?L!xZ&nqb({>0>DY%=oa?w*8481HS@TVF+Q29EmcCI zVn`|{PrK*I@3+45t*ziQr{^~L@V7J*kjZ*$RPjlV$v>yNrSGKo@5j8YlYDr}WPL?f z?;usVSL@;-vN?}bcHk__1&h<&`@xXznfi&z2Cq?7lBynwb>kDH=Z9me_LItZPB*>! zOV{4cnMOs(`^CAzldwxfQy(Q&KW6j-SXw8HDSw=zcLZ%^2F~z%>HBpNYe2VnylVmo|kXe07QyK9+;k8utPG>8(miO8j0n53F z9EEv17x6QU>vGfR6QRlX{}3E)!kN|7eF+Ej0S>bUj`q`FIZHPBBAMohqFLysB06U7 z;7@5reBgRIac9T*_r61=4}XaA{lk=#U(lK0`z9lPiIJfa%s(EGDuZJQc4@I)_Hb-H zL$>oAS$&@Mqo|G?xGKohWx+JUUr{r7nU>@^YVafwZhqSYc;~0THKC`0_=7_)%e;F(ni0DOJUod9vX+zN< z?s1j~`!(6;<%TYYQ))_HiYLO?qJsRzRzW-f`TwOw$VFUG73Y|_1LGs4%XgESxlgOP z2bHQ1Yxt?{`bVmd{W!kjIIMYr$bKE;W!yh!ZAWOc?kTh8Ytw>D@@T>}79g{RQI`~D zsCfhU#mbYb|eFM6grHUl@XRNCCkea=ppbt{>!=x9$ zk^09CIlkufVa<2Rs+YiVxXZEDM|v3?O^ikO{sP9Fptumkj^iEKT)*6Rg8iqH6-VJO zQ&dKsD-1@CrT*}(aoAptZ-HYd;ppGZQBOF=gNP<1b>5b>DB(!+bSEQ*R4yE+X^(W_ zK&0nko91KPJeKNX{d6~OxBay1AG_?Lz6p+F@8W<>y81w@$ILMqGRF)!9$|f?9NTkF z99Cmtj;66Le=ydIk0Lfd-OV4@<$yidKNMnT>;C;YSRc&6b}2DOFiDw#p93E_mJk}d8 zDM!VlC?l1NnalDO$C30OyM*t#Noy132k(gsa)EuvEI+2KJ_9>E1&$HK?NM-`R!104 zAN}Bf&+p~nxP^~Ilb*I&mqS)N+5V%B7a|q&O?zml37lAeXV&H%XIiEtwL^$y-?eB^pWKC zR3A%8KAnf3vRzmoDF@;)Dhfq&=#3}jpHjIu$mOiYj&6NH ztpWq*b&i+49L!Pz%RE?0^2+qI7+{{)_vu$s&U6N^>uIPi?$T8`M;mCtj8Ha){LLMG z80KhrR?YcFRec?oeG`{G>->Z5!VH|Fa2;2LrW$HvMYd>OJixM2IjP+J<~Pt=x_4{g zh@O+0)_vGW7|R?R7;P{#J*#U$jQ+!z67+_;f*y$D)PNn z^aj+BXWjmZoc$QmXDP3)2j8GJe5LIh#I9uyy#j^>Um5Oo8t8T41M#@jaZa|QE65+* zf1%E(F>nrsa+o;T&M6PD}7bgyrl zX7~p((EXy^H1pEX3ie_DE6abv2cJpxxZkXb^0c0ke{($>eBUlgYnS9E#kgLOe^1x+ z%1fW6bMJ4qDKD{JIKR*`7%K8jT?x*o@A91dZ{hzJ-Lc09R8>9;+5e(V?7{Jf+16x+ z`+m3n1~~@%I^CJY@W;%6KKU&$yts=2wWODO*KgQ=bWg3(jo_>3sV`9rdalZ!U5n%Y D)@uf- literal 0 HcmV?d00001 diff --git a/common/assets.c b/common/assets.c index e3cc541..8680ca3 100644 --- a/common/assets.c +++ b/common/assets.c @@ -27,6 +27,9 @@ assetsDataEntry g_assetsDataList[AssetId_Max] = { GENASSET("wifi3_icon.bin"), GENASSET("eth_icon.bin"), GENASSET("eth_none_icon.bin"), + GENASSET("star_small.bin"), + GENASSET("star_on.bin"), + GENASSET("star_off.bin"), }; static void assetsClearEntry(assetsDataEntry *entry) { diff --git a/common/assets.h b/common/assets.h index 6eb23e2..fed4a66 100644 --- a/common/assets.h +++ b/common/assets.h @@ -17,6 +17,9 @@ typedef enum { AssetId_wifi3_icon, AssetId_eth_icon, AssetId_eth_none_icon, + AssetId_star_small, + AssetId_star_on, + AssetId_star_off, AssetId_Max } AssetId; diff --git a/common/language.c b/common/language.c index e634e02..f8a95bb 100644 --- a/common/language.c +++ b/common/language.c @@ -1,4 +1,4 @@ -#include "language.h" +#include "language.h" #ifdef __SWITCH__ #define STR_JP(_str) [SetLanguage_JA] = _str @@ -331,6 +331,28 @@ const char* const g_strings[StrId_Max][16] = STR_TW("应用"), }, + [StrId_Actions_Star] = + { + STR_EN("Star"), + STR_FR("Star"), + STR_DE("Star"), + STR_ES("Star"), + STR_JP("Star"), + STR_KO("Star"), + STR_TW("Star"), + }, + + [StrId_Actions_UnStar] = + { + STR_EN("UnStar"), + STR_FR("UnStar"), + STR_DE("UnStar"), + STR_ES("UnStar"), + STR_JP("UnStar"), + STR_KO("UnStar"), + STR_TW("UnStar"), + }, + [StrId_ThemeMenu] = { STR_EN("Theme Menu"), diff --git a/common/language.h b/common/language.h index d76839c..8bf1f34 100644 --- a/common/language.h +++ b/common/language.h @@ -23,6 +23,8 @@ typedef enum StrId_Actions_Open, StrId_Actions_Back, StrId_Actions_Apply, + StrId_Actions_Star, + StrId_Actions_UnStar, StrId_MsgBox_OK, diff --git a/common/menu-entry.c b/common/menu-entry.c index ed90336..9f17974 100644 --- a/common/menu-entry.c +++ b/common/menu-entry.c @@ -490,6 +490,13 @@ bool menuEntryLoad(menuEntry_s* me, const char* name, bool shortcut) { return false; } + //check for .filename.star in same path + strptr = getSlash(me->path); + if (strptr[0] == '/') strptr++; + snprintf(tempbuf, sizeof(tempbuf)-1, "%.*s.%.*s.star", (int)((strlen(me->path)) - (strlen(strptr))), me->path, (int)(strlen(strptr)), strptr); + strcpy(me->starpath, tempbuf); + me->starred = fileExists(me->starpath); + return true; } diff --git a/common/menu-list.c b/common/menu-list.c index d693f54..1073622 100644 --- a/common/menu-list.c +++ b/common/menu-list.c @@ -96,20 +96,32 @@ static void menuSort(void) { menu_s* m = &s_menu[!s_curMenu]; int nEntries = m->nEntries; if (nEntries==0) return; + int nEntriesStar = 0, nEntriesNoStar = 0; menuEntry_s** list = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*)); if(list == NULL) return; + menuEntry_s** listStar = (menuEntry_s**)calloc(nEntries, sizeof(menuEntry_s*)); + if(listStar == NULL) return; menuEntry_s* p = m->firstEntry; for(i = 0; i < nEntries; ++i) { - list[i] = p; + if (p->starred) { + listStar[nEntriesStar++] = p; + } else { + list[nEntriesNoStar++] = p; + } p = p->next; } - qsort(list, nEntries, sizeof(menuEntry_s*), menuEntryCmp); + qsort(listStar, nEntriesStar, sizeof(menuEntry_s*), menuEntryCmp); + qsort(list, nEntriesNoStar, sizeof(menuEntry_s*), menuEntryCmp); menuEntry_s** pp = &m->firstEntry; - for(i = 0; i < nEntries; ++i) { + for(i = 0; i < nEntriesStar; ++i) { + *pp = listStar[i]; + pp = &(*pp)->next; + } + for(i = 0; i < nEntriesNoStar; ++i) { *pp = list[i]; pp = &(*pp)->next; } @@ -117,6 +129,14 @@ static void menuSort(void) { *pp = NULL; free(list); + free(listStar); +} + +void menuReSort (void) { + s_curMenu = !s_curMenu; + menuSort(); + s_curMenu = !s_curMenu; + menuClear(); } int menuScan(const char* target) { diff --git a/common/menu.c b/common/menu.c index 3643763..9201ad4 100644 --- a/common/menu.c +++ b/common/menu.c @@ -1,6 +1,7 @@ #include #include "common.h" #include "netloader.h" +#include #ifndef __SWITCH__ #include "switch/runtime/nxlink.h" @@ -29,6 +30,39 @@ void launchMenuEntryTask(menuEntry_s* arg) { launchMenuEntry(me); } +void toggleStarState(menuEntry_s* arg) { + menuEntry_s* me = arg; + if (me->starred) + { + if (fileExists(me->starpath)) + remove(me->starpath); + } else { + if (!fileExists(me->starpath)) + { + int fd = open(me->starpath,O_CREAT|O_WRONLY, ACCESSPERMS); + close(fd); + } + } + me->starred = fileExists(me->starpath); + //todo: error handling/message? + + menuReSort(); + menu_s* menu = menuGetCurrent(); + menuEntry_s* meSearch = menu->firstEntry; + menu->curEntry = -1; + int i = 0; + while (menu->curEntry == -1) + { + if (me == meSearch) + { + menu->curEntry = i; + } else { + meSearch = meSearch->next; + i++; + } + } +} + static enum { HBMENU_DEFAULT, @@ -73,6 +107,19 @@ void menuHandleAButton(void) { } } +void menuHandleXButton(void) { + menu_s* menu = menuGetCurrent(); + + if (menu->nEntries > 0 && hbmenu_state == HBMENU_DEFAULT) + { + int i; + menuEntry_s* me; + for (i = 0, me = menu->firstEntry; i != menu->curEntry; i ++, me = me->next); + toggleStarState(me); + } +} + + void launchApplyThemeTask(menuEntry_s* arg) { const char* themePath = arg->path; SetThemePathToConfig(themePath); @@ -246,6 +293,8 @@ 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); + if (me->starred) + drawImage(start_x + 105 + 12, start_y - 12, 35, 33, themeCurrent.starSmallImage, IMAGE_MODE_RGBA32); } if (is_active && largeimg) { @@ -283,6 +332,14 @@ static void drawEntry(menuEntry_s* me, int off_x, int is_active) { 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); } + + if (me->starred) + { + drawImage(start_x - 64, 100, 64, 61, themeCurrent.starOnImage, IMAGE_MODE_RGBA32); + } else { + if (smallimg != theme_icon_small)//if (me->type != ENTRY_TYPE_THEME) <- why this crash? + drawImage(start_x - 64, 100, 64, 61, themeCurrent.starOffImage, IMAGE_MODE_RGBA32); + } } } @@ -666,6 +723,18 @@ void menuLoop(void) { } drawButtons(menu, false, &menupath_x_endpos); + + if(active_entry != NULL && active_entry->type != ENTRY_TYPE_THEME) { + getX = GetTextXCoordinate(interuiregular18, menupath_x_endpos - 32, textGetString(StrId_Actions_UnStar), 'r'); + DrawText(fontscale7, getX - 36, 720 - 47 + 24, themeCurrent.textColor, themeCurrent.buttonXText); + if (active_entry->starred) { + DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_UnStar)); + } else { + DrawText(interuiregular18, getX, 720 - 47 + 24, themeCurrent.textColor, textGetString(StrId_Actions_Star)); + } + menupath_x_endpos = getX - 36 - 40; + } + } DrawTextTruncate(interuiregular18, 40, 720 - 47 + 24, themeCurrent.textColor, menu->dirname, menupath_x_endpos - 40, "..."); diff --git a/common/menu.h b/common/menu.h index bd7894f..2208d59 100644 --- a/common/menu.h +++ b/common/menu.h @@ -51,6 +51,7 @@ struct menuEntry_s_tag MenuEntryType type; char path[PATH_MAX+8]; + char starpath[PATH_MAX+8]; argData_s args; bool fileassoc_type;//0=file_extension, 1 = filename @@ -64,6 +65,8 @@ struct menuEntry_s_tag size_t icon_size; uint8_t *icon_gfx; uint8_t *icon_gfx_small; + + bool starred; NacpStruct *nacp; }; @@ -97,11 +100,13 @@ void menuDeleteEntry(menuEntry_s* me, bool skip_icongfx); menu_s* menuGetCurrent(void); menu_s* menuFileassocGetCurrent(void); +void menuReSort (void); int menuScan(const char* target); int themeMenuScan(const char* target); int menuFileassocScan(const char* target); void launchMenuEntryTask(menuEntry_s* arg); +void toggleStarState(menuEntry_s* arg); void launchApplyThemeTask(menuEntry_s* arg); void launchMenuBackTask(); void launchMenuNetloaderTask(); @@ -109,6 +114,7 @@ char *menuGetRootPath(void); char *menuGetRootBasePath(void); void menuHandleAButton(void); +void menuHandleXButton(void); bool menuIsNetloaderActive(void); diff --git a/common/theme.c b/common/theme.c index c18853b..7b0bfd7 100644 --- a/common/theme.c +++ b/common/theme.c @@ -26,10 +26,14 @@ void themeStartup(ThemePreset preset) { .enableWaveBlending = 0, .buttonAText = "\uE0E0", .buttonBText = "\uE0E1", + .buttonXText = "\uE0E2", .buttonYText = "\uE0E3", .buttonPText = "\uE0EF", .buttonMText = "\uE0F0", - .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_light) + .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_light), + .starSmallImage = assetsGetDataBuffer(AssetId_star_small), + .starOnImage = assetsGetDataBuffer(AssetId_star_on), + .starOffImage = assetsGetDataBuffer(AssetId_star_off) }; theme_t themeDark = (theme_t) { @@ -46,10 +50,14 @@ void themeStartup(ThemePreset preset) { .enableWaveBlending = 0, .buttonAText = "\uE0A0", .buttonBText = "\uE0A1", + .buttonXText = "\uE0A2", .buttonYText = "\uE0A3", .buttonPText = "\uE0B3", .buttonMText = "\uE0B4", - .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark) + .hbmenuLogoImage = assetsGetDataBuffer(AssetId_hbmenu_logo_dark), + .starSmallImage = assetsGetDataBuffer(AssetId_star_small), + .starOnImage = assetsGetDataBuffer(AssetId_star_on), + .starOffImage = assetsGetDataBuffer(AssetId_star_off) }; char themePath[PATH_MAX] = {0}; @@ -61,7 +69,7 @@ void themeStartup(ThemePreset preset) { config_setting_t *theme = NULL; color_t text, frontWave, middleWave, backWave, background, highlight, separator, borderColor, borderTextColor, progressBarColor; int waveBlending; - const char *AText, *BText, *YText, *PText, *MText; + const char *AText, *BText, *XText, *YText, *PText, *MText; bool good_cfg = false; if(themePath[0]!=0) @@ -110,6 +118,8 @@ void themeStartup(ThemePreset preset) { AText = themeDefault->buttonAText; if (!config_setting_lookup_string(theme, "buttonBText", &BText)) BText = themeDefault->buttonBText; + if (!config_setting_lookup_string(theme, "buttonXText", &XText)) + XText = themeDefault->buttonXText; if (!config_setting_lookup_string(theme, "buttonYText", &YText)) YText = themeDefault->buttonYText; if (!config_setting_lookup_string(theme, "buttonPText", &PText)) @@ -132,6 +142,7 @@ void themeStartup(ThemePreset preset) { }; strncpy(themeCurrent.buttonAText, AText, sizeof(themeCurrent.buttonAText)-1); strncpy(themeCurrent.buttonBText, BText, sizeof(themeCurrent.buttonBText)-1); + strncpy(themeCurrent.buttonXText, XText, sizeof(themeCurrent.buttonXText)-1); strncpy(themeCurrent.buttonYText, YText, sizeof(themeCurrent.buttonYText)-1); strncpy(themeCurrent.buttonPText, PText, sizeof(themeCurrent.buttonPText)-1); strncpy(themeCurrent.buttonMText, MText, sizeof(themeCurrent.buttonMText)-1); diff --git a/common/theme.h b/common/theme.h index 65ef7d4..5869f4a 100644 --- a/common/theme.h +++ b/common/theme.h @@ -18,10 +18,14 @@ typedef struct bool enableWaveBlending; char buttonAText[32]; char buttonBText[32]; + char buttonXText[32]; char buttonYText[32]; char buttonPText[32]; char buttonMText[32]; const uint8_t *hbmenuLogoImage; + const uint8_t *starSmallImage; + const uint8_t *starOnImage; + const uint8_t *starOffImage; } theme_t; typedef enum diff --git a/nx_main/main.c b/nx_main/main.c index b968e7e..4b2a2c4 100644 --- a/nx_main/main.c +++ b/nx_main/main.c @@ -204,6 +204,10 @@ bool menuUpdate(void) { { launchMenuNetloaderTask(); } + else if (down & KEY_X) + { + menuHandleXButton(); + } else if (down & KEY_A) { menuHandleAButton(); diff --git a/nx_main/nx_touch.c b/nx_main/nx_touch.c index 1584033..593997b 100644 --- a/nx_main/nx_touch.c +++ b/nx_main/nx_touch.c @@ -13,6 +13,11 @@ #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))) @@ -127,6 +132,16 @@ void handleTouch(menu_s* 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(); + } + } } // Vertical Swipe else if (abs(x1 - x2) < VERTICAL_SWIPE_HORIZONTAL_PLAY && distance(x1, y1, x2, y2) > VERTICAL_SWIPE_MINIMUM_DISTANCE) { diff --git a/pc_main/main.cpp b/pc_main/main.cpp index f038dc7..dd1b574 100644 --- a/pc_main/main.cpp +++ b/pc_main/main.cpp @@ -74,6 +74,8 @@ extern "C" bool menuUpdate(void) { int new_esc_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Escape); static int return_state = 0; int new_return_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Return); + static int x_state = 0; + int new_x_state = sf::Keyboard::isKeyPressed(sf::Keyboard::X); static int y_state = 0; int new_y_state = sf::Keyboard::isKeyPressed(sf::Keyboard::Y); static int t_state = 0; @@ -85,6 +87,12 @@ extern "C" bool menuUpdate(void) { } + if(!new_x_state && x_state) + { + menuHandleXButton(); + + } + if (!new_esc_state && esc_state) { launchMenuBackTask(); diff --git a/resources/star_off.png b/resources/star_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e52b4e1f3ba3ae0b593f791d24012e036dd85763 GIT binary patch literal 4496 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 E0`Y!j5dZ)H literal 0 HcmV?d00001