Skip to content

Commit

Permalink
HighDPI UI behavouir (Kenix3#467)
Browse files Browse the repository at this point in the history
* Allow ImGui to scale itself by dpi and added Open Sans as default font to have a nice looking UI on HighDPI Monitors.

* - Changed OpenSans-Regular to OpenSans-Semibold witch is better readable and adjusted the font config for the new font.
- Changed the names of the new variables.
- Simplifyed the dpi stuff and moved the two new floats to the Header as private.
- Added comments to the changes.

* Run clang-format

* Removed new font

* Reworked GUI scaling by getting display dpi and apply the scale on events.

* Using ImGui_ImplWin32_GetDpiScaleForMonitor to support Windows 8.1
Get DpiScale instaed of DPI in window events

* Put SDL_GetDisplayDPI into if statement to prevent crash on Switch.

---------

Co-authored-by: Mirco <you@example.com>
  • Loading branch information
DarkMicro and Mirco authored Apr 21, 2024
1 parent 26ecbc1 commit b73cdb5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/window/gui/Gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARA

#endif

#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif

namespace LUS {
#define TOGGLE_BTN ImGuiKey_F1
#define TOGGLE_PAD_BTN ImGuiKey_GamepadBack
Expand Down Expand Up @@ -279,6 +283,8 @@ void Gui::Update(WindowEvent event) {
mNeedsConsoleVariableSave = false;
}

float dpiScale = 0;

switch (Context::GetInstance()->GetWindow()->GetWindowBackend()) {
#ifdef __WIIU__
case WindowBackend::GX2:
Expand All @@ -289,6 +295,21 @@ void Gui::Update(WindowEvent event) {
case WindowBackend::SDL_METAL:
ImGui_ImplSDL2_ProcessEvent(static_cast<const SDL_Event*>(event.Sdl.Event));

if (static_cast<const SDL_Event*>(event.Sdl.Event)->window.event == SDL_WINDOWEVENT_DISPLAY_CHANGED ||
mDpiInit) {
int display = 0;
if (Context::GetInstance()->GetWindow()->GetWindowBackend() == WindowBackend::SDL_OPENGL) {
display = SDL_GetWindowDisplayIndex(static_cast<SDL_Window*>(mImpl.Opengl.Window));
} else {
display = SDL_GetWindowDisplayIndex(static_cast<SDL_Window*>(mImpl.Metal.Window));
}

float dpi;
if (SDL_GetDisplayDPI(display, &dpi, nullptr, nullptr) == 0) {
dpiScale = dpi / USER_DEFAULT_SCREEN_DPI;
}
}

#ifdef __SWITCH__
LUS::Switch::ImGuiProcessEvent(mImGuiIo->WantTextInput);
#endif
Expand All @@ -301,11 +322,30 @@ void Gui::Update(WindowEvent event) {
case WindowBackend::DX11:
ImGui_ImplWin32_WndProcHandler(static_cast<HWND>(event.Win32.Handle), event.Win32.Msg, event.Win32.Param1,
event.Win32.Param2);

if (event.Win32.Msg == WM_DPICHANGED || mDpiInit) {
HMONITOR monitor = MonitorFromWindow(static_cast<HWND>(event.Win32.Handle), MONITOR_DEFAULTTONEAREST);
dpiScale = (float)ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
}
break;
#endif
default:
break;
}

if (dpiScale > 0) {
if (mDpiInit) {
mLastDpiScale = 1.f;
mDpiInit = false;
}

float diff = dpiScale / mLastDpiScale;
mLastDpiScale = dpiScale;

ImGui::GetStyle().ScaleAllSizes(diff);
ImFont* font = ImGui::GetFont();
font->Scale *= diff;
}
}

bool Gui::ImGuiGamepadNavigationEnabled() {
Expand All @@ -322,12 +362,24 @@ void Gui::UnblockImGuiGamepadNavigation() {
}
}

float Gui::GetCurrentDpiScale() {
if (mLastDpiScale <= 0) {
return 1.f;
}

return mLastDpiScale;
}

void Gui::DrawMenu() {
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")->Update();
ImGuiBackendNewFrame();
ImGuiWMNewFrame();
ImGui::NewFrame();

if (mLastDpiScale == 0) {
mDpiInit = true;
}

const std::shared_ptr<Window> wnd = Context::GetInstance()->GetWindow();
const std::shared_ptr<Config> conf = Context::GetInstance()->GetConfig();

Expand Down
4 changes: 4 additions & 0 deletions src/window/gui/Gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Gui {
bool ImGuiGamepadNavigationEnabled();
void BlockImGuiGamepadNavigation();
void UnblockImGuiGamepadNavigation();
float GetCurrentDpiScale();

protected:
void ImGuiWMInit();
Expand All @@ -111,6 +112,9 @@ class Gui {
std::shared_ptr<GuiMenuBar> mMenuBar;
std::map<std::string, GuiTextureMetadata> mGuiTextures;
std::map<std::string, std::shared_ptr<GuiWindow>> mGuiWindows;

bool mDpiInit = false;
float mLastDpiScale = 0;
};
} // namespace LUS

Expand Down

0 comments on commit b73cdb5

Please sign in to comment.