update homebrew menu when app is installed from the appstore, add same effect to a few other menus (unused).
This commit is contained in:
@@ -192,6 +192,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static auto GetAccountList() -> std::vector<AccountProfileBase> {
|
||||
std::vector<AccountProfileBase> out;
|
||||
|
||||
AccountUid uids[8];
|
||||
s32 account_count;
|
||||
if (R_SUCCEEDED(accountListAllUsers(uids, std::size(uids), &account_count))) {
|
||||
for (s32 i = 0; i < account_count; i++) {
|
||||
AccountProfile profile;
|
||||
if (R_SUCCEEDED(accountGetProfile(&profile, uids[i]))) {
|
||||
ON_SCOPE_EXIT(accountProfileClose(&profile));
|
||||
|
||||
AccountProfileBase base;
|
||||
if (R_SUCCEEDED(accountProfileGet(&profile, nullptr, &base))) {
|
||||
out.emplace_back(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// private:
|
||||
static constexpr inline auto CONFIG_PATH = "/config/sphaira/config.ini";
|
||||
static constexpr inline auto PLAYLOG_PATH = "/config/sphaira/playlog.ini";
|
||||
|
||||
@@ -154,6 +154,8 @@ struct FsDirCollection {
|
||||
|
||||
using FsDirCollections = std::vector<FsDirCollection>;
|
||||
|
||||
void SignalChange();
|
||||
|
||||
struct Menu;
|
||||
|
||||
struct FsView final : Widget {
|
||||
@@ -244,7 +246,7 @@ private:
|
||||
}
|
||||
|
||||
void Sort();
|
||||
void SortAndFindLastFile();
|
||||
void SortAndFindLastFile(bool scan = false);
|
||||
void SetIndexFromLastFile(const LastFile& last_file);
|
||||
|
||||
void OnDeleteCallback();
|
||||
|
||||
@@ -25,6 +25,7 @@ enum OrderType {
|
||||
using LayoutType = grid::LayoutType;
|
||||
|
||||
auto GetNroEntries() -> std::span<const NroEntry>;
|
||||
void SignalChange();
|
||||
|
||||
struct Menu final : grid::Menu {
|
||||
Menu();
|
||||
@@ -47,7 +48,7 @@ private:
|
||||
void InstallHomebrew();
|
||||
void ScanHomebrew();
|
||||
void Sort();
|
||||
void SortAndFindLastFile();
|
||||
void SortAndFindLastFile(bool scan = false);
|
||||
void FreeEntries();
|
||||
void OnLayoutChange();
|
||||
|
||||
@@ -61,6 +62,7 @@ private:
|
||||
std::vector<NroEntry> m_entries{};
|
||||
s64 m_index{}; // where i am in the array
|
||||
std::unique_ptr<List> m_list{};
|
||||
bool m_dirty{};
|
||||
|
||||
option::OptionLong m_sort{INI_SECTION, "sort", SortType::SortType_AlphabeticalStar};
|
||||
option::OptionLong m_order{INI_SECTION, "order", OrderType::OrderType_Descending};
|
||||
|
||||
@@ -81,6 +81,8 @@ enum OrderType {
|
||||
|
||||
using LayoutType = grid::LayoutType;
|
||||
|
||||
void SignalChange();
|
||||
|
||||
struct Menu final : grid::Menu {
|
||||
Menu(u32 flags);
|
||||
~Menu();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ui/menus/appstore.hpp"
|
||||
#include "ui/menus/homebrew.hpp"
|
||||
#include "ui/sidebar.hpp"
|
||||
#include "ui/popup_list.hpp"
|
||||
#include "ui/progress_box.hpp"
|
||||
@@ -798,6 +799,7 @@ void EntryMenu::UpdateOptions() {
|
||||
App::Push(std::make_shared<ProgressBox>(m_entry.image.image, "Downloading "_i18n, m_entry.title, [this](auto pbox){
|
||||
return InstallApp(pbox, m_entry);
|
||||
}, [this](Result rc){
|
||||
homebrew::SignalChange();
|
||||
App::PushErrorBox(rc, "Failed to, TODO: add message here"_i18n);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
@@ -813,6 +815,7 @@ void EntryMenu::UpdateOptions() {
|
||||
App::Push(std::make_shared<ProgressBox>(m_entry.image.image, "Uninstalling "_i18n, m_entry.title, [this](auto pbox){
|
||||
return UninstallApp(pbox, m_entry);
|
||||
}, [this](Result rc){
|
||||
homebrew::SignalChange();
|
||||
App::PushErrorBox(rc, "Failed to, TODO: add message here"_i18n);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
namespace sphaira::ui::menu::filebrowser {
|
||||
namespace {
|
||||
|
||||
constinit UEvent g_change_uevent;
|
||||
|
||||
constexpr FsEntry FS_ENTRY_DEFAULT{
|
||||
"microSD card", "/", FsType::Sd, FsEntryFlag_Assoc,
|
||||
};
|
||||
@@ -289,6 +291,10 @@ auto GetRomIcon(fs::Fs* fs, ProgressBox* pbox, std::string filename, const RomDa
|
||||
|
||||
} // namespace
|
||||
|
||||
void SignalChange() {
|
||||
ueventSignal(&g_change_uevent);
|
||||
}
|
||||
|
||||
FsView::FsView(Menu* menu, const fs::FsPath& path, const FsEntry& entry, ViewSide side) : m_menu{menu}, m_side{side} {
|
||||
this->SetActions(
|
||||
std::make_pair(Button::L2, Action{[this](){
|
||||
@@ -1083,13 +1089,17 @@ void FsView::Sort() {
|
||||
std::sort(m_entries_current.begin(), m_entries_current.end(), sorter);
|
||||
}
|
||||
|
||||
void FsView::SortAndFindLastFile() {
|
||||
void FsView::SortAndFindLastFile(bool scan) {
|
||||
std::optional<LastFile> last_file;
|
||||
if (!m_path.empty() && !m_entries_current.empty()) {
|
||||
last_file = LastFile(GetEntry().name, m_index, m_list->GetYoff(), m_entries_current.size());
|
||||
}
|
||||
|
||||
Sort();
|
||||
if (scan) {
|
||||
Scan(m_path);
|
||||
} else {
|
||||
Sort();
|
||||
}
|
||||
|
||||
if (last_file.has_value()) {
|
||||
SetIndexFromLastFile(*last_file);
|
||||
@@ -1851,12 +1861,22 @@ Menu::Menu(u32 flags) : MenuBase{"FileBrowser"_i18n, flags} {
|
||||
}
|
||||
|
||||
view = view_left = std::make_shared<FsView>(this, ViewSide::Left);
|
||||
ueventCreate(&g_change_uevent, true);
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
|
||||
if (IsSplitScreen()) {
|
||||
view_left->SortAndFindLastFile(true);
|
||||
view_right->SortAndFindLastFile(true);
|
||||
} else {
|
||||
view->SortAndFindLastFile(true);
|
||||
}
|
||||
}
|
||||
|
||||
// workaround the buttons not being display properly.
|
||||
// basically, inherit all actions from the view, draw them,
|
||||
// then restore state after.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "defines.hpp"
|
||||
#include "i18n.hpp"
|
||||
#include "image.hpp"
|
||||
#include "swkbd.hpp"
|
||||
|
||||
#include "ui/menus/game_menu.hpp"
|
||||
#include "ui/sidebar.hpp"
|
||||
@@ -945,6 +946,33 @@ Menu::Menu(u32 flags) : grid::Menu{"Games"_i18n, flags} {
|
||||
options->Add(std::make_shared<SidebarEntryBool>("Title cache"_i18n, m_title_cache.Get(), [this](bool& v_out){
|
||||
m_title_cache.Set(v_out);
|
||||
}));
|
||||
|
||||
// todo: impl this.
|
||||
#if 0
|
||||
options->Add(std::make_shared<SidebarEntryCallback>("Create save"_i18n, [this](){
|
||||
ui::PopupList::Items items{};
|
||||
const auto accounts = App::GetAccountList();
|
||||
for (auto& p : accounts) {
|
||||
items.emplace_back(p.nickname);
|
||||
}
|
||||
|
||||
fsCreateSaveDataFileSystem;
|
||||
|
||||
App::Push(std::make_shared<ui::PopupList>(
|
||||
"Select user to create save for"_i18n, items, [accounts](auto op_index){
|
||||
if (op_index) {
|
||||
s64 out;
|
||||
if (R_SUCCEEDED(swkbd::ShowNumPad(out, "Enter the save size"_i18n.c_str()))) {
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
// 1. Select user to create save for.
|
||||
// 2. Enter the save size.
|
||||
// 3. Enter the journal size (0 for default).
|
||||
}));
|
||||
#endif
|
||||
}})
|
||||
);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace sphaira::ui::menu::homebrew {
|
||||
namespace {
|
||||
|
||||
Menu* g_menu{};
|
||||
constinit UEvent g_change_uevent;
|
||||
|
||||
auto GenerateStarPath(const fs::FsPath& nro_path) -> fs::FsPath {
|
||||
fs::FsPath out{};
|
||||
@@ -35,6 +36,10 @@ void FreeEntry(NVGcontext* vg, NroEntry& e) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void SignalChange() {
|
||||
ueventSignal(&g_change_uevent);
|
||||
}
|
||||
|
||||
auto GetNroEntries() -> std::span<const NroEntry> {
|
||||
if (!g_menu) {
|
||||
return {};
|
||||
@@ -139,6 +144,7 @@ Menu::Menu() : grid::Menu{"Homebrew"_i18n, MenuFlag_Tab} {
|
||||
);
|
||||
|
||||
OnLayoutChange();
|
||||
ueventCreate(&g_change_uevent, true);
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
@@ -147,6 +153,14 @@ Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
if (m_dirty) {
|
||||
SortAndFindLastFile(true);
|
||||
}
|
||||
|
||||
MenuBase::Update(controller, touch);
|
||||
m_list->OnUpdate(controller, touch, m_index, m_entries.size(), [this](bool touch, auto i) {
|
||||
if (touch && m_index == i) {
|
||||
@@ -297,6 +311,7 @@ void Menu::ScanHomebrew() {
|
||||
|
||||
this->Sort();
|
||||
SetIndex(0);
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void Menu::Sort() {
|
||||
@@ -391,9 +406,13 @@ void Menu::Sort() {
|
||||
std::sort(m_entries.begin(), m_entries.end(), sorter);
|
||||
}
|
||||
|
||||
void Menu::SortAndFindLastFile() {
|
||||
void Menu::SortAndFindLastFile(bool scan) {
|
||||
const auto path = m_entries[m_index].path;
|
||||
Sort();
|
||||
if (scan) {
|
||||
ScanHomebrew();
|
||||
} else {
|
||||
Sort();
|
||||
}
|
||||
SetIndex(0);
|
||||
|
||||
s64 index = -1;
|
||||
|
||||
@@ -41,6 +41,8 @@ constexpr u32 NX_SAVE_META_MAGIC = 0x4A4B5356; // JKSV
|
||||
constexpr u32 NX_SAVE_META_VERSION = 1;
|
||||
constexpr const char* NX_SAVE_META_NAME = ".nx_save_meta.bin";
|
||||
|
||||
constinit UEvent g_change_uevent;
|
||||
|
||||
// https://github.com/J-D-K/JKSV/issues/264#issuecomment-2618962807
|
||||
struct NXSaveMeta {
|
||||
u32 magic{}; // NX_SAVE_META_MAGIC
|
||||
@@ -714,6 +716,10 @@ void ThreadFunc(void* user) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void SignalChange() {
|
||||
ueventSignal(&g_change_uevent);
|
||||
}
|
||||
|
||||
ThreadData::ThreadData() {
|
||||
ueventCreate(&m_uevent, true);
|
||||
mutexInit(&m_mutex_id);
|
||||
@@ -928,21 +934,7 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} {
|
||||
OnLayoutChange();
|
||||
nsInitialize();
|
||||
|
||||
AccountUid uids[8];
|
||||
s32 account_count;
|
||||
if (R_SUCCEEDED(accountListAllUsers(uids, std::size(uids), &account_count))) {
|
||||
for (s32 i = 0; i < account_count; i++) {
|
||||
AccountProfile profile;
|
||||
if (R_SUCCEEDED(accountGetProfile(&profile, uids[i]))) {
|
||||
ON_SCOPE_EXIT(accountProfileClose(&profile));
|
||||
|
||||
AccountProfileBase base;
|
||||
if (R_SUCCEEDED(accountProfileGet(&profile, nullptr, &base))) {
|
||||
m_accounts.emplace_back(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_accounts = App::GetAccountList();
|
||||
|
||||
// try and find the last / default account and set that.
|
||||
AccountUid uid{};
|
||||
@@ -965,6 +957,7 @@ Menu::Menu(u32 flags) : grid::Menu{"Saves"_i18n, flags} {
|
||||
threadCreate(&m_thread, ThreadFunc, &m_thread_data, nullptr, 1024*32, THREAD_PRIO, THREAD_CORE);
|
||||
svcSetThreadCoreMask(m_thread.handle, THREAD_CORE, THREAD_AFFINITY_DEFAULT(THREAD_CORE));
|
||||
threadStart(&m_thread);
|
||||
ueventCreate(&g_change_uevent, true);
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
@@ -982,6 +975,10 @@ Menu::~Menu() {
|
||||
}
|
||||
|
||||
void Menu::Update(Controller* controller, TouchInfo* touch) {
|
||||
if (R_SUCCEEDED(waitSingle(waiterForUEvent(&g_change_uevent), 0))) {
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
if (m_dirty) {
|
||||
App::Notify("Updating application record list");
|
||||
SortAndFindLastFile(true);
|
||||
|
||||
Reference in New Issue
Block a user