mirror of
https://github.com/joel16/VITA-Homebrew-Sorter.git
synced 2024-11-23 11:29:50 +00:00
applist: Add option to sort by Title IDs
This commit is contained in:
parent
cd566bf3c1
commit
19ff15c4e6
@ -4,7 +4,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
typedef struct AppInfoIcon {
|
||||
struct AppInfoIcon {
|
||||
int pageId = 0;
|
||||
int pageNo = 0;
|
||||
int pos = 0;
|
||||
@ -12,24 +12,32 @@ typedef struct AppInfoIcon {
|
||||
char titleId[16];
|
||||
int reserved01 = 0;
|
||||
bool folder = false;
|
||||
} AppInfoIcon;
|
||||
};
|
||||
|
||||
typedef struct AppInfoPage {
|
||||
struct AppInfoPage {
|
||||
int pageId = 0;
|
||||
int pageNo = 0;
|
||||
} AppInfoPage;
|
||||
};
|
||||
|
||||
typedef struct AppInfoFolder {
|
||||
struct AppInfoFolder {
|
||||
int pageId = 0;
|
||||
int index = 0;
|
||||
} AppInfoFolder;
|
||||
};
|
||||
|
||||
struct AppEntries {
|
||||
std::vector<AppInfoIcon> icons;
|
||||
std::vector<AppInfoPage> pages;
|
||||
std::vector<AppInfoFolder> folders;
|
||||
};
|
||||
|
||||
extern int sort_mode;
|
||||
|
||||
namespace AppList {
|
||||
int Get(std::vector<AppInfoIcon> &entries, std::vector<AppInfoPage> &pages, std::vector<AppInfoFolder> &folders);
|
||||
int Get(AppEntries *entries);
|
||||
int Save(std::vector<AppInfoIcon> &entries);
|
||||
bool SortAlphabeticalAsc(const AppInfoIcon &entryA, const AppInfoIcon &entryB);
|
||||
bool SortAlphabeticalDesc(const AppInfoIcon &entryA, const AppInfoIcon &entryB);
|
||||
void Sort(std::vector<AppInfoIcon> &entries, std::vector<AppInfoPage> &pages, std::vector<AppInfoFolder> &folders);
|
||||
void Sort(AppEntries *entries);
|
||||
int Backup(void);
|
||||
int Restore(void);
|
||||
bool Compare(const char *db_name);
|
||||
|
@ -11,10 +11,10 @@
|
||||
namespace AppList {
|
||||
constexpr char path[] = "ur0:shell/db/app.db";
|
||||
|
||||
int Get(std::vector<AppInfoIcon> &entries, std::vector<AppInfoPage> &pages, std::vector<AppInfoFolder> &folders) {
|
||||
entries.clear();
|
||||
pages.clear();
|
||||
folders.clear();
|
||||
int Get(AppEntries *entries) {
|
||||
entries->icons.clear();
|
||||
entries->pages.clear();
|
||||
entries->folders.clear();
|
||||
|
||||
sqlite3 *db;
|
||||
int ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, nullptr);
|
||||
@ -32,16 +32,16 @@ namespace AppList {
|
||||
ret = sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, nullptr);
|
||||
|
||||
while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
|
||||
AppInfoIcon entry;
|
||||
entry.pageId = std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
|
||||
entry.pageNo = sqlite3_column_int(stmt, 1);
|
||||
entry.pos = sqlite3_column_int(stmt, 2);
|
||||
std::snprintf(entry.title, 128, "%s", reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)));
|
||||
std::snprintf(entry.titleId, 16, "%s", sqlite3_column_text(stmt, 4));
|
||||
if (std::string(entry.titleId) == "(null)")
|
||||
entry.reserved01 = (std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5))));
|
||||
entry.folder = (std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6)))) == 7? true : false;
|
||||
entries.push_back(entry);
|
||||
AppInfoIcon icon;
|
||||
icon.pageId = std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
|
||||
icon.pageNo = sqlite3_column_int(stmt, 1);
|
||||
icon.pos = sqlite3_column_int(stmt, 2);
|
||||
std::snprintf(icon.title, 128, "%s", reinterpret_cast<const char*>(sqlite3_column_text(stmt, 3)));
|
||||
std::snprintf(icon.titleId, 16, "%s", sqlite3_column_text(stmt, 4));
|
||||
if (std::string(icon.titleId) == "(null)")
|
||||
icon.reserved01 = (std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 5))));
|
||||
icon.folder = (std::stoi(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 6)))) == 7? true : false;
|
||||
entries->icons.push_back(icon);
|
||||
}
|
||||
|
||||
if (ret != SQLITE_DONE) {
|
||||
@ -69,11 +69,11 @@ namespace AppList {
|
||||
if (pageNo >= 0) {
|
||||
page.pageId = sqlite3_column_int(stmt, 0);
|
||||
page.pageNo = pageNo;
|
||||
pages.push_back(page);
|
||||
entries->pages.push_back(page);
|
||||
}
|
||||
else if (pageNo < 0) {
|
||||
folder.pageId = sqlite3_column_int(stmt, 0);
|
||||
folders.push_back(folder);
|
||||
entries->folders.push_back(folder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,8 +149,8 @@ namespace AppList {
|
||||
}
|
||||
|
||||
bool SortAlphabeticalAsc(const AppInfoIcon &entryA, const AppInfoIcon &entryB) {
|
||||
std::string entryAname = entryA.title;
|
||||
std::string entryBname = entryB.title;
|
||||
std::string entryAname = sort_mode == 0? entryA.title : entryA.titleId;
|
||||
std::string entryBname = sort_mode == 0? entryB.title : entryB.titleId;
|
||||
|
||||
std::transform(entryAname.begin(), entryAname.end(), entryAname.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
std::transform(entryBname.begin(), entryBname.end(), entryBname.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
@ -162,8 +162,8 @@ namespace AppList {
|
||||
}
|
||||
|
||||
bool SortAlphabeticalDesc(const AppInfoIcon &entryA, const AppInfoIcon &entryB) {
|
||||
std::string entryAname = entryA.title;
|
||||
std::string entryBname = entryB.title;
|
||||
std::string entryAname = sort_mode == 0? entryA.title : entryA.titleId;
|
||||
std::string entryBname = sort_mode == 0? entryB.title : entryB.titleId;
|
||||
|
||||
std::transform(entryAname.begin(), entryAname.end(), entryAname.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
std::transform(entryBname.begin(), entryBname.end(), entryBname.begin(), [](unsigned char c){ return std::tolower(c); });
|
||||
@ -174,9 +174,9 @@ namespace AppList {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sort(std::vector<AppInfoIcon> &entries, std::vector<AppInfoPage> &pages, std::vector<AppInfoFolder> &folders) {
|
||||
void Sort(AppEntries *entries) {
|
||||
int pos = 0, pageCounter = 0;
|
||||
for (int i = 0; i < entries.size(); i ++) {
|
||||
for (int i = 0; i < entries->icons.size(); i ++) {
|
||||
// Reset position
|
||||
if (pos > 9) {
|
||||
pos = 0;
|
||||
@ -184,17 +184,17 @@ namespace AppList {
|
||||
}
|
||||
|
||||
// App/Game belongs to a folder
|
||||
if (entries[i].pageNo < 0) {
|
||||
for (int j = 0; j < folders.size(); j++) {
|
||||
if (entries[i].pageId == folders[j].pageId) {
|
||||
entries[i].pos = folders[j].index;
|
||||
folders[j].index++;
|
||||
if (entries->icons[i].pageNo < 0) {
|
||||
for (int j = 0; j < entries->folders.size(); j++) {
|
||||
if (entries->icons[i].pageId == entries->folders[j].pageId) {
|
||||
entries->icons[i].pos = entries->folders[j].index;
|
||||
entries->folders[j].index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
entries[i].pos = pos;
|
||||
entries[i].pageId = pages[pageCounter].pageId;
|
||||
entries->icons[i].pos = pos;
|
||||
entries->icons[i].pageId = entries->pages[pageCounter].pageId;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "textures.h"
|
||||
#include "utils.h"
|
||||
|
||||
int sort_mode = 0;
|
||||
|
||||
namespace Renderer {
|
||||
static void End(bool clear, ImVec4 clear_color) {
|
||||
glViewport(0, 0, static_cast<int>(ImGui::GetIO().DisplaySize.x), static_cast<int>(ImGui::GetIO().DisplaySize.y));
|
||||
@ -223,16 +225,14 @@ namespace GUI {
|
||||
int RenderLoop(void) {
|
||||
bool done = false;
|
||||
backupExists = (FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db") || FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db.bkp"));
|
||||
std::vector<AppInfoIcon> apps;
|
||||
std::vector<AppInfoPage> pages;
|
||||
std::vector<AppInfoFolder> folders;
|
||||
AppEntries entries;
|
||||
std::vector<SceIoDirent> loadouts;
|
||||
int ret = AppList::Get(apps, pages, folders);
|
||||
int ret = AppList::Get(&entries);
|
||||
ret = FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
||||
int date_format = Utils::GetDateFormat();
|
||||
std::string loadout_name;
|
||||
|
||||
enum SortMode {
|
||||
enum SortBy {
|
||||
SortDefault,
|
||||
SortAsc,
|
||||
SortDesc
|
||||
@ -244,8 +244,8 @@ namespace GUI {
|
||||
Folder
|
||||
};
|
||||
|
||||
static SortMode sort = SortDefault;
|
||||
static State state = StateNone;
|
||||
SortBy sort = SortDefault;
|
||||
State state = StateNone;
|
||||
|
||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
||||
@ -259,27 +259,32 @@ namespace GUI {
|
||||
if (ImGui::BeginTabItem("Sort/Backup")) {
|
||||
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
||||
|
||||
ImGui::SetNextItemWidth(100.0f);
|
||||
ImGui::Combo("Sort by", &sort_mode, "Title\0Title ID\0");
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Default", sort == SortDefault)) {
|
||||
sort = SortDefault;
|
||||
ret = AppList::Get(apps, pages, folders);
|
||||
ret = AppList::Get(&entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Asc", sort == SortAsc)) {
|
||||
sort = SortAsc;
|
||||
ret = AppList::Get(apps, pages, folders);
|
||||
std::sort(apps.begin(), apps.end(), AppList::SortAlphabeticalAsc);
|
||||
AppList::Sort(apps, pages, folders);
|
||||
ret = AppList::Get(&entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAlphabeticalAsc);
|
||||
AppList::Sort(&entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::RadioButton("Desc", sort == SortDesc)) {
|
||||
sort = SortDesc;
|
||||
ret = AppList::Get(apps, pages, folders);
|
||||
std::sort(apps.begin(), apps.end(), AppList::SortAlphabeticalDesc);
|
||||
AppList::Sort(apps, pages, folders);
|
||||
ret = AppList::Get(&entries);
|
||||
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAlphabeticalDesc);
|
||||
AppList::Sort(&entries);
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
@ -306,26 +311,26 @@ namespace GUI {
|
||||
ImGui::TableSetupColumn("Position");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (int i = 0; i < apps.size(); i++) {
|
||||
for (int i = 0; i < entries.icons.size(); i++) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(apps[i].folder? icons[Folder].id : icons[App].id), ImVec2(20, 20));
|
||||
ImGui::Image(reinterpret_cast<ImTextureID>(entries.icons[i].folder? icons[Folder].id : icons[App].id), ImVec2(20, 20));
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Selectable(apps[i].title, false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
ImGui::Selectable(entries.icons[i].title, false, ImGuiSelectableFlags_SpanAllColumns);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", apps[i].pageId);
|
||||
ImGui::Text("%d", entries.icons[i].pageId);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (apps[i].pageNo < 0)
|
||||
if (entries.icons[i].pageNo < 0)
|
||||
ImGui::Text("Inside folder");
|
||||
else
|
||||
ImGui::Text("%d", apps[i].pageNo);
|
||||
ImGui::Text("%d", entries.icons[i].pageNo);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", apps[i].pos);
|
||||
ImGui::Text("%d", entries.icons[i].pos);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
@ -383,7 +388,7 @@ namespace GUI {
|
||||
}
|
||||
|
||||
GUI::ExitWindow();
|
||||
GUI::Prompt(&state, apps, loadout_name.c_str());
|
||||
GUI::Prompt(&state, entries.icons, loadout_name.c_str());
|
||||
Renderer::End(true, ImVec4(0.45f, 0.55f, 0.60f, 1.00f));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user