Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HighDPI UI behavouir #467

Merged
merged 9 commits into from
Apr 21, 2024
Merged

HighDPI UI behavouir #467

merged 9 commits into from
Apr 21, 2024

Conversation

DarkMicro
Copy link
Contributor

@DarkMicro DarkMicro commented Apr 4, 2024

What always bothered me about SoH was this when playing on my 4K Monitor:

grafik

The UI needs to be set on X-Large and the Font looks not that great. Also you can barely see the litte ship in the left corner which looks very ood but thats a problem of Shipwright. (But can be solved in the same way)

ImGui provides a CurrentDpiScale value which holds the perfect scale to compensate the dpi difference.

float scaleCurrent = 1.f;             // Needs to be 1.0 at start
float scaleNew, scaleDiff;

scaleNew = GImGui->CurrentDpiScale;   // Get the CurrentDpiScale
scaleDiff = scaleNew / scaleCurrent;  // Get the difference between the last frame and the current Frame 
scaleCurrent = scaleNew;              // Store the new scale

// And apply the scaleDiff to ImGui
ImGui::GetStyle().ScaleAllSizes(scaleDiff);
ImFont *font = ImGui::GetFont();
font->Scale *= scaleDiff;
2160p 1080p
Menu new hi Menu new low

With these changes the UI goes to a reasonable size no matter which resolution is used. Even if you move the window to a monitor with a different resolution the UI automatically applys the new DPI scale.

I also implemented OpenSans-Semibold as default Font to make it look nice and crisp at High DPI. But feel free to get a better font in the future. I only took that because it was convenient.

I only tested this on Windows 11 and Ubuntu 23.03 so maybe it breaks on other platforms.

That should increase the user experience. 🤓

Mirco and others added 4 commits April 3, 2024 18:13
…t to have a nice looking UI on HighDPI Monitors.
…ble 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.
@DarkMicro DarkMicro changed the title UI changes HighDPI UI changes and better Font Apr 4, 2024
@Malkierian
Copy link
Contributor

I take it, then, this applies scaling automatically, making the scaling option dropdown redundant? If the default size plus the scaling coefficient looks that readable on any screen resolution, I see no reason to keep the dropdown around. Not sure if that needs to be done here or not, though.

I'm curious, though, when using the dropdown, going from .75 to 1 or 2 and back multiple times would gradually desync the base value, such that 1 could look significantly bigger than it should or does when you first boot up SoH. Does that happen with this? Say, if you were going from 4k to something between that and 1080p and back again.

@DarkMicro
Copy link
Contributor Author

No i didn't experience anything like that. The only thing is if going to a smaller scale in the dropdown and drag the window to a different resolution the row paddings are getting messed up:
grafik

But i think this menu is useless now like you said. Large would be too big to use.
The base menu size should be increased by ~25% imo like this:
grafik
That would be perfect to use.

Copy link
Owner

@Kenix3 Kenix3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First thing I've noticed:
What are the licenses in the new fonts being included?

Further our pattern is to load data from the archive instead of include it with the executable. The font C file breaks that.

@DarkMicro
Copy link
Contributor Author

That would be SIL OPEN FONT LICENSE Version 1.1 Source: https://github.com/googlefonts/opensans/tree/main?tab=License-1-ov-file

Didn't know that would be a problem since we allready have that font c file which also loads FontAwsome.

@Malkierian
Copy link
Contributor

Malkierian commented Apr 6, 2024

The problem with gui element sizing and padding is known, and a side effect of them not having been made with scaling in mind.

Btw, how does this mesh with Windows DPI scaling? It looks like the difference you showed between 1080 and 4k was the same proportion. If you increase Windows DPI setting, does it still look the same size on 4k as it does at 100% for 4k?

Copy link
Contributor Author

@DarkMicro DarkMicro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have set the scale of my two monitors to show the OS windows at the same size. The 4K at 175% and the HD at 100%. It seems like ImGui grabs that setting for the CurrentDpiScale value. If i change the scale in the monitor settings and restart soh it changes the size. So that works as it should be.

@Kenix3
Copy link
Owner

Kenix3 commented Apr 7, 2024

That would be SIL OPEN FONT LICENSE Version 1.1 Source: https://github.com/googlefonts/opensans/tree/main?tab=License-1-ov-file

Didn't know that would be a problem since we allready have that font c file which also loads FontAwsome.

Ah my mistake. I'm not saying it's a problem, just asking questions since it came to my attention just now. Double checking, you know.

I think we still probably want to load fonts externally instead of building them in, though

@DarkMicro
Copy link
Contributor Author

Ok i get that. I think you want to add it to soh.otr right? I removed the font change so it can be done in soh instead.

@DarkMicro DarkMicro changed the title HighDPI UI changes and better Font HighDPI UI behavouir Apr 8, 2024
Copy link
Owner

@Kenix3 Kenix3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thankyou for addressing the feedback. Will leave this open for others to take a look for a few days.

src/window/gui/Gui.cpp Outdated Show resolved Hide resolved
@DarkMicro
Copy link
Contributor Author

I rewoked the scaling like suggested by @briaguya-ai . Now we get the display DPI ourself and calculate the scale at specific window events. In DirectX i use WM_DPICHANGED like suggested and in SDL i use SDL_WINDOWEVENT_DISPLAY_CHANGED.
To scale the GUI at application start, i set a flag right after i called ImGui::NewFrame(). ImGui needs to be fully initialized to accept scales without an error. Because i use a flag to run the scaling once i can't use wParam of WM_DPICHANGED if you're wondering why i use GetDpiForWindow for Windows.

I also implemented a public function to provide the current scale to the game: LUS::Gui::GetCurrentDpiScale()
This should be usefull to scale textures like the ship icon.

I tested it on Windows 11 and Ubuntu 23.10
The new code has the same functionality as before.

@@ -301,11 +318,29 @@ 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)
dpi = (float)GetDpiForWindow(static_cast<HWND>(event.Win32.Handle));
Copy link
Contributor

@Spodi Spodi Apr 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetDpiForWindow is Win 10 and up only. Definitely breaks compatibility with Win 8.1, wich the last release of SoH still worked with (another user on Discord confirmed it working).
You can probably use GetDpiScaleForMonitor instead like this:

if (event.Win32.Msg == WM_DPICHANGED || mDpiInit) {
    HMONITOR monitor = MonitorFromWindow(static_cast<HWND>(event.Win32.Handle), MONITOR_DEFAULTTONEAREST);
    dpi = (float)GetDpiScaleForMonito(monitor);
}

EDIT: Apparently you need to link more dependencies with the Windows default. Urg

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There also is ImGui's ImGui_ImplWin32_GetDpiScaleForMonitor for Windows. This is already a scale however.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you're right. I didn't see that.

What i could do is this:

if (event.Win32.Msg == WM_DPICHANGED || mDpiInit) {
    HMONITOR monitor = MonitorFromWindow(static_cast<HWND>(event.Win32.Handle), MONITOR_DEFAULTTONEAREST);
    dpi = (float)ImGui_ImplWin32_GetDpiScaleForMonitor(monitor) * USER_DEFAULT_SCREEN_DPI;
}

ImGui_ImplWin32_GetDpiScaleForMonitor gives me the dvided by 96 scale value.
Better would be to link aginst Shcore.lib and just use GetDpiForMonitor instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better idea is that we just get the scale in both windows events and save the extra step. I updated the code.

@Kenix3 Kenix3 merged commit b73cdb5 into Kenix3:main Apr 21, 2024
4 checks passed
briaguya-ai added a commit to briaguya-ai/libultraship that referenced this pull request Apr 22, 2024
@briaguya-ai briaguya-ai mentioned this pull request Apr 22, 2024
@Kenix3
Copy link
Owner

Kenix3 commented Apr 22, 2024

See #502. This had to be taken out.

Kenix3 pushed a commit that referenced this pull request Apr 22, 2024
* Revert "fix: ifdef macro that doesn't exist on switch (#501)"

This reverts commit 8a079ed.

* Revert "HighDPI UI behavouir (#467)"

This reverts commit b73cdb5.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants