1
0
mirror of synced 2025-02-21 12:29:47 +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); static int selection = static_cast<int>(setting);
const char* themes[] = { const char* themes[] = {
"hex.builtin.setting.interface.color.system"_lang,
"hex.builtin.setting.interface.color.dark"_lang, "hex.builtin.setting.interface.color.dark"_lang,
"hex.builtin.setting.interface.color.light"_lang, "hex.builtin.setting.interface.color.light"_lang,
"hex.builtin.setting.interface.color.classic"_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.general.show_tips", "Tipps beim start anzeigen" },
{ "hex.builtin.setting.interface", "Aussehen" }, { "hex.builtin.setting.interface", "Aussehen" },
{ "hex.builtin.setting.interface.color", "Farbthema" }, { "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.dark", "Dunkel" },
{ "hex.builtin.setting.interface.color.light", "Hell" }, { "hex.builtin.setting.interface.color.light", "Hell" },
{ "hex.builtin.setting.interface.color.classic", "Klassisch" }, { "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.general.show_tips", "Show tips on startup" },
{ "hex.builtin.setting.interface", "Interface" }, { "hex.builtin.setting.interface", "Interface" },
{ "hex.builtin.setting.interface.color", "Color theme" }, { "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.dark", "Dark" },
{ "hex.builtin.setting.interface.color.light", "Light" }, { "hex.builtin.setting.interface.color.light", "Light" },
{ "hex.builtin.setting.interface.color.classic", "Classic" }, { "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.general.show_tips", "Mostra consigli all'avvio" },
{ "hex.builtin.setting.interface", "Interfaccia" }, { "hex.builtin.setting.interface", "Interfaccia" },
{ "hex.builtin.setting.interface.color", "Colore del Tema" }, { "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.dark", "Scuro" },
{ "hex.builtin.setting.interface.color.light", "Chiaro" }, { "hex.builtin.setting.interface.color.light", "Chiaro" },
{ "hex.builtin.setting.interface.color.classic", "Classico" }, { "hex.builtin.setting.interface.color.classic", "Classico" },

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,9 @@
#if defined(OS_LINUX) #if defined(OS_LINUX)
#include <nlohmann/json.hpp>
#include <sys/wait.h>
namespace hex { namespace hex {
void Window::initNative() { void Window::initNative() {
@ -9,7 +12,28 @@
} }
void Window::setupNativeWindow() { 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() { void Window::updateNativeWindow() {

View File

@ -2,6 +2,8 @@
#if defined(OS_MACOS) #if defined(OS_MACOS)
#include <nlohmann/json.hpp>
namespace hex { namespace hex {
void Window::initNative() { void Window::initNative() {
@ -9,7 +11,16 @@
} }
void Window::setupNativeWindow() { 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() { void Window::updateNativeWindow() {

View File

@ -4,11 +4,14 @@
#if defined(OS_WINDOWS) #if defined(OS_WINDOWS)
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <codicons_font.h> #include <codicons_font.h>
#include <nlohmann/json.hpp>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32
#include <GLFW/glfw3native.h> #include <GLFW/glfw3native.h>
@ -140,6 +143,15 @@
return HTCAPTION; return HTCAPTION;
else break; else break;
} }
break;
}
case WM_SETTINGCHANGE:
{
if (LPCTSTR(lParam) == std::string_view("ImmersiveColorSet")) {
EventManager::post<EventOSThemeChanged>();
}
break;
} }
default: 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); ::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); ::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() { void Window::updateNativeWindow() {

View File

@ -85,47 +85,12 @@ namespace hex {
this->initGLFW(); this->initGLFW();
this->initImGui(); this->initImGui();
this->setupNativeWindow();
EventManager::subscribe<EventSettingsChanged>(this, [this]() { EventManager::subscribe<EventSettingsChanged>(this, [this]() {
{ {
auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color"); auto theme = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.color");
EventManager::post<RequestChangeTheme>(theme.get<int>());
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);
}
}
} }
{ {
@ -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){ EventManager::subscribe<EventFileLoaded>(this, [](const std::string &path){
SharedData::recentFilePaths.push_front(path); SharedData::recentFilePaths.push_front(path);
@ -262,6 +264,7 @@ namespace hex {
EventManager::unsubscribe<RequestCloseImHex>(this); EventManager::unsubscribe<RequestCloseImHex>(this);
EventManager::unsubscribe<RequestChangeWindowTitle>(this); EventManager::unsubscribe<RequestChangeWindowTitle>(this);
EventManager::unsubscribe<EventAbnormalTermination>(this); EventManager::unsubscribe<EventAbnormalTermination>(this);
EventManager::unsubscribe<RequestChangeTheme>(this);
ImGui::UnloadImage(this->m_bannerTexture); ImGui::UnloadImage(this->m_bannerTexture);
ImGui::UnloadImage(this->m_logoTexture); ImGui::UnloadImage(this->m_logoTexture);
@ -691,8 +694,6 @@ namespace hex {
this->m_windowTitle = "ImHex"; this->m_windowTitle = "ImHex";
this->m_window = glfwCreateWindow(1280 * SharedData::globalScale, 720 * SharedData::globalScale, this->m_windowTitle.c_str(), nullptr, nullptr); this->m_window = glfwCreateWindow(1280 * SharedData::globalScale, 720 * SharedData::globalScale, this->m_windowTitle.c_str(), nullptr, nullptr);
this->setupNativeWindow();
glfwSetWindowUserPointer(this->m_window, this); glfwSetWindowUserPointer(this->m_window, this);
if (this->m_window == nullptr) if (this->m_window == nullptr)