#include #include #include #include #include "ui/MainApplication.hpp" #include "ui/mainPage.hpp" #include "util/util.hpp" #include "util/config.hpp" #include "util/lang.hpp" #include "sigInstall.hpp" #include "HDInstall.hpp" #include "data/buffered_placeholder_writer.hpp" #include "nx/usbhdd.h" #include "usbhsfs.h" #include "util/theme.hpp" #include #define COLOR(hex) pu::ui::Color::FromHex(hex) int statvfs(const char* path, struct statvfs* buf); s32 prev_touchcount = 0; double GetAvailableSpace(const char* path) { struct statvfs stat; if (statvfs(path, &stat) != 0) { // error happens, just quits here return -1; } // the available size is f_bsize * f_bavail return stat.f_bsize * stat.f_bavail; } double amountOfDiskSpaceUsed(const char* path) { struct statvfs stat; if (statvfs(path, &stat) != 0) { // error happens, just quits here return -1; } const auto total = static_cast(stat.f_blocks); const auto available = static_cast(stat.f_bavail); const auto availableToRoot = static_cast(stat.f_bfree); const auto used = total - availableToRoot; const auto nonRootTotal = used + available; return 100.0 * static_cast(used) / static_cast(nonRootTotal); } double totalsize(const char* path) { struct statvfs stat; if (statvfs(path, &stat) != 0) { // error happens, just quits here return -1; } return stat.f_blocks * stat.f_frsize; } namespace inst::ui { extern MainApplication* mainApp; bool appletFinished = false; bool updateFinished = false; void mathstuff() { double math = (GetAvailableSpace("./") / 1024) / 1024; //megabytes float math2 = ((float)math / 1024); //gigabytes double used = (amountOfDiskSpaceUsed("./")); //same file path as sdmc double total = (totalsize("sdmc:/") / 1024) / 1024; //megabytes float total2 = ((float)total / 1024); //gigabytes // float GB = math2; std::stringstream stream; stream << std::fixed << std::setprecision(2) << GB; //only show 2 decimal places std::string freespace = stream.str(); float GB2 = total2; std::stringstream stream2; stream2 << std::fixed << std::setprecision(2) << GB2; //only show 2 decimal places std::string sdsize = stream2.str(); //printf("\nSdCard Free Space in MB: %li", math); //printf("\nSdCard Free Space in GB: %.2f", math2); std::stringstream stream3; stream3 << std::fixed << std::setprecision(2) << used; //only show 2 decimal places std::string percent = stream3.str(); //unmount sd here and mount system.... //fsdevUnmountDevice("sdmc"); FsFileSystem nandFS; fsOpenBisFileSystem(&nandFS, FsBisPartitionId_User, ""); fsdevMountDevice("user", nandFS); double math3 = (GetAvailableSpace("user:/") / 1024) / 1024; //megabytes float math4 = ((float)math3 / 1024); //gigabytes double used2 = (amountOfDiskSpaceUsed("user:/")); //same file path as sdmc double total3 = (totalsize("user:/") / 1024) / 1024; //megabytes float total4 = ((float)total3 / 1024); //gigabytes // float GB3 = math4; std::stringstream stream4; stream4 << std::fixed << std::setprecision(2) << GB3; //only show 2 decimal places std::string freespace2 = stream4.str(); float GB4 = total4; std::stringstream stream5; stream5 << std::fixed << std::setprecision(2) << GB4; //only show 2 decimal places std::string sdsize2 = stream5.str(); //printf("\nSdCard Free Space in MB: %li", math); //printf("\nSdCard Free Space in GB: %.2f", math2); std::stringstream stream6; stream6 << std::fixed << std::setprecision(2) << used2; //only show 2 decimal places std::string percent2 = stream6.str(); //unmount user now as we already know how much space we have fsdevUnmountDevice("user"); std::string Info = ("usage.system_size"_lang + sdsize2 + "usage.gb"_lang + "usage.freespace"_lang + freespace2 + "usage.gb"_lang + "usage.percent_used"_lang + percent2 + "usage.percent"_lang + "usage.sd_size"_lang + sdsize + "usage.gb"_lang + "usage.sd_space"_lang + freespace + "usage.gb"_lang + "usage.sd_used"_lang + percent + "usage.percent_symbol"_lang); inst::ui::mainApp->CreateShowDialog("usage.space_info"_lang, Info, { "common.ok"_lang }, true, "romfs:/images/icons/drive.png"); } void mainMenuThread() { bool menuLoaded = mainApp->IsShown(); if (!appletFinished && appletGetAppletType() == AppletType_LibraryApplet) { tin::data::NUM_BUFFER_SEGMENTS = 2; if (menuLoaded) { inst::ui::appletFinished = true; mainApp->CreateShowDialog("main.applet.title"_lang, "main.applet.desc"_lang, { "common.ok"_lang }, true, "romfs:/images/icons/information.png"); } } else if (!appletFinished) { inst::ui::appletFinished = true; tin::data::NUM_BUFFER_SEGMENTS = 128; } if (!updateFinished && (!inst::config::autoUpdate || inst::util::getIPAddress() == "1.0.0.127")) updateFinished = true; if (!updateFinished && menuLoaded && inst::config::updateInfo.size()) { updateFinished = true; optionsPage::askToUpdate(inst::config::updateInfo); } } MainPage::MainPage() : Layout::Layout() { std::string default_background = inst::config::appDir + "bg_images.default_background"_theme; std::string main_top = inst::config::appDir + "bg_images.main_top"_theme; std::string icons_sd = inst::config::appDir + "icons_mainmenu.sd"_theme; std::string icons_net = inst::config::appDir + "icons_mainmenu.net"_theme; std::string icons_usb = inst::config::appDir + "icons_mainmenu.usb"_theme; std::string icons_hdd = inst::config::appDir + "icons_mainmenu.hdd"_theme; std::string icons_hdd_connected = inst::config::appDir + "icons_mainmenu.hdd_connected"_theme; std::string icons_settings = inst::config::appDir + "icons_mainmenu.settings"_theme; std::string icons_exit = inst::config::appDir + "icons_mainmenu.exit"_theme; std::string bg_colour = "colour.background"_theme; std::string tbar_colour = "colour.topbar"_theme; std::string bbar_colour = "colour.bottombar"_theme; std::string bottombar_text = "colour.bottombar_text"_theme; std::string text_colour = "colour.main_text"_theme; std::string background_overlay1 = "colour.background_overlay1"_theme; std::string background_overlay2 = "colour.background_overlay2"_theme; std::string focus = "colour.focus"_theme; std::string scrollbar = "colour.scrollbar"_theme; if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->SetBackgroundColor(COLOR(bg_colour)); else this->SetBackgroundColor(COLOR("#000000FF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR(tbar_colour)); else this->topRect = Rectangle::New(0, 0, 1280, 94, COLOR("#000000FF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR(bbar_colour)); else this->botRect = Rectangle::New(0, 659, 1280, 61, COLOR("#000000FF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(main_top)) this->titleImage = Image::New(0, 0, (main_top)); else this->titleImage = Image::New(0, 0, "romfs:/images/Main.png"); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(default_background)) this->SetBackgroundImage(default_background); else this->SetBackgroundImage("romfs:/images/Background.png"); this->butText = TextBlock::New(10, 678, "main.buttons"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->butText->SetColor(COLOR(bottombar_text)); else this->butText->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->optionMenu = pu::ui::elm::Menu::New(0, 95, 1280, COLOR(background_overlay1), COLOR(background_overlay2), 94, 6); else this->optionMenu = pu::ui::elm::Menu::New(0, 95, 1280, COLOR("#FFFFFF00"), COLOR("#4f4f4d33"), 94, 6); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->optionMenu->SetItemsFocusColor(COLOR(focus)); else this->optionMenu->SetItemsFocusColor(COLOR("#4f4f4dAA")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->optionMenu->SetScrollbarColor(COLOR(scrollbar)); else this->optionMenu->SetScrollbarColor(COLOR("#1A1919FF")); this->installMenuItem = pu::ui::elm::MenuItem::New("main.menu.sd"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->installMenuItem->SetColor(COLOR(text_colour)); else this->installMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_sd)) this->installMenuItem->SetIcon(icons_sd); else this->installMenuItem->SetIcon("romfs:/images/icons/micro-sd.png"); this->netInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.net"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->netInstallMenuItem->SetColor(COLOR(text_colour)); else this->netInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_net)) this->netInstallMenuItem->SetIcon(icons_net); else this->netInstallMenuItem->SetIcon("romfs:/images/icons/cloud-download.png"); this->usbInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.usb"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->usbInstallMenuItem->SetColor(COLOR(text_colour)); else this->usbInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_usb)) this->usbInstallMenuItem->SetIcon(icons_usb); else this->usbInstallMenuItem->SetIcon("romfs:/images/icons/usb-port.png"); this->HdInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.hdd"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->HdInstallMenuItem->SetColor(COLOR(text_colour)); else this->HdInstallMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_hdd)) this->HdInstallMenuItem->SetIcon(icons_hdd); else this->HdInstallMenuItem->SetIcon("romfs:/images/icons/usb-hd.png"); this->settingsMenuItem = pu::ui::elm::MenuItem::New("main.menu.set"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->settingsMenuItem->SetColor(COLOR(text_colour)); else this->settingsMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_settings)) this->settingsMenuItem->SetIcon(icons_settings); else this->settingsMenuItem->SetIcon("romfs:/images/icons/settings.png"); this->exitMenuItem = pu::ui::elm::MenuItem::New("main.menu.exit"_lang); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json")) this->exitMenuItem->SetColor(COLOR(text_colour)); else this->exitMenuItem->SetColor(COLOR("#FFFFFFFF")); if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_exit)) this->exitMenuItem->SetIcon(icons_exit); else this->exitMenuItem->SetIcon("romfs:/images/icons/exit-run.png"); this->Add(this->topRect); this->Add(this->botRect); this->Add(this->titleImage); this->Add(this->butText); this->optionMenu->AddItem(this->installMenuItem); this->optionMenu->AddItem(this->netInstallMenuItem); this->optionMenu->AddItem(this->usbInstallMenuItem); this->optionMenu->AddItem(this->HdInstallMenuItem); this->optionMenu->AddItem(this->settingsMenuItem); this->optionMenu->AddItem(this->exitMenuItem); if (nx::hdd::count() && nx::hdd::rootPath()) { if (inst::config::useTheme && std::filesystem::exists(inst::config::appDir + "/theme/theme.json") && std::filesystem::exists(icons_hdd_connected)) this->hdd = Image::New(1156, 669, icons_hdd_connected); else this->hdd = Image::New(1156, 669, "romfs:/images/icons/usb-hd-connected.png"); this->Add(this->hdd); } this->Add(this->optionMenu); this->AddRenderCallback(mainMenuThread); } void MainPage::installMenuItem_Click() { mainApp->sdinstPage->drawMenuItems(true, "sdmc:/"); mainApp->sdinstPage->menu->SetSelectedIndex(0); mainApp->LoadLayout(mainApp->sdinstPage); } void MainPage::netInstallMenuItem_Click() { if (inst::util::getIPAddress() == "1.0.0.127") { inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, { "common.ok"_lang }, true, "romfs:/images/icons/information.png"); return; } mainApp->netinstPage->startNetwork(); } void MainPage::usbInstallMenuItem_Click() { if (!inst::config::usbAck) { if (mainApp->CreateShowDialog("main.usb.warn.title"_lang, "main.usb.warn.desc"_lang, { "common.ok"_lang, "main.usb.warn.opt1"_lang }, false, "romfs:/images/icons/usb.png") == 1) { inst::config::usbAck = true; inst::config::setConfig(); } } if (inst::util::getUsbState() == 5) mainApp->usbinstPage->startUsb(); else mainApp->CreateShowDialog("main.usb.error.title"_lang, "main.usb.error.desc"_lang, { "common.ok"_lang }, true, "romfs:/images/icons/usb.png"); } void MainPage::HdInstallMenuItem_Click() { if (nx::hdd::count() && nx::hdd::rootPath()) { mainApp->HDinstPage->drawMenuItems(true, nx::hdd::rootPath()); mainApp->HDinstPage->menu->SetSelectedIndex(0); mainApp->LoadLayout(mainApp->HDinstPage); } else { inst::ui::mainApp->CreateShowDialog("main.hdd.title"_lang, "main.hdd.notfound"_lang, { "common.ok"_lang }, true, "romfs:/images/icons/drive.png"); } } void MainPage::exitMenuItem_Click() { mainApp->FadeOut(); mainApp->Close(); } void MainPage::settingsMenuItem_Click() { mainApp->LoadLayout(mainApp->optionspage); } void MainPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::TouchPoint touch_pos) { if (((Down & HidNpadButton_Plus) || (Down & HidNpadButton_Minus) || ((Held & HidNpadButton_L) && (Down & HidNpadButton_R)) || ((Down & HidNpadButton_L) && (Held & HidNpadButton_R))) && mainApp->IsShown()) { mainApp->FadeOut(); mainApp->Close(); } HidTouchScreenState state = { 0 }; if (hidGetTouchScreenStates(&state, 1)) { if ((Down & HidNpadButton_A) || (state.count != prev_touchcount)) { prev_touchcount = state.count; if (prev_touchcount != 1) { int menuindex = this->optionMenu->GetSelectedIndex(); switch (menuindex) { case 0: this->installMenuItem_Click(); break; case 1: this->netInstallMenuItem_Click(); break; case 2: MainPage::usbInstallMenuItem_Click(); break; case 3: MainPage::HdInstallMenuItem_Click(); break; case 4: MainPage::settingsMenuItem_Click(); break; case 5: MainPage::exitMenuItem_Click(); break; default: break; } } } } if (Down & HidNpadButton_X) { } if (Up & HidNpadButton_A) { } if (Down & HidNpadButton_Y) { mathstuff(); } if (Down & HidNpadButton_ZL) { } if (Down & HidNpadButton_ZR) { } if (Down & HidNpadButton_L) { } if (Down & HidNpadButton_R) { } } }