Compare commits
4 Commits
617265f004
...
b5296d6686
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5296d6686 | ||
|
|
b5ba2d71df | ||
|
|
a61fa67dca | ||
|
|
90b3902311 |
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# devkitPro / Switch build outputs
|
||||
build.nx/
|
||||
*.elf
|
||||
*.nro
|
||||
*.nacp
|
||||
*.nso
|
||||
*.npdm
|
||||
*.nsp
|
||||
*.lst
|
||||
*.map
|
||||
|
||||
# editor / OS
|
||||
.vscode/
|
||||
.idea/
|
||||
*~
|
||||
*.bak
|
||||
.DS_Store
|
||||
4
Makefile
4
Makefile
@@ -159,8 +159,8 @@ all: $(BUILD)
|
||||
$(ROMFS):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@echo Merging ROMFS...
|
||||
@cp -ruf $(CURDIR)/$(BOREALIS_PATH)/resources/. $(CURDIR)/$(ROMFS)/borealis/
|
||||
@cp -ruf $(CURDIR)/$(RESOURCES)/. $(CURDIR)/$(ROMFS)/
|
||||
@cp -rf $(CURDIR)/$(BOREALIS_PATH)/resources/. $(CURDIR)/$(ROMFS)/borealis/
|
||||
@cp -rf $(CURDIR)/$(RESOURCES)/. $(CURDIR)/$(ROMFS)/
|
||||
|
||||
$(BUILD): $(ROMFS)
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
BIN
resources/gui_icon.png
Normal file
BIN
resources/gui_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -4,18 +4,18 @@
|
||||
*/
|
||||
|
||||
#include "about_tab.h"
|
||||
#include "i18n.h"
|
||||
#include "logo.h"
|
||||
|
||||
AboutTab::AboutTab()
|
||||
{
|
||||
// Logo
|
||||
this->addView(new Logo(LogoStyle::ABOUT));
|
||||
this->addView(new Logo());
|
||||
|
||||
// Subtitle
|
||||
brls::Label *subTitle = new brls::Label(
|
||||
brls::LabelStyle::REGULAR,
|
||||
"Switchroot INI Configuration Editor\n"
|
||||
"Edit your Linux, Android and Lakka OC settings without a PC!",
|
||||
I18n::aboutSubtitle(),
|
||||
true
|
||||
);
|
||||
subTitle->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
@@ -24,22 +24,17 @@ AboutTab::AboutTab()
|
||||
// Copyright
|
||||
brls::Label *copyright = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Licensed under GPL-3.0\n"
|
||||
"Powered by Borealis UI framework\n"
|
||||
"Based on the work of Switchroot\n"
|
||||
"\u00A9 2026 NiklasCFW",
|
||||
I18n::aboutCopyright(),
|
||||
true
|
||||
);
|
||||
copyright->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
this->addView(copyright);
|
||||
|
||||
// Links
|
||||
this->addView(new brls::Header("Links and Resources"));
|
||||
this->addView(new brls::Header(I18n::headerLinksAndResources()));
|
||||
brls::Label *links = new brls::Label(
|
||||
brls::LabelStyle::SMALL,
|
||||
"\uE016 NiklasCFW Docs for setup guides and documentation\n"
|
||||
"\uE016 NiklasCFW's Discord server for support and community\n"
|
||||
"\uE016 Source code available on the OmniNX GitHub",
|
||||
I18n::aboutLinks(),
|
||||
true
|
||||
);
|
||||
this->addView(links);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "file_browser.h"
|
||||
#include "i18n.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -78,7 +79,7 @@ std::vector<FileBrowser::DirEntry> FileBrowser::listDirectory(const std::string&
|
||||
void FileBrowser::navigate(const std::string& dir)
|
||||
{
|
||||
this->currentDir = dir;
|
||||
this->setTitle("Select INI \u2014 " + dir);
|
||||
this->setTitle(std::string(I18n::fileBrowserTitlePrefix()) + dir);
|
||||
|
||||
// Create a fresh list (setContentView frees the old one)
|
||||
this->list = new brls::List();
|
||||
@@ -89,7 +90,7 @@ void FileBrowser::navigate(const std::string& dir)
|
||||
|
||||
if (entries.empty())
|
||||
{
|
||||
brls::ListItem* emptyItem = new brls::ListItem("No .ini files found in " + dir);
|
||||
brls::ListItem* emptyItem = new brls::ListItem(I18n::fileBrowserNoIni(dir));
|
||||
this->list->addView(emptyItem);
|
||||
return;
|
||||
}
|
||||
|
||||
264
src/i18n.cpp
Normal file
264
src/i18n.cpp
Normal file
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
SWR INI Tool - Switchroot INI Configuration Editor
|
||||
Copyright (C) 2026 Switchroot
|
||||
*/
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool gGerman = false;
|
||||
|
||||
#ifdef __SWITCH__
|
||||
void detectSystemLanguage()
|
||||
{
|
||||
gGerman = false;
|
||||
Result rc = setInitialize();
|
||||
if (!R_SUCCEEDED(rc))
|
||||
return;
|
||||
|
||||
u64 code = 0;
|
||||
SetLanguage lang = SetLanguage_ENUS;
|
||||
if (R_SUCCEEDED(setGetSystemLanguage(&code)) && R_SUCCEEDED(setMakeLanguage(code, &lang)))
|
||||
{
|
||||
if (lang == SetLanguage_DE)
|
||||
gGerman = true;
|
||||
}
|
||||
setExit();
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Triple
|
||||
{
|
||||
const char* key;
|
||||
const char* en;
|
||||
const char* de;
|
||||
};
|
||||
|
||||
static const Triple OC_BOOL_LABEL[] = {
|
||||
{"oc", "Overclocking", "Übertaktung"},
|
||||
{"dvfsb", "CPU DVFS Boost", "CPU-DVFS-Boost"},
|
||||
{"gpu_dvfsc", "GPU DVFS Scaling", "GPU-DVFS-Skalierung"},
|
||||
{"usb3force", "Force USB 3.0", "USB 3.0 erzwingen"},
|
||||
{"ddr200_enable", "DDR200 Enable", "DDR200 aktivieren"},
|
||||
};
|
||||
|
||||
static const Triple OC_FREQ_LABEL[] = {
|
||||
{"max_cpu_freq", "Max CPU Frequency", "Max. CPU-Taktfrequenz"},
|
||||
{"max_gpu_freq", "Max GPU Frequency", "Max. GPU-Taktfrequenz"},
|
||||
{"ram_oc", "RAM Frequency", "RAM-Taktfrequenz"},
|
||||
};
|
||||
|
||||
static const Triple OC_VOLT_LABEL[] = {
|
||||
{"ram_oc_vdd2", "RAM VDD2 Voltage", "RAM VDD2-Spannung"},
|
||||
{"ram_oc_vddq", "RAM VDDQ Voltage", "RAM VDDQ-Spannung"},
|
||||
};
|
||||
|
||||
const char* lookup(const Triple* table, size_t n, const std::string& key, const char* fallback)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
if (key == table[i].key)
|
||||
return gGerman ? table[i].de : table[i].en;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace I18n
|
||||
{
|
||||
|
||||
void init()
|
||||
{
|
||||
#ifdef __SWITCH__
|
||||
detectSystemLanguage();
|
||||
#else
|
||||
gGerman = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isGerman()
|
||||
{
|
||||
return gGerman;
|
||||
}
|
||||
|
||||
const char* appTitle()
|
||||
{
|
||||
return gGerman ? "SWR INI-Tool" : "SWR INI Tool";
|
||||
}
|
||||
|
||||
const char* tabSettings()
|
||||
{
|
||||
return gGerman ? "Einstellungen" : "Settings";
|
||||
}
|
||||
|
||||
const char* tabAbout()
|
||||
{
|
||||
return gGerman ? "Über" : "About";
|
||||
}
|
||||
|
||||
const char* wordOn()
|
||||
{
|
||||
return gGerman ? "Ein" : "ON";
|
||||
}
|
||||
|
||||
const char* wordOff()
|
||||
{
|
||||
return gGerman ? "Aus" : "OFF";
|
||||
}
|
||||
|
||||
std::string sectionEditLine(const std::string& section, const std::string& path)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Abschnitt [" + section + "] aus " + path;
|
||||
return "Editing section [" + section + "] from " + path;
|
||||
}
|
||||
|
||||
const char* headerToggleOptions()
|
||||
{
|
||||
return gGerman ? "Schalter" : "Toggle Options";
|
||||
}
|
||||
|
||||
const char* headerFrequencySettings()
|
||||
{
|
||||
return gGerman ? "Frequenz" : "Frequency Settings";
|
||||
}
|
||||
|
||||
const char* headerVoltageSettings()
|
||||
{
|
||||
return gGerman ? "Spannung" : "Voltage Settings";
|
||||
}
|
||||
|
||||
const char* headerOther()
|
||||
{
|
||||
return gGerman ? "Sonstiges" : "Other";
|
||||
}
|
||||
|
||||
const char* headerIniFilePaths()
|
||||
{
|
||||
return gGerman ? "INI-Dateipfade" : "INI File Paths";
|
||||
}
|
||||
|
||||
const char* headerLinksAndResources()
|
||||
{
|
||||
return gGerman ? "Links und Infos" : "Links and Resources";
|
||||
}
|
||||
|
||||
const char* errorListItemTitleIni()
|
||||
{
|
||||
return gGerman ? "\uE150 INI-Problem" : "\uE150 INI file not found";
|
||||
}
|
||||
|
||||
std::string iniLoadErrorBody(const std::string& path)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Die Datei konnte nicht geladen werden:\n" + path + "\n\n"
|
||||
"Prüfen Sie den Pfad in den Einstellungen.";
|
||||
return "Could not load " + path + "\n\n"
|
||||
"Make sure the INI file exists at the expected path.\n"
|
||||
"You can configure paths in the Settings tab.";
|
||||
}
|
||||
|
||||
std::string iniSectionErrorBody(const std::string& path, const std::string& osName)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Kein OS-Abschnitt in " + path + "\n\n"
|
||||
"Die INI sollte z. B. einen Abschnitt ["
|
||||
+ osName + " OC] enthalten.";
|
||||
return "No OS section found in " + path + "\n\n"
|
||||
"The INI file should contain a section like\n"
|
||||
"[" + osName + " OC] with your configuration.";
|
||||
}
|
||||
|
||||
const char* notifyConfigSaved()
|
||||
{
|
||||
return gGerman ? "\uE14B Konfiguration gespeichert" : "\uE14B Configuration saved";
|
||||
}
|
||||
|
||||
const char* notifyConfigSaveError()
|
||||
{
|
||||
return gGerman ? "\uE150 Fehler beim Speichern!" : "\uE150 Error saving configuration!";
|
||||
}
|
||||
|
||||
const char* notifyPathUpdated()
|
||||
{
|
||||
return gGerman ? "\uE14B Pfad aktualisiert" : "\uE14B Path updated";
|
||||
}
|
||||
|
||||
const char* settingsIntro()
|
||||
{
|
||||
return gGerman ? "Wählen Sie, welche INI-Datei jeder Reiter liest und schreibt.\n"
|
||||
"Änderungen gelten sofort."
|
||||
: "Select which INI file each OS tab reads and writes.\n"
|
||||
"Changes take effect immediately.";
|
||||
}
|
||||
|
||||
const char* pathListDescriptionLakka()
|
||||
{
|
||||
return gGerman ? "Tippen, um eine INI-Datei zu wählen" : "Tap to browse for an INI file";
|
||||
}
|
||||
|
||||
const char* fileBrowserTitlePrefix()
|
||||
{
|
||||
return gGerman ? "INI wählen \u2014 " : "Select INI \u2014 ";
|
||||
}
|
||||
|
||||
std::string fileBrowserNoIni(const std::string& dir)
|
||||
{
|
||||
if (gGerman)
|
||||
return "Keine .ini-Dateien in " + dir;
|
||||
return "No .ini files found in " + dir;
|
||||
}
|
||||
|
||||
const char* aboutSubtitle()
|
||||
{
|
||||
return gGerman ? "Switchroot INI-Konfiguration\n"
|
||||
"Linux-, Android- und Lakka-OC ohne PC bearbeiten!"
|
||||
: "Switchroot INI Configuration Editor\n"
|
||||
"Edit your Linux, Android and Lakka OC settings without a PC!";
|
||||
}
|
||||
|
||||
const char* aboutCopyright()
|
||||
{
|
||||
return gGerman ? "Lizenziert unter GPL-3.0\n"
|
||||
"UI: Borealis\n"
|
||||
"Basierend auf der Arbeit von Switchroot\n"
|
||||
"\u00A9 2026 NiklasCFW"
|
||||
: "Licensed under GPL-3.0\n"
|
||||
"Powered by Borealis UI framework\n"
|
||||
"Based on the work of Switchroot\n"
|
||||
"\u00A9 2026 NiklasCFW";
|
||||
}
|
||||
|
||||
const char* aboutLinks()
|
||||
{
|
||||
return gGerman ? "\uE016 NiklasCFW-Dokumentation: Anleitungen und Infos\n"
|
||||
"\uE016 NiklasCFW-Discord: Fragen und Community\n"
|
||||
"\uE016 Quellcode auf GitHub (OmniNX)"
|
||||
: "\uE016 NiklasCFW Docs for setup guides and documentation\n"
|
||||
"\uE016 NiklasCFW's Discord server for support and community\n"
|
||||
"\uE016 Source code available on the OmniNX GitHub";
|
||||
}
|
||||
|
||||
const char* ocBoolLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_BOOL_LABEL, sizeof(OC_BOOL_LABEL) / sizeof(OC_BOOL_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
const char* ocFreqLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_FREQ_LABEL, sizeof(OC_FREQ_LABEL) / sizeof(OC_FREQ_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
const char* ocVoltageLabel(const std::string& key)
|
||||
{
|
||||
return lookup(OC_VOLT_LABEL, sizeof(OC_VOLT_LABEL) / sizeof(OC_VOLT_LABEL[0]), key, key.c_str());
|
||||
}
|
||||
|
||||
} // namespace I18n
|
||||
57
src/i18n.h
Normal file
57
src/i18n.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
SWR INI Tool - Switchroot INI Configuration Editor
|
||||
Copyright (C) 2026 Switchroot
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace I18n
|
||||
{
|
||||
|
||||
void init();
|
||||
|
||||
bool isGerman();
|
||||
|
||||
const char* appTitle();
|
||||
|
||||
const char* tabSettings();
|
||||
const char* tabAbout();
|
||||
|
||||
const char* wordOn();
|
||||
const char* wordOff();
|
||||
|
||||
std::string sectionEditLine(const std::string& section, const std::string& path);
|
||||
|
||||
const char* headerToggleOptions();
|
||||
const char* headerFrequencySettings();
|
||||
const char* headerVoltageSettings();
|
||||
const char* headerOther();
|
||||
const char* headerIniFilePaths();
|
||||
const char* headerLinksAndResources();
|
||||
|
||||
const char* errorListItemTitleIni();
|
||||
std::string iniLoadErrorBody(const std::string& path);
|
||||
std::string iniSectionErrorBody(const std::string& path, const std::string& osName);
|
||||
|
||||
const char* notifyConfigSaved();
|
||||
const char* notifyConfigSaveError();
|
||||
const char* notifyPathUpdated();
|
||||
|
||||
const char* settingsIntro();
|
||||
|
||||
const char* pathListDescriptionLakka();
|
||||
|
||||
const char* fileBrowserTitlePrefix();
|
||||
std::string fileBrowserNoIni(const std::string& dir);
|
||||
|
||||
const char* aboutSubtitle();
|
||||
const char* aboutCopyright();
|
||||
const char* aboutLinks();
|
||||
|
||||
const char* ocBoolLabel(const std::string& key);
|
||||
const char* ocFreqLabel(const std::string& key);
|
||||
const char* ocVoltageLabel(const std::string& key);
|
||||
|
||||
} // namespace I18n
|
||||
31
src/logo.cpp
31
src/logo.cpp
@@ -5,9 +5,9 @@
|
||||
|
||||
#include "logo.h"
|
||||
|
||||
Logo::Logo(LogoStyle style)
|
||||
Logo::Logo()
|
||||
{
|
||||
this->logoLabel = new brls::Label(brls::LabelStyle::LIST_ITEM, "SWR", style == LogoStyle::ABOUT);
|
||||
this->logoLabel = new brls::Label(brls::LabelStyle::LIST_ITEM, "SWR", true);
|
||||
this->logoLabel->setParent(this);
|
||||
|
||||
int logoFont = brls::Application::findFont(LOGO_FONT_NAME);
|
||||
@@ -16,35 +16,18 @@ Logo::Logo(LogoStyle style)
|
||||
this->logoLabel->setFont(logoFont);
|
||||
}
|
||||
|
||||
if (style == LogoStyle::ABOUT)
|
||||
{
|
||||
this->logoLabel->setFontSize(LOGO_ABOUT_FONT_SIZE);
|
||||
this->logoLabel->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
if (style == LogoStyle::HEADER)
|
||||
{
|
||||
this->logoLabel->setFontSize(LOGO_HEADER_FONT_SIZE);
|
||||
this->descLabel = new brls::Label(brls::LabelStyle::LIST_ITEM, "INI Tool");
|
||||
this->descLabel->setParent(this);
|
||||
this->descLabel->setFontSize(LOGO_DESC_FONT_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
Logo::~Logo()
|
||||
{
|
||||
delete this->logoLabel;
|
||||
|
||||
if (this->descLabel)
|
||||
delete this->descLabel;
|
||||
}
|
||||
|
||||
void Logo::draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx)
|
||||
{
|
||||
this->logoLabel->frame(ctx);
|
||||
|
||||
if (this->descLabel)
|
||||
this->descLabel->frame(ctx);
|
||||
}
|
||||
|
||||
void Logo::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash)
|
||||
@@ -52,14 +35,4 @@ void Logo::layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash)
|
||||
this->logoLabel->setBoundaries(this->x, this->y + LOGO_OFFSET, this->width, this->height);
|
||||
this->logoLabel->layout(vg, style, stash);
|
||||
this->height = this->logoLabel->getHeight();
|
||||
|
||||
if (this->descLabel)
|
||||
{
|
||||
this->descLabel->layout(vg, style, stash);
|
||||
this->descLabel->setBoundaries(
|
||||
this->x + LOGO_HEADER_SPACING + this->logoLabel->getWidth(),
|
||||
this->y + style->AppletFrame.titleOffset - 1,
|
||||
this->descLabel->getWidth(),
|
||||
height);
|
||||
}
|
||||
}
|
||||
|
||||
12
src/logo.h
12
src/logo.h
@@ -9,30 +9,20 @@
|
||||
|
||||
#define APP_ASSET(p) APP_RESOURCES p
|
||||
|
||||
enum class LogoStyle
|
||||
{
|
||||
HEADER = 0,
|
||||
ABOUT
|
||||
};
|
||||
|
||||
#define LOGO_FONT_NAME "logo"
|
||||
#define LOGO_FONT_PATH APP_ASSET("fira/FiraSans-Medium-rnx.ttf")
|
||||
|
||||
#define LOGO_HEADER_FONT_SIZE 45
|
||||
#define LOGO_HEADER_SPACING 12
|
||||
#define LOGO_ABOUT_FONT_SIZE 55
|
||||
#define LOGO_DESC_FONT_SIZE 28
|
||||
#define LOGO_OFFSET 2
|
||||
|
||||
class Logo : public brls::View
|
||||
{
|
||||
protected:
|
||||
brls::Label* logoLabel = nullptr;
|
||||
brls::Label* descLabel = nullptr;
|
||||
void layout(NVGcontext* vg, brls::Style* style, brls::FontStash* stash);
|
||||
void draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx) override;
|
||||
|
||||
public:
|
||||
Logo(LogoStyle style);
|
||||
Logo();
|
||||
virtual ~Logo();
|
||||
};
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
#include "main_frame.h"
|
||||
#include "logo.h"
|
||||
#include "app_config.h"
|
||||
#include "i18n.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
I18n::init();
|
||||
|
||||
// Init the app
|
||||
if (!brls::Application::init("SWR INI Tool"))
|
||||
if (!brls::Application::init(I18n::appTitle()))
|
||||
{
|
||||
brls::Logger::error("Unable to init Borealis application");
|
||||
return EXIT_FAILURE;
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
#include "os_config_tab.h"
|
||||
#include "settings_tab.h"
|
||||
#include "about_tab.h"
|
||||
#include "logo.h"
|
||||
#include "app_config.h"
|
||||
#include "i18n.h"
|
||||
#include "logo.h"
|
||||
|
||||
OsConfigTab* MainFrame::osTabs[(int)OsTarget::COUNT] = {};
|
||||
|
||||
@@ -17,8 +18,10 @@ MainFrame::MainFrame() : TabFrame()
|
||||
{
|
||||
AppConfig& cfg = AppConfig::get();
|
||||
|
||||
// Header logo
|
||||
this->setIcon(new Logo(LogoStyle::HEADER));
|
||||
this->setTitle(I18n::appTitle());
|
||||
brls::Image* headerIcon = new brls::Image(APP_ASSET("gui_icon.png"));
|
||||
headerIcon->setScaleType(brls::ImageScaleType::FIT);
|
||||
this->setIcon(headerIcon);
|
||||
|
||||
// OS configuration tabs — paths from config
|
||||
osTabs[(int)OsTarget::ANDROID] = new OsConfigTab("Android", cfg.getPath(OsTarget::ANDROID));
|
||||
@@ -28,11 +31,11 @@ MainFrame::MainFrame() : TabFrame()
|
||||
this->addTab("Android", osTabs[(int)OsTarget::ANDROID]);
|
||||
this->addTab("Linux", osTabs[(int)OsTarget::LINUX]);
|
||||
this->addTab("Lakka", osTabs[(int)OsTarget::LAKKA]);
|
||||
this->addTab("Settings", new SettingsTab());
|
||||
this->addTab(I18n::tabSettings(), new SettingsTab());
|
||||
|
||||
this->addSeparator();
|
||||
|
||||
this->addTab("About", new AboutTab());
|
||||
this->addTab(I18n::tabAbout(), new AboutTab());
|
||||
}
|
||||
|
||||
MainFrame::~MainFrame()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "os_config_tab.h"
|
||||
#include "i18n.h"
|
||||
#include "oc_defs.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -13,18 +14,14 @@ OsConfigTab::OsConfigTab(const std::string& osName, const std::string& iniPath)
|
||||
{
|
||||
if (!this->ini.load(iniPath))
|
||||
{
|
||||
buildErrorUI("Could not load " + iniPath + "\n\n"
|
||||
"Make sure the INI file exists at the expected path.\n"
|
||||
"You can configure paths in the Settings tab.");
|
||||
buildErrorUI(I18n::errorListItemTitleIni(), I18n::iniLoadErrorBody(iniPath));
|
||||
return;
|
||||
}
|
||||
|
||||
this->osSection = this->ini.findOsSection();
|
||||
if (this->osSection.empty())
|
||||
{
|
||||
buildErrorUI("No OS section found in " + iniPath + "\n\n"
|
||||
"The INI file should contain a section like\n"
|
||||
"[" + osName + " OC] with your configuration.");
|
||||
buildErrorUI(I18n::errorListItemTitleIni(), I18n::iniSectionErrorBody(iniPath, osName));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,30 +38,26 @@ void OsConfigTab::reload(const std::string& newIniPath)
|
||||
|
||||
if (!this->ini.load(iniPath))
|
||||
{
|
||||
buildErrorUI("Could not load " + iniPath + "\n\n"
|
||||
"Make sure the INI file exists at the expected path.\n"
|
||||
"You can configure paths in the Settings tab.");
|
||||
buildErrorUI(I18n::errorListItemTitleIni(), I18n::iniLoadErrorBody(iniPath));
|
||||
return;
|
||||
}
|
||||
|
||||
this->osSection = this->ini.findOsSection();
|
||||
if (this->osSection.empty())
|
||||
{
|
||||
buildErrorUI("No OS section found in " + iniPath + "\n\n"
|
||||
"The INI file should contain a section like\n"
|
||||
"[" + osName + " OC] with your configuration.");
|
||||
buildErrorUI(I18n::errorListItemTitleIni(), I18n::iniSectionErrorBody(iniPath, osName));
|
||||
return;
|
||||
}
|
||||
|
||||
buildUI();
|
||||
}
|
||||
|
||||
void OsConfigTab::buildErrorUI(const std::string& message)
|
||||
void OsConfigTab::buildErrorUI(const std::string& title, const std::string& message)
|
||||
{
|
||||
this->setSpacing(15);
|
||||
|
||||
// Use a ListItem (focusable) so borealis doesn't crash on controller nav
|
||||
brls::ListItem *errorItem = new brls::ListItem("\uE150 INI file not found", message);
|
||||
brls::ListItem *errorItem = new brls::ListItem(title, message);
|
||||
this->addView(errorItem);
|
||||
}
|
||||
|
||||
@@ -76,51 +69,44 @@ void OsConfigTab::buildUI()
|
||||
// Section name info
|
||||
brls::Label *sectionInfo = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Editing section [" + this->osSection + "] from " + this->iniPath,
|
||||
I18n::sectionEditLine(this->osSection, this->iniPath),
|
||||
true
|
||||
);
|
||||
this->addView(sectionInfo);
|
||||
|
||||
// ── Toggle Options ──
|
||||
this->addView(new brls::Header("Toggle Options"));
|
||||
this->addView(new brls::Header(I18n::headerToggleOptions()));
|
||||
|
||||
for (const auto& def : OC_BOOL_KEYS)
|
||||
{
|
||||
if (this->ini.hasKey(this->osSection, def.key))
|
||||
{
|
||||
bool val = this->ini.getBool(this->osSection, def.key);
|
||||
addBooleanToggle(def.label, "", def.key, val);
|
||||
}
|
||||
bool val = this->ini.getBool(this->osSection, def.key, false);
|
||||
addBooleanToggle(I18n::ocBoolLabel(def.key), "", def.key, val);
|
||||
}
|
||||
|
||||
// ── Frequency Settings ──
|
||||
brls::Rectangle* spacer1 = new brls::Rectangle(nvgRGBA(0, 0, 0, 0));
|
||||
spacer1->setHeight(30);
|
||||
this->addView(spacer1);
|
||||
this->addView(new brls::Header("Frequency Settings"));
|
||||
this->addView(new brls::Header(I18n::headerFrequencySettings()));
|
||||
|
||||
for (const auto& def : OC_FREQ_KEYS)
|
||||
{
|
||||
if (this->ini.hasKey(this->osSection, def.key))
|
||||
{
|
||||
uint32_t val = (uint32_t)this->ini.getInt(this->osSection, def.key, 0);
|
||||
addFreqDropdown(def.label, "", def.key, val, def.options);
|
||||
}
|
||||
int defVal = def.options.empty() ? 0 : (int)def.options.front();
|
||||
uint32_t val = (uint32_t)this->ini.getInt(this->osSection, def.key, defVal);
|
||||
addFreqDropdown(I18n::ocFreqLabel(def.key), "", def.key, val, def.options);
|
||||
}
|
||||
|
||||
// ── Voltage Settings ──
|
||||
brls::Rectangle* spacer2 = new brls::Rectangle(nvgRGBA(0, 0, 0, 0));
|
||||
spacer2->setHeight(30);
|
||||
this->addView(spacer2);
|
||||
this->addView(new brls::Header("Voltage Settings"));
|
||||
this->addView(new brls::Header(I18n::headerVoltageSettings()));
|
||||
|
||||
for (const auto& def : OC_VOLTAGE_KEYS)
|
||||
{
|
||||
if (this->ini.hasKey(this->osSection, def.key))
|
||||
{
|
||||
uint32_t val = (uint32_t)this->ini.getInt(this->osSection, def.key, 0);
|
||||
addVoltageDropdown(def.label, "", def.key, val, def.options);
|
||||
}
|
||||
int defVal = def.options.empty() ? 0 : (int)def.options.front();
|
||||
uint32_t val = (uint32_t)this->ini.getInt(this->osSection, def.key, defVal);
|
||||
addVoltageDropdown(I18n::ocVoltageLabel(def.key), "", def.key, val, def.options);
|
||||
}
|
||||
|
||||
// ── Other Keys (read-only info) ──
|
||||
@@ -148,7 +134,7 @@ void OsConfigTab::buildUI()
|
||||
brls::Rectangle* spacerOther = new brls::Rectangle(nvgRGBA(0, 0, 0, 0));
|
||||
spacerOther->setHeight(30);
|
||||
this->addView(spacerOther);
|
||||
this->addView(new brls::Header("Other"));
|
||||
this->addView(new brls::Header(I18n::headerOther()));
|
||||
hasOtherKeys = true;
|
||||
}
|
||||
|
||||
@@ -163,11 +149,11 @@ void OsConfigTab::saveAndNotify()
|
||||
{
|
||||
if (this->ini.save())
|
||||
{
|
||||
brls::Application::notify("\uE14B Configuration saved");
|
||||
brls::Application::notify(I18n::notifyConfigSaved());
|
||||
}
|
||||
else
|
||||
{
|
||||
brls::Application::notify("\uE150 Error saving configuration!");
|
||||
brls::Application::notify(I18n::notifyConfigSaveError());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +161,7 @@ void OsConfigTab::addBooleanToggle(const std::string& label, const std::string&
|
||||
const std::string& key, bool currentValue)
|
||||
{
|
||||
brls::ToggleListItem *toggle = new brls::ToggleListItem(
|
||||
label, currentValue, description, "ON", "OFF"
|
||||
label, currentValue, description, I18n::wordOn(), I18n::wordOff()
|
||||
);
|
||||
|
||||
std::string keyCopy = key;
|
||||
|
||||
@@ -23,7 +23,7 @@ private:
|
||||
std::string osSection;
|
||||
|
||||
void buildUI();
|
||||
void buildErrorUI(const std::string& message);
|
||||
void buildErrorUI(const std::string& title, const std::string& message);
|
||||
void saveAndNotify();
|
||||
|
||||
// Create a toggle for a boolean key
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "settings_tab.h"
|
||||
#include "file_browser.h"
|
||||
#include "i18n.h"
|
||||
#include "main_frame.h"
|
||||
#include "os_config_tab.h"
|
||||
|
||||
@@ -15,14 +16,13 @@ SettingsTab::SettingsTab()
|
||||
|
||||
brls::Label *info = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Select which INI file each OS tab reads and writes.\n"
|
||||
"Changes take effect immediately.",
|
||||
I18n::settingsIntro(),
|
||||
true
|
||||
);
|
||||
this->addView(info);
|
||||
|
||||
// ── INI File Paths ──
|
||||
this->addView(new brls::Header("INI File Paths"));
|
||||
this->addView(new brls::Header(I18n::headerIniFilePaths()));
|
||||
|
||||
addPathItem(OsTarget::ANDROID);
|
||||
addPathItem(OsTarget::LINUX);
|
||||
@@ -35,7 +35,7 @@ void SettingsTab::addPathItem(OsTarget target)
|
||||
std::string currentPath = cfg.getPath(target);
|
||||
std::string label = std::string(AppConfig::getLabel(target)) + " INI";
|
||||
|
||||
std::string description = (target == OsTarget::LAKKA) ? "Tap to browse for an INI file" : "";
|
||||
std::string description = (target == OsTarget::LAKKA) ? I18n::pathListDescriptionLakka() : "";
|
||||
brls::ListItem* item = new brls::ListItem(label, description);
|
||||
item->setValue(currentPath);
|
||||
|
||||
@@ -59,7 +59,7 @@ void SettingsTab::addPathItem(OsTarget target)
|
||||
if (tab)
|
||||
tab->reload(selectedPath);
|
||||
|
||||
brls::Application::notify("\uE14B Path updated");
|
||||
brls::Application::notify(I18n::notifyPathUpdated());
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user