/*
Copyright 2025 flyinghead
This file is part of Flycast.
Flycast is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Flycast is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Flycast. If not, see .
*/
#include "settings.h"
#include "gui.h"
#include "IconsFontAwesome6.h"
#include "mainui.h"
#include "oslib/storage.h"
#include "stdclass.h"
#include "achievements/achievements.h"
#include "imgui_stdlib.h"
static std::vector* g_currentPathList = nullptr;
static void managePathListCallback(std::string selection)
{
if (g_currentPathList != nullptr)
{
g_currentPathList->push_back(selection);
g_currentPathList = nullptr;
}
}
static void manageSinglePath(const char* label, const char *popupName, config::Option& pathOption, const char* helpText)
{
ImVec2 size;
size.x = 0.0f;
size.y = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2.f;
bool openPopup = false;
ImVec2 childSize;
if (beginFrame(label, size, &childSize))
{
ImGui::AlignTextToFramePadding();
if (pathOption.get().empty()) {
ImguiStyleVar _(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3));
std::string buttonLabel = T("Set") + std::string("##") + label;
openPopup = ImGui::Button(buttonLabel.c_str());
}
else
{
float w = childSize.x - ImGui::CalcTextSize(ICON_FA_TRASH_CAN).x - ImGui::GetStyle().FramePadding.x * 2
- ImGui::GetStyle().ItemSpacing.x;
std::string s = middleEllipsis(pathOption, w);
ImGui::Text("%s", s.c_str());
ImGui::SameLine(0, w - ImGui::CalcTextSize(s.c_str()).x + ImGui::GetStyle().ItemSpacing.x);
std::string buttonLabel = std::string(ICON_FA_TRASH_CAN "##") + label;
if (ImGui::Button(buttonLabel.c_str()))
pathOption.get().clear();
}
endFrame();
}
ImGui::SameLine();
ShowHelpMarker(helpText);
static std::string *pCurrentPath;
pCurrentPath = &pathOption.get();
select_file_popup(popupName, [](bool cancelled, std::string selection) {
if (!cancelled)
*pCurrentPath = selection;
return true;
});
if (openPopup)
ImGui::OpenPopup(T(popupName));
}
static void managePathList(const char* label, const char *popupName, std::vector& paths, const char* helpText)
{
ImguiID _(label);
ImVec2 size;
size.x = 0.0f;
size.y = (ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2.f)
* (paths.size() + 1);
bool openPopup = false;
ImVec2 childSize;
if (beginFrame(label, size, &childSize))
{
ImGui::AlignTextToFramePadding();
int to_delete = -1;
for (u32 i = 0; i < paths.size(); i++)
{
ImguiID _(std::to_string(i).c_str());
float maxW = childSize.x - ImGui::CalcTextSize(ICON_FA_TRASH_CAN).x - ImGui::GetStyle().FramePadding.x * 2
- ImGui::GetStyle().ItemSpacing.x;
std::string s = middleEllipsis(paths[i], maxW);
ImGui::Text("%s", s.c_str());
ImGui::SameLine(0, maxW - ImGui::CalcTextSize(s.c_str()).x + ImGui::GetStyle().ItemSpacing.x);
if (ImGui::Button(ICON_FA_TRASH_CAN))
to_delete = (int)i;
}
ImguiStyleVar _(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3));
std::string buttonLabel = T("Add") + std::string("##") + label;
openPopup = ImGui::Button(buttonLabel.c_str());
endFrame();
if (to_delete >= 0)
{
paths.erase(paths.begin() + to_delete);
SaveSettings();
}
}
ImGui::SameLine();
ShowHelpMarker(helpText);
// Handle file selection popup (following the same pattern as addContentPath)
if (openPopup)
g_currentPathList = &paths;
select_file_popup(popupName, [](bool cancelled, std::string selection) {
if (!cancelled)
managePathListCallback(selection);
return true;
});
#ifdef __ANDROID__
if (openPopup)
{
bool supported = hostfs::addStorage(true, false, T(popupName), [](bool cancelled, std::string selection) {
if (!cancelled)
managePathListCallback(selection);
});
if (!supported)
ImGui::OpenPopup(T(popupName));
}
#else
if (openPopup)
ImGui::OpenPopup(T(popupName));
#endif
}
static void addContentPathCallback(const std::string& path)
{
auto& contentPath = config::ContentPath.get();
if (std::count(contentPath.begin(), contentPath.end(), path) == 0)
{
scanner.stop();
contentPath.push_back(path);
if (gui_state == GuiState::Main)
// when adding content path from empty game list
SaveSettings();
scanner.refresh();
}
}
void addContentPath(bool start)
{
const char *title = T("Select a Content Folder");
select_file_popup(title, [](bool cancelled, std::string selection) {
if (!cancelled)
addContentPathCallback(selection);
return true;
});
#ifdef __ANDROID__
if (start)
{
bool supported = hostfs::addStorage(true, false, title, [](bool cancelled, std::string selection) {
if (!cancelled)
addContentPathCallback(selection);
});
if (!supported)
ImGui::OpenPopup(title);
}
#else
if (start)
ImGui::OpenPopup(title);
#endif
}
void gui_settings_general()
{
struct
{
const char* label;
const char* value;
}
UILanguages[] = {
{ T("System Default"), "" },
{ "English", "en" },
{ "Français", "fr" },
{ "Magyar", "hu" },
{ "日本語", "ja" },
{ "Português (Brasil)", "pt_BR" },
{ "Svenska", "sv" },
{ "Türkçe", "tr" },
{ "简体中文", "zh_CN" },
{ "正體中文", "zh_TW" },
};
// Determine the preview text
const std::string currentLanguage = config::UILanguage.get();
std::string preview;
for (const auto& it : UILanguages)
{
if (currentLanguage == it.value) {
preview = it.label;
break;
}
}
if (ImGui::BeginCombo(T("UI Language"), preview.c_str()))
{
for (const auto& lang : UILanguages)
{
const bool selected = (currentLanguage == lang.value);
if (ImGui::Selectable(lang.label, selected)) {
config::UILanguage = lang.value;
i18n::reloadLanguage();
}
if (selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
{
DisabledScope scope(settings.platform.isArcade());
const char *languages[] = { T("Japanese"), T("English"), T("German"), T("French"), T("Spanish"), T("Italian"), T("Default") };
OptionComboBox(T("Dreamcast Language"), config::Language, languages, std::size(languages),
T("The language as configured in the Dreamcast BIOS"));
const char *broadcast[] = { "NTSC", "PAL", "PAL/M", "PAL/N", T("Default") };
OptionComboBox(T("Broadcast"), config::Broadcast, broadcast, std::size(broadcast),
T("TV broadcasting standard for non-VGA modes"));
}
const char *consoleRegion[] = { T("Japan"), T("USA"), T("Europe"), T("Default") };
const char *arcadeRegion[] = { T("Japan"), T("USA"), i18n::translateCtx("region", "Export"), T("Korea") };
const char **region = settings.platform.isArcade() ? arcadeRegion : consoleRegion;
OptionComboBox(T("Region"), config::Region, region, std::size(consoleRegion),
T("BIOS region"));
const char *cable[] = { T("VGA"), T("RGB Component"), T("TV Composite") };
{
DisabledScope scope(config::Cable.isReadOnly() || settings.platform.isArcade());
const char *value = config::Cable == 0 ? cable[0]
: config::Cable > 0 && config::Cable <= (int)std::size(cable) ? cable[config::Cable - 1]
: "?";
if (ImGui::BeginCombo(T("Cable"), value, ImGuiComboFlags_None))
{
for (int i = 0; i < IM_ARRAYSIZE(cable); i++)
{
bool is_selected = i == 0 ? config::Cable <= 1 : config::Cable - 1 == i;
if (ImGui::Selectable(cable[i], &is_selected))
config::Cable = i == 0 ? 0 : i + 1;
if (is_selected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::SameLine();
ShowHelpMarker(T("Video connection type"));
}
#if !defined(TARGET_IPHONE)
ImVec2 size;
size.x = 0.0f;
size.y = (ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2.f)
* (config::ContentPath.get().size() + 1);
ImVec2 childSize;
if (beginFrame(T("Content Location"), size, &childSize))
{
int to_delete = -1;
for (u32 i = 0; i < config::ContentPath.get().size(); i++)
{
ImguiID _(config::ContentPath.get()[i].c_str());
ImGui::AlignTextToFramePadding();
float maxW = childSize.x - ImGui::CalcTextSize(ICON_FA_TRASH_CAN).x - ImGui::GetStyle().FramePadding.x * 2
- ImGui::GetStyle().ItemSpacing.x;
std::string s = middleEllipsis(config::ContentPath.get()[i], maxW);
ImGui::Text("%s", s.c_str());
ImGui::SameLine(0, maxW - ImGui::CalcTextSize(s.c_str()).x + ImGui::GetStyle().ItemSpacing.x);
if (ImGui::Button(ICON_FA_TRASH_CAN))
to_delete = i;
}
ImguiStyleVar _(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3));
const bool addContent = ImGui::Button((T("Add") + std::string("##") + "ContentLocation").c_str());
addContentPath(addContent);
ImGui::SameLine();
if (ImGui::Button(T("Rescan Content")))
scanner.refresh();
endFrame();
if (to_delete >= 0)
{
scanner.stop();
config::ContentPath.get().erase(config::ContentPath.get().begin() + to_delete);
scanner.refresh();
}
}
ImGui::SameLine();
ShowHelpMarker(T("The folders where your games are stored"));
size.y = ImGui::GetTextLineHeightWithSpacing() + ImGui::GetStyle().FramePadding.y * 2.0f;
ImGui::Spacing();
#if defined(__linux__) && !defined(__ANDROID__)
if (beginFrame(T("Data Folder"), size, &childSize))
{
float w = childSize.x - ImGui::GetStyle().FramePadding.x;
std::string s = middleEllipsis(get_writable_data_path(""), w);
ImGui::Text("%s", s.c_str());
endFrame();
}
ImGui::SameLine();
ShowHelpMarker(T("The folder containing BIOS files, as well as saved VMUs and states"));
#else
#if defined(__ANDROID__) || defined(TARGET_MAC)
size.y += ImGui::GetTextLineHeightWithSpacing();
#endif
if (beginFrame(T("Home Folder"), size, &childSize))
{
float w = childSize.x - ImGui::GetStyle().FramePadding.x;
std::string s = middleEllipsis(get_writable_config_path(""), w);
ImGui::Text("%s", s.c_str());
ImguiStyleVar _(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3));
#ifdef __ANDROID__
{
DisabledScope _(!config::UseSafFilePicker);
if (ImGui::Button(i18n::translateCtx("action", "Import")))
hostfs::importHomeDirectory();
ImGui::SameLine();
if (ImGui::Button(i18n::translateCtx("action", "Export")))
hostfs::exportHomeDirectory();
}
#endif
#ifdef TARGET_MAC
if (ImGui::Button(T("Reveal in Finder")))
{
char temp[512];
snprintf(temp, sizeof(temp), "open \"%s\"", get_writable_config_path("").c_str());
system(temp);
}
#endif
endFrame();
}
ImGui::SameLine();
ShowHelpMarker(T("The folder where Flycast saves configuration files and VMUs. BIOS files should be in a subfolder named \"data\""));
#endif // !linux
ImGui::Spacing();
#else // TARGET_IPHONE
{
ImguiStyleVar _(ImGuiStyleVar_FramePadding, ScaledVec2(24, 3));
if (ImGui::Button(T("Rescan Content")))
scanner.refresh();
}
#endif
ImGui::Spacing();
OptionCheckbox(T("Box Art Game List"), config::BoxartDisplayMode,
T("Display game cover art in the game list."));
OptionCheckbox(T("Fetch Box Art"), config::FetchBoxart,
T("Fetch cover images from TheGamesDB.net."));
if (OptionSlider(T("UI Scaling"), config::UIScaling, 50, 200, T("Adjust the size of UI elements and fonts."), "%d%%"))
uiUserScaleUpdated = true;
if (uiUserScaleUpdated)
{
ImGui::SameLine();
if (ImGui::Button(T("Apply"))) {
mainui_reinit();
uiUserScaleUpdated = false;
}
}
const char *themes[] = { T("Dark"), T("Light"), T("Dreamcast"), T("High Contrast"), T("Nintendo"), T("Aqua Chill") };
int previousUITheme = config::UITheme;
OptionComboBox(T("UI Theme"), config::UITheme, themes, std::size(themes),
T("Select the UI color theme."));
// Auto-apply theme when selection changes
if (previousUITheme != config::UITheme) {
applyCurrentTheme();
}
if (OptionCheckbox(T("Hide Legacy Naomi Roms"), config::HideLegacyNaomiRoms,
T("Hide .bin and .dat files from the content browser")))
scanner.refresh();
#ifdef __ANDROID__
OptionCheckbox(T("Use SAF File Picker"), config::UseSafFilePicker,
T("Use Android Storage Access Framework file picker to select folders and files. Ignored on Android 10 and later."));
#endif
ImGui::Text("%s", T("Automatic State:"));
OptionCheckbox(T("Load"), config::AutoLoadState,
T("Load the last saved state of the game when starting"));
ImGui::SameLine();
OptionCheckbox(T("Save"), config::AutoSaveState,
T("Save the state of the game when stopping"));
OptionCheckbox(T("Naomi Free Play"), config::ForceFreePlay, T("Configure Naomi games in Free Play mode."));
#if USE_DISCORD
OptionCheckbox(T("Discord Presence"), config::DiscordPresence, T("Show which game you are playing on Discord"));
#endif
#ifdef USE_RACHIEVEMENTS
OptionCheckbox(T("Enable RetroAchievements"), config::EnableAchievements, T("Track your game achievements using RetroAchievements.org"));
{
DisabledScope _(!config::EnableAchievements);
ImGui::Indent();
OptionCheckbox(T("Show Achievement Popups"), config::ShowAchievementPopups,
T("Shows achievement popups ingame."));
OptionCheckbox(T("Hardcore Mode"), config::AchievementsHardcoreMode,
T("Enable RetroAchievements hardcore mode. Using cheats and loading a state are not allowed in this mode."));
InputText(T("Username"), &config::AchievementsUserName.get(),
achievements::isLoggedOn() ? ImGuiInputTextFlags_ReadOnly : ImGuiInputTextFlags_None);
if (config::EnableAchievements)
{
static std::future futureLogin;
achievements::init();
if (achievements::isLoggedOn())
{
ImGui::Text("%s", T("Authentication successful"));
if (futureLogin.valid())
futureLogin.get();
if (ImGui::Button(T("Logout"), ScaledVec2(100, 0)))
achievements::logout();
}
else
{
static char password[256];
InputText(T("Password"), password, sizeof(password), ImGuiInputTextFlags_Password);
if (futureLogin.valid())
{
if (futureLogin.wait_for(std::chrono::seconds::zero()) == std::future_status::timeout) {
ImGui::Text("%s", T("Authenticating..."));
}
else
{
try {
futureLogin.get();
} catch (const FlycastException& e) {
gui_error(e.what());
}
}
}
{
DisabledScope _(config::AchievementsUserName.get().empty() || password[0] == '\0');
if (ImGui::Button(T("Login"), ScaledVec2(100, 0)) && !futureLogin.valid())
{
futureLogin = achievements::login(config::AchievementsUserName.get().c_str(), password);
memset(password, 0, sizeof(password));
}
}
}
}
ImGui::Unindent();
}
#endif
// Custom Paths section - hidden on Android and iOS
#if !defined(TARGET_IPHONE)
ImGui::Spacing();
header(T("Custom Paths"));
managePathList(T("BIOS Folders"), T("Select a BIOS folder"), config::BiosPath.get(),
T("Folders containing BIOS files (e.g. dc_boot.bin or dc_bios.bin) and arcade BIOS"));
ImGui::Spacing();
#if !defined(__ANDROID__)
manageSinglePath(T("VMU Folder"), T("Select the VMU folder"), config::VMUPath,
T("Folder where VMU (.bin) saves are stored"));
ImGui::Spacing();
managePathList(T("Savestate Folders"), T("Select a savestate folder"), config::SavestatePath.get(),
T("Folders for save states. First path is used for new states; all are searched when loading"));
ImGui::Spacing();
manageSinglePath(T("Game Save Folder"), T("Select the game save folder"), config::SavePath,
T("Folder for game save data (e.g. arcade NVRAM)"));
ImGui::Spacing();
#endif
managePathList(T("Texture Pack Folders"), T("Select a texture pack folder"), config::TexturePath.get(),
T("Folders containing textures/ or under a textures subfolder"));
ImGui::Spacing();
#if !defined(__ANDROID__)
manageSinglePath(T("Texture Dump Folder"), T("Select the texture dump folder"), config::TextureDumpPath,
T("Folder where texture dumps are saved. Game-specific subfolders will be created automatically"));
ImGui::Spacing();
manageSinglePath(T("Box Art Folder"), T("Select the box art folder"), config::BoxartPath,
T("Folder containing box art images (png/jpg). If empty, Flycast will use the default Home Folder/boxart for downloads and generated art"));
ImGui::Spacing();
managePathList(T("Controller Mapping Folders"), T("Select a controller mapping folder"), config::MappingsPath.get(),
T("Folders containing controller mapping files (.cfg). The emulator also looks in Home Folder/mappings. Per-game mappings are suffixed with _.cfg"));
ImGui::Spacing();
managePathList(T("Cheat Folders"), T("Select a cheat folder"), config::CheatPath.get(),
T("Folders containing cheat files (.cht/.txt) named with the game ID. Flycast will auto-load matching files if present"));
ImGui::Spacing();
#endif // !ANDROID
#endif // !IPHONE
}
static void applyDarkTheme()
{
// Reset style first, then apply dark colors - exactly like original Flycast
ImGui::GetStyle() = ImGuiStyle{};
ImGui::StyleColorsDark();
// Apply original Flycast styling to match exactly how it was
ImGuiStyle& style = ImGui::GetStyle();
style.TabRounding = 5.0f;
style.FrameRounding = 3.0f;
style.ItemSpacing = ImVec2(8, 8); // from 8,4
style.ItemInnerSpacing = ImVec2(4, 6); // from 4,4
// Reset style properties to defaults to ensure clean theme switching
style.TabBorderSize = 0.0f; // Revert to default
style.FrameBorderSize = 0.0f; // Revert to default
}
static void applyLightTheme()
{
ImGui::StyleColorsLight();
ImGuiStyle& style = ImGui::GetStyle();
// Improved light theme with better contrast
style.Colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); // Black text
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f); // Darker gray for disabled text
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.97f, 1.00f); // Very light blue-gray
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.98f, 0.98f, 1.00f, 1.00f); // Almost white for popups (fully opaque)
style.Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.80f, 0.50f); // Medium blue-gray borders (semi-transparent ok)
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); // No border shadows
// Darker frame backgrounds (unchecked boxes, etc.)
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.70f, 0.70f, 0.80f, 1.00f); // Darker blue-gray backgrounds
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.60f, 0.60f, 0.75f, 1.00f); // Slightly darker when hovered
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.50f, 0.50f, 0.70f, 1.00f); // Even darker when active
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.70f, 0.70f, 0.85f, 1.00f); // Light blue-gray title bar
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.60f, 0.60f, 0.80f, 1.00f); // Darker title bar when active
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.80f, 0.80f, 0.90f, 0.75f); // Lighter when collapsed (transparency ok)
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.80f, 0.80f, 0.90f, 1.00f); // Light blue-gray menu bar
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.85f, 0.85f, 0.90f, 1.00f); // Very light scrollbar background
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.65f, 0.65f, 0.80f, 1.00f); // Medium blue-gray scrollbar (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.55f, 0.55f, 0.75f, 1.00f); // Darker when hovered (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.45f, 0.45f, 0.70f, 1.00f); // Even darker when active (fully opaque)
style.Colors[ImGuiCol_CheckMark] = ImVec4(0.00f, 0.45f, 0.90f, 1.00f); // Bright blue checkmarks
style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.50f, 0.50f, 0.80f, 1.00f); // Medium blue-gray slider (fully opaque)
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.40f, 0.40f, 0.70f, 1.00f); // Darker when active (fully opaque)
style.Colors[ImGuiCol_Button] = ImVec4(0.67f, 0.67f, 0.83f, 1.00f); // Medium blue-gray buttons (fully opaque)
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.57f, 0.57f, 0.77f, 1.00f); // Darker when hovered (fully opaque)
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.47f, 0.47f, 0.73f, 1.00f); // Even darker when active (fully opaque)
style.Colors[ImGuiCol_Header] = ImVec4(0.60f, 0.60f, 0.80f, 0.80f); // Medium blue-gray headers (semi-transparent ok)
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.50f, 0.50f, 0.75f, 1.00f); // Darker when hovered (fully opaque)
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.45f, 0.45f, 0.70f, 1.00f); // Even darker when active (fully opaque)
style.Colors[ImGuiCol_Separator] = ImVec4(0.60f, 0.60f, 0.70f, 0.60f); // Visible separators (semi-transparent ok)
style.Colors[ImGuiCol_Tab] = ImVec4(0.65f, 0.65f, 0.80f, 1.00f); // Medium blue-gray tabs (fully opaque)
style.Colors[ImGuiCol_TabHovered] = ImVec4(0.55f, 0.55f, 0.75f, 1.00f); // Darker when hovered (fully opaque)
style.Colors[ImGuiCol_TabActive] = ImVec4(0.50f, 0.50f, 0.70f, 1.00f); // Even darker when active (fully opaque)
style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.75f, 0.75f, 0.85f, 1.00f); // Lighter when unfocused (fully opaque)
style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.65f, 0.65f, 0.80f, 1.00f); // Medium when unfocused but active (fully opaque)
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.45f, 0.45f, 0.85f, 0.35f); // Visible selection background (transparency ok)
style.TabBorderSize = 0.0f; // Revert to default
style.FrameBorderSize = 0.0f; // Revert to default
}
static void applyDreamcastTheme()
{
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
// Dreamcast-inspired theme with higher contrast
// Pure white text - maximum brightness
style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); // Pure white text
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.70f, 0.70f, 0.70f, 0.50f); // More transparent for disabled text (transparency ok)
// Darker backgrounds for higher contrast
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.05f, 0.07f, 0.10f, 1.00f); // Much darker DC Menu Background for contrast
style.Colors[ImGuiCol_ChildBg] = ImVec4(0.05f, 0.07f, 0.10f, 1.00f); // Match window background
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.13f, 0.16f, 0.40f, 1.00f); // DC Logo Blue (fully opaque)
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.18f, 0.22f, 0.50f, 1.00f); // Brighter DC Blue when active
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.43f, 0.73f, 0.70f); // More transparent when collapsed (transparency ok)
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.10f, 0.12f, 0.15f, 1.00f); // Dark but slightly lighter than window
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.05f, 0.07f, 0.10f, 1.00f); // Darker, same as window background
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.95f, 0.95f, 0.95f, 1.00f); // DC Shell White (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.95f, 0.95f, 0.95f, 1.00f); // Fully opaque when hovered
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.95f, 0.95f, 0.95f, 1.00f); // Fully opaque when active
// Controller button colors - more vibrant
style.Colors[ImGuiCol_Button] = ImVec4(0.90f, 0.50f, 0.10f, 1.00f); // Brighter orange buttons
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(1.00f, 0.70f, 0.40f, 1.00f); // Brighter when hovered
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.95f, 0.45f, 0.00f, 1.00f); // Brighter when active
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.07f, 0.10f, 1.00f); // Darker DC Menu Background (100% opaque)
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.15f, 0.17f, 0.22f, 1.00f); // Darker DC Menu (fully opaque)
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.10f, 0.70f, 0.50f, 1.00f); // Brighter Y Button (Green) (fully opaque)
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.06f, 0.60f, 0.35f, 1.00f); // Y Button (Green) (fully opaque)
style.Colors[ImGuiCol_Header] = ImVec4(0.15f, 0.18f, 0.45f, 1.00f); // Brighter B Button (Blue) (fully opaque)
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.20f, 0.23f, 0.55f, 1.00f); // Even brighter B Button (Blue) (fully opaque)
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.10f, 0.13f, 0.33f, 1.00f); // B Button darker
// A Button Red - more vibrant
style.Colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 0.30f, 0.30f, 1.00f); // Brighter A Button (Red) - fully opaque
style.Colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 0.30f, 0.30f, 1.00f); // Brighter A Button (Red) (fully opaque)
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.90f, 0.20f, 0.20f, 1.00f); // A Button darker
// Tabs - using X Button Blue - more vibrant
style.Colors[ImGuiCol_Tab] = ImVec4(0.13f, 0.16f, 0.40f, 1.00f); // X Button Blue
style.Colors[ImGuiCol_TabHovered] = ImVec4(0.25f, 0.30f, 0.60f, 1.00f); // Brighter when hovered (fully opaque)
style.Colors[ImGuiCol_TabActive] = ImVec4(0.30f, 0.35f, 0.65f, 1.00f); // Much brighter & whiter when active
style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.13f, 0.16f, 0.40f, 1.00f); // Same blue but fully opaque
style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.25f, 0.30f, 0.60f, 1.00f); // Brighter for unfocused active (fully opaque)
// Other elements - more vibrant
style.Colors[ImGuiCol_Border] = ImVec4(1.00f, 0.85f, 0.25f, 0.70f); // Brighter DC "X" yellow borders (some transparency ok)
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); // No border shadows
style.Colors[ImGuiCol_Separator] = ImVec4(0.00f, 0.50f, 0.80f, 0.75f); // Brighter DC Logo Blue separators (some transparency ok)
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 0.50f, 0.00f, 0.35f); // DC Swirl Orange selection (transparency ok)
// Table colors - more vibrant
style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.15f, 0.18f, 0.45f, 1.00f); // Brighter X Button Blue for headers (fully opaque)
style.Colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.50f, 0.80f, 1.00f); // Brighter DC Logo Blue borders
style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.00f, 0.50f, 0.80f, 0.70f); // Brighter borders (some transparency ok)
style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.05f, 0.07f, 0.10f, 1.00f); // Same as window bg
style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.10f, 0.12f, 0.15f, 1.00f); // Slightly lighter for alt rows
}
static void applyHighContrastTheme()
{
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
// High contrast theme with Dreamcast color accents
// Base colors - extreme contrast
style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); // Pure white text
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.75f, 0.75f, 0.75f, 1.00f); // Light gray for disabled text
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); // Pure black background
style.Colors[ImGuiCol_ChildBg] = ImVec4(0.05f, 0.05f, 0.05f, 1.00f); // Very dark gray child windows
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.07f, 0.07f, 0.09f, 1.00f); // Very dark for popups
style.Colors[ImGuiCol_Border] = ImVec4(0.00f, 0.43f, 0.73f, 0.50f); // DC Logo Blue borders (semi-transparent ok)
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); // No shadows
// Frame elements (checkboxes, input fields)
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); // Dark gray frame backgrounds
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.30f, 0.30f, 0.30f, 1.00f); // Medium gray when hovered
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.15f, 0.15f, 0.15f, 1.00f); // Darker gray when active
// Title bars
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); // Dark gray title bar
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // DC Logo Blue active title
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.43f, 0.73f, 0.50f); // Semi-transparent when collapsed (transparency ok)
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); // Dark gray menu bar
// Scrollbars
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); // Dark scrollbar background
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f); // Medium gray scrollbar
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.56f, 0.56f, 0.56f, 1.00f); // Lighter when hovered
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.00f, 0.65f, 0.90f, 1.00f); // DC Highlight Blue when active
// Interactive elements
style.Colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 0.50f, 0.00f, 1.00f); // DC Swirl Orange for checkmarks
style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.00f, 0.65f, 0.90f, 1.00f); // DC Highlight Blue for sliders
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(1.00f, 0.50f, 0.00f, 1.00f); // DC Swirl Orange when active
// Buttons
style.Colors[ImGuiCol_Button] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // DC Logo Blue buttons
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.00f, 0.65f, 0.90f, 1.00f); // DC Highlight Blue when hovered
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.00f, 0.33f, 0.60f, 1.00f); // Darker blue when active
// Headers (collapsing headers, tree nodes)
style.Colors[ImGuiCol_Header] = ImVec4(0.00f, 0.43f, 0.73f, 0.80f); // Semi-transparent DC Logo Blue (some transparency ok)
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.65f, 0.90f, 1.00f); // DC Highlight Blue when hovered (fully opaque)
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // Solid DC Logo Blue when active
// Tables
style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.15f, 0.15f, 0.15f, 1.00f); // Dark gray table headers
style.Colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // DC Logo Blue table borders
style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.00f, 0.43f, 0.73f, 0.50f); // Lighter DC Logo Blue inner borders (semi-transparent ok)
// Tabs
style.Colors[ImGuiCol_Tab] = ImVec4(0.15f, 0.15f, 0.15f, 1.00f); // Dark gray tabs
style.Colors[ImGuiCol_TabHovered] = ImVec4(0.00f, 0.65f, 0.90f, 1.00f); // DC Highlight Blue when hovered
style.Colors[ImGuiCol_TabActive] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // DC Logo Blue when active
style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.15f, 0.15f, 0.15f, 1.00f); // Dark gray when unfocused
style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.00f, 0.43f, 0.73f, 1.00f); // DC Logo Blue when unfocused but active (fully opaque)
// Other UI elements
style.Colors[ImGuiCol_Separator] = ImVec4(1.00f, 1.00f, 1.00f, 0.40f); // Semi-transparent white separators (transparency ok)
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 0.50f, 0.00f, 0.35f); // Semi-transparent DC Swirl Orange selection (transparency ok)
// Increase contrast even more
style.Alpha = 1.0f; // No transparency
style.FrameBorderSize = 1.0f; // Add borders to frames
style.WindowBorderSize = 1.0f; // Add borders to windows
style.PopupBorderSize = 1.0f; // Add borders to popups
style.TabBorderSize = 1.0f; // Add borders to tabs
}
static void applyNintendoTheme()
{
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
// Nintendo color palette
ImVec4 nintendoRed = ImVec4(0.90f, 0.10f, 0.10f, 1.00f); // Nintendo logo/Switch red
ImVec4 nintendoRedLight = ImVec4(1.00f, 0.30f, 0.30f, 1.00f); // Lighter red
ImVec4 nintendoRedDark = ImVec4(0.65f, 0.05f, 0.05f, 1.00f); // Darker red
ImVec4 luigiGreen = ImVec4(0.00f, 0.65f, 0.00f, 1.00f); // Luigi green
ImVec4 luigiGreenLight = ImVec4(0.30f, 0.85f, 0.30f, 1.00f); // Lighter green
ImVec4 gameboy = ImVec4(0.70f, 0.80f, 0.15f, 1.00f); // GameBoy screen color
ImVec4 gamecubePurple = ImVec4(0.35f, 0.20f, 0.65f, 1.00f); // GameCube purple
// Text colors
style.Colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); // Pure white text
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f); // Light gray for disabled (keep transparency)
// Window background and elements - darker blue-black like classic consoles
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.03f, 0.03f, 0.10f, 1.00f); // Dark blue-black background (fully opaque)
style.Colors[ImGuiCol_ChildBg] = ImVec4(0.03f, 0.03f, 0.10f, 1.00f); // Match window background (fully opaque)
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.02f, 0.02f, 0.08f, 1.00f); // Slightly darker for popup (fully opaque)
// Frame elements - using GameCube purple for frames
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.12f, 0.08f, 0.20f, 1.00f); // Dark purple-ish background (fully opaque)
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.20f, 0.14f, 0.35f, 1.00f); // Lighter purple when hovered (fully opaque)
style.Colors[ImGuiCol_FrameBgActive] = gamecubePurple; // GameCube purple when active
// Title elements - using Nintendo red
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.05f, 0.05f, 0.12f, 1.00f); // Dark blue background (fully opaque)
style.Colors[ImGuiCol_TitleBgActive] = nintendoRed; // Nintendo red for active title
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.05f, 0.05f, 0.12f, 0.75f); // Keep semi-transparent when collapsed
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.08f, 0.08f, 0.15f, 1.00f); // Dark menu bar (fully opaque)
// Scrollbars - GameBoy inspired
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.04f, 0.04f, 0.10f, 1.00f); // Dark scrollbar background (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.30f, 0.40f, 0.10f, 1.00f); // GameBoy green-yellow (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.50f, 0.60f, 0.15f, 1.00f); // Brighter GameBoy color (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabActive] = gameboy; // Full GameBoy color when active
// Button elements - Nintendo red
style.Colors[ImGuiCol_Button] = nintendoRed; // Nintendo red button
style.Colors[ImGuiCol_ButtonHovered] = nintendoRedLight; // Lighter red when hovered
style.Colors[ImGuiCol_ButtonActive] = nintendoRedDark; // Darker red when active
// Interactive elements - Luigi green for checkmarks and sliders
style.Colors[ImGuiCol_CheckMark] = luigiGreenLight; // Bright Luigi green for checkmarks
style.Colors[ImGuiCol_SliderGrab] = luigiGreen; // Luigi green for sliders
style.Colors[ImGuiCol_SliderGrabActive] = luigiGreenLight; // Lighter when active
// Headers (collapsing headers, tree nodes) - GameCube purple
style.Colors[ImGuiCol_Header] = ImVec4(0.20f, 0.12f, 0.35f, 1.00f); // GameCube purple (fully opaque)
style.Colors[ImGuiCol_HeaderHovered] = gamecubePurple; // Full purple when hovered
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.45f, 0.25f, 0.75f, 1.00f); // Brighter purple when active
// Tab elements - Red/green for Mario/Luigi contrast
style.Colors[ImGuiCol_Tab] = ImVec4(0.15f, 0.10f, 0.30f, 1.00f); // Dark purple tabs (fully opaque)
style.Colors[ImGuiCol_TabHovered] = luigiGreenLight; // Luigi green when hovered
style.Colors[ImGuiCol_TabActive] = nintendoRed; // Mario red when active
style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.10f, 0.08f, 0.20f, 1.00f); // Darker when unfocused (fully opaque)
style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.40f, 0.10f, 0.10f, 1.00f); // Darker red when unfocused but active (fully opaque)
// Border and separator
style.Colors[ImGuiCol_Border] = ImVec4(0.40f, 0.40f, 0.50f, 0.50f); // Keep subtle border transparency
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); // No shadows
style.Colors[ImGuiCol_Separator] = nintendoRed; // Nintendo red separators
// Table elements
style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.15f, 0.10f, 0.25f, 1.00f); // Dark purple headers (fully opaque)
style.Colors[ImGuiCol_TableBorderStrong] = nintendoRed; // Nintendo red strong borders
style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.40f, 0.10f, 0.10f, 0.70f); // Lighter red inner borders (keep transparency)
style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.03f, 0.03f, 0.10f, 1.00f); // Match window background (fully opaque)
style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.06f, 0.06f, 0.14f, 1.00f); // Slightly lighter for alt rows (fully opaque)
// Selected text - keep transparency for selection highlight
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(luigiGreen.x, luigiGreen.y, luigiGreen.z, 0.35f); // Semi-transparent Luigi green
// Reset to defaults for these
style.TabBorderSize = 0.0f;
style.FrameBorderSize = 0.0f;
}
static void applySoftTheme()
{
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
// Soft, blue/turquoise theme that's easy on the eyes
// Soft text colors
style.Colors[ImGuiCol_Text] = ImVec4(0.85f, 0.90f, 0.92f, 1.00f); // Soft blue-white text
style.Colors[ImGuiCol_TextDisabled] = ImVec4(0.55f, 0.60f, 0.65f, 0.70f); // Muted blue-gray for disabled text (some transparency)
// Soft dark backgrounds with turquoise tint
style.Colors[ImGuiCol_WindowBg] = ImVec4(0.15f, 0.18f, 0.20f, 1.00f); // Soft dark background with blue tint (fully opaque)
style.Colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.20f, 1.00f); // Match window background (fully opaque)
style.Colors[ImGuiCol_TitleBg] = ImVec4(0.10f, 0.25f, 0.30f, 1.00f); // Deep turquoise title bar (fully opaque)
style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.15f, 0.35f, 0.45f, 1.00f); // Brighter turquoise when active (fully opaque)
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.10f, 0.25f, 0.30f, 0.75f); // Keep some transparency when collapsed
style.Colors[ImGuiCol_MenuBarBg] = ImVec4(0.17f, 0.21f, 0.24f, 1.00f); // Slightly lighter than background (fully opaque)
// Soft scrollbars
style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(0.15f, 0.18f, 0.20f, 1.00f); // Match window background (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.25f, 0.45f, 0.50f, 1.00f); // Soft turquoise (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.30f, 0.55f, 1.00f, 1.00f); // Brighter when hovered (fully opaque)
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.35f, 0.65f, 1.00f, 1.00f); // Even brighter when active (fully opaque)
// Soft, muted button colors
style.Colors[ImGuiCol_Button] = ImVec4(0.20f, 0.40f, 0.45f, 1.00f); // Muted turquoise (fully opaque)
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.25f, 0.50f, 0.55f, 1.00f); // Slightly brighter when hovered (fully opaque)
style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.30f, 0.60f, 0.65f, 1.00f); // Even brighter when active (fully opaque)
style.Colors[ImGuiCol_PopupBg] = ImVec4(0.15f, 0.18f, 0.20f, 1.00f); // Match window background (fully opaque)
// Frames (checkboxes, input fields)
style.Colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.28f, 0.33f, 1.00f); // Soft blue-gray frames (fully opaque)
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.25f, 0.35f, 0.40f, 1.00f); // Slightly brighter when hovered (fully opaque)
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.30f, 0.45f, 0.50f, 1.00f); // Even brighter when active (fully opaque)
// Headers (collapsing headers, tree nodes)
style.Colors[ImGuiCol_Header] = ImVec4(0.20f, 0.35f, 0.45f, 1.00f); // Soft blue headers (fully opaque)
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.25f, 0.40f, 0.50f, 1.00f); // Slightly brighter when hovered (fully opaque)
style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.30f, 0.50f, 0.60f, 1.00f); // Even brighter when active (fully opaque)
// Accent colors - light turquoise
style.Colors[ImGuiCol_CheckMark] = ImVec4(0.40f, 0.80f, 0.90f, 1.00f); // Light turquoise checkmarks (fully opaque)
style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.35f, 0.65f, 0.75f, 1.00f); // Turquoise sliders (fully opaque)
style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.45f, 0.75f, 0.85f, 1.00f); // Brighter when active (fully opaque)
// Tabs - soft blue palette
style.Colors[ImGuiCol_Tab] = ImVec4(0.15f, 0.30f, 0.40f, 1.00f); // Soft blue tabs (fully opaque)
style.Colors[ImGuiCol_TabHovered] = ImVec4(0.25f, 0.40f, 0.50f, 1.00f); // Slightly brighter when hovered (fully opaque)
style.Colors[ImGuiCol_TabActive] = ImVec4(0.30f, 0.50f, 0.60f, 1.00f); // Turquoise blue when active (fully opaque)
style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.10f, 0.25f, 0.35f, 1.00f); // More muted when unfocused (fully opaque)
style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.20f, 0.35f, 0.45f, 1.00f); // In-between for unfocused active (fully opaque)
// Other elements
style.Colors[ImGuiCol_Border] = ImVec4(0.20f, 0.35f, 0.45f, 0.60f); // Soft blue borders (some transparency ok)
style.Colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.35f, 0.45f, 0.75f); // Soft blue separators (some transparency ok)
style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.30f, 0.50f, 0.60f, 0.35f); // Soft blue selection (keep transparency)
// Table colors
style.Colors[ImGuiCol_TableHeaderBg] = ImVec4(0.15f, 0.30f, 0.40f, 1.00f); // Soft blue headers (fully opaque)
style.Colors[ImGuiCol_TableBorderStrong] = ImVec4(0.20f, 0.35f, 0.45f, 1.00f); // Soft blue borders (fully opaque)
style.Colors[ImGuiCol_TableBorderLight] = ImVec4(0.20f, 0.35f, 0.45f, 0.70f); // Lighter borders (some transparency)
style.Colors[ImGuiCol_TableRowBg] = ImVec4(0.15f, 0.18f, 0.20f, 1.00f); // Match window bg (fully opaque)
style.Colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.17f, 0.21f, 0.24f, 1.00f); // Slightly lighter for alt rows (fully opaque)
// Reset to defaults for these
style.TabBorderSize = 0.0f;
style.FrameBorderSize = 0.0f;
}
// Add the common function before gui_initFonts
void applyCurrentTheme()
{
if (config::UITheme == 0)
applyDarkTheme();
else if (config::UITheme == 1)
applyLightTheme();
else if (config::UITheme == 2)
applyDreamcastTheme();
else if (config::UITheme == 3)
applyHighContrastTheme();
else if (config::UITheme == 4)
applyNintendoTheme(); // Fixed ordering - was High Contrast
else if (config::UITheme == 5)
applySoftTheme(); // New "Aqua Chill" theme
else
applyDarkTheme();
}