Add GetDpiScaleFactor to native window API

-This includes implementations of the API for the Editor and Windows, all other platforms will have a 1.0 scale for now

Signed-off-by: nvsickle <nvsickle@amazon.com>
This commit is contained in:
nvsickle
2021-06-21 20:56:40 -07:00
parent da529edfb5
commit 6b76eceb1f
10 changed files with 86 additions and 2 deletions
+1
View File
@@ -219,6 +219,7 @@ public:
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override { return 1.0f; };
void ConnectViewportInteractionRequestBus();
void DisconnectViewportInteractionRequestBus();
@@ -731,10 +731,12 @@ namespace AzFramework
bool Application::IsPrefabSystemEnabled() const
{
bool value = true;
/*
if (auto* registry = AZ::SettingsRegistry::Get())
{
registry->Get(value, ApplicationInternal::s_prefabSystemKey);
}
*/
return value;
}
@@ -116,6 +116,11 @@ namespace AzFramework
SetFullScreenState(!GetFullScreenState());
}
float NativeWindow::GetDpiScaleFactor() const
{
return m_pimpl->GetDpiScaleFactor();
}
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{
NativeWindowHandle defaultWindowHandle = nullptr;
@@ -228,4 +233,10 @@ namespace AzFramework
return false;
}
float NativeWindow::Implementation::GetDpiScaleFactor() const
{
// For platforms that aren't DPI-aware, we simply return a 1.0 ratio for no scaling
return 1.0f;
}
} // namespace AzFramework
@@ -128,6 +128,7 @@ namespace AzFramework
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
//! Get the full screen state of the default window.
//! \return True if the default window is currently in full screen, false otherwise.
@@ -169,6 +170,7 @@ namespace AzFramework
virtual bool GetFullScreenState() const;
virtual void SetFullScreenState(bool fullScreenState);
virtual bool CanToggleFullScreenState() const;
virtual float GetDpiScaleFactor() const;
protected:
uint32_t m_width = 0;
@@ -68,6 +68,11 @@ namespace AzFramework
//! Toggle the full screen state of the window.
virtual void ToggleFullScreenState() = 0;
//! Returns a scalar multiplier representing how dots-per-inch this window has, compared
//! to a "standard" value of 96, the default for Windows in a DPI unaware setting. This can
//! be used to scale user interface elements to ensure legibility on high density displays.
virtual float GetDpiScaleFactor() const = 0;
};
using WindowRequestBus = AZ::EBus<WindowRequests>;
@@ -87,6 +92,9 @@ namespace AzFramework
//! This is called once when the window is Activated and also called if the user resizes the window.
virtual void OnWindowResized(uint32_t width, uint32_t height) { AZ_UNUSED(width); AZ_UNUSED(height); };
//! This is called if the window's underyling DPI scaling factor changes.
virtual void OnDpiScaleFactorChanged(float dpiScaleFactor) { AZ_UNUSED(dpiScaleFactor); }
//! This is called when the window is deactivated from code or if the user closes the window.
virtual void OnWindowClosed() {};
};
@@ -17,7 +17,7 @@ namespace AzFramework
{
public:
AZ_CLASS_ALLOCATOR(NativeWindowImpl_Win32, AZ::SystemAllocator, 0);
NativeWindowImpl_Win32() = default;
NativeWindowImpl_Win32();
~NativeWindowImpl_Win32() override;
// NativeWindow::Implementation overrides...
@@ -33,6 +33,7 @@ namespace AzFramework
bool GetFullScreenState() const override;
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
float GetDpiScaleFactor() const override;
private:
static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks);
@@ -49,6 +50,9 @@ namespace AzFramework
RECT m_windowRectToRestoreOnFullScreenExit; //!< The position and size of the window to restore when exiting full screen.
UINT m_windowStyleToRestoreOnFullScreenExit; //!< The style(s) of the window to restore when exiting full screen.
bool m_isInBorderlessWindowFullScreenState = false; //!< Was a borderless window used to enter full screen state?
using GetDpiForWindowType = UINT(HWND hwnd);
GetDpiForWindowType* m_getDpiFunction = nullptr;
};
const char* NativeWindowImpl_Win32::s_defaultClassName = "O3DEWin32Class";
@@ -58,6 +62,16 @@ namespace AzFramework
return aznew NativeWindowImpl_Win32();
}
NativeWindowImpl_Win32::NativeWindowImpl_Win32()
{
// Attempt to load GetDpiForWindow from user32 at runtime, available on Windows 10+ versions >= 1607
auto user32module = LoadLibraryA("user32.dll");
if (user32module)
{
m_getDpiFunction = reinterpret_cast<GetDpiForWindowType*>(GetProcAddress(user32module, "GetDpiForWindow"));
}
}
NativeWindowImpl_Win32::~NativeWindowImpl_Win32()
{
DestroyWindow(m_win32Handle);
@@ -237,6 +251,11 @@ namespace AzFramework
// Send all other WM_SYSKEYDOWN messages to the default WndProc.
break;
}
case WM_DPICHANGED:
{
const float newScaleFactor = nativeWindowImpl->GetDpiScaleFactor();
WindowNotificationBus::Event(nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnDpiScaleFactorChanged, newScaleFactor);
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
@@ -330,6 +349,17 @@ namespace AzFramework
}
}
float NativeWindowImpl_Win32::GetDpiScaleFactor() const
{
constexpr UINT defaultDotsPerInch = 96;
UINT dotsPerInch = defaultDotsPerInch;
if (m_getDpiFunction)
{
dotsPerInch = m_getDpiFunction(m_win32Handle);
}
return aznumeric_cast<float>(dotsPerInch) / aznumeric_cast<float>(defaultDotsPerInch);
}
void NativeWindowImpl_Win32::EnterBorderlessWindowFullScreen()
{
if (m_isInBorderlessWindowFullScreenState)