From 7d8a5be286172bae0e991831a69e5736eb88bb32 Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Fri, 17 Apr 2026 03:17:34 +0200 Subject: [PATCH] Added scale factor to WindowCore --- .clangd | 1 + src/ogfx/gui/Window.cpp | 68 ++++++++++++++++++++++++++++++++++++----- src/ogfx/gui/Window.hpp | 18 ++++++++++- src/test/GuiTest.cpp | 1 - 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/.clangd b/.clangd index e6defe1..c60968a 100644 --- a/.clangd +++ b/.clangd @@ -1,4 +1,5 @@ CompileFlags: CompilationDatabase: bin + Add: ["--target=x86_64-w64-mingw32"] Diagnostics: MissingIncludes: None \ No newline at end of file diff --git a/src/ogfx/gui/Window.cpp b/src/ogfx/gui/Window.cpp index 8b3d26e..5cc6edb 100644 --- a/src/ogfx/gui/Window.cpp +++ b/src/ogfx/gui/Window.cpp @@ -89,6 +89,10 @@ namespace ogfx SDL_SetWindowPosition(m_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SetWindowTitle(m_window, m_title.c_str()); SDL_StartTextInput(m_window); + + m_systemScale = SDL_GetWindowDisplayScale(m_window); + setUserScale(1.0f); + SDL_ShowWindow(m_window); m_cursor_Default = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_DEFAULT); @@ -246,6 +250,29 @@ namespace ogfx } } + void WindowCore::setUserScale(f32 scale) + { + m_userScale = std::clamp(scale, 0.1f, 10.0f); //TODO: Handle min and max scale better + f32 s = getScaleFactor(); + auto state = getWindowState(); + if (!state.maximized && !state.fullscreen) + setSize(getWindowWidth() * s, getWindowHeight() * s); + SDL_SetRenderScale(m_renderer, s, s); + } + + WindowCore::State WindowCore::getWindowState(void) const + { + SDL_WindowFlags flags = SDL_GetWindowFlags(m_window); + State state; + state.fullscreen = flags & SDL_WINDOW_FULLSCREEN; + state.borderless = flags & SDL_WINDOW_BORDERLESS; + state.resizable = flags & SDL_WINDOW_RESIZABLE; + state.minimized = flags & SDL_WINDOW_MINIMIZED; + state.maximized = flags & SDL_WINDOW_MAXIMIZED; + state.alwaysOnTop = flags & SDL_WINDOW_ALWAYS_ON_TOP; + return state; + } + WindowCore::eCursor WindowCore::getCurosr(void) const { auto cur = SDL_GetCursor(); @@ -315,10 +342,32 @@ namespace ogfx __on_signal(signal); } - MouseEventData WindowCore::get_mouse_state(void) + MouseEventData WindowCore::get_mouse_state(SDL_Event& event) { - f32 mx = 0, my = 0; - u32 btn = SDL_GetMouseState(&mx, &my); + f32 mx = 0, my = 0, _mx = 0, _my = 0; + u32 btn = SDL_GetMouseState(&_mx, &_my); + f32 scale = getScaleFactor(); + switch (event.type) + { + case SDL_EVENT_MOUSE_MOTION: + mx = event.motion.x / scale; + my = event.motion.y / scale; + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + mx = event.button.x / scale; + my = event.button.y / scale; + btn = event.button.button; + break; + case SDL_EVENT_MOUSE_WHEEL: + mx = event.wheel.mouse_x / scale; + my = event.wheel.mouse_y / scale; + break; + default: + mx = _mx / scale; + my = _my / scale; + break; + } MouseEventData::eButton button = MouseEventData::eButton::None; switch (btn) { @@ -372,6 +421,11 @@ namespace ogfx { close(); } + else if (event.type == SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED) + { + m_systemScale = SDL_GetWindowDisplayScale(m_window); + updateScalleFactor(); + } else if (event.type == SDL_EVENT_DROP_FILE) { DropEventData ded(*this, DropEventData::eDropType::File); @@ -402,12 +456,12 @@ namespace ogfx } else if (event.type == SDL_EVENT_MOUSE_MOTION) { - MouseEventData mmd = get_mouse_state(); + MouseEventData mmd = get_mouse_state(event); ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseMoved, ostd::Signal::Priority::RealTime, mmd); } else if (event.type == SDL_EVENT_MOUSE_WHEEL) { - MouseEventData mmd = get_mouse_state(); + MouseEventData mmd = get_mouse_state(event); if (event.wheel.y == -1) mmd.scroll = MouseEventData::eScrollDirection::Down; else if (event.wheel.y == 1) @@ -418,12 +472,12 @@ namespace ogfx } else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) { - MouseEventData mmd = get_mouse_state(); + MouseEventData mmd = get_mouse_state(event); ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MousePressed, ostd::Signal::Priority::RealTime, mmd); } else if (event.type == SDL_EVENT_MOUSE_BUTTON_UP) { - MouseEventData mmd = get_mouse_state(); + MouseEventData mmd = get_mouse_state(event); switch (event.button.button) { case SDL_BUTTON_MASK(1): mmd.button = MouseEventData::eButton::Left; break; diff --git a/src/ogfx/gui/Window.hpp b/src/ogfx/gui/Window.hpp index 5ef4828..91eaba2 100644 --- a/src/ogfx/gui/Window.hpp +++ b/src/ogfx/gui/Window.hpp @@ -65,6 +65,15 @@ namespace ogfx Center, Left }; + public: struct State + { + bool fullscreen { false }; + bool borderless { false }; + bool resizable { false }; + bool minimized { false }; + bool maximized { false }; + bool alwaysOnTop { false }; + }; public: inline WindowCore(void) { } virtual ~WindowCore(void); @@ -75,6 +84,8 @@ namespace ogfx void setSize(i32 width, i32 height); void setTitle(const String& title); void setCursor(eCursor cursor); + void setUserScale(f32 scale); + State getWindowState(void) const; eCursor getCurosr(void) const; void enableResizable(bool enable = true); void setIcon(const String& iconFilePath); @@ -103,9 +114,11 @@ namespace ogfx inline bool isBlockingEventsEnabled(void) const { return m_blockingEvents; } inline ostd::ConsoleOutputHandler& out(void) { return m_out; } inline GraphicsWindowOutputHandler& wout(void) { return m_wout; } + inline f32 getScaleFactor(void) const { return m_systemScale * m_userScale; } + inline void updateScalleFactor(void) { setUserScale(m_userScale); } protected: - MouseEventData get_mouse_state(void); + MouseEventData get_mouse_state(SDL_Event& event); virtual void handle_events(void); virtual void before_render(void); virtual void after_render(void); @@ -144,6 +157,9 @@ namespace ogfx bool m_resizeable { true }; bool m_refreshScreen { true }; + f32 m_systemScale { 1.0f }; + f32 m_userScale { 1.0f }; + SDL_Cursor* m_cursor_Default { nullptr }; SDL_Cursor* m_cursor_Text { nullptr }; SDL_Cursor* m_cursor_Wait { nullptr }; diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 545e979..c3f5172 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -46,7 +46,6 @@ class Window : public ogfx::gui::Window // m_anim.setSpriteSheet(m_img); - m_label1.setText("Show Panel2"); m_label1.setMousePressedCallback([&](const ogfx::gui::Event& event) -> void { m_check1.setChecked(!m_check1.isChecked());