Merge branch 'fix-per-window-dpi' of git://github.com/stefnotch/FlaxEngine into stefnotch-fix-per-window-dpi

# Conflicts:
#	Source/Editor/Utilities/Utils.cs
#	Source/Editor/Windows/Assets/MaterialWindow.cs
#	Source/Editor/Windows/Assets/ParticleEmitterWindow.cs
#	Source/Engine/Platform/Linux/LinuxWindow.cpp
#	Source/Engine/Platform/Windows/WindowsWindow.cpp
This commit is contained in:
Wojtek Figat
2021-03-08 20:50:31 +01:00
25 changed files with 130 additions and 64 deletions

View File

@@ -29,7 +29,7 @@ namespace FlaxEditor.Content
if (asset) if (asset)
{ {
var source = Editor.GetShaderSourceCode(asset); var source = Editor.GetShaderSourceCode(asset);
Utilities.Utils.ShowSourceCodeWindow(source, "Shader Source"); Utilities.Utils.ShowSourceCodeWindow(source, "Shader Source", item.RootWindow.Window);
} }
return null; return null;
} }

View File

@@ -1181,7 +1181,7 @@ namespace FlaxEditor
var win = Windows.GameWin.Root; var win = Windows.GameWin.Root;
if (win != null && win.RootWindow is WindowRootControl root && root.Window.IsFocused) if (win != null && win.RootWindow is WindowRootControl root && root.Window.IsFocused)
{ {
pos = Vector2.Round(Windows.GameWin.Viewport.PointFromWindow(root.Window.ScreenToClient(pos))); pos = Vector2.Round(Windows.GameWin.Viewport.PointFromScreen(pos) * root.DpiScale);
} }
else else
{ {
@@ -1201,7 +1201,7 @@ namespace FlaxEditor
var win = Windows.GameWin.Root; var win = Windows.GameWin.Root;
if (win != null && win.RootWindow is WindowRootControl root && root.Window.IsFocused) if (win != null && win.RootWindow is WindowRootControl root && root.Window.IsFocused)
{ {
pos = Vector2.Round(root.Window.ClientToScreen(Windows.GameWin.Viewport.PointToWindow(pos))); pos = Vector2.Round(Windows.GameWin.Viewport.PointToScreen(pos / root.DpiScale));
} }
else else
{ {
@@ -1231,13 +1231,18 @@ namespace FlaxEditor
var gameWin = Windows.GameWin; var gameWin = Windows.GameWin;
if (gameWin != null) if (gameWin != null)
{ {
// Handle case when Game window is not selected in tab view var win = gameWin.Root;
var dockedTo = gameWin.ParentDockPanel; if (win != null && win.RootWindow is WindowRootControl root)
if (dockedTo != null && dockedTo.SelectedTab != gameWin && dockedTo.SelectedTab != null) {
resultAsRef = dockedTo.SelectedTab.Size; // Handle case when Game window is not selected in tab view
else var dockedTo = gameWin.ParentDockPanel;
resultAsRef = gameWin.Size; if (dockedTo != null && dockedTo.SelectedTab != gameWin && dockedTo.SelectedTab != null)
resultAsRef = Vector2.Round(resultAsRef); resultAsRef = dockedTo.SelectedTab.Size * root.DpiScale;
else
resultAsRef = gameWin.Size * root.DpiScale;
resultAsRef = Vector2.Round(resultAsRef);
}
} }
} }

View File

@@ -124,7 +124,7 @@ namespace FlaxEditor.GUI.ContextMenu
PerformLayout(); PerformLayout();
// Calculate popup direction and initial location (fit on a single monitor) // Calculate popup direction and initial location (fit on a single monitor)
var dpiScale = Platform.DpiScale; var dpiScale = parentWin.DpiScale;
Vector2 dpiSize = Size * dpiScale; Vector2 dpiSize = Size * dpiScale;
Vector2 locationWS = parent.PointToWindow(location); Vector2 locationWS = parent.PointToWindow(location);
Vector2 locationSS = parentWin.PointToScreen(locationWS); Vector2 locationSS = parentWin.PointToScreen(locationWS);
@@ -275,7 +275,7 @@ namespace FlaxEditor.GUI.ContextMenu
{ {
if (_window != null) if (_window != null)
{ {
_window.ClientSize = Size * Platform.DpiScale; _window.ClientSize = Size * _window.DpiScale;
} }
} }

View File

@@ -143,7 +143,7 @@ namespace FlaxEditor.GUI.Dialogs
// Setup initial window settings // Setup initial window settings
CreateWindowSettings settings = CreateWindowSettings.Default; CreateWindowSettings settings = CreateWindowSettings.Default;
settings.Title = _title; settings.Title = _title;
settings.Size = _dialogSize * Platform.DpiScale; settings.Size = _dialogSize * parentWindow.DpiScale;
settings.AllowMaximize = false; settings.AllowMaximize = false;
settings.AllowMinimize = false; settings.AllowMinimize = false;
settings.HasSizingFrame = false; settings.HasSizingFrame = false;

View File

@@ -123,9 +123,8 @@ namespace FlaxEditor.GUI.Docking
if (parentWin == null) if (parentWin == null)
throw new InvalidOperationException("Missing parent window."); throw new InvalidOperationException("Missing parent window.");
var control = _tabsProxy != null ? (Control)_tabsProxy : this; var control = _tabsProxy != null ? (Control)_tabsProxy : this;
var dpiScale = Platform.DpiScale;
var clientPos = control.PointToWindow(Vector2.Zero); var clientPos = control.PointToWindow(Vector2.Zero);
return new Rectangle(parentWin.PointToScreen(clientPos), control.Size * dpiScale); return new Rectangle(parentWin.PointToScreen(clientPos), control.Size * RootWindow.DpiScale);
} }
} }

View File

@@ -190,15 +190,15 @@ namespace FlaxEditor.GUI
private WindowHitCodes OnHitTest(ref Vector2 mouse) private WindowHitCodes OnHitTest(ref Vector2 mouse)
{ {
var pos = _window.ScreenToClient(mouse * Platform.DpiScale); var dpiScale = _window.DpiScale;
if (_window.IsMinimized) if (_window.IsMinimized)
return WindowHitCodes.NoWhere; return WindowHitCodes.NoWhere;
if (!_window.IsMaximized) if (!_window.IsMaximized)
{ {
var dpiScale = Platform.DpiScale; var pos = _window.ScreenToClient(mouse * dpiScale); // pos is not DPI adjusted
var winSize = RootWindow.Size * dpiScale; var winSize = _window.Size;
// Distance from which the mouse is considered to be on the border/corner // Distance from which the mouse is considered to be on the border/corner
float distance = 5.0f * dpiScale; float distance = 5.0f * dpiScale;
@@ -228,11 +228,11 @@ namespace FlaxEditor.GUI
return WindowHitCodes.Bottom; return WindowHitCodes.Bottom;
} }
var menuPos = PointFromWindow(pos); var mousePos = PointFromScreen(mouse * dpiScale);
var controlUnderMouse = GetChildAt(menuPos); var controlUnderMouse = GetChildAt(mousePos);
var isMouseOverSth = controlUnderMouse != null && controlUnderMouse != _title; var isMouseOverSth = controlUnderMouse != null && controlUnderMouse != _title;
var rb = GetRightButton(); 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, _minimizeButton.BottomLeft - rb.UpperRight).Contains(ref mousePos) && !isMouseOverSth)
return WindowHitCodes.Caption; return WindowHitCodes.Caption;
return WindowHitCodes.Client; return WindowHitCodes.Client;

View File

@@ -707,8 +707,9 @@ namespace FlaxEditor.Modules
var dpiScale = Platform.DpiScale; var dpiScale = Platform.DpiScale;
var settings = CreateWindowSettings.Default; var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor"; settings.Title = "Flax Editor";
settings.Size = new Vector2(1300 * dpiScale, 900 * dpiScale); settings.Size = Platform.DesktopSize;
settings.StartPosition = WindowStartPosition.CenterScreen; settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true;
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS
if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem) if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)

View File

@@ -108,11 +108,13 @@ namespace FlaxEditor.Surface.ContextMenu
{ {
_resultPanel.DisposeChildren(); _resultPanel.DisposeChildren();
var dpiScale = RootWindow.DpiScale;
if (items.Count == 0) if (items.Count == 0)
{ {
Height = _searchBox.Height + 1; Height = _searchBox.Height + 1;
_resultPanel.ScrollBars = ScrollBars.None; _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; return;
} }
@@ -146,7 +148,7 @@ namespace FlaxEditor.Surface.ContextMenu
MatchedItems.Add(searchItem); 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(); PerformLayout();
} }

View File

@@ -1646,8 +1646,8 @@ namespace FlaxEditor.Utilities
/// </summary> /// </summary>
/// <param name="source">The source code.</param> /// <param name="source">The source code.</param>
/// <param name="title">The window title.</param> /// <param name="title">The window title.</param>
/// <param name="control">The context control used to show source code window popup in a proper location.</param> /// <param name="parentWindow">The optional parent window.</param>
public static void ShowSourceCodeWindow(string source, string title, Control control = null) public static void ShowSourceCodeWindow(string source, string title, Window parentWindow = null)
{ {
if (string.IsNullOrEmpty(source)) if (string.IsNullOrEmpty(source))
{ {
@@ -1661,8 +1661,8 @@ namespace FlaxEditor.Utilities
settings.AllowMinimize = false; settings.AllowMinimize = false;
settings.HasSizingFrame = false; settings.HasSizingFrame = false;
settings.StartPosition = WindowStartPosition.CenterParent; settings.StartPosition = WindowStartPosition.CenterParent;
settings.Size = new Vector2(500, 600) * Platform.DpiScale; settings.Size = new Vector2(500, 600) * (parentWindow?.DpiScale ?? Platform.DpiScale);
settings.Parent = control?.RootWindow?.Window ?? Editor.Instance.Windows.MainWindow; settings.Parent = parentWindow;
settings.Title = title; settings.Title = title;
var dialog = Platform.CreateWindow(ref settings); var dialog = Platform.CreateWindow(ref settings);

View File

@@ -240,7 +240,7 @@ namespace FlaxEditor.Windows.Assets
private void ShowSourceCode() private void ShowSourceCode()
{ {
var source = Editor.GetShaderSourceCode(_asset); var source = Editor.GetShaderSourceCode(_asset);
Utilities.Utils.ShowSourceCodeWindow(source, "Material Source", this); Utilities.Utils.ShowSourceCodeWindow(source, "Material Source", RootWindow.Window);
} }
/// <summary> /// <summary>

View File

@@ -146,7 +146,7 @@ namespace FlaxEditor.Windows.Assets
private void ShowSourceCode() private void ShowSourceCode()
{ {
var source = Editor.GetShaderSourceCode(_asset); var source = Editor.GetShaderSourceCode(_asset);
Utilities.Utils.ShowSourceCodeWindow(source, "Particle Emitter GPU Simulation Source", this); Utilities.Utils.ShowSourceCodeWindow(source, "Particle Emitter GPU Simulation Source", RootWindow.Window);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -371,7 +371,7 @@ namespace FlaxEditor.Windows
// Focus content window // Focus content window
Focus(); Focus();
RootWindow?.Window.Focus(); RootWindow?.Focus();
} }
// Refresh database and view now // Refresh database and view now

View File

@@ -6,10 +6,14 @@
#include "Engine/Graphics/RenderTask.h" #include "Engine/Graphics/RenderTask.h"
#include <Engine/Main/Android/android_native_app_glue.h> #include <Engine/Main/Android/android_native_app_glue.h>
#define DefaultDPI 96
AndroidWindow::AndroidWindow(const CreateWindowSettings& settings) AndroidWindow::AndroidWindow(const CreateWindowSettings& settings)
: WindowBase(settings) : WindowBase(settings)
{ {
_clientSize = settings.Size; _clientSize = settings.Size;
_dpi = DefaultDPI;
_dpiScale = (float)_dpi / (float)DefaultDPI;
} }
AndroidWindow::~AndroidWindow() AndroidWindow::~AndroidWindow()

View File

@@ -569,17 +569,17 @@ public:
API_PROPERTY() static BatteryInfo GetBatteryInfo(); API_PROPERTY() static BatteryInfo GetBatteryInfo();
/// <summary> /// <summary>
/// Gets the screen DPI setting. /// Gets the primary monitor's DPI setting.
/// </summary> /// </summary>
API_PROPERTY() static int32 GetDpi(); API_PROPERTY() static int32 GetDpi();
/// <summary> /// <summary>
/// Gets the screen DPI setting scale factor (1 is default). Includes custom DPI scale. /// Gets the primary monitor's DPI setting scale factor (1 is default). Includes custom DPI scale.
/// </summary> /// </summary>
API_PROPERTY() static float GetDpiScale(); API_PROPERTY() static float GetDpiScale();
/// <summary> /// <summary>
/// The custom screen DPI scale factor to apply globally. Can be used to adjust the User Interface scale (resolution). /// The custom DPI scale factor to apply globally. Can be used to adjust the User Interface scale (resolution).
/// </summary> /// </summary>
API_FIELD() static float CustomDpiScale; API_FIELD() static float CustomDpiScale;

View File

@@ -281,6 +281,8 @@ protected:
String _title; String _title;
CursorType _cursor; CursorType _cursor;
Vector2 _clientSize; Vector2 _clientSize;
int _dpi;
float _dpiScale;
Vector2 _trackingMouseOffset; Vector2 _trackingMouseOffset;
bool _isUsingMouseOffset; bool _isUsingMouseOffset;
@@ -542,6 +544,21 @@ public:
/// <returns>The screen space position.</returns> /// <returns>The screen space position.</returns>
API_FUNCTION() virtual Vector2 ClientToScreen(const Vector2& clientPos) const = 0; API_FUNCTION() virtual Vector2 ClientToScreen(const Vector2& clientPos) const = 0;
/// <summary>
/// Gets the window DPI setting.
/// </summary>
API_PROPERTY() int GetDpi() const
{
return _dpi;
}
/// <summary>
/// Gets the window DPI scale factor (1 is default). Includes custom DPI scale
/// </summary>
API_PROPERTY() float GetDpiScale() const
{
return Platform::CustomDpiScale * _dpiScale;
}
public: public:
/// <summary> /// <summary>

View File

@@ -31,6 +31,7 @@
#define _NET_WM_STATE_REMOVE 0L // remove/unset property #define _NET_WM_STATE_REMOVE 0L // remove/unset property
#define _NET_WM_STATE_ADD 1L // add/set property #define _NET_WM_STATE_ADD 1L // add/set property
#define _NET_WM_STATE_TOGGLE 2L // toggle property #define _NET_WM_STATE_TOGGLE 2L // toggle property
#define DefaultDPI 96
// Window routines function prolog // Window routines function prolog
#define LINUX_WINDOW_PROLOG X11::Display* display = (X11::Display*)LinuxPlatform::GetXDisplay(); X11::Window window = (X11::Window)_window #define LINUX_WINDOW_PROLOG X11::Display* display = (X11::Display*)LinuxPlatform::GetXDisplay(); X11::Window window = (X11::Window)_window
@@ -150,7 +151,10 @@ LinuxWindow::LinuxWindow(const CreateWindowSettings& settings)
X11::XSetTransientForHint(display, window, (X11::Window)((LinuxWindow*)settings.Parent)->GetNativePtr()); X11::XSetTransientForHint(display, window, (X11::Window)((LinuxWindow*)settings.Parent)->GetNativePtr());
} }
// Set events mask _dpi = Platform::GetDpi();
_dpiScale = (float)_dpi / (float)DefaultDPI;
// Set input mask
long eventMask = long eventMask =
ExposureMask | FocusChangeMask | ExposureMask | FocusChangeMask |
KeyPressMask | KeyReleaseMask | KeyPressMask | KeyReleaseMask |

View File

@@ -100,7 +100,6 @@ private:
UWPWindowImpl* _impl; UWPWindowImpl* _impl;
float _dpi, _dpiScale;
Vector2 _logicalSize; Vector2 _logicalSize;
public: public:

View File

@@ -7,8 +7,6 @@ namespace FlaxEngine
{ {
partial class Window partial class Window
{ {
internal float _dpiScale;
/// <summary> /// <summary>
/// Window closing delegate. /// Window closing delegate.
/// </summary> /// </summary>
@@ -176,7 +174,6 @@ namespace FlaxEngine
private Window() private Window()
{ {
GUI = new WindowRootControl(this); GUI = new WindowRootControl(this);
_dpiScale = Platform.DpiScale;
} }
internal void Internal_OnShow() internal void Internal_OnShow()
@@ -192,7 +189,7 @@ namespace FlaxEngine
internal void Internal_OnDraw() internal void Internal_OnDraw()
{ {
Matrix3x3.Scaling(_dpiScale, out var scale); Matrix3x3.Scaling(DpiScale, out var scale);
Render2D.PushTransform(ref scale); Render2D.PushTransform(ref scale);
GUI.Draw(); GUI.Draw();
Render2D.PopTransform(); Render2D.PopTransform();
@@ -200,7 +197,7 @@ namespace FlaxEngine
internal void Internal_OnResize(int width, int height) 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) internal void Internal_OnCharInput(char c)
@@ -223,7 +220,7 @@ namespace FlaxEngine
internal void Internal_OnMouseDown(ref Vector2 mousePos, MouseButton button) internal void Internal_OnMouseDown(ref Vector2 mousePos, MouseButton button)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
bool handled = false; bool handled = false;
MouseDown?.Invoke(ref pos, button, ref handled); MouseDown?.Invoke(ref pos, button, ref handled);
@@ -235,7 +232,7 @@ namespace FlaxEngine
internal void Internal_OnMouseUp(ref Vector2 mousePos, MouseButton button) internal void Internal_OnMouseUp(ref Vector2 mousePos, MouseButton button)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
bool handled = false; bool handled = false;
MouseUp?.Invoke(ref pos, button, ref handled); MouseUp?.Invoke(ref pos, button, ref handled);
@@ -247,7 +244,7 @@ namespace FlaxEngine
internal void Internal_OnMouseDoubleClick(ref Vector2 mousePos, MouseButton button) internal void Internal_OnMouseDoubleClick(ref Vector2 mousePos, MouseButton button)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
bool handled = false; bool handled = false;
MouseDoubleClick?.Invoke(ref pos, button, ref handled); MouseDoubleClick?.Invoke(ref pos, button, ref handled);
@@ -259,7 +256,7 @@ namespace FlaxEngine
internal void Internal_OnMouseWheel(ref Vector2 mousePos, float delta) internal void Internal_OnMouseWheel(ref Vector2 mousePos, float delta)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
bool handled = false; bool handled = false;
MouseWheel?.Invoke(ref pos, delta, ref handled); MouseWheel?.Invoke(ref pos, delta, ref handled);
@@ -271,7 +268,7 @@ namespace FlaxEngine
internal void Internal_OnMouseMove(ref Vector2 mousePos) internal void Internal_OnMouseMove(ref Vector2 mousePos)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
MouseMove?.Invoke(ref pos); MouseMove?.Invoke(ref pos);
GUI.OnMouseMove(pos); GUI.OnMouseMove(pos);
@@ -285,7 +282,7 @@ namespace FlaxEngine
internal void Internal_OnTouchDown(ref Vector2 pointerPosition, int pointerId) internal void Internal_OnTouchDown(ref Vector2 pointerPosition, int pointerId)
{ {
Vector2 pos = pointerPosition / _dpiScale; Vector2 pos = pointerPosition / DpiScale;
bool handled = false; bool handled = false;
TouchDown?.Invoke(ref pos, pointerId, ref handled); TouchDown?.Invoke(ref pos, pointerId, ref handled);
@@ -297,7 +294,7 @@ namespace FlaxEngine
internal void Internal_OnTouchMove(ref Vector2 pointerPosition, int pointerId) internal void Internal_OnTouchMove(ref Vector2 pointerPosition, int pointerId)
{ {
Vector2 pos = pointerPosition / _dpiScale; Vector2 pos = pointerPosition / DpiScale;
bool handled = false; bool handled = false;
TouchMove?.Invoke(ref pos, pointerId, ref handled); TouchMove?.Invoke(ref pos, pointerId, ref handled);
@@ -309,7 +306,7 @@ namespace FlaxEngine
internal void Internal_OnTouchUp(ref Vector2 pointerPosition, int pointerId) internal void Internal_OnTouchUp(ref Vector2 pointerPosition, int pointerId)
{ {
Vector2 pos = pointerPosition / _dpiScale; Vector2 pos = pointerPosition / DpiScale;
bool handled = false; bool handled = false;
TouchUp?.Invoke(ref pos, pointerId, ref handled); TouchUp?.Invoke(ref pos, pointerId, ref handled);
@@ -335,7 +332,7 @@ namespace FlaxEngine
{ {
if (HitTest != null) if (HitTest != null)
{ {
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
result = HitTest(ref pos); result = HitTest(ref pos);
handled = true; handled = true;
} }
@@ -356,7 +353,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]); dragData = new DragDataText(data[0]);
else else
dragData = new DragDataFiles(data); dragData = new DragDataFiles(data);
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
return GUI.OnDragEnter(ref pos, dragData); return GUI.OnDragEnter(ref pos, dragData);
} }
@@ -367,7 +364,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]); dragData = new DragDataText(data[0]);
else else
dragData = new DragDataFiles(data); dragData = new DragDataFiles(data);
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
return GUI.OnDragMove(ref pos, dragData); return GUI.OnDragMove(ref pos, dragData);
} }
@@ -378,7 +375,7 @@ namespace FlaxEngine
dragData = new DragDataText(data[0]); dragData = new DragDataText(data[0]);
else else
dragData = new DragDataFiles(data); dragData = new DragDataFiles(data);
Vector2 pos = mousePos / _dpiScale; Vector2 pos = mousePos / DpiScale;
return GUI.OnDragDrop(ref pos, dragData); return GUI.OnDragDrop(ref pos, dragData);
} }

View File

@@ -673,7 +673,7 @@ void WindowsPlatform::SetHighDpiAwarenessEnabled(bool enable)
if (setProcessDpiAwareness) if (setProcessDpiAwareness)
{ {
setProcessDpiAwareness(enable ? PROCESS_SYSTEM_DPI_AWARE : PROCESS_DPI_UNAWARE); setProcessDpiAwareness(enable ? PROCESS_PER_MONITOR_DPI_AWARE : PROCESS_DPI_UNAWARE);
} }
SystemDpi = CalculateDpi(shCoreDll); SystemDpi = CalculateDpi(shCoreDll);

View File

@@ -13,6 +13,8 @@
#include "../Win32/IncludeWindowsHeaders.h" #include "../Win32/IncludeWindowsHeaders.h"
#include <propidl.h> #include <propidl.h>
#define DefaultDPI 96
// Use improved borderless window support for Editor // Use improved borderless window support for Editor
#define WINDOWS_USE_NEW_BORDER_LESS USE_EDITOR && 0 #define WINDOWS_USE_NEW_BORDER_LESS USE_EDITOR && 0
#if WINDOWS_USE_NEW_BORDER_LESS #if WINDOWS_USE_NEW_BORDER_LESS
@@ -123,6 +125,21 @@ WindowsWindow::WindowsWindow(const CreateWindowSettings& settings)
(HINSTANCE)Platform::Instance, (HINSTANCE)Platform::Instance,
nullptr); nullptr);
// Query DPI
_dpi = Platform::GetDpi();
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 // Validate result
if (!HasHWND()) if (!HasHWND())
{ {
@@ -1021,6 +1038,22 @@ LRESULT WindowsWindow::WndProc(UINT msg, WPARAM wParam, LPARAM lParam)
} }
break; 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: case WM_ENTERSIZEMOVE:
{ {
_isResizing = true; _isResizing = true;

View File

@@ -67,7 +67,7 @@ bool FontManagerService::Init()
ASSERT(Library == nullptr); ASSERT(Library == nullptr);
// Scale UI fonts to match the monitor DPI // 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 // Init Free Type
FreeTypeMemory.user = nullptr; FreeTypeMemory.user = nullptr;

View File

@@ -310,7 +310,7 @@ namespace FlaxEngine.GUI
/// <summary> /// <summary>
/// Gets the GUI window root control which contains that control (or null if not linked to any). /// Gets the GUI window root control which contains that control (or null if not linked to any).
/// </summary> /// </summary>
public virtual WindowRootControl RootWindow => _parent?.RootWindow; public virtual WindowRootControl RootWindow => _root?.RootWindow;
/// <summary> /// <summary>
/// Gets screen position of the control (upper left corner). /// Gets screen position of the control (upper left corner).

View File

@@ -224,7 +224,7 @@ namespace FlaxEngine.GUI
/// </summary> /// </summary>
public void SyncBackbufferSize() public void SyncBackbufferSize()
{ {
float scale = ResolutionScale * Platform.DpiScale; float scale = ResolutionScale * (RootWindow?.DpiScale ?? Platform.DpiScale);
int width = Mathf.CeilToInt(Width * scale); int width = Mathf.CeilToInt(Width * scale);
int height = Mathf.CeilToInt(Height * scale); int height = Mathf.CeilToInt(Height * scale);
if (_customResolution.HasValue) if (_customResolution.HasValue)

View File

@@ -68,7 +68,7 @@ namespace FlaxEngine.GUI
var parentWin = target.Root; var parentWin = target.Root;
if (parentWin == null) if (parentWin == null)
return; return;
float dpiScale = Platform.DpiScale; float dpiScale = target.RootWindow.DpiScale;
Vector2 dpiSize = Size * dpiScale; Vector2 dpiSize = Size * dpiScale;
Vector2 locationWS = target.PointToWindow(location); Vector2 locationWS = target.PointToWindow(location);
Vector2 locationSS = parentWin.PointToScreen(locationWS); Vector2 locationSS = parentWin.PointToScreen(locationWS);
@@ -183,7 +183,7 @@ namespace FlaxEngine.GUI
{ {
if (_window) if (_window)
{ {
_window.ClientSize = Size * Platform.DpiScale; _window.ClientSize = Size * _window.DpiScale;
} }
} }

View File

@@ -55,6 +55,11 @@ namespace FlaxEngine.GUI
/// </summary> /// </summary>
public bool IsMaximized => _window.IsMaximized; public bool IsMaximized => _window.IsMaximized;
/// <summary>
/// Gets the window DPI scale factor (1 is default). Includes custom DPI scale
/// </summary>
public float DpiScale => _window.DpiScale;
internal WindowRootControl(Window window) internal WindowRootControl(Window window)
{ {
_window = window; _window = window;
@@ -151,7 +156,7 @@ namespace FlaxEngine.GUI
} }
/// <inheritdoc /> /// <inheritdoc />
public override Vector2 TrackingMouseOffset => _window.TrackingMouseOffset / _window._dpiScale; public override Vector2 TrackingMouseOffset => _window.TrackingMouseOffset / _window.DpiScale;
/// <inheritdoc /> /// <inheritdoc />
public override WindowRootControl RootWindow => this; public override WindowRootControl RootWindow => this;
@@ -159,8 +164,8 @@ namespace FlaxEngine.GUI
/// <inheritdoc /> /// <inheritdoc />
public override Vector2 MousePosition public override Vector2 MousePosition
{ {
get => _window.MousePosition / _window._dpiScale; get => _window.MousePosition / _window.DpiScale;
set => _window.MousePosition = value * _window._dpiScale; set => _window.MousePosition = value * _window.DpiScale;
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -234,13 +239,13 @@ namespace FlaxEngine.GUI
/// <inheritdoc /> /// <inheritdoc />
public override Vector2 PointFromScreen(Vector2 location) public override Vector2 PointFromScreen(Vector2 location)
{ {
return _window.ScreenToClient(location) / _window._dpiScale; return _window.ScreenToClient(location) / _window.DpiScale;
} }
/// <inheritdoc /> /// <inheritdoc />
public override Vector2 PointToScreen(Vector2 location) public override Vector2 PointToScreen(Vector2 location)
{ {
return _window.ClientToScreen(location * _window._dpiScale); return _window.ClientToScreen(location * _window.DpiScale);
} }
/// <inheritdoc /> /// <inheritdoc />