Add filter options.

This commit is contained in:
Steven Smith 2016-05-26 20:46:03 -07:00
parent e73b07bbd8
commit b87332ff68
10 changed files with 341 additions and 80 deletions

View File

@ -5,3 +5,5 @@ gamecard=FFFF0000
dstitle=FF82004B dstitle=FF82004B
file=FF000000 file=FF000000
directory=FF0000FF directory=FF0000FF
enabled=FF00FF00
disabled=FF0000FF

View File

@ -203,6 +203,10 @@ void screen_init() {
colorConfig[COLOR_FILE] = color; colorConfig[COLOR_FILE] = color;
} else if(strcasecmp(key, "directory") == 0) { } else if(strcasecmp(key, "directory") == 0) {
colorConfig[COLOR_DIRECTORY] = color; colorConfig[COLOR_DIRECTORY] = color;
} else if(strcasecmp(key, "enabled") == 0) {
colorConfig[COLOR_ENABLED] = color;
} else if(strcasecmp(key, "disabled") == 0) {
colorConfig[COLOR_DISABLED] = color;
} }
} }
} }

View File

@ -41,7 +41,7 @@
#define TEXTURE_WIFI_3 30 #define TEXTURE_WIFI_3 30
#define TEXTURE_AUTO_START 31 #define TEXTURE_AUTO_START 31
#define NUM_COLORS 7 #define NUM_COLORS 9
#define COLOR_TEXT 0 #define COLOR_TEXT 0
#define COLOR_NAND 1 #define COLOR_NAND 1
@ -50,6 +50,8 @@
#define COLOR_DS_TITLE 4 #define COLOR_DS_TITLE 4
#define COLOR_FILE 5 #define COLOR_FILE 5
#define COLOR_DIRECTORY 6 #define COLOR_DIRECTORY 6
#define COLOR_ENABLED 7
#define COLOR_DISABLED 8
void screen_init(); void screen_init();
void screen_exit(); void screen_exit();

View File

@ -19,6 +19,9 @@ static list_item delete_save_data = {"Delete Save Data", COLOR_TEXT, action_dele
typedef struct { typedef struct {
populate_ext_save_data_data populateData; populate_ext_save_data_data populateData;
bool showSD;
bool showNAND;
bool populated; bool populated;
} extsavedata_data; } 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); 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) { 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) { if(selected != NULL && selected->data != NULL) {
ui_draw_ext_save_data_info(view, selected->data, x1, y1, x2, y2); 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; return;
} }
if(hidKeysDown() & KEY_SELECT) {
extsavedata_filters_open(listData);
return;
}
if(!listData->populated || (hidKeysDown() & KEY_X)) { if(!listData->populated || (hidKeysDown() & KEY_X)) {
if(!listData->populateData.finished) { if(!listData->populateData.finished) {
svcSignalEvent(listData->populateData.cancelEvent); 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() { void extsavedata_open() {
extsavedata_data* data = (extsavedata_data*) calloc(1, sizeof(extsavedata_data)); extsavedata_data* data = (extsavedata_data*) calloc(1, sizeof(extsavedata_data));
if(data == NULL) { if(data == NULL) {
@ -140,7 +206,13 @@ void extsavedata_open() {
return; return;
} }
data->populateData.filter = extsavedata_filter;
data->populateData.filterData = data;
data->populateData.finished = true; 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);
} }

View File

@ -48,6 +48,11 @@ typedef struct {
FS_Path archivePath; FS_Path archivePath;
FS_Archive archive; FS_Archive archive;
bool showDirectories;
bool showCias;
bool showTickets;
bool showMisc;
char currDir[FILE_PATH_MAX]; char currDir[FILE_PATH_MAX];
list_item* dirItem; list_item* dirItem;
} files_data; } 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); 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) { 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) { if(selected != NULL && selected->data != NULL) {
ui_draw_file_info(view, selected->data, x1, y1, x2, y2); 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) { if((hidKeysDown() & KEY_Y) && listData->dirItem != NULL) {
files_action_open(items, listData->dirItem, listData); files_action_open(items, listData->dirItem, listData);
return; 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) { void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
files_data* data = (files_data*) calloc(1, sizeof(files_data)); files_data* data = (files_data*) calloc(1, sizeof(files_data));
if(data == NULL) { if(data == NULL) {
@ -285,10 +365,18 @@ void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
data->populateData.includeBase = false; data->populateData.includeBase = false;
data->populateData.dirsFirst = true; data->populateData.dirsFirst = true;
data->populateData.filter = files_filter;
data->populateData.filterData = data;
data->populateData.finished = true; data->populateData.finished = true;
data->populated = false; data->populated = false;
data->showDirectories = true;
data->showCias = true;
data->showTickets = true;
data->showMisc = true;
data->archiveId = archiveId; data->archiveId = archiveId;
data->archivePath.type = archivePath.type; data->archivePath.type = archivePath.type;
data->archivePath.size = archivePath.size; data->archivePath.size = archivePath.size;
@ -317,7 +405,7 @@ void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
return; 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() { void files_open_sd() {

View File

@ -35,73 +35,75 @@ static Result task_populate_ext_save_data_from(populate_ext_save_data_data* data
break; break;
} }
list_item* item = (list_item*) calloc(1, sizeof(list_item)); if(data->filter == NULL || data->filter(data->filterData, extSaveDataIds[i], mediaType)) {
if(item != NULL) { list_item* item = (list_item*) calloc(1, sizeof(list_item));
ext_save_data_info* extSaveDataInfo = (ext_save_data_info*) calloc(1, sizeof(ext_save_data_info)); if(item != NULL) {
if(extSaveDataInfo != NULL) { ext_save_data_info* extSaveDataInfo = (ext_save_data_info*) calloc(1, sizeof(ext_save_data_info));
extSaveDataInfo->mediaType = mediaType; if(extSaveDataInfo != NULL) {
extSaveDataInfo->extSaveDataId = extSaveDataIds[i]; extSaveDataInfo->mediaType = mediaType;
extSaveDataInfo->shared = mediaType == MEDIATYPE_NAND; extSaveDataInfo->extSaveDataId = extSaveDataIds[i];
extSaveDataInfo->hasMeta = false; 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)); SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
if(smdh != NULL) { if(smdh != NULL) {
u32 smdhBytesRead = 0; u32 smdhBytesRead = 0;
if(R_SUCCEEDED(FSUSER_ReadExtSaveDataIcon(&smdhBytesRead, info, sizeof(SMDH), (u8*) smdh)) && smdhBytesRead == sizeof(SMDH)) { 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') { if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
u8 systemLanguage = CFG_LANGUAGE_EN; u8 systemLanguage = CFG_LANGUAGE_EN;
CFGU_GetSystemLanguage(&systemLanguage); 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; 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.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.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); 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->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); if(empty) {
} snprintf(item->name, LIST_ITEM_NAME_MAX, "%016llX", extSaveDataIds[i]);
bool empty = strlen(item->name) == 0;
if(!empty) {
empty = true;
char* curr = item->name;
while(*curr) {
if(*curr != ' ') {
empty = false;
break;
}
curr++;
} }
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 { } else {
free(item);
res = R_FBI_OUT_OF_MEMORY; res = R_FBI_OUT_OF_MEMORY;
} }
} else {
res = R_FBI_OUT_OF_MEMORY;
} }
} }
} }

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <3ds.h> #include <3ds.h>
#include <3ds/services/fs.h>
#include "task.h" #include "task.h"
#include "../../list.h" #include "../../list.h"
@ -192,25 +193,27 @@ static void task_populate_files_thread(void* arg) {
char name[FILE_NAME_MAX] = {'\0'}; char name[FILE_NAME_MAX] = {'\0'};
utf16_to_utf8((uint8_t*) name, entries[i].name, FILE_NAME_MAX - 1); utf16_to_utf8((uint8_t*) name, entries[i].name, FILE_NAME_MAX - 1);
char path[FILE_PATH_MAX] = {'\0'}; if(data->filter == NULL || data->filter(data->filterData, name, entries[i].attributes)) {
snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name); char path[FILE_PATH_MAX] = {'\0'};
snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name);
list_item* item = NULL; list_item* item = NULL;
if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path))) { 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) { if(curr->isDirectory && strncmp(curr->path, data->base->path, FILE_PATH_MAX) == 0) {
file_info* info = (file_info*) item->data; file_info* info = (file_info*) item->data;
if(info->isCia) { if(info->isCia) {
data->base->containsCias = true; data->base->containsCias = true;
} else if(info->isTicket) { } else if(info->isTicket) {
data->base->containsTickets = true; data->base->containsTickets = true;
}
} }
}
if(data->recursive && ((file_info*) item->data)->isDirectory) { if(data->recursive && ((file_info*) item->data)->isDirectory) {
linked_list_add(&queue, item); linked_list_add(&queue, item);
} else { } else {
linked_list_add(data->items, item); linked_list_add(data->items, item);
}
} }
} }
} }

View File

@ -273,12 +273,14 @@ static Result task_populate_titles_from(populate_titles_data* data, FS_MediaType
break; break;
} }
bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0; if(data->filter == NULL || data->filter(data->filterData, titleIds[i], mediaType)) {
if(dsiWare != useDSiWare) { bool dsiWare = ((titleIds[i] >> 32) & 0x8000) != 0;
continue; 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]);
}
} }
} }

View File

@ -130,6 +130,9 @@ typedef struct data_op_info_s {
typedef struct { typedef struct {
linked_list* items; linked_list* items;
bool (*filter)(void* data, u64 extSaveDataId, FS_MediaType mediaType);
void* filterData;
volatile bool finished; volatile bool finished;
Result result; Result result;
Handle cancelEvent; Handle cancelEvent;
@ -144,6 +147,9 @@ typedef struct {
bool includeBase; bool includeBase;
bool dirsFirst; bool dirsFirst;
bool (*filter)(void* data, const char* name, u32 attributes);
void* filterData;
volatile bool finished; volatile bool finished;
Result result; Result result;
Handle cancelEvent; Handle cancelEvent;
@ -176,6 +182,9 @@ typedef struct {
typedef struct { typedef struct {
linked_list* items; linked_list* items;
bool (*filter)(void* data, u64 titleId, FS_MediaType mediaType);
void* filterData;
volatile bool finished; volatile bool finished;
Result result; Result result;
Handle cancelEvent; Handle cancelEvent;

View File

@ -24,6 +24,10 @@ static list_item delete_secure_value = {"Delete Secure Value", COLOR_TEXT, actio
typedef struct { typedef struct {
populate_titles_data populateData; populate_titles_data populateData;
bool showGameCard;
bool showSD;
bool showNAND;
bool populated; bool populated;
} titles_data; } 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); 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) { 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) { if(selected != NULL && selected->data != NULL) {
ui_draw_title_info(view, selected->data, x1, y1, x2, y2); 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; return;
} }
if(hidKeysDown() & KEY_SELECT) {
titles_filters_open(listData);
return;
}
if(!listData->populated || (hidKeysDown() & KEY_X)) { if(!listData->populated || (hidKeysDown() & KEY_X)) {
if(!listData->populateData.finished) { if(!listData->populateData.finished) {
svcSignalEvent(listData->populateData.cancelEvent); 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() { void titles_open() {
titles_data* data = (titles_data*) calloc(1, sizeof(titles_data)); titles_data* data = (titles_data*) calloc(1, sizeof(titles_data));
if(data == NULL) { if(data == NULL) {
@ -165,7 +235,14 @@ void titles_open() {
return; return;
} }
data->populateData.filter = titles_filter;
data->populateData.filterData = data;
data->populateData.finished = true; 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);
} }