1
0
mirror of synced 2025-01-18 00:56:49 +01:00

ui: Add interface scaling setting. Closes #7, #283

This commit is contained in:
WerWolv 2021-08-21 13:55:21 +02:00
parent 8ad0239bca
commit 72cf94106c
14 changed files with 140 additions and 39 deletions

View File

@ -183,14 +183,13 @@ namespace ImGui {
void Disabled(const std::function<void()> &widgets, bool disabled) {
if (disabled) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5F);
BeginDisabled();
widgets();
ImGui::PopStyleVar();
ImGui::PopItemFlag();
EndDisabled();
} else {
widgets();
}
}
void TextSpinner(const char* label) {
@ -293,6 +292,7 @@ namespace ImGui {
if (imageData == nullptr)
return { nullptr, -1, -1 };
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

View File

@ -25,6 +25,7 @@ namespace hex::prv {
bool isReadable() override;
bool isWritable() override;
bool isResizable() override;
bool isSavable() override;
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
void write(u64 offset, const void *buffer, size_t size) override;
@ -34,6 +35,9 @@ namespace hex::prv {
void writeRaw(u64 offset, const void *buffer, size_t size) override;
size_t getActualSize() override;
void save() override;
void saveAs(const std::string &path) override;
std::vector<std::pair<std::string, std::string>> getDataInformation() override;
private:

View File

@ -49,7 +49,7 @@ namespace hex {
GLFWwindow* m_window = nullptr;
float m_globalScale = 1.0f, m_fontScale = 1.0f;
float m_globalScale = 1.0F, m_fontScale = 1.0F;
double m_targetFps = 60.0;
bool m_demoWindowOpen = false;
bool m_layoutConfigured = false;

View File

@ -21,6 +21,25 @@ namespace hex::plugin::builtin {
return false;
});
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0, [](auto name, nlohmann::json &setting) {
static int selection = setting.is_number() ? static_cast<int>(setting) : 0;
const char* scaling[] = {
"hex.builtin.setting.interface.scaling.native"_lang,
"hex.builtin.setting.interface.scaling.x0_5"_lang,
"hex.builtin.setting.interface.scaling.x1_0"_lang,
"hex.builtin.setting.interface.scaling.x1_5"_lang,
"hex.builtin.setting.interface.scaling.x2_0"_lang,
};
if (ImGui::Combo(name.data(), &selection, scaling, IM_ARRAYSIZE(scaling))) {
setting = selection;
return true;
}
return false;
});
ContentRegistry::Settings::add("hex.builtin.setting.interface", "hex.builtin.setting.interface.language", "en-US", [](auto name, nlohmann::json &setting) {
auto &languages = LangEntry::getSupportedLanguages();

View File

@ -540,6 +540,12 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.interface.color.dark", "Dunkel" },
{ "hex.builtin.setting.interface.color.light", "Hell" },
{ "hex.builtin.setting.interface.color.classic", "Klassisch" },
{ "hex.builtin.setting.interface.scaling", "Skalierung" },
{ "hex.builtin.setting.interface.scaling.native", "Nativ" },
{ "hex.builtin.setting.interface.scaling.x0_5", "x0.5" },
{ "hex.builtin.setting.interface.scaling.x1_0", "x1.0" },
{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
{ "hex.builtin.setting.interface.language", "Sprache" },
{ "hex.builtin.setting.interface.fps", "FPS Limite" },
{ "hex.builtin.setting.interface.highlight_alpha", "Markierungssichtbarkeit" },

View File

@ -541,6 +541,12 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.interface.color.dark", "Dark" },
{ "hex.builtin.setting.interface.color.light", "Light" },
{ "hex.builtin.setting.interface.color.classic", "Classic" },
{ "hex.builtin.setting.interface.scaling", "Scaling" },
{ "hex.builtin.setting.interface.scaling.native", "Native" },
{ "hex.builtin.setting.interface.scaling.x0_5", "x0.5" },
{ "hex.builtin.setting.interface.scaling.x1_0", "x1.0" },
{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
{ "hex.builtin.setting.interface.language", "Language" },
{ "hex.builtin.setting.interface.fps", "FPS Limit" },
{ "hex.builtin.setting.interface.highlight_alpha", "Highlighting opacity" },

View File

@ -541,6 +541,12 @@ namespace hex::plugin::builtin {
{ "hex.builtin.setting.interface.color.light", "Chiaro" },
{ "hex.builtin.setting.interface.color.classic", "Classico" },
{ "hex.builtin.setting.interface.language", "Lingua" },
//{ "hex.builtin.setting.interface.scaling", "Scaling" },
//{ "hex.builtin.setting.interface.scaling.native", "Native" },
//{ "hex.builtin.setting.interface.scaling.x0_5", "x0.5" },
//{ "hex.builtin.setting.interface.scaling.x1_0", "x1.0" },
//{ "hex.builtin.setting.interface.scaling.x1_5", "x1.5" },
//{ "hex.builtin.setting.interface.scaling.x2_0", "x2.0" },
{ "hex.builtin.setting.interface.fps", "Limite FPS" },
{ "hex.builtin.setting.interface.highlight_alpha", "Evidenziazione dell'opacità" },

View File

@ -10,6 +10,13 @@ namespace hex {
struct ImHexApi {
ImHexApi() = delete;
struct Common {
static void closeImHex(bool noQuestions = false);
static void restartImHex();
};
struct Bookmarks {
Bookmarks() = delete;
@ -27,6 +34,7 @@ namespace hex {
static std::list<Entry>& getEntries();
};
};
}

View File

@ -9,6 +9,7 @@
#include <codicons_font.h>
#include <nfd.hpp>
#include <hex/api/imhex_api.hpp>
#include <hex/api/event.hpp>
#include <hex/providers/provider.hpp>

View File

@ -5,6 +5,18 @@
namespace hex {
void ImHexApi::Common::closeImHex(bool noQuestions) {
EventManager::post<RequestCloseImHex>(noQuestions);
}
void ImHexApi::Common::restartImHex() {
EventManager::post<RequestCloseImHex>(false);
std::atexit([]{
execve(SharedData::mainArgv[0], SharedData::mainArgv, nullptr);
});
}
void ImHexApi::Bookmarks::add(Region region, std::string_view name, std::string_view comment, u32 color) {
Entry entry;

View File

@ -66,7 +66,7 @@ namespace hex {
ImGui::NewLine();
ImGui::Separator();
if (ImGui::Button("hex.common.okay"_lang) || ImGui::IsKeyDown(ImGuiKey_Escape)) {
EventManager::post<RequestCloseImHex>();
ImHexApi::Common::closeImHex();
ImGui::CloseCurrentPopup();
}

View File

@ -286,7 +286,7 @@ namespace hex {
ImGui::NewLine();
confirmButtons("hex.common.yes"_lang, "hex.common.no"_lang, [] {
EventManager::post<RequestCloseImHex>();
ImHexApi::Common::closeImHex(true);
},
[] {
ImGui::CloseCurrentPopup();

View File

@ -18,6 +18,7 @@
static LONG_PTR oldWndProc;
static float titleBarHeight;
static ImGuiMouseCursor mouseCursorIcon;
static float borderScaling;
LRESULT wndProcImHex(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
@ -72,9 +73,10 @@
POINT cursor = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
const POINT border{
::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER),
::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)
static_cast<LONG>((::GetSystemMetrics(SM_CXFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * borderScaling / 2.0F),
static_cast<LONG>((::GetSystemMetrics(SM_CYFRAME) + ::GetSystemMetrics(SM_CXPADDEDBORDER)) * borderScaling / 2.0F)
};
RECT window;
if (!::GetWindowRect(hwnd, &window)) {
return HTNOWHERE;
@ -122,15 +124,19 @@
void Window::setupNativeWindow() {
auto hwnd = glfwGetWin32Window(this->m_window);
oldWndProc = SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)wndProcImHex);
MARGINS borderless = {1,1,1,1};
DwmExtendFrameIntoClientArea(hwnd, &borderless);
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);
}
void Window::updateNativeWindow() {
titleBarHeight = ImGui::GetCurrentWindow()->MenuBarHeight();
borderScaling = this->m_globalScale;
if (mouseCursorIcon != ImGuiMouseCursor_None)
ImGui::SetMouseCursor(mouseCursorIcon);
@ -170,8 +176,7 @@
if (ImGui::TitleBarButton(ICON_VS_CHROME_CLOSE, buttonSize)) {
EventManager::post<RequestCloseImHex>();
EventManager::post<EventWindowClosing>(this->m_window);
ImHexApi::Common::closeImHex();
}
ImGui::PopStyleColor(5);

View File

@ -118,6 +118,19 @@ namespace hex {
}
}
{
auto scaling = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling");
if (scaling.is_number()) {
static bool firstTime = true;
if (!firstTime) {
ImHexApi::Common::restartImHex();
}
firstTime = false;
}
}
{
auto language = ContentRegistry::Settings::getSetting("hex.builtin.setting.interface", "hex.builtin.setting.interface.language");
@ -174,8 +187,11 @@ namespace hex {
}
});
EventManager::subscribe<RequestCloseImHex>(this, [this]() {
EventManager::subscribe<RequestCloseImHex>(this, [this](bool noQuestions) {
glfwSetWindowShouldClose(this->m_window, true);
if (!noQuestions)
EventManager::post<EventWindowClosing>(this->m_window);
});
EventManager::subscribe<RequestChangeWindowTitle>(this, [this](std::string windowTitle) {
@ -209,8 +225,6 @@ namespace hex {
}
}
EventManager::post<EventSettingsChanged>();
for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files"))
SharedData::recentFilePaths.push_back(path);
@ -230,6 +244,8 @@ namespace hex {
std::signal(SIGFPE, signalHandler);
this->m_logoTexture = ImGui::LoadImageFromMemory(imhex_logo, imhex_logo_size);
EventManager::post<EventSettingsChanged>();
}
Window::~Window() {
@ -441,7 +457,6 @@ namespace hex {
ImGui::PopStyleVar(2);
// Popup for when no plugins were loaded. Intentionally left untranslated because localization isn't available
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
if (ImGui::BeginPopupModal("No Plugins", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
ImGui::TextUnformatted("No ImHex plugins loaded (including the built-in plugin)!");
@ -707,11 +722,31 @@ namespace hex {
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
switch (ContentRegistry::Settings::read("hex.builtin.setting.interface", "hex.builtin.setting.interface.scaling", 0)) {
default:
case 0:
this->m_globalScale = this->m_fontScale = -1.0F;
break;
case 1:
this->m_globalScale = this->m_fontScale = 0.5F;
break;
case 2:
this->m_globalScale = this->m_fontScale = 1.0F;
break;
case 3:
this->m_globalScale = this->m_fontScale = 1.5F;
break;
case 4:
this->m_globalScale = this->m_fontScale = 2.0F;
break;
}
if (auto *monitor = glfwGetPrimaryMonitor(); monitor) {
float xscale, yscale;
glfwGetMonitorContentScale(monitor, &xscale, &yscale);
// In case the horizontal and vertical scale are different, fall back on the average
if (this->m_globalScale <= 0.0F)
this->m_globalScale = this->m_fontScale = std::midpoint(xscale, yscale);
}
@ -749,7 +784,7 @@ namespace hex {
glfwSetWindowPosCallback(this->m_window, [](GLFWwindow *window, int x, int y) {
SharedData::windowPos = ImVec2(x, y);
if (ImGui::GetCurrentContext()->WithinFrameScope) return;
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
auto win = static_cast<Window*>(glfwGetWindowUserPointer(window));
win->frameBegin();
@ -760,7 +795,7 @@ namespace hex {
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
SharedData::windowSize = ImVec2(width, height);
if (ImGui::GetCurrentContext()->WithinFrameScope) return;
if (auto g = ImGui::GetCurrentContext(); g == nullptr || g->WithinFrameScope) return;
auto win = static_cast<Window*>(glfwGetWindowUserPointer(window));
win->frameBegin();
@ -801,7 +836,7 @@ namespace hex {
EventManager::post<EventWindowClosing>(window);
});
glfwSetWindowSizeLimits(this->m_window, 720, 480, GLFW_DONT_CARE, GLFW_DONT_CARE);
glfwSetWindowSizeLimits(this->m_window, 720 * this->m_globalScale, 480 * this->m_globalScale, GLFW_DONT_CARE, GLFW_DONT_CARE);
if (gladLoadGL() == 0)
throw std::runtime_error("Failed to initialize OpenGL loader!");
@ -860,7 +895,6 @@ namespace hex {
io.UserData = new ImGui::ImHexCustomData();
if (this->m_globalScale != 0.0f)
style.ScaleAllSizes(this->m_globalScale);
std::string fontFile;