diff --git a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
index 6caf7f651..57aeccbc7 100644
--- a/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
+++ b/Source/Editor/GUI/ContextMenu/ContextMenuBase.cs
@@ -124,7 +124,7 @@ namespace FlaxEditor.GUI.ContextMenu
PerformLayout();
// Calculate popup direction and initial location (fit on a single monitor)
- var dpiScale = Platform.DpiScale;
+ var dpiScale = parentWin.Window.DpiScale;
Vector2 dpiSize = Size * dpiScale;
Vector2 locationWS = parent.PointToWindow(location);
Vector2 locationSS = parentWin.PointToScreen(locationWS);
@@ -275,7 +275,7 @@ namespace FlaxEditor.GUI.ContextMenu
{
if (_window != null)
{
- _window.ClientSize = Size * Platform.DpiScale;
+ _window.ClientSize = Size * _window.DpiScale;
}
}
diff --git a/Source/Editor/GUI/Dialogs/Dialog.cs b/Source/Editor/GUI/Dialogs/Dialog.cs
index 173dd9128..c33429609 100644
--- a/Source/Editor/GUI/Dialogs/Dialog.cs
+++ b/Source/Editor/GUI/Dialogs/Dialog.cs
@@ -143,7 +143,7 @@ namespace FlaxEditor.GUI.Dialogs
// Setup initial window settings
CreateWindowSettings settings = CreateWindowSettings.Default;
settings.Title = _title;
- settings.Size = _dialogSize * Platform.DpiScale;
+ settings.Size = _dialogSize * parentWindow.DpiScale;
settings.AllowMaximize = false;
settings.AllowMinimize = false;
settings.HasSizingFrame = false;
diff --git a/Source/Editor/GUI/Docking/DockPanel.cs b/Source/Editor/GUI/Docking/DockPanel.cs
index f6e10e653..23b70f719 100644
--- a/Source/Editor/GUI/Docking/DockPanel.cs
+++ b/Source/Editor/GUI/Docking/DockPanel.cs
@@ -123,9 +123,8 @@ namespace FlaxEditor.GUI.Docking
if (parentWin == null)
throw new InvalidOperationException("Missing parent window.");
var control = _tabsProxy != null ? (Control)_tabsProxy : this;
- var dpiScale = Platform.DpiScale;
var clientPos = control.PointToWindow(Vector2.Zero);
- return new Rectangle(parentWin.PointToScreen(clientPos), control.Size * dpiScale);
+ return new Rectangle(parentWin.PointToScreen(clientPos), control.Size * RootWindow.Window.DpiScale);
}
}
diff --git a/Source/Editor/GUI/MainMenu.cs b/Source/Editor/GUI/MainMenu.cs
index 7c49d85ac..f0f9458e7 100644
--- a/Source/Editor/GUI/MainMenu.cs
+++ b/Source/Editor/GUI/MainMenu.cs
@@ -185,14 +185,14 @@ namespace FlaxEditor.GUI
private WindowHitCodes OnHitTest(ref Vector2 mouse)
{
- var pos = _window.ScreenToClient(mouse * Platform.DpiScale);
+ var dpiScale = _window.DpiScale;
+ var pos = _window.ScreenToClient(mouse * dpiScale);
if (_window.IsMinimized)
return WindowHitCodes.NoWhere;
if (!_window.IsMaximized)
{
- var dpiScale = Platform.DpiScale;
var winSize = RootWindow.Size * dpiScale;
// Distance from which the mouse is considered to be on the border/corner
@@ -227,7 +227,7 @@ namespace FlaxEditor.GUI
var controlUnderMouse = GetChildAt(menuPos);
var isMouseOverSth = controlUnderMouse != null && controlUnderMouse != _title;
var rb = GetRightButton();
- if (rb != null && _minimizeButton != null && new Rectangle(rb.UpperRight * Platform.DpiScale, (_minimizeButton.BottomLeft - rb.UpperRight) * Platform.DpiScale).Contains(ref menuPos) && !isMouseOverSth)
+ if (rb != null && _minimizeButton != null && new Rectangle(rb.UpperRight * dpiScale, (_minimizeButton.BottomLeft - rb.UpperRight) * dpiScale).Contains(ref menuPos) && !isMouseOverSth)
return WindowHitCodes.Caption;
return WindowHitCodes.Client;
diff --git a/Source/Editor/Modules/WindowsModule.cs b/Source/Editor/Modules/WindowsModule.cs
index a8058b9d8..9dc6d4f93 100644
--- a/Source/Editor/Modules/WindowsModule.cs
+++ b/Source/Editor/Modules/WindowsModule.cs
@@ -709,7 +709,7 @@ namespace FlaxEditor.Modules
var dpiScale = Platform.DpiScale;
var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor";
- settings.Size = new Vector2(1300 * dpiScale, 900 * dpiScale);
+ settings.Size = new Vector2(1300 * dpiScale, 900 * dpiScale); // TODO: Place the window on the correct screen (and use that screen's size)
settings.StartPosition = WindowStartPosition.CenterScreen;
if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
diff --git a/Source/Editor/Surface/ContextMenu/ContentFinder.cs b/Source/Editor/Surface/ContextMenu/ContentFinder.cs
index 76e8d2e33..fd986f4f5 100644
--- a/Source/Editor/Surface/ContextMenu/ContentFinder.cs
+++ b/Source/Editor/Surface/ContextMenu/ContentFinder.cs
@@ -108,11 +108,13 @@ namespace FlaxEditor.Surface.ContextMenu
{
_resultPanel.DisposeChildren();
+ var dpiScale = RootWindow.Window.DpiScale;
+
if (items.Count == 0)
{
Height = _searchBox.Height + 1;
_resultPanel.ScrollBars = ScrollBars.None;
- RootWindow.Window.ClientSize = new Vector2(RootWindow.Window.ClientSize.X, Height * Platform.DpiScale);
+ RootWindow.Window.ClientSize = new Vector2(RootWindow.Window.ClientSize.X, Height * dpiScale);
return;
}
@@ -146,7 +148,7 @@ namespace FlaxEditor.Surface.ContextMenu
MatchedItems.Add(searchItem);
}
- RootWindow.Window.ClientSize = new Vector2(RootWindow.Window.ClientSize.X, Height * Platform.DpiScale);
+ RootWindow.Window.ClientSize = new Vector2(RootWindow.Window.ClientSize.X, Height * dpiScale);
PerformLayout();
}
diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs
index ac34d9e45..18dff245f 100644
--- a/Source/Editor/Utilities/Utils.cs
+++ b/Source/Editor/Utilities/Utils.cs
@@ -1657,7 +1657,7 @@ namespace FlaxEditor.Utilities
settings.AllowMinimize = false;
settings.HasSizingFrame = false;
settings.StartPosition = WindowStartPosition.CenterScreen;
- settings.Size = new Vector2(500, 600) * Platform.DpiScale;
+ settings.Size = new Vector2(500, 600) * Platform.DpiScale; // TODO: Place the window on the correct screen (and use that screen's size)
settings.Title = title;
var dialog = Platform.CreateWindow(ref settings);
diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h
index 3da48bb7a..6fab84504 100644
--- a/Source/Engine/Platform/Base/WindowBase.h
+++ b/Source/Engine/Platform/Base/WindowBase.h
@@ -281,6 +281,8 @@ protected:
String _title;
CursorType _cursor;
Vector2 _clientSize;
+ int _dpi;
+ float _dpiScale;
Vector2 _trackingMouseOffset;
bool _isUsingMouseOffset;
@@ -541,6 +543,22 @@ public:
/// The screen space position.
API_FUNCTION() virtual Vector2 ClientToScreen(const Vector2& clientPos) const = 0;
+ ///
+ /// Gets the window DPI setting.
+ ///
+ API_PROPERTY() int GetDpi() const
+ {
+ return _dpi;
+ }
+
+ // TODO: This doesn't actually include the custom DPI scale
+ ///
+ /// Gets the window DPI scale factor (1 is default). Includes custom DPI scale
+ ///
+ API_PROPERTY() float GetDpiScale() const
+ {
+ return Platform::CustomDpiScale * _dpiScale;
+ }
public:
///
diff --git a/Source/Engine/Platform/Window.cs b/Source/Engine/Platform/Window.cs
index 8a8a19c01..d000c6f90 100644
--- a/Source/Engine/Platform/Window.cs
+++ b/Source/Engine/Platform/Window.cs
@@ -7,8 +7,6 @@ namespace FlaxEngine
{
partial class Window
{
- internal float _dpiScale;
-
///
/// Window closing delegate.
///
@@ -176,7 +174,6 @@ namespace FlaxEngine
private Window()
{
GUI = new WindowRootControl(this);
- _dpiScale = Platform.DpiScale;
}
internal void Internal_OnShow()
@@ -192,7 +189,7 @@ namespace FlaxEngine
internal void Internal_OnDraw()
{
- Matrix3x3.Scaling(_dpiScale, out var scale);
+ Matrix3x3.Scaling(DpiScale, out var scale);
Render2D.PushTransform(ref scale);
GUI.Draw();
Render2D.PopTransform();
@@ -200,7 +197,7 @@ namespace FlaxEngine
internal void Internal_OnResize(int width, int height)
{
- GUI.Size = new Vector2(width / _dpiScale, height / _dpiScale);
+ GUI.Size = new Vector2(width / DpiScale, height / DpiScale);
}
internal void Internal_OnCharInput(char c)
@@ -223,7 +220,7 @@ namespace FlaxEngine
internal void Internal_OnMouseDown(ref Vector2 mousePos, MouseButton button)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
bool handled = false;
MouseDown?.Invoke(ref pos, button, ref handled);
@@ -235,7 +232,7 @@ namespace FlaxEngine
internal void Internal_OnMouseUp(ref Vector2 mousePos, MouseButton button)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
bool handled = false;
MouseUp?.Invoke(ref pos, button, ref handled);
@@ -247,7 +244,7 @@ namespace FlaxEngine
internal void Internal_OnMouseDoubleClick(ref Vector2 mousePos, MouseButton button)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
bool handled = false;
MouseDoubleClick?.Invoke(ref pos, button, ref handled);
@@ -259,7 +256,7 @@ namespace FlaxEngine
internal void Internal_OnMouseWheel(ref Vector2 mousePos, float delta)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
bool handled = false;
MouseWheel?.Invoke(ref pos, delta, ref handled);
@@ -271,7 +268,7 @@ namespace FlaxEngine
internal void Internal_OnMouseMove(ref Vector2 mousePos)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
MouseMove?.Invoke(ref pos);
GUI.OnMouseMove(pos);
@@ -285,7 +282,7 @@ namespace FlaxEngine
internal void Internal_OnTouchDown(ref Vector2 pointerPosition, int pointerId)
{
- Vector2 pos = pointerPosition / _dpiScale;
+ Vector2 pos = pointerPosition / DpiScale;
bool handled = false;
TouchDown?.Invoke(ref pos, pointerId, ref handled);
@@ -297,7 +294,7 @@ namespace FlaxEngine
internal void Internal_OnTouchMove(ref Vector2 pointerPosition, int pointerId)
{
- Vector2 pos = pointerPosition / _dpiScale;
+ Vector2 pos = pointerPosition / DpiScale;
bool handled = false;
TouchMove?.Invoke(ref pos, pointerId, ref handled);
@@ -309,7 +306,7 @@ namespace FlaxEngine
internal void Internal_OnTouchUp(ref Vector2 pointerPosition, int pointerId)
{
- Vector2 pos = pointerPosition / _dpiScale;
+ Vector2 pos = pointerPosition / DpiScale;
bool handled = false;
TouchUp?.Invoke(ref pos, pointerId, ref handled);
@@ -335,7 +332,7 @@ namespace FlaxEngine
{
if (HitTest != null)
{
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
result = HitTest(ref pos);
handled = true;
}
@@ -356,7 +353,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
return GUI.OnDragEnter(ref pos, dragData);
}
@@ -367,7 +364,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
return GUI.OnDragMove(ref pos, dragData);
}
@@ -378,7 +375,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]);
else
dragData = new DragDataFiles(data);
- Vector2 pos = mousePos / _dpiScale;
+ Vector2 pos = mousePos / DpiScale;
return GUI.OnDragDrop(ref pos, dragData);
}
diff --git a/Source/Engine/Platform/Windows/WindowsPlatform.cpp b/Source/Engine/Platform/Windows/WindowsPlatform.cpp
index 0b1f70989..fae4add2d 100644
--- a/Source/Engine/Platform/Windows/WindowsPlatform.cpp
+++ b/Source/Engine/Platform/Windows/WindowsPlatform.cpp
@@ -58,7 +58,7 @@ int32 CalculateDpi(HMODULE shCoreDll)
if (getDPIForMonitor)
{
- HMONITOR monitor = GetPrimaryMonitorHandle();
+ HMONITOR monitor = GetPrimaryMonitorHandle(); // TODO: Use the game window monitor
UINT x = 0, y = 0;
HRESULT hr = getDPIForMonitor(monitor, 0, &x, &y);
@@ -659,7 +659,7 @@ void WindowsPlatform::SetHighDpiAwarenessEnabled(bool enable)
if (setProcessDpiAwareness)
{
- setProcessDpiAwareness(enable ? PROCESS_SYSTEM_DPI_AWARE : PROCESS_DPI_UNAWARE);
+ setProcessDpiAwareness(enable ? PROCESS_PER_MONITOR_DPI_AWARE : PROCESS_DPI_UNAWARE);
}
SystemDpi = CalculateDpi(shCoreDll);
diff --git a/Source/Engine/Platform/Windows/WindowsWindow.cpp b/Source/Engine/Platform/Windows/WindowsWindow.cpp
index dc130949c..1b270d80b 100644
--- a/Source/Engine/Platform/Windows/WindowsWindow.cpp
+++ b/Source/Engine/Platform/Windows/WindowsWindow.cpp
@@ -16,6 +16,8 @@
// TODO: finish better borderless window on windows (fix mouse pos offset when maximized and fix white flicker on window show)
#define WINDOWS_USE_NEW_BORDER_LESS 0
+#define DefaultDPI 96
+
#if WINDOWS_USE_NEW_BORDER_LESS
#pragma comment(lib, "Gdi32.lib")
#endif
@@ -95,6 +97,23 @@ WindowsWindow::WindowsWindow(const CreateWindowSettings& settings)
nullptr,
(HINSTANCE)Platform::Instance,
nullptr);
+
+ _dpi = DefaultDPI;
+ // TODO: Is this the correct way of doing this?
+ const HMODULE user32Dll = LoadLibraryW(L"user32.dll");
+ if (user32Dll)
+ {
+ typedef UINT(STDAPICALLTYPE* GetDpiForWindowProc)(HWND hwnd);
+ const GetDpiForWindowProc getDpiForWindowProc = (GetDpiForWindowProc)GetProcAddress(user32Dll, "GetDpiForWindow");
+
+ if (getDpiForWindowProc)
+ {
+ _dpi = getDpiForWindowProc(_handle);
+ }
+ FreeLibrary(user32Dll);
+ }
+
+ _dpiScale = (float)_dpi / (float)DefaultDPI;
// Validate result
if (!HasHWND())
@@ -966,6 +985,28 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
break;
}
+ case WM_DPICHANGED:
+ {
+ // Maybe https://stackoverflow.com/a/45110656
+ _dpi = HIWORD(wParam);
+ _dpiScale = (float)_dpi / (float)DefaultDPI;
+
+
+ RECT* windowRect = (RECT*)lParam;
+ SetWindowPos(_handle,
+ nullptr,
+ windowRect->left,
+ windowRect->top,
+ windowRect->right - windowRect->left,
+ windowRect->bottom - windowRect->top,
+ SWP_NOZORDER | SWP_NOACTIVATE);
+
+
+ // Todo: Recalculate fonts
+
+ return 0;
+ }
+
case WM_ENTERSIZEMOVE:
{
_isResizing = true;
diff --git a/Source/Engine/Render2D/FontManager.cpp b/Source/Engine/Render2D/FontManager.cpp
index ec7a61257..8eda2d5ba 100644
--- a/Source/Engine/Render2D/FontManager.cpp
+++ b/Source/Engine/Render2D/FontManager.cpp
@@ -67,7 +67,7 @@ bool FontManagerService::Init()
ASSERT(Library == nullptr);
// Scale UI fonts to match the monitor DPI
- FontManager::FontScale = (float)Platform::GetDpi() / (float)DefaultDPI;
+ FontManager::FontScale = (float)Platform::GetDpi() / (float)DefaultDPI; // TODO: Adjust this at runtime
// Init Free Type
FreeTypeMemory.user = nullptr;
diff --git a/Source/Engine/UI/GUI/Control.cs b/Source/Engine/UI/GUI/Control.cs
index 1c4eda965..6f4603e1a 100644
--- a/Source/Engine/UI/GUI/Control.cs
+++ b/Source/Engine/UI/GUI/Control.cs
@@ -310,7 +310,7 @@ namespace FlaxEngine.GUI
///
/// Gets the GUI window root control which contains that control (or null if not linked to any).
///
- public virtual WindowRootControl RootWindow => _parent?.RootWindow;
+ public virtual WindowRootControl RootWindow => _parent?.RootWindow; // TODO: Why doesn't this just go "_root?.RootWindow" or something?
///
/// Gets screen position of the control (upper left corner).
diff --git a/Source/Engine/UI/GUI/RenderOutputControl.cs b/Source/Engine/UI/GUI/RenderOutputControl.cs
index 74210c9df..fb6897516 100644
--- a/Source/Engine/UI/GUI/RenderOutputControl.cs
+++ b/Source/Engine/UI/GUI/RenderOutputControl.cs
@@ -221,7 +221,7 @@ namespace FlaxEngine.GUI
///
public void SyncBackbufferSize()
{
- float scale = ResolutionScale * Platform.DpiScale;
+ float scale = ResolutionScale * (Root?.RootWindow?.Window?.DpiScale ?? 1); // TODO: Figure this out
int width = Mathf.CeilToInt(Width * scale);
int height = Mathf.CeilToInt(Height * scale);
if (_customResolution.HasValue)
diff --git a/Source/Engine/UI/GUI/Tooltip.cs b/Source/Engine/UI/GUI/Tooltip.cs
index 24c0651ed..fca4bd645 100644
--- a/Source/Engine/UI/GUI/Tooltip.cs
+++ b/Source/Engine/UI/GUI/Tooltip.cs
@@ -68,7 +68,7 @@ namespace FlaxEngine.GUI
var parentWin = target.Root;
if (parentWin == null)
return;
- float dpiScale = Platform.DpiScale;
+ float dpiScale = target.RootWindow.Window.DpiScale;
Vector2 dpiSize = Size * dpiScale;
Vector2 locationWS = target.PointToWindow(location);
Vector2 locationSS = parentWin.PointToScreen(locationWS);
@@ -185,7 +185,7 @@ namespace FlaxEngine.GUI
{
if (_window)
{
- _window.ClientSize = Size * Platform.DpiScale;
+ _window.ClientSize = Size * _window.DpiScale;
}
}
diff --git a/Source/Engine/UI/GUI/WindowRootControl.cs b/Source/Engine/UI/GUI/WindowRootControl.cs
index 02c996b68..1e9785195 100644
--- a/Source/Engine/UI/GUI/WindowRootControl.cs
+++ b/Source/Engine/UI/GUI/WindowRootControl.cs
@@ -151,7 +151,7 @@ namespace FlaxEngine.GUI
}
///
- public override Vector2 TrackingMouseOffset => _window.TrackingMouseOffset / _window._dpiScale;
+ public override Vector2 TrackingMouseOffset => _window.TrackingMouseOffset / _window.DpiScale;
///
public override WindowRootControl RootWindow => this;
@@ -159,8 +159,8 @@ namespace FlaxEngine.GUI
///
public override Vector2 MousePosition
{
- get => _window.MousePosition / _window._dpiScale;
- set => _window.MousePosition = value * _window._dpiScale;
+ get => _window.MousePosition / _window.DpiScale;
+ set => _window.MousePosition = value * _window.DpiScale;
}
///
@@ -234,13 +234,13 @@ namespace FlaxEngine.GUI
///
public override Vector2 PointFromScreen(Vector2 location)
{
- return _window.ScreenToClient(location) / _window._dpiScale;
+ return _window.ScreenToClient(location) / _window.DpiScale;
}
///
public override Vector2 PointToScreen(Vector2 location)
{
- return _window.ClientToScreen(location * _window._dpiScale);
+ return _window.ClientToScreen(location * _window.DpiScale);
}
///