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>
main
nvsickle 5 years ago
parent da529edfb5
commit 6b76eceb1f

@ -219,6 +219,7 @@ public:
void SetFullScreenState(bool fullScreenState) override; void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override; bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override; void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override { return 1.0f; };
void ConnectViewportInteractionRequestBus(); void ConnectViewportInteractionRequestBus();
void DisconnectViewportInteractionRequestBus(); void DisconnectViewportInteractionRequestBus();

@ -731,10 +731,12 @@ namespace AzFramework
bool Application::IsPrefabSystemEnabled() const bool Application::IsPrefabSystemEnabled() const
{ {
bool value = true; bool value = true;
/*
if (auto* registry = AZ::SettingsRegistry::Get()) if (auto* registry = AZ::SettingsRegistry::Get())
{ {
registry->Get(value, ApplicationInternal::s_prefabSystemKey); registry->Get(value, ApplicationInternal::s_prefabSystemKey);
} }
*/
return value; return value;
} }

@ -116,6 +116,11 @@ namespace AzFramework
SetFullScreenState(!GetFullScreenState()); SetFullScreenState(!GetFullScreenState());
} }
float NativeWindow::GetDpiScaleFactor() const
{
return m_pimpl->GetDpiScaleFactor();
}
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow() /*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{ {
NativeWindowHandle defaultWindowHandle = nullptr; NativeWindowHandle defaultWindowHandle = nullptr;
@ -228,4 +233,10 @@ namespace AzFramework
return false; 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 } // namespace AzFramework

@ -128,6 +128,7 @@ namespace AzFramework
void SetFullScreenState(bool fullScreenState) override; void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override; bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override; void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
//! Get the full screen state of the default window. //! Get the full screen state of the default window.
//! \return True if the default window is currently in full screen, false otherwise. //! \return True if the default window is currently in full screen, false otherwise.
@ -169,6 +170,7 @@ namespace AzFramework
virtual bool GetFullScreenState() const; virtual bool GetFullScreenState() const;
virtual void SetFullScreenState(bool fullScreenState); virtual void SetFullScreenState(bool fullScreenState);
virtual bool CanToggleFullScreenState() const; virtual bool CanToggleFullScreenState() const;
virtual float GetDpiScaleFactor() const;
protected: protected:
uint32_t m_width = 0; uint32_t m_width = 0;

@ -68,6 +68,11 @@ namespace AzFramework
//! Toggle the full screen state of the window. //! Toggle the full screen state of the window.
virtual void ToggleFullScreenState() = 0; 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>; 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. //! 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); }; 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. //! This is called when the window is deactivated from code or if the user closes the window.
virtual void OnWindowClosed() {}; virtual void OnWindowClosed() {};
}; };

@ -17,7 +17,7 @@ namespace AzFramework
{ {
public: public:
AZ_CLASS_ALLOCATOR(NativeWindowImpl_Win32, AZ::SystemAllocator, 0); AZ_CLASS_ALLOCATOR(NativeWindowImpl_Win32, AZ::SystemAllocator, 0);
NativeWindowImpl_Win32() = default; NativeWindowImpl_Win32();
~NativeWindowImpl_Win32() override; ~NativeWindowImpl_Win32() override;
// NativeWindow::Implementation overrides... // NativeWindow::Implementation overrides...
@ -33,6 +33,7 @@ namespace AzFramework
bool GetFullScreenState() const override; bool GetFullScreenState() const override;
void SetFullScreenState(bool fullScreenState) override; void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; } bool CanToggleFullScreenState() const override { return true; }
float GetDpiScaleFactor() const override;
private: private:
static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks); 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. 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. 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? 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"; const char* NativeWindowImpl_Win32::s_defaultClassName = "O3DEWin32Class";
@ -58,6 +62,16 @@ namespace AzFramework
return aznew NativeWindowImpl_Win32(); 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() NativeWindowImpl_Win32::~NativeWindowImpl_Win32()
{ {
DestroyWindow(m_win32Handle); DestroyWindow(m_win32Handle);
@ -237,6 +251,11 @@ namespace AzFramework
// Send all other WM_SYSKEYDOWN messages to the default WndProc. // Send all other WM_SYSKEYDOWN messages to the default WndProc.
break; break;
} }
case WM_DPICHANGED:
{
const float newScaleFactor = nativeWindowImpl->GetDpiScaleFactor();
WindowNotificationBus::Event(nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnDpiScaleFactorChanged, newScaleFactor);
}
default: default:
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
break; 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() void NativeWindowImpl_Win32::EnterBorderlessWindowFullScreen()
{ {
if (m_isInBorderlessWindowFullScreenState) if (m_isInBorderlessWindowFullScreenState)

@ -65,8 +65,14 @@ namespace AZ
ConstViewPtr GetDefaultView() const; ConstViewPtr GetDefaultView() const;
//! Gets the current size of the viewport. //! Gets the current size of the viewport.
//! This value is cached and updated on-demand, so may be performantly queried.
AzFramework::WindowSize GetViewportSize() const; AzFramework::WindowSize GetViewportSize() const;
//! Gets the screen DPI scaling factor.
//! This value is cached and updated on-demand, so may be performantly queried.
//! \see AzFramework::WindowRequests::GetDpiScaleFactor
float GetDpiScalingFactor() const;
// SceneNotificationBus interface // SceneNotificationBus interface
//! Ensures our default view remains set when our scene's render pipelines are modified. //! Ensures our default view remains set when our scene's render pipelines are modified.
void OnRenderPipelineAdded(RenderPipelinePtr pipeline) override; void OnRenderPipelineAdded(RenderPipelinePtr pipeline) override;
@ -76,8 +82,10 @@ namespace AZ
void OnBeginPrepareRender() override; void OnBeginPrepareRender() override;
//WindowNotificationBus interface //WindowNotificationBus interface
//! Used to fire a notification when our window resizes //! Used to fire a notification when our window resizes.
void OnWindowResized(uint32_t width, uint32_t height) override; void OnWindowResized(uint32_t width, uint32_t height) override;
//! Used to fire a notification when our window DPI changes.
void OnDpiScaleFactorChanged(float dpiScaleFactor) override;
using SizeChangedEvent = AZ::Event<AzFramework::WindowSize>; using SizeChangedEvent = AZ::Event<AzFramework::WindowSize>;
//! Notifies consumers when the viewport size has changed. //! Notifies consumers when the viewport size has changed.
@ -130,6 +138,7 @@ namespace AZ
WindowContextSharedPtr m_windowContext; WindowContextSharedPtr m_windowContext;
ViewPtr m_defaultView; ViewPtr m_defaultView;
AzFramework::WindowSize m_viewportSize; AzFramework::WindowSize m_viewportSize;
float m_viewportDpiScaleFactor = 1.0f;
SizeChangedEvent m_sizeChangedEvent; SizeChangedEvent m_sizeChangedEvent;
MatrixChangedEvent m_viewMatrixChangedEvent; MatrixChangedEvent m_viewMatrixChangedEvent;

@ -10,6 +10,7 @@
#include <Atom/RPI.Public/ViewportContextBus.h> #include <Atom/RPI.Public/ViewportContextBus.h>
#include <Atom/RPI.Public/ViewportContextManager.h> #include <Atom/RPI.Public/ViewportContextManager.h>
#include <Atom/RPI.Public/View.h> #include <Atom/RPI.Public/View.h>
#include "..\..\Include\Atom\RPI.Public\ViewportContext.h"
namespace AZ namespace AZ
{ {
@ -28,6 +29,10 @@ namespace AZ
m_viewportSize, m_viewportSize,
nativeWindow, nativeWindow,
&AzFramework::WindowRequestBus::Events::GetClientAreaSize); &AzFramework::WindowRequestBus::Events::GetClientAreaSize);
AzFramework::WindowRequestBus::EventResult(
m_viewportDpiScaleFactor,
nativeWindow,
&AzFramework::WindowRequestBus::Events::GetDpiScaleFactor);
AzFramework::WindowNotificationBus::Handler::BusConnect(nativeWindow); AzFramework::WindowNotificationBus::Handler::BusConnect(nativeWindow);
AzFramework::ViewportRequestBus::Handler::BusConnect(id); AzFramework::ViewportRequestBus::Handler::BusConnect(id);
@ -148,6 +153,11 @@ namespace AZ
return m_viewportSize; return m_viewportSize;
} }
float ViewportContext::GetDpiScalingFactor() const
{
return m_viewportDpiScaleFactor;
}
void ViewportContext::ConnectSizeChangedHandler(SizeChangedEvent::Handler& handler) void ViewportContext::ConnectSizeChangedHandler(SizeChangedEvent::Handler& handler)
{ {
handler.Connect(m_sizeChangedEvent); handler.Connect(m_sizeChangedEvent);
@ -289,5 +299,10 @@ namespace AZ
m_sizeChangedEvent.Signal(m_viewportSize); m_sizeChangedEvent.Signal(m_viewportSize);
} }
} }
void ViewportContext::OnDpiScaleFactorChanged(float dpiScaleFactor)
{
m_viewportDpiScaleFactor = dpiScaleFactor;
}
} // namespace RPI } // namespace RPI
} // namespace AZ } // namespace AZ

@ -113,6 +113,7 @@ namespace AtomToolsFramework
void SetFullScreenState(bool fullScreenState) override; void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override; bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override; void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
protected: protected:
// AzFramework::InputChannelEventListener ... // AzFramework::InputChannelEventListener ...

@ -540,4 +540,9 @@ namespace AtomToolsFramework
{ {
// The RenderViewportWidget does not currently support full screen. // The RenderViewportWidget does not currently support full screen.
} }
float RenderViewportWidget::GetDpiScaleFactor() const
{
return aznumeric_cast<float>(devicePixelRatioF());
}
} //namespace AtomToolsFramework } //namespace AtomToolsFramework

Loading…
Cancel
Save