1
0
mirror of synced 2025-02-19 19:51:41 +01:00

ui: Add follow system theme option

This commit is contained in:
WerWolv 2021-09-16 22:23:51 +02:00
parent e1f410ceff
commit bf493c5763
12 changed files with 141 additions and 75 deletions

View File

@ -31,6 +31,7 @@ namespace hex::plugin::builtin {
static int selection = static_cast<int>(setting);
const char* themes[] = {
"hex.builtin.setting.interface.color.system"_lang,
"hex.builtin.setting.interface.color.dark"_lang,
"hex.builtin.setting.interface.color.light"_lang,
"hex.builtin.setting.interface.color.classic"_lang

View File

@ -583,6 +583,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.general.show_tips", "Tipps beim start anzeigen" },
{ "hex.builtin.setting.interface", "Aussehen" },
{ "hex.builtin.setting.interface.color", "Farbthema" },
{ "hex.builtin.setting.interface.color.system", "System" },
{ "hex.builtin.setting.interface.color.dark", "Dunkel" },
{ "hex.builtin.setting.interface.color.light", "Hell" },
{ "hex.builtin.setting.interface.color.classic", "Klassisch" },

View File

@ -584,6 +584,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.general.show_tips", "Show tips on startup" },
{ "hex.builtin.setting.interface", "Interface" },
{ "hex.builtin.setting.interface.color", "Color theme" },
{ "hex.builtin.setting.interface.color.system", "System" },
{ "hex.builtin.setting.interface.color.dark", "Dark" },
{ "hex.builtin.setting.interface.color.light", "Light" },
{ "hex.builtin.setting.interface.color.classic", "Classic" },

View File

@ -582,6 +582,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.general.show_tips", "Mostra consigli all'avvio" },
{ "hex.builtin.setting.interface", "Interfaccia" },
{ "hex.builtin.setting.interface.color", "Colore del Tema" },
{ "hex.builtin.setting.interface.color.system", "Sistema" },
{ "hex.builtin.setting.interface.color.dark", "Scuro" },
{ "hex.builtin.setting.interface.color.light", "Chiaro" },
{ "hex.builtin.setting.interface.color.classic", "Classico" },

View File

@ -106,6 +106,7 @@ namespace hex {
EVENT_DEF(EventProjectFileLoad);
EVENT_DEF(EventSettingsChanged);
EVENT_DEF(EventAbnormalTermination, int);
EVENT_DEF(EventOSThemeChanged);
EVENT_DEF(RequestOpenWindow, std::string);
EVENT_DEF(RequestSelectionChange, Region);
@ -114,6 +115,7 @@ namespace hex {
EVENT_DEF(RequestChangeWindowTitle, std::string);
EVENT_DEF(RequestCloseImHex, bool);
EVENT_DEF(RequestOpenFile, std::string);
EVENT_DEF(RequestChangeTheme, u32);
EVENT_DEF(QuerySelection, Region&);

View File

@ -8,6 +8,7 @@
#include <cstring>
#include <cctype>
#include <functional>
#include <limits>
#include <memory>
#include <optional>
#include <string>

View File

@ -9,25 +9,21 @@
namespace hex {
ViewDataProcessor::ViewDataProcessor() : View("hex.view.data_processor.name") {
EventManager::subscribe<EventSettingsChanged>(this, [] {
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
if (theme.is_number()) {
switch (static_cast<int>(theme)) {
default:
case 0: /* Dark theme */
ImNodes::StyleColorsDark();
break;
case 1: /* Light theme */
ImNodes::StyleColorsLight();
break;
case 2: /* Classic theme */
ImNodes::StyleColorsClassic();
break;
}
ImNodes::GetStyle().Flags = ImNodesStyleFlags_NodeOutline | ImNodesStyleFlags_GridLines;
EventManager::subscribe<RequestChangeTheme>(this, [](u32 theme) {
switch (theme) {
default:
case 1: /* Dark theme */
ImNodes::StyleColorsDark();
break;
case 2: /* Light theme */
ImNodes::StyleColorsLight();
break;
case 3: /* Classic theme */
ImNodes::StyleColorsClassic();
break;
}
ImNodes::GetStyle().Flags = ImNodesStyleFlags_NodeOutline | ImNodesStyleFlags_GridLines;
});
EventManager::subscribe<EventProjectFileStore>(this, [this] {
@ -50,7 +46,7 @@ namespace hex {
for (auto &node : this->m_nodes)
delete node;
EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<RequestChangeTheme>(this);
EventManager::unsubscribe<EventFileLoaded>(this);
EventManager::unsubscribe<EventProjectFileStore>(this);
EventManager::unsubscribe<EventProjectFileLoad>(this);

View File

@ -152,22 +152,18 @@ namespace hex {
/* Settings */
{
EventManager::subscribe<EventSettingsChanged>(this, [this]() {
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
if (theme.is_number()) {
switch (static_cast<int>(theme)) {
default:
case 0: /* Dark theme */
this->m_textEditor.SetPalette(TextEditor::GetDarkPalette());
break;
case 1: /* Light theme */
this->m_textEditor.SetPalette(TextEditor::GetLightPalette());
break;
case 2: /* Classic theme */
this->m_textEditor.SetPalette(TextEditor::GetRetroBluePalette());
break;
}
EventManager::subscribe<RequestChangeTheme>(this, [this](u32 theme) {
switch (theme) {
default:
case 1: /* Dark theme */
this->m_textEditor.SetPalette(TextEditor::GetDarkPalette());
break;
case 2: /* Light theme */
this->m_textEditor.SetPalette(TextEditor::GetLightPalette());
break;
case 3: /* Classic theme */
this->m_textEditor.SetPalette(TextEditor::GetRetroBluePalette());
break;
}
});
@ -181,7 +177,7 @@ namespace hex {
EventManager::unsubscribe<EventProjectFileLoad>(this);
EventManager::unsubscribe<RequestAppendPatternLanguageCode>(this);
EventManager::unsubscribe<EventFileLoaded>(this);
EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<RequestChangeTheme>(this);
}
void ViewPatternEditor::drawMenu() {

View File

@ -2,6 +2,9 @@
#if defined(OS_LINUX)
#include <nlohmann/json.hpp>
#include <sys/wait.h>
namespace hex {
void Window::initNative() {
@ -9,7 +12,28 @@
}
void Window::setupNativeWindow() {
bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0;
EventManager::subscribe<EventOSThemeChanged>(this, [themeFollowSystem]{
if (!themeFollowSystem) return;
std::array<char, 128> buffer = { 0 };
std::string result;
// TODO: In the future maybe support more DEs instead of just GNOME
FILE* pipe = popen("gsettings get org.gnome.desktop.interface gtk-theme 2>&1", "r");
if (pipe == nullptr) return;
while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
result += buffer.data();
auto exitCode = WEXITSTATUS(pclose(pipe));
if (exitCode != 0) return;
EventManager::post<RequestChangeTheme>(hex::containsIgnoreCase(result, "dark") ? 1 : 2);
});
if (themeFollowSystem)
EventManager::post<EventOSThemeChanged>();
}
void Window::updateNativeWindow() {

View File

@ -2,6 +2,8 @@
#if defined(OS_MACOS)
#include <nlohmann/json.hpp>
namespace hex {
void Window::initNative() {
@ -9,7 +11,16 @@
}
void Window::setupNativeWindow() {
bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0;
EventManager::subscribe<EventOSThemeChanged>(this, [themeFollowSystem]{
if (!themeFollowSystem) return;
// TODO: Implement this when MacOS build is working again
EventManager::post<RequestChangeTheme>(1);
});
if (themeFollowSystem)
EventManager::post<EventOSThemeChanged>();
}
void Window::updateNativeWindow() {

View File

@ -4,11 +4,14 @@
#if defined(OS_WINDOWS)
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
#include <imgui.h>
#include <imgui_internal.h>
#include <codicons_font.h>
#include <nlohmann/json.hpp>
#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h>
@ -140,6 +143,15 @@
return HTCAPTION;
else break;
}
break;
}
case WM_SETTINGCHANGE:
{
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
EventManager::post<EventOSThemeChanged>();
}
break;
}
default: break;
}
@ -172,6 +184,25 @@
::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS | SWP_NOSIZE | SWP_NOMOVE);
::SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) | WS_POPUP | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU);
bool themeFollowSystem = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color") == 0;
EventManager::subscribe<EventOSThemeChanged>(this, [themeFollowSystem]{
if (!themeFollowSystem) return;
HKEY hkey;
if (RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", &hkey) == ERROR_SUCCESS) {
DWORD value = 0;
DWORD size = sizeof(DWORD);
auto error = RegQueryValueEx(hkey, "AppsUseLightTheme", nullptr, nullptr, reinterpret_cast<LPBYTE>(&value), &size);
if (error == ERROR_SUCCESS) {
EventManager::post<RequestChangeTheme>(value == 0 ? 1 : 2);
}
}
});
if (themeFollowSystem)
EventManager::post<EventOSThemeChanged>();
}
void Window::updateNativeWindow() {

View File

@ -85,47 +85,12 @@ namespace hex {
this->initGLFW();
this->initImGui();
this->setupNativeWindow();
EventManager::subscribe<EventSettingsChanged>(this, [this]() {
{
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
if (this->m_bannerTexture.valid())
ImGui::UnloadImage(this->m_bannerTexture);
if (theme.is_number()) {
switch (static_cast<int>(theme)) {
default:
case 0: /* Dark theme */
ImGui::StyleColorsDark();
ImGui::StyleCustomColorsDark();
ImPlot::StyleColorsDark();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_dark, banner_dark_size);
break;
case 1: /* Light theme */
ImGui::StyleColorsLight();
ImGui::StyleCustomColorsLight();
ImPlot::StyleColorsLight();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_light, banner_light_size);
break;
case 2: /* Classic theme */
ImGui::StyleColorsClassic();
ImGui::StyleCustomColorsClassic();
ImPlot::StyleColorsClassic();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_dark, banner_dark_size);
break;
}
ImGui::GetStyle().Colors[ImGuiCol_DockingEmptyBg] = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBg] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgCollapsed] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
if (!this->m_bannerTexture.valid()) {
log::fatal("Failed to load banner texture!");
exit(EXIT_FAILURE);
}
}
EventManager::post<RequestChangeTheme>(theme.get<int>());
}
{
@ -154,6 +119,43 @@ namespace hex {
}
});
EventManager::subscribe<RequestChangeTheme>(this, [this](u32 theme) {
if (this->m_bannerTexture.valid())
ImGui::UnloadImage(this->m_bannerTexture);
switch (theme) {
default:
case 1: /* Dark theme */
ImGui::StyleColorsDark();
ImGui::StyleCustomColorsDark();
ImPlot::StyleColorsDark();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_dark, banner_dark_size);
break;
case 2: /* Light theme */
ImGui::StyleColorsLight();
ImGui::StyleCustomColorsLight();
ImPlot::StyleColorsLight();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_light, banner_light_size);
break;
case 3: /* Classic theme */
ImGui::StyleColorsClassic();
ImGui::StyleCustomColorsClassic();
ImPlot::StyleColorsClassic();
this->m_bannerTexture = ImGui::LoadImageFromMemory(banner_dark, banner_dark_size);
break;
}
ImGui::GetStyle().Colors[ImGuiCol_DockingEmptyBg] = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBg] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgActive] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
ImGui::GetStyle().Colors[ImGuiCol_TitleBgCollapsed] = ImGui::GetStyle().Colors[ImGuiCol_MenuBarBg];
if (!this->m_bannerTexture.valid()) {
log::fatal("Failed to load banner texture!");
std::abort();
}
});
EventManager::subscribe<EventFileLoaded>(this, [](const std::string &path){
SharedData::recentFilePaths.push_front(path);
@ -262,6 +264,7 @@ namespace hex {
EventManager::unsubscribe<RequestCloseImHex>(this);
EventManager::unsubscribe<RequestChangeWindowTitle>(this);
EventManager::unsubscribe<EventAbnormalTermination>(this);
EventManager::unsubscribe<RequestChangeTheme>(this);
ImGui::UnloadImage(this->m_bannerTexture);
ImGui::UnloadImage(this->m_logoTexture);
@ -691,8 +694,6 @@ namespace hex {
this->m_windowTitle = "ImHex";
this->m_window = glfwCreateWindow(1280 * SharedData::globalScale, 720 * SharedData::globalScale, this->m_windowTitle.c_str(), nullptr, nullptr);
this->setupNativeWindow();
glfwSetWindowUserPointer(this->m_window, this);
if (this->m_window == nullptr)