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;
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)

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

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

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

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

Loading…
Cancel
Save