mirror of
https://github.com/joel16/VITA-Homebrew-Sorter.git
synced 2024-11-23 11:29:50 +00:00
640 lines
25 KiB
C++
640 lines
25 KiB
C++
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <psp2/power.h>
|
|
#include <psp2/kernel/clib.h>
|
|
#include <vitaGL.h>
|
|
|
|
#include "applist.h"
|
|
#include "config.h"
|
|
#include "fs.h"
|
|
#include "imgui_impl_vitagl.h"
|
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
|
#include "imgui_internal.h"
|
|
#include "loadouts.h"
|
|
#include "sqlite3.h"
|
|
#include "textures.h"
|
|
#include "utils.h"
|
|
|
|
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));
|
|
|
|
if (clear) {
|
|
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
ImGui::Render();
|
|
ImGui_ImplVitaGL_RenderDrawData(ImGui::GetDrawData());
|
|
vglSwapBuffers(GL_TRUE);
|
|
}
|
|
}
|
|
|
|
namespace GUI {
|
|
enum State {
|
|
StateNone,
|
|
StateConfirmSort,
|
|
StateConfirmSwap,
|
|
StateRestore,
|
|
StateLoadoutRestore,
|
|
StateWarning,
|
|
StateDone,
|
|
StateDelete,
|
|
StateError
|
|
};
|
|
|
|
enum SortMode {
|
|
SortDefault,
|
|
SortAsc,
|
|
SortDesc
|
|
};
|
|
|
|
enum IconType {
|
|
App,
|
|
DB,
|
|
Folder,
|
|
Page,
|
|
Trash
|
|
};
|
|
|
|
static bool backupExists = false;
|
|
static const ImVec2 tex_size = ImVec2(20, 20);
|
|
static const char *sort_by[] = {"Title", "Title ID"};
|
|
static const char *sort_folders[] = {"Both", "Apps only", "Folders only"};
|
|
static int old_page_id = -1;
|
|
|
|
static void SetupPopup(const char *id) {
|
|
ImGui::OpenPopup(id);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, tex_size);
|
|
ImGui::SetNextWindowPos(ImVec2(480.0f, 272.0f), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
|
};
|
|
|
|
static void ExitPopup(void) {
|
|
ImGui::EndPopup();
|
|
ImGui::PopStyleVar();
|
|
};
|
|
|
|
static void SetupWindow(void) {
|
|
ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Once);
|
|
ImGui::SetNextWindowSize(ImVec2(960.0f, 544.0f), ImGuiCond_Once);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
};
|
|
|
|
static void ExitWindow(void) {
|
|
ImGui::End();
|
|
ImGui::PopStyleVar();
|
|
};
|
|
|
|
static void DisableButtonInit(bool disable) {
|
|
if (disable) {
|
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
|
}
|
|
}
|
|
|
|
static void DisableButtonExit(bool disable) {
|
|
if (disable) {
|
|
ImGui::PopItemFlag();
|
|
ImGui::PopStyleVar();
|
|
}
|
|
}
|
|
|
|
static void Prompt(State &state, AppEntries &entries, std::vector<SceIoDirent> &loadouts, const std::string &db_name) {
|
|
if (state == StateNone)
|
|
return;
|
|
|
|
std::string title, prompt;
|
|
|
|
switch (state) {
|
|
case StateConfirmSort:
|
|
title = "Confirm";
|
|
prompt = "Are you sure you want to apply this sorting method? This may take a minute.";
|
|
break;
|
|
|
|
case StateConfirmSwap:
|
|
title = "Confirm";
|
|
prompt = "Are you sure you want to apply this change?";
|
|
break;
|
|
|
|
case StateRestore:
|
|
title = "Restore Backup";
|
|
prompt = "Are you sure you want to restore this backup?";
|
|
break;
|
|
|
|
case StateLoadoutRestore:
|
|
title = "Restore Loadout";
|
|
prompt = "Are you sure you want to apply this loadout?";
|
|
break;
|
|
|
|
case StateWarning:
|
|
title = "Warning";
|
|
prompt = "This loadout is outdated and may not include some newly installed apps.";
|
|
break;
|
|
|
|
case StateDone:
|
|
title = "Restart";
|
|
prompt = "Do you wish to restart your device?";
|
|
break;
|
|
|
|
case StateDelete:
|
|
title = "Delete";
|
|
prompt = "Are you sure you want to delete this loadout?";
|
|
break;
|
|
|
|
case StateError:
|
|
title = "Error";
|
|
prompt = "An error occured and has been logged. The app will restore your app.db backup.";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
GUI::SetupPopup(title.c_str());
|
|
|
|
if (ImGui::BeginPopupModal(title.c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
|
ImGui::Text(prompt.c_str());
|
|
|
|
if ((state == StateConfirmSort) || (state == StateRestore) || (state == StateLoadoutRestore)) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f));
|
|
ImGui::Text("You must reboot your device for the changes to take effect.");
|
|
}
|
|
else if (state == StateWarning) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f));
|
|
ImGui::Text("Do you still wish to continue restoring this loadout?");
|
|
}
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f));
|
|
|
|
if (ImGui::Button("Ok", ImVec2(120, 0))) {
|
|
switch (state) {
|
|
case StateConfirmSort:
|
|
AppList::Backup();
|
|
backupExists = true;
|
|
if ((AppList::Save(entries.icons)) == 0)
|
|
state = StateDone;
|
|
else
|
|
state = StateError;
|
|
break;
|
|
|
|
case StateConfirmSwap:
|
|
AppList::Backup();
|
|
backupExists = true;
|
|
if ((AppList::SavePages(entries.pages)) == 0)
|
|
state = StateDone;
|
|
else
|
|
state = StateError;
|
|
break;
|
|
|
|
case StateRestore:
|
|
AppList::Restore();
|
|
state = StateDone;
|
|
break;
|
|
|
|
case StateLoadoutRestore:
|
|
if (AppList::Compare(db_name)) {
|
|
state = StateWarning;
|
|
}
|
|
else {
|
|
Loadouts::Restore(db_name);
|
|
state = StateDone;
|
|
}
|
|
break;
|
|
|
|
case StateWarning:
|
|
Loadouts::Restore(db_name);
|
|
state = StateDone;
|
|
break;
|
|
|
|
case StateDone:
|
|
scePowerRequestColdReset();
|
|
break;
|
|
|
|
case StateDelete:
|
|
Loadouts::Delete(db_name);
|
|
FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
|
state = StateNone;
|
|
break;
|
|
|
|
case StateError:
|
|
state = StateNone;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
|
|
ImGui::SameLine(0.0f, 15.0f);
|
|
|
|
if (ImGui::Button("Cancel", ImVec2(120, 0))) {
|
|
ImGui::CloseCurrentPopup();
|
|
state = StateNone;
|
|
}
|
|
}
|
|
|
|
GUI::ExitPopup();
|
|
}
|
|
|
|
static void SortTab(AppEntries &entries, State &state) {
|
|
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
|
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
|
|
|
if (ImGui::BeginTabItem("Sort/Backup")) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
ImGui::PushID("sort_by");
|
|
ImGui::PushItemWidth(100.f);
|
|
if (ImGui::BeginCombo("", sort_by[cfg.sort_by])) {
|
|
for (int i = 0; i < IM_ARRAYSIZE(sort_by); i++) {
|
|
const bool is_selected = (cfg.sort_by == i);
|
|
|
|
if (ImGui::Selectable(sort_by[i], is_selected)) {
|
|
cfg.sort_by = i;
|
|
Config::Save(cfg);
|
|
}
|
|
|
|
if (is_selected)
|
|
ImGui::SetItemDefaultFocus();
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopID();
|
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushID("sort_folders");
|
|
ImGui::PushItemWidth(150.f);
|
|
if (ImGui::BeginCombo("", sort_folders[cfg.sort_folders])) {
|
|
for (int i = 0; i < IM_ARRAYSIZE(sort_folders); i++) {
|
|
const bool is_selected = (cfg.sort_folders == i);
|
|
|
|
if (ImGui::Selectable(sort_folders[i], is_selected)) {
|
|
cfg.sort_folders = i;
|
|
Config::Save(cfg);
|
|
}
|
|
|
|
if (is_selected)
|
|
ImGui::SetItemDefaultFocus();
|
|
}
|
|
|
|
ImGui::EndCombo();
|
|
}
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopID();
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Default", cfg.sort_mode == SortDefault)) {
|
|
cfg.sort_mode = SortDefault;
|
|
AppList::Get(entries);
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Asc", cfg.sort_mode == SortAsc)) {
|
|
cfg.sort_mode = SortAsc;
|
|
AppList::Get(entries);
|
|
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppAsc);
|
|
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppAsc);
|
|
AppList::Sort(entries);
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Desc", cfg.sort_mode == SortDesc)) {
|
|
cfg.sort_mode = SortDesc;
|
|
AppList::Get(entries);
|
|
std::sort(entries.icons.begin(), entries.icons.end(), AppList::SortAppDesc);
|
|
std::sort(entries.child_apps.begin(), entries.child_apps.end(), AppList::SortChildAppDesc);
|
|
AppList::Sort(entries);
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
GUI::DisableButtonInit(cfg.sort_mode == SortDefault);
|
|
if (ImGui::Button("Apply Sort", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f)))
|
|
state = StateConfirmSort;
|
|
GUI::DisableButtonExit(cfg.sort_mode == SortDefault);
|
|
|
|
ImGui::SameLine();
|
|
|
|
GUI::DisableButtonInit(!backupExists);
|
|
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f)))
|
|
state = StateRestore;
|
|
GUI::DisableButtonExit(!backupExists);
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
if (ImGui::BeginTable("AppList", 5, tableFlags)) {
|
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("Title");
|
|
ImGui::TableSetupColumn("Page ID", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("Page No", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("Pos", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableHeadersRow();
|
|
|
|
for (unsigned int i = 0, counter = 0; i < entries.icons.size(); i++) {
|
|
if (entries.icons[i].icon0Type == 7) {
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Folder].id), tex_size);
|
|
|
|
ImGui::TableNextColumn();
|
|
std::string title = std::to_string(counter) + ") ";
|
|
title.append(entries.icons[i].title);
|
|
bool open = ImGui::TreeNodeEx(title.c_str(), ImGuiTreeNodeFlags_SpanFullWidth);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pageId);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pageNo);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pos);
|
|
|
|
if (open) {
|
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth;
|
|
int reserved01 = std::stoi(std::string(entries.icons[i].reserved01));
|
|
|
|
for (unsigned int j = 0; j < entries.child_apps.size(); j++) {
|
|
if (entries.child_apps[j].pageNo == reserved01) {
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::TreeNodeEx(entries.child_apps[j].title, flags);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.child_apps[j].pageId);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("-");
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.child_apps[j].pos);
|
|
}
|
|
}
|
|
|
|
ImGui::TreePop();
|
|
}
|
|
|
|
counter++;
|
|
}
|
|
else if (entries.icons[i].pageNo >= 0) {
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Image(reinterpret_cast<ImTextureID>(icons[App].id), tex_size);
|
|
|
|
ImGui::TableNextColumn();
|
|
std::string title = std::to_string(counter) + ") ";
|
|
title.append(entries.icons[i].title);
|
|
ImGui::Selectable(title.c_str(), false, ImGuiSelectableFlags_SpanAllColumns);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pageId);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pageNo);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.icons[i].pos);
|
|
|
|
counter++;
|
|
}
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
}
|
|
|
|
static void PagesTab(AppEntries &entries, State &state) {
|
|
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter;
|
|
|
|
if (ImGui::BeginTabItem("Pages")) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
if (ImGui::Button("Reset", ImVec2(ImGui::GetContentRegionAvail().x * 0.33f, 0.0f))) {
|
|
AppList::Get(entries);
|
|
old_page_id = -1;
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Apply Changes", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 0.0f)))
|
|
state = StateConfirmSwap;
|
|
|
|
ImGui::SameLine();
|
|
|
|
GUI::DisableButtonInit(!backupExists);
|
|
if (ImGui::Button("Restore Backup", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f)))
|
|
state = StateRestore;
|
|
GUI::DisableButtonExit(!backupExists);
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
if (ImGui::BeginTable("PagesList", 3, tableFlags)) {
|
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("pageId");
|
|
ImGui::TableSetupColumn("pageNo");
|
|
ImGui::TableHeadersRow();
|
|
|
|
for (unsigned int i = 0; i < entries.pages.size(); i++) {
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Image(reinterpret_cast<ImTextureID>(icons[Page].id), tex_size);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%d", entries.pages[i].pageId);
|
|
|
|
ImGui::TableNextColumn();
|
|
std::string pageNo = std::to_string(entries.pages[i].pageNo);
|
|
const bool is_selected = (old_page_id == static_cast<int>(i));
|
|
if (ImGui::Selectable(pageNo.c_str(), is_selected)) {
|
|
if (old_page_id == -1)
|
|
old_page_id = i;
|
|
else {
|
|
int temp = entries.pages[i].pageNo;
|
|
entries.pages[i].pageNo = entries.pages[old_page_id].pageNo;
|
|
entries.pages[old_page_id].pageNo = temp;
|
|
old_page_id = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
}
|
|
|
|
static void LoadoutsTab(std::vector<SceIoDirent> &loadouts, State &state, int &date_format, std::string &loadout_name) {
|
|
ImGuiTableFlags tableFlags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter |
|
|
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_ScrollY;
|
|
|
|
if (ImGui::BeginTabItem("Loadouts")) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
if (ImGui::Button("Backup current loadout", ImVec2(ImGui::GetContentRegionAvail().x * 1.0f, 0.0f))) {
|
|
if (R_SUCCEEDED(Loadouts::Backup()))
|
|
FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
|
}
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
if (ImGui::BeginTable("LoadoutList", 4, tableFlags)) {
|
|
if (loadouts.empty())
|
|
ImGui::Text("No loadouts found");
|
|
else {
|
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("Title");
|
|
ImGui::TableSetupColumn("Date", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
|
ImGui::TableHeadersRow();
|
|
|
|
for (unsigned int i = 0; i < loadouts.size(); i++) {
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Image(reinterpret_cast<ImTextureID>(icons[DB].id), tex_size);
|
|
|
|
ImGui::TableNextColumn();
|
|
if (ImGui::Selectable(loadouts[i].d_name, false)) {
|
|
loadout_name = loadouts[i].d_name;
|
|
state = StateLoadoutRestore;
|
|
}
|
|
|
|
ImGui::TableNextColumn();
|
|
char date[16];
|
|
Utils::GetDateString(date, static_cast<SceSystemParamDateFormat>(date_format), loadouts[i].d_stat.st_mtime);
|
|
ImGui::Text(date);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::PushID(i);
|
|
if (ImGui::ImageButton(reinterpret_cast<ImTextureID>(icons[Trash].id), tex_size, ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
|
loadout_name = loadouts[i].d_name;
|
|
state = StateDelete;
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
}
|
|
|
|
static void SettingsTab(void) {
|
|
if (ImGui::BeginTabItem("Settings")) {
|
|
ImGui::Dummy(ImVec2(0.0f, 5.0f)); // Spacing
|
|
|
|
ImGui::Indent(5.f);
|
|
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Beta features:");
|
|
ImGui::Indent(15.f);
|
|
|
|
if (ImGui::RadioButton("Enabled", cfg.beta_features == true)) {
|
|
cfg.beta_features = true;
|
|
Config::Save(cfg);
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Disabled", cfg.beta_features == false)) {
|
|
cfg.beta_features = false;
|
|
Config::Save(cfg);
|
|
}
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
|
ImGui::Unindent();
|
|
|
|
ImGui::Indent(5.f);
|
|
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "App Info:");
|
|
ImGui::Indent(15.f);
|
|
std::string version = APP_VERSION;
|
|
version.erase(0, std::min(version.find_first_not_of('0'), version.size() - 1));
|
|
ImGui::Text("App version: %s", version.c_str());
|
|
ImGui::Text("Author: Joel16");
|
|
ImGui::Text("Assets: PreetiSketch");
|
|
ImGui::Text("Dear imGui version: %s", ImGui::GetVersion());
|
|
ImGui::Text("SQLite 3 version: %s", sqlite3_libversion());
|
|
|
|
ImGui::Dummy(ImVec2(0.0f, 10.0f)); // Spacing
|
|
ImGui::Unindent();
|
|
|
|
ImGui::Indent(5.f);
|
|
ImGui::TextColored(ImVec4(0.70f, 0.16f, 0.31f, 1.0f), "Usage:");
|
|
ImGui::Indent(15.f);
|
|
std::string usage = std::string("VITA Homebrew Sorter is a basic PS VITA homebrew application that sorts the application database in your LiveArea.")
|
|
+ " The application sorts apps and games that are inside folders as well. This applications also allows you to backup your current 'loadout' that "
|
|
+ " you can switch into as you wish. A backup will be made before any changes are applied to the application database."
|
|
+ " This backup is overwritten each time you use the sort option. You can find the backup in ux0:/data/VITAHomebrewSorter/backups/app.db."
|
|
+ " \n\nIt is always recommended to restart your vita so that it can refresh your livearea/app.db for any changes (deleted icons, new folders, etc.)"
|
|
+ " before you run this application.";
|
|
ImGui::TextWrapped(usage.c_str());
|
|
ImGui::Unindent();
|
|
|
|
ImGui::EndTabItem();
|
|
}
|
|
}
|
|
|
|
int RenderLoop(void) {
|
|
bool done = false;
|
|
backupExists = (FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db") || FS::FileExists("ux0:/data/VITAHomebrewSorter/backup/app.db.bkp"));
|
|
|
|
AppEntries entries;
|
|
std::vector<SceIoDirent> loadouts;
|
|
|
|
AppList::Get(entries);
|
|
FS::GetDirList("ux0:data/VITAHomebrewSorter/loadouts", loadouts);
|
|
|
|
int date_format = Utils::GetDateFormat();
|
|
|
|
std::string loadout_name;
|
|
State state = StateNone;
|
|
SceCtrlData pad = { 0 };
|
|
|
|
while (!done) {
|
|
ImGui_ImplVitaGL_NewFrame();
|
|
ImGui::NewFrame();
|
|
GUI::SetupWindow();
|
|
|
|
if (ImGui::Begin("VITA Homebrew Sorter", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) {
|
|
if (ImGui::BeginTabBar("VITA Homebrew Sorter tabs")) {
|
|
GUI::SortTab(entries, state);
|
|
GUI::PagesTab(entries, state);
|
|
GUI::DisableButtonInit(!cfg.beta_features);
|
|
GUI::LoadoutsTab(loadouts, state, date_format, loadout_name);
|
|
GUI::DisableButtonExit(!cfg.beta_features);
|
|
GUI::SettingsTab();
|
|
ImGui::EndTabBar();
|
|
}
|
|
}
|
|
|
|
GUI::ExitWindow();
|
|
GUI::Prompt(state, entries, loadouts, loadout_name.c_str());
|
|
Renderer::End(true, ImVec4(0.45f, 0.55f, 0.60f, 1.00f));
|
|
|
|
pad = Utils::ReadControls();
|
|
|
|
if (pressed & SCE_CTRL_START)
|
|
done = true;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|