mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-04-06 03:58:02 +08:00
Add filter options.
This commit is contained in:
parent
e73b07bbd8
commit
b87332ff68
@ -4,4 +4,6 @@ sd=FF00FF00
|
||||
gamecard=FFFF0000
|
||||
dstitle=FF82004B
|
||||
file=FF000000
|
||||
directory=FF0000FF
|
||||
directory=FF0000FF
|
||||
enabled=FF00FF00
|
||||
disabled=FF0000FF
|
@ -203,6 +203,10 @@ void screen_init() {
|
||||
colorConfig[COLOR_FILE] = color;
|
||||
} else if(strcasecmp(key, "directory") == 0) {
|
||||
colorConfig[COLOR_DIRECTORY] = color;
|
||||
} else if(strcasecmp(key, "enabled") == 0) {
|
||||
colorConfig[COLOR_ENABLED] = color;
|
||||
} else if(strcasecmp(key, "disabled") == 0) {
|
||||
colorConfig[COLOR_DISABLED] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@
|
||||
#define TEXTURE_WIFI_3 30
|
||||
#define TEXTURE_AUTO_START 31
|
||||
|
||||
#define NUM_COLORS 7
|
||||
#define NUM_COLORS 9
|
||||
|
||||
#define COLOR_TEXT 0
|
||||
#define COLOR_NAND 1
|
||||
@ -50,6 +50,8 @@
|
||||
#define COLOR_DS_TITLE 4
|
||||
#define COLOR_FILE 5
|
||||
#define COLOR_DIRECTORY 6
|
||||
#define COLOR_ENABLED 7
|
||||
#define COLOR_DISABLED 8
|
||||
|
||||
void screen_init();
|
||||
void screen_exit();
|
||||
|
@ -19,6 +19,9 @@ static list_item delete_save_data = {"Delete Save Data", COLOR_TEXT, action_dele
|
||||
typedef struct {
|
||||
populate_ext_save_data_data populateData;
|
||||
|
||||
bool showSD;
|
||||
bool showNAND;
|
||||
|
||||
bool populated;
|
||||
} extsavedata_data;
|
||||
|
||||
@ -77,6 +80,54 @@ static void extsavedata_action_open(linked_list* items, list_item* selected) {
|
||||
list_display("Ext Save Data Action", "A: Select, B: Return", data, extsavedata_action_update, extsavedata_action_draw_top);
|
||||
}
|
||||
|
||||
static void extsavedata_filters_add_entry(linked_list* items, const char* name, bool* val) {
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
if(item != NULL) {
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%s", name);
|
||||
item->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
item->data = val;
|
||||
|
||||
linked_list_add(items, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void extsavedata_filters_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
|
||||
extsavedata_data* listData = (extsavedata_data*) data;
|
||||
|
||||
if(hidKeysDown() & KEY_B) {
|
||||
linked_list_iter iter;
|
||||
linked_list_iterate(items, &iter);
|
||||
|
||||
while(linked_list_iter_has_next(&iter)) {
|
||||
free(linked_list_iter_next(&iter));
|
||||
linked_list_iter_remove(&iter);
|
||||
}
|
||||
|
||||
ui_pop();
|
||||
list_destroy(view);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
|
||||
bool* val = (bool*) selected->data;
|
||||
*val = !(*val);
|
||||
|
||||
selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
|
||||
listData->populated = false;
|
||||
}
|
||||
|
||||
if(linked_list_size(items) == 0) {
|
||||
extsavedata_filters_add_entry(items, "Show SD", &listData->showSD);
|
||||
extsavedata_filters_add_entry(items, "Show NAND", &listData->showNAND);
|
||||
}
|
||||
}
|
||||
|
||||
static void extsavedata_filters_open(extsavedata_data* data) {
|
||||
list_display("Filters", "A: Toggle, B: Return", data, extsavedata_filters_update, NULL);
|
||||
}
|
||||
|
||||
static void extsavedata_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected) {
|
||||
if(selected != NULL && selected->data != NULL) {
|
||||
ui_draw_ext_save_data_info(view, selected->data, x1, y1, x2, y2);
|
||||
@ -103,6 +154,11 @@ static void extsavedata_update(ui_view* view, void* data, linked_list* items, li
|
||||
return;
|
||||
}
|
||||
|
||||
if(hidKeysDown() & KEY_SELECT) {
|
||||
extsavedata_filters_open(listData);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!listData->populated || (hidKeysDown() & KEY_X)) {
|
||||
if(!listData->populateData.finished) {
|
||||
svcSignalEvent(listData->populateData.cancelEvent);
|
||||
@ -132,6 +188,16 @@ static void extsavedata_update(ui_view* view, void* data, linked_list* items, li
|
||||
}
|
||||
}
|
||||
|
||||
static bool extsavedata_filter(void* data, u64 titleId, FS_MediaType mediaType) {
|
||||
extsavedata_data* listData = (extsavedata_data*) data;
|
||||
|
||||
if(mediaType == MEDIATYPE_SD) {
|
||||
return listData->showSD;
|
||||
} else {
|
||||
return listData->showNAND;
|
||||
}
|
||||
}
|
||||
|
||||
void extsavedata_open() {
|
||||
extsavedata_data* data = (extsavedata_data*) calloc(1, sizeof(extsavedata_data));
|
||||
if(data == NULL) {
|
||||
@ -140,7 +206,13 @@ void extsavedata_open() {
|
||||
return;
|
||||
}
|
||||
|
||||
data->populateData.filter = extsavedata_filter;
|
||||
data->populateData.filterData = data;
|
||||
|
||||
data->populateData.finished = true;
|
||||
|
||||
list_display("Ext Save Data", "A: Select, B: Return, X: Refresh", data, extsavedata_update, extsavedata_draw_top);
|
||||
data->showSD = true;
|
||||
data->showNAND = true;
|
||||
|
||||
list_display("Ext Save Data", "A: Select, B: Return, X: Refresh, Select: Filter", data, extsavedata_update, extsavedata_draw_top);
|
||||
}
|
@ -48,6 +48,11 @@ typedef struct {
|
||||
FS_Path archivePath;
|
||||
FS_Archive archive;
|
||||
|
||||
bool showDirectories;
|
||||
bool showCias;
|
||||
bool showTickets;
|
||||
bool showMisc;
|
||||
|
||||
char currDir[FILE_PATH_MAX];
|
||||
list_item* dirItem;
|
||||
} files_data;
|
||||
@ -152,6 +157,56 @@ static void files_action_open(linked_list* items, list_item* selected, files_dat
|
||||
list_display(((file_info*) selected->data)->isDirectory ? "Directory Action" : "File Action", "A: Select, B: Return", data, files_action_update, files_action_draw_top);
|
||||
}
|
||||
|
||||
static void files_filters_add_entry(linked_list* items, const char* name, bool* val) {
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
if(item != NULL) {
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%s", name);
|
||||
item->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
item->data = val;
|
||||
|
||||
linked_list_add(items, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void files_filters_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
|
||||
files_data* listData = (files_data*) data;
|
||||
|
||||
if(hidKeysDown() & KEY_B) {
|
||||
linked_list_iter iter;
|
||||
linked_list_iterate(items, &iter);
|
||||
|
||||
while(linked_list_iter_has_next(&iter)) {
|
||||
free(linked_list_iter_next(&iter));
|
||||
linked_list_iter_remove(&iter);
|
||||
}
|
||||
|
||||
ui_pop();
|
||||
list_destroy(view);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
|
||||
bool* val = (bool*) selected->data;
|
||||
*val = !(*val);
|
||||
|
||||
selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
|
||||
listData->populated = false;
|
||||
}
|
||||
|
||||
if(linked_list_size(items) == 0) {
|
||||
files_filters_add_entry(items, "Show directories", &listData->showDirectories);
|
||||
files_filters_add_entry(items, "Show CIAs", &listData->showCias);
|
||||
files_filters_add_entry(items, "Show tickets", &listData->showTickets);
|
||||
files_filters_add_entry(items, "Show miscellaneous", &listData->showMisc);
|
||||
}
|
||||
}
|
||||
|
||||
static void files_filters_open(files_data* data) {
|
||||
list_display("Filters", "A: Toggle, B: Return", data, files_filters_update, NULL);
|
||||
}
|
||||
|
||||
static void files_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected) {
|
||||
if(selected != NULL && selected->data != NULL) {
|
||||
ui_draw_file_info(view, selected->data, x1, y1, x2, y2);
|
||||
@ -246,6 +301,11 @@ static void files_update(ui_view* view, void* data, linked_list* items, list_ite
|
||||
}
|
||||
}
|
||||
|
||||
if(hidKeysDown() & KEY_SELECT) {
|
||||
files_filters_open(listData);
|
||||
return;
|
||||
}
|
||||
|
||||
if((hidKeysDown() & KEY_Y) && listData->dirItem != NULL) {
|
||||
files_action_open(items, listData->dirItem, listData);
|
||||
return;
|
||||
@ -273,6 +333,26 @@ static void files_update(ui_view* view, void* data, linked_list* items, list_ite
|
||||
}
|
||||
}
|
||||
|
||||
static bool files_filter(void* data, const char* name, u32 attributes) {
|
||||
files_data* listData = (files_data*) data;
|
||||
|
||||
if((attributes & FS_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
return listData->showDirectories;
|
||||
} else {
|
||||
size_t len = strlen(name);
|
||||
if(len >= 4) {
|
||||
const char* extension = name + len - 4;
|
||||
if(strncmp(extension, ".cia", 4) == 0) {
|
||||
return listData->showCias;
|
||||
} else if(strncmp(extension, ".tik", 4) == 0) {
|
||||
return listData->showTickets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return listData->showMisc;
|
||||
}
|
||||
|
||||
void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
|
||||
files_data* data = (files_data*) calloc(1, sizeof(files_data));
|
||||
if(data == NULL) {
|
||||
@ -285,10 +365,18 @@ void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
|
||||
data->populateData.includeBase = false;
|
||||
data->populateData.dirsFirst = true;
|
||||
|
||||
data->populateData.filter = files_filter;
|
||||
data->populateData.filterData = data;
|
||||
|
||||
data->populateData.finished = true;
|
||||
|
||||
data->populated = false;
|
||||
|
||||
data->showDirectories = true;
|
||||
data->showCias = true;
|
||||
data->showTickets = true;
|
||||
data->showMisc = true;
|
||||
|
||||
data->archiveId = archiveId;
|
||||
data->archivePath.type = archivePath.type;
|
||||
data->archivePath.size = archivePath.size;
|
||||
@ -317,7 +405,7 @@ void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("Files", "A: Select, B: Back, X: Refresh, Y: Directory Action", data, files_update, files_draw_top);
|
||||
list_display("Files", "A: Select, B: Back, X: Refresh, Y: Dir, Select: Filter", data, files_update, files_draw_top);
|
||||
}
|
||||
|
||||
void files_open_sd() {
|
||||
|
@ -35,73 +35,75 @@ static Result task_populate_ext_save_data_from(populate_ext_save_data_data* data
|
||||
break;
|
||||
}
|
||||
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
if(item != NULL) {
|
||||
ext_save_data_info* extSaveDataInfo = (ext_save_data_info*) calloc(1, sizeof(ext_save_data_info));
|
||||
if(extSaveDataInfo != NULL) {
|
||||
extSaveDataInfo->mediaType = mediaType;
|
||||
extSaveDataInfo->extSaveDataId = extSaveDataIds[i];
|
||||
extSaveDataInfo->shared = mediaType == MEDIATYPE_NAND;
|
||||
extSaveDataInfo->hasMeta = false;
|
||||
if(data->filter == NULL || data->filter(data->filterData, extSaveDataIds[i], mediaType)) {
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
if(item != NULL) {
|
||||
ext_save_data_info* extSaveDataInfo = (ext_save_data_info*) calloc(1, sizeof(ext_save_data_info));
|
||||
if(extSaveDataInfo != NULL) {
|
||||
extSaveDataInfo->mediaType = mediaType;
|
||||
extSaveDataInfo->extSaveDataId = extSaveDataIds[i];
|
||||
extSaveDataInfo->shared = mediaType == MEDIATYPE_NAND;
|
||||
extSaveDataInfo->hasMeta = false;
|
||||
|
||||
FS_ExtSaveDataInfo info = {.mediaType = mediaType, .saveId = extSaveDataIds[i]};
|
||||
FS_ExtSaveDataInfo info = {.mediaType = mediaType, .saveId = extSaveDataIds[i]};
|
||||
|
||||
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
||||
if(smdh != NULL) {
|
||||
u32 smdhBytesRead = 0;
|
||||
if(R_SUCCEEDED(FSUSER_ReadExtSaveDataIcon(&smdhBytesRead, info, sizeof(SMDH), (u8*) smdh)) && smdhBytesRead == sizeof(SMDH)) {
|
||||
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
||||
u8 systemLanguage = CFG_LANGUAGE_EN;
|
||||
CFGU_GetSystemLanguage(&systemLanguage);
|
||||
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
||||
if(smdh != NULL) {
|
||||
u32 smdhBytesRead = 0;
|
||||
if(R_SUCCEEDED(FSUSER_ReadExtSaveDataIcon(&smdhBytesRead, info, sizeof(SMDH), (u8*) smdh)) && smdhBytesRead == sizeof(SMDH)) {
|
||||
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
||||
u8 systemLanguage = CFG_LANGUAGE_EN;
|
||||
CFGU_GetSystemLanguage(&systemLanguage);
|
||||
|
||||
utf16_to_utf8((uint8_t*) item->name, smdh->titles[systemLanguage].shortDescription, LIST_ITEM_NAME_MAX - 1);
|
||||
utf16_to_utf8((uint8_t*) item->name, smdh->titles[systemLanguage].shortDescription, LIST_ITEM_NAME_MAX - 1);
|
||||
|
||||
extSaveDataInfo->hasMeta = true;
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(extSaveDataInfo->meta.shortDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(extSaveDataInfo->meta.longDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(extSaveDataInfo->meta.publisher) - 1);
|
||||
extSaveDataInfo->meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
||||
extSaveDataInfo->hasMeta = true;
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.shortDescription, smdh->titles[systemLanguage].shortDescription, sizeof(extSaveDataInfo->meta.shortDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.longDescription, smdh->titles[systemLanguage].longDescription, sizeof(extSaveDataInfo->meta.longDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) extSaveDataInfo->meta.publisher, smdh->titles[systemLanguage].publisher, sizeof(extSaveDataInfo->meta.publisher) - 1);
|
||||
extSaveDataInfo->meta.texture = screen_load_texture_tiled_auto(smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
||||
}
|
||||
}
|
||||
|
||||
free(smdh);
|
||||
}
|
||||
|
||||
bool empty = strlen(item->name) == 0;
|
||||
if(!empty) {
|
||||
empty = true;
|
||||
|
||||
char* curr = item->name;
|
||||
while(*curr) {
|
||||
if(*curr != ' ') {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
|
||||
free(smdh);
|
||||
}
|
||||
|
||||
bool empty = strlen(item->name) == 0;
|
||||
if(!empty) {
|
||||
empty = true;
|
||||
|
||||
char* curr = item->name;
|
||||
while(*curr) {
|
||||
if(*curr != ' ') {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
|
||||
curr++;
|
||||
if(empty) {
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%016llX", extSaveDataIds[i]);
|
||||
}
|
||||
|
||||
if(mediaType == MEDIATYPE_NAND) {
|
||||
item->color = COLOR_NAND;
|
||||
} else if(mediaType == MEDIATYPE_SD) {
|
||||
item->color = COLOR_SD;
|
||||
}
|
||||
|
||||
item->data = extSaveDataInfo;
|
||||
|
||||
linked_list_add(data->items, item);
|
||||
} else {
|
||||
free(item);
|
||||
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(empty) {
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%016llX", extSaveDataIds[i]);
|
||||
}
|
||||
|
||||
if(mediaType == MEDIATYPE_NAND) {
|
||||
item->color = COLOR_NAND;
|
||||
} else if(mediaType == MEDIATYPE_SD) {
|
||||
item->color = COLOR_SD;
|
||||
}
|
||||
|
||||
item->data = extSaveDataInfo;
|
||||
|
||||
linked_list_add(data->items, item);
|
||||
} else {
|
||||
free(item);
|
||||
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <3ds.h>
|
||||
#include <3ds/services/fs.h>
|
||||
|
||||
#include "task.h"
|
||||
#include "../../list.h"
|
||||
@ -192,25 +193,27 @@ static void task_populate_files_thread(void* arg) {
|
||||
char name[FILE_NAME_MAX] = {'\0'};
|
||||
utf16_to_utf8((uint8_t*) name, entries[i].name, FILE_NAME_MAX - 1);
|
||||
|
||||
char path[FILE_PATH_MAX] = {'\0'};
|
||||
snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name);
|
||||
if(data->filter == NULL || data->filter(data->filterData, name, entries[i].attributes)) {
|
||||
char path[FILE_PATH_MAX] = {'\0'};
|
||||
snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name);
|
||||
|
||||
list_item* item = NULL;
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) {
|
||||
if(curr->isDirectory && strncmp(curr->path, data->base->path, FILE_PATH_MAX) == 0) {
|
||||
file_info* info = (file_info*) item->data;
|
||||
list_item* item = NULL;
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) {
|
||||
if(curr->isDirectory && strncmp(curr->path, data->base->path, FILE_PATH_MAX) == 0) {
|
||||
file_info* info = (file_info*) item->data;
|
||||
|
||||
if(info->isCia) {
|
||||
data->base->containsCias = true;
|
||||
} else if(info->isTicket) {
|
||||
data->base->containsTickets = true;
|
||||
if(info->isCia) {
|
||||
data->base->containsCias = true;
|
||||
} else if(info->isTicket) {
|
||||
data->base->containsTickets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(data->recursive && ((file_info*) item->data)->isDirectory) {
|
||||
linked_list_add(&queue, item);
|
||||
} else {
|
||||
linked_list_add(data->items, item);
|
||||
if(data->recursive && ((file_info*) item->data)->isDirectory) {
|
||||
linked_list_add(&queue, item);
|
||||
} else {
|
||||
linked_list_add(data->items, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,12 +273,14 @@ static Result task_populate_titles_from(populate_titles_data* data, FS_MediaType
|
||||
break;
|
||||
}
|
||||
|
||||
bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0;
|
||||
if(dsiWare != useDSiWare) {
|
||||
continue;
|
||||
}
|
||||
if(data->filter == NULL || data->filter(data->filterData, titleIds[i], mediaType)) {
|
||||
bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0;
|
||||
if(dsiWare != useDSiWare) {
|
||||
continue;
|
||||
}
|
||||
|
||||
res = dsiWare ? task_populate_titles_add_twl(data, mediaType, titleIds[i]) : task_populate_titles_add_ctr(data, mediaType, titleIds[i]);
|
||||
res = dsiWare ? task_populate_titles_add_twl(data, mediaType, titleIds[i]) : task_populate_titles_add_ctr(data, mediaType, titleIds[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,9 @@ typedef struct data_op_info_s {
|
||||
typedef struct {
|
||||
linked_list* items;
|
||||
|
||||
bool (*filter)(void* data, u64 extSaveDataId, FS_MediaType mediaType);
|
||||
void* filterData;
|
||||
|
||||
volatile bool finished;
|
||||
Result result;
|
||||
Handle cancelEvent;
|
||||
@ -144,6 +147,9 @@ typedef struct {
|
||||
bool includeBase;
|
||||
bool dirsFirst;
|
||||
|
||||
bool (*filter)(void* data, const char* name, u32 attributes);
|
||||
void* filterData;
|
||||
|
||||
volatile bool finished;
|
||||
Result result;
|
||||
Handle cancelEvent;
|
||||
@ -176,6 +182,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
linked_list* items;
|
||||
|
||||
bool (*filter)(void* data, u64 titleId, FS_MediaType mediaType);
|
||||
void* filterData;
|
||||
|
||||
volatile bool finished;
|
||||
Result result;
|
||||
Handle cancelEvent;
|
||||
|
@ -24,6 +24,10 @@ static list_item delete_secure_value = {"Delete Secure Value", COLOR_TEXT, actio
|
||||
typedef struct {
|
||||
populate_titles_data populateData;
|
||||
|
||||
bool showGameCard;
|
||||
bool showSD;
|
||||
bool showNAND;
|
||||
|
||||
bool populated;
|
||||
} titles_data;
|
||||
|
||||
@ -102,6 +106,55 @@ static void titles_action_open(linked_list* items, list_item* selected) {
|
||||
list_display("Title Action", "A: Select, B: Return", data, titles_action_update, titles_action_draw_top);
|
||||
}
|
||||
|
||||
static void titles_filters_add_entry(linked_list* items, const char* name, bool* val) {
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
if(item != NULL) {
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%s", name);
|
||||
item->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
item->data = val;
|
||||
|
||||
linked_list_add(items, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void titles_filters_update(ui_view* view, void* data, linked_list* items, list_item* selected, bool selectedTouched) {
|
||||
titles_data* listData = (titles_data*) data;
|
||||
|
||||
if(hidKeysDown() & KEY_B) {
|
||||
linked_list_iter iter;
|
||||
linked_list_iterate(items, &iter);
|
||||
|
||||
while(linked_list_iter_has_next(&iter)) {
|
||||
free(linked_list_iter_next(&iter));
|
||||
linked_list_iter_remove(&iter);
|
||||
}
|
||||
|
||||
ui_pop();
|
||||
list_destroy(view);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(selected != NULL && selected->data != NULL && (selectedTouched || (hidKeysDown() & KEY_A))) {
|
||||
bool* val = (bool*) selected->data;
|
||||
*val = !(*val);
|
||||
|
||||
selected->color = *val ? COLOR_ENABLED : COLOR_DISABLED;
|
||||
|
||||
listData->populated = false;
|
||||
}
|
||||
|
||||
if(linked_list_size(items) == 0) {
|
||||
titles_filters_add_entry(items, "Show game card", &listData->showGameCard);
|
||||
titles_filters_add_entry(items, "Show SD", &listData->showSD);
|
||||
titles_filters_add_entry(items, "Show NAND", &listData->showNAND);
|
||||
}
|
||||
}
|
||||
|
||||
static void titles_filters_open(titles_data* data) {
|
||||
list_display("Filters", "A: Toggle, B: Return", data, titles_filters_update, NULL);
|
||||
}
|
||||
|
||||
static void titles_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected) {
|
||||
if(selected != NULL && selected->data != NULL) {
|
||||
ui_draw_title_info(view, selected->data, x1, y1, x2, y2);
|
||||
@ -128,6 +181,11 @@ static void titles_update(ui_view* view, void* data, linked_list* items, list_it
|
||||
return;
|
||||
}
|
||||
|
||||
if(hidKeysDown() & KEY_SELECT) {
|
||||
titles_filters_open(listData);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!listData->populated || (hidKeysDown() & KEY_X)) {
|
||||
if(!listData->populateData.finished) {
|
||||
svcSignalEvent(listData->populateData.cancelEvent);
|
||||
@ -157,6 +215,18 @@ static void titles_update(ui_view* view, void* data, linked_list* items, list_it
|
||||
}
|
||||
}
|
||||
|
||||
static bool titles_filter(void* data, u64 titleId, FS_MediaType mediaType) {
|
||||
titles_data* listData = (titles_data*) data;
|
||||
|
||||
if(mediaType == MEDIATYPE_GAME_CARD) {
|
||||
return listData->showGameCard;
|
||||
} else if(mediaType == MEDIATYPE_SD) {
|
||||
return listData->showSD;
|
||||
} else {
|
||||
return listData->showNAND;
|
||||
}
|
||||
}
|
||||
|
||||
void titles_open() {
|
||||
titles_data* data = (titles_data*) calloc(1, sizeof(titles_data));
|
||||
if(data == NULL) {
|
||||
@ -165,7 +235,14 @@ void titles_open() {
|
||||
return;
|
||||
}
|
||||
|
||||
data->populateData.filter = titles_filter;
|
||||
data->populateData.filterData = data;
|
||||
|
||||
data->populateData.finished = true;
|
||||
|
||||
list_display("Titles", "A: Select, B: Return, X: Refresh", data, titles_update, titles_draw_top);
|
||||
data->showGameCard = true;
|
||||
data->showSD = true;
|
||||
data->showNAND = true;
|
||||
|
||||
list_display("Titles", "A: Select, B: Return, X: Refresh, Select: Filter", data, titles_update, titles_draw_top);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user