mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
Qt: Serialize icon & theme, properly set them
This commit is contained in:
parent
95cc79e0a3
commit
6f90c25fd2
8 changed files with 128 additions and 26 deletions
|
@ -280,6 +280,7 @@ set(SOURCE_FILES src/emulator.cpp src/io_file.cpp src/config.cpp
|
||||||
src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp
|
src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp
|
||||||
src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp
|
src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp
|
||||||
src/discord_rpc.cpp src/lua.cpp src/memory_mapped_file.cpp src/miniaudio.cpp src/renderdoc.cpp
|
src/discord_rpc.cpp src/lua.cpp src/memory_mapped_file.cpp src/miniaudio.cpp src/renderdoc.cpp
|
||||||
|
src/frontend_settings.cpp
|
||||||
)
|
)
|
||||||
set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp)
|
set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp)
|
||||||
set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp
|
set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp
|
||||||
|
@ -361,7 +362,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp
|
||||||
include/PICA/pica_vert_config.hpp include/sdl_sensors.hpp include/PICA/draw_acceleration.hpp include/renderdoc.hpp
|
include/PICA/pica_vert_config.hpp include/sdl_sensors.hpp include/PICA/draw_acceleration.hpp include/renderdoc.hpp
|
||||||
include/align.hpp include/audio/aac_decoder.hpp include/PICA/pica_simd.hpp include/services/fonts.hpp
|
include/align.hpp include/audio/aac_decoder.hpp include/PICA/pica_simd.hpp include/services/fonts.hpp
|
||||||
include/audio/audio_interpolation.hpp include/audio/hle_mixer.hpp include/audio/dsp_simd.hpp
|
include/audio/audio_interpolation.hpp include/audio/hle_mixer.hpp include/audio/dsp_simd.hpp
|
||||||
include/services/dsp_firmware_db.hpp
|
include/services/dsp_firmware_db.hpp include/frontend_settings.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
cmrc_add_resource_library(
|
cmrc_add_resource_library(
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "audio/dsp_core.hpp"
|
#include "audio/dsp_core.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
#include "frontend_settings.hpp"
|
||||||
|
|
||||||
struct AudioDeviceConfig {
|
struct AudioDeviceConfig {
|
||||||
float volumeRaw = 1.0f;
|
float volumeRaw = 1.0f;
|
||||||
|
@ -86,6 +87,7 @@ struct EmulatorConfig {
|
||||||
|
|
||||||
WindowSettings windowSettings;
|
WindowSettings windowSettings;
|
||||||
AudioDeviceConfig audioDeviceConfig;
|
AudioDeviceConfig audioDeviceConfig;
|
||||||
|
FrontendSettings frontendSettings;
|
||||||
|
|
||||||
EmulatorConfig(const std::filesystem::path& path);
|
EmulatorConfig(const std::filesystem::path& path);
|
||||||
void load();
|
void load();
|
||||||
|
|
30
include/frontend_settings.hpp
Normal file
30
include/frontend_settings.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Some UI settings that aren't fully frontend-dependent. Note: Not all frontends will support the same settings.
|
||||||
|
// Note: Any enums should ideally be ordered in the same order we want to show them in UI dropdown menus, so that we can cast indices to enums
|
||||||
|
// directly.
|
||||||
|
struct FrontendSettings {
|
||||||
|
enum class Theme : int {
|
||||||
|
System = 0,
|
||||||
|
Light = 1,
|
||||||
|
Dark = 2,
|
||||||
|
GreetingsCat = 3,
|
||||||
|
Cream = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Different panda-themed window icons
|
||||||
|
enum class WindowIcon : int {
|
||||||
|
Rpog = 0,
|
||||||
|
Rsyn = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
Theme theme = Theme::Dark;
|
||||||
|
WindowIcon icon = WindowIcon::Rpog;
|
||||||
|
|
||||||
|
static Theme themeFromString(std::string inString);
|
||||||
|
static const char* themeToString(Theme theme);
|
||||||
|
|
||||||
|
static WindowIcon iconFromString(std::string inString);
|
||||||
|
static const char* iconToString(WindowIcon icon);
|
||||||
|
};
|
|
@ -15,6 +15,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "emulator.hpp"
|
#include "emulator.hpp"
|
||||||
|
#include "frontend_settings.hpp"
|
||||||
|
|
||||||
class ConfigWindow : public QDialog {
|
class ConfigWindow : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -23,21 +24,8 @@ class ConfigWindow : public QDialog {
|
||||||
using ConfigCallback = std::function<void()>;
|
using ConfigCallback = std::function<void()>;
|
||||||
using IconCallback = std::function<void(const QString&)>;
|
using IconCallback = std::function<void(const QString&)>;
|
||||||
|
|
||||||
enum class Theme : int {
|
using Theme = FrontendSettings::Theme;
|
||||||
System = 0,
|
using WindowIcon = FrontendSettings::WindowIcon;
|
||||||
Light = 1,
|
|
||||||
Dark = 2,
|
|
||||||
GreetingsCat = 3,
|
|
||||||
Cream = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class WindowIcon : int {
|
|
||||||
Rpog = 0,
|
|
||||||
Rsyn = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
Theme currentTheme;
|
|
||||||
WindowIcon currentIcon;
|
|
||||||
|
|
||||||
QTextEdit* helpText = nullptr;
|
QTextEdit* helpText = nullptr;
|
||||||
QListWidget* widgetList = nullptr;
|
QListWidget* widgetList = nullptr;
|
||||||
|
@ -54,8 +42,8 @@ class ConfigWindow : public QDialog {
|
||||||
IconCallback updateIcon;
|
IconCallback updateIcon;
|
||||||
|
|
||||||
void addWidget(QWidget* widget, QString title, QString icon, QString helpText);
|
void addWidget(QWidget* widget, QString title, QString icon, QString helpText);
|
||||||
void setTheme(Theme theme);
|
void setTheme(FrontendSettings::Theme theme);
|
||||||
void setIcon(WindowIcon icon);
|
void setIcon(FrontendSettings::WindowIcon icon);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConfigWindow(ConfigCallback configCallback, IconCallback iconCallback, const EmulatorConfig& config, QWidget* parent = nullptr);
|
ConfigWindow(ConfigCallback configCallback, IconCallback iconCallback, const EmulatorConfig& config, QWidget* parent = nullptr);
|
||||||
|
|
|
@ -130,6 +130,16 @@ void EmulatorConfig::load() {
|
||||||
sdWriteProtected = toml::find_or<toml::boolean>(sd, "WriteProtectVirtualSD", false);
|
sdWriteProtected = toml::find_or<toml::boolean>(sd, "WriteProtectVirtualSD", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.contains("UI")) {
|
||||||
|
auto uiResult = toml::expect<toml::value>(data.at("UI"));
|
||||||
|
if (uiResult.is_ok()) {
|
||||||
|
auto ui = uiResult.unwrap();
|
||||||
|
|
||||||
|
frontendSettings.theme = FrontendSettings::themeFromString(toml::find_or<std::string>(ui, "Theme", "dark"));
|
||||||
|
frontendSettings.icon = FrontendSettings::iconFromString(toml::find_or<std::string>(ui, "WindowIcon", "rpog"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatorConfig::save() {
|
void EmulatorConfig::save() {
|
||||||
|
@ -186,6 +196,9 @@ void EmulatorConfig::save() {
|
||||||
data["SD"]["UseVirtualSD"] = sdCardInserted;
|
data["SD"]["UseVirtualSD"] = sdCardInserted;
|
||||||
data["SD"]["WriteProtectVirtualSD"] = sdWriteProtected;
|
data["SD"]["WriteProtectVirtualSD"] = sdWriteProtected;
|
||||||
|
|
||||||
|
data["UI"]["Theme"] = std::string(FrontendSettings::themeToString(frontendSettings.theme));
|
||||||
|
data["UI"]["WindowIcon"] = std::string(FrontendSettings::iconToString(frontendSettings.icon));
|
||||||
|
|
||||||
std::ofstream file(path, std::ios::out);
|
std::ofstream file(path, std::ios::out);
|
||||||
file << data;
|
file << data;
|
||||||
file.close();
|
file.close();
|
||||||
|
|
59
src/frontend_settings.cpp
Normal file
59
src/frontend_settings.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "frontend_settings.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
// Frontend setting serialization/deserialization functions
|
||||||
|
|
||||||
|
FrontendSettings::Theme FrontendSettings::themeFromString(std::string inString) {
|
||||||
|
// Transform to lower-case to make the setting case-insensitive
|
||||||
|
std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, Theme> map = {
|
||||||
|
{"system", Theme::System}, {"light", Theme::Light}, {"dark", Theme::Dark}, {"greetingscat", Theme::GreetingsCat}, {"cream", Theme::Cream},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto search = map.find(inString); search != map.end()) {
|
||||||
|
return search->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to dark theme
|
||||||
|
return Theme::Dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* FrontendSettings::themeToString(Theme theme) {
|
||||||
|
switch (theme) {
|
||||||
|
case Theme::System: return "system";
|
||||||
|
case Theme::Light: return "light";
|
||||||
|
case Theme::GreetingsCat: return "greetingscat";
|
||||||
|
case Theme::Cream: return "cream";
|
||||||
|
|
||||||
|
case Theme::Dark:
|
||||||
|
default: return "dark";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FrontendSettings::WindowIcon FrontendSettings::iconFromString(std::string inString) { // Transform to lower-case to make the setting case-insensitive
|
||||||
|
std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, WindowIcon> map = {
|
||||||
|
{"rpog", WindowIcon::Rpog}, {"rsyn", WindowIcon::Rsyn},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto search = map.find(inString); search != map.end()) {
|
||||||
|
return search->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to the icon rpog icon
|
||||||
|
return WindowIcon::Rpog;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* FrontendSettings::iconToString(WindowIcon icon) {
|
||||||
|
switch (icon) {
|
||||||
|
case WindowIcon::Rsyn: return "rsyn";
|
||||||
|
|
||||||
|
case WindowIcon::Rpog:
|
||||||
|
default: return "rpog";
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,8 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, IconCallback iconCallb
|
||||||
updateIcon = std::move(iconCallback);
|
updateIcon = std::move(iconCallback);
|
||||||
|
|
||||||
// Set up theme selection
|
// Set up theme selection
|
||||||
setTheme(Theme::Dark);
|
setTheme(config.frontendSettings.theme);
|
||||||
setIcon(WindowIcon::Rpog);
|
setIcon(config.frontendSettings.icon);
|
||||||
|
|
||||||
// Initialize the widget list and the widget container widgets
|
// Initialize the widget list and the widget container widgets
|
||||||
widgetList = new QListWidget(this);
|
widgetList = new QListWidget(this);
|
||||||
|
@ -65,17 +65,25 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, IconCallback iconCallb
|
||||||
themeSelect->addItem(tr("Dark"));
|
themeSelect->addItem(tr("Dark"));
|
||||||
themeSelect->addItem(tr("Greetings Cat"));
|
themeSelect->addItem(tr("Greetings Cat"));
|
||||||
themeSelect->addItem(tr("Cream"));
|
themeSelect->addItem(tr("Cream"));
|
||||||
themeSelect->setCurrentIndex(static_cast<int>(currentTheme));
|
themeSelect->setCurrentIndex(static_cast<int>(config.frontendSettings.theme));
|
||||||
connect(themeSelect, &QComboBox::currentIndexChanged, this, [&](int index) {
|
connect(themeSelect, &QComboBox::currentIndexChanged, this, [&](int index) {
|
||||||
|
config.frontendSettings.theme = static_cast<Theme>(index);
|
||||||
setTheme(static_cast<Theme>(index));
|
setTheme(static_cast<Theme>(index));
|
||||||
|
|
||||||
|
updateConfig();
|
||||||
});
|
});
|
||||||
guiLayout->addRow(tr("Color theme"), themeSelect);
|
guiLayout->addRow(tr("Color theme"), themeSelect);
|
||||||
|
|
||||||
QComboBox* iconSelect = new QComboBox();
|
QComboBox* iconSelect = new QComboBox();
|
||||||
iconSelect->addItem(tr("Happy panda"));
|
iconSelect->addItem(tr("Happy panda"));
|
||||||
iconSelect->addItem(tr("Happy panda (colourful)"));
|
iconSelect->addItem(tr("Happy panda (colourful)"));
|
||||||
iconSelect->setCurrentIndex(static_cast<int>(currentIcon));
|
iconSelect->setCurrentIndex(static_cast<int>(config.frontendSettings.icon));
|
||||||
connect(iconSelect, &QComboBox::currentIndexChanged, this, [&](int index) { setIcon(static_cast<WindowIcon>(index)); });
|
connect(iconSelect, &QComboBox::currentIndexChanged, this, [&](int index) {
|
||||||
|
config.frontendSettings.icon = static_cast<WindowIcon>(index);
|
||||||
|
setIcon(static_cast<WindowIcon>(index));
|
||||||
|
|
||||||
|
updateConfig();
|
||||||
|
});
|
||||||
guiLayout->addRow(tr("Window icon"), iconSelect);
|
guiLayout->addRow(tr("Window icon"), iconSelect);
|
||||||
|
|
||||||
QCheckBox* showAppVersion = new QCheckBox(tr("Show version on window title"));
|
QCheckBox* showAppVersion = new QCheckBox(tr("Show version on window title"));
|
||||||
|
@ -286,8 +294,6 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, IconCallback iconCallb
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigWindow::setTheme(Theme theme) {
|
void ConfigWindow::setTheme(Theme theme) {
|
||||||
currentTheme = theme;
|
|
||||||
|
|
||||||
switch (theme) {
|
switch (theme) {
|
||||||
case Theme::Dark: {
|
case Theme::Dark: {
|
||||||
QApplication::setStyle(QStyleFactory::create("Fusion"));
|
QApplication::setStyle(QStyleFactory::create("Fusion"));
|
||||||
|
|
|
@ -420,6 +420,9 @@ void MainWindow::dispatchMessage(const EmulatorMessage& message) {
|
||||||
case MessageType::UpdateConfig:
|
case MessageType::UpdateConfig:
|
||||||
emu->getConfig() = configWindow->getConfig();
|
emu->getConfig() = configWindow->getConfig();
|
||||||
emu->reloadSettings();
|
emu->reloadSettings();
|
||||||
|
|
||||||
|
// Save new settings to disk
|
||||||
|
emu->getConfig().save();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue