From 48be56de645d9affc3a51770b17c3987fcbf5393 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 7 Jun 2020 23:18:14 +0100 Subject: [PATCH] Added support for curve-based DPI scaling. --- CHANGES.md | 4 +- Source/ImGui/Private/ImGuiModuleSettings.cpp | 60 +++++++++++++++++--- Source/ImGui/Private/ImGuiModuleSettings.h | 29 +++++++--- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4f9d268..36bbd85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,11 +5,11 @@ Versions marked as 'unofficial' are labelled only for the needs of this changelo Change History -------------- -Version: 1.19 (2020/03-04) +Version: 1.19 (2020/03-06) - Integrated fix for issue with ImGui popup/modal windows not being able to be closed in transparent mouse input mode. - Integrated first version of Adaptive Canvas Size. - Added different options to define canvas size, with Adaptive Canvas Size being one of the options (viewport). -- Added option for DPI scaling. Current implementation scales the whole Slate widget and invert-scales the ImGui canvas size to maintain consistent size on the screen. +- Added option for DPI scaling. Version: 1.18 (2020/01) - Updated to engine version 4.24. diff --git a/Source/ImGui/Private/ImGuiModuleSettings.cpp b/Source/ImGui/Private/ImGuiModuleSettings.cpp index bfeba33..96cfc73 100644 --- a/Source/ImGui/Private/ImGuiModuleSettings.cpp +++ b/Source/ImGui/Private/ImGuiModuleSettings.cpp @@ -8,6 +8,37 @@ #include "ImGuiModuleProperties.h" +//==================================================================================================== +// FImGuiDPIScaleInfo +//==================================================================================================== + +FImGuiDPIScaleInfo::FImGuiDPIScaleInfo() +{ + if (FRichCurve* Curve = DPICurve.GetRichCurve()) + { + Curve->AddKey( 0.0f, 1.f); + + Curve->AddKey(2159.5f, 1.f); + Curve->AddKey(2160.0f, 2.f); + + Curve->AddKey(4319.5f, 2.f); + Curve->AddKey(4320.0f, 4.f); + } +} + +float FImGuiDPIScaleInfo::CalculateResolutionBasedScale() const +{ + float ResolutionBasedScale = Scale; + if (bScaleWithCurve && GEngine && GEngine->GameUserSettings) + { + if (const FRichCurve* Curve = DPICurve.GetRichCurveConst()) + { + ResolutionBasedScale *= Curve->Eval((float)GEngine->GameUserSettings->GetDesktopResolution().Y, 1.f); + } + } + return ResolutionBasedScale; +} + //==================================================================================================== // UImGuiSettings //==================================================================================================== @@ -77,10 +108,10 @@ FImGuiModuleSettings::FImGuiModuleSettings(FImGuiModuleProperties& InProperties, // Delegate initializer to support settings loaded after this object creation (in stand-alone builds) and potential // reloading of settings. - UImGuiSettings::OnSettingsLoaded.AddRaw(this, &FImGuiModuleSettings::UpdateSettings); + UImGuiSettings::OnSettingsLoaded.AddRaw(this, &FImGuiModuleSettings::InitializeAllSettings); // Call initializer to support settings already loaded (editor). - UpdateSettings(); + InitializeAllSettings(); } FImGuiModuleSettings::~FImGuiModuleSettings() @@ -93,6 +124,12 @@ FImGuiModuleSettings::~FImGuiModuleSettings() #endif } +void FImGuiModuleSettings::InitializeAllSettings() +{ + UpdateSettings(); + UpdateDPIScaleInfo(); +} + void FImGuiModuleSettings::UpdateSettings() { if (UImGuiSettings* SettingsObject = UImGuiSettings::Get()) @@ -104,6 +141,13 @@ void FImGuiModuleSettings::UpdateSettings() SetUseSoftwareCursor(SettingsObject->bUseSoftwareCursor); SetToggleInputKey(SettingsObject->ToggleInput); SetCanvasSizeInfo(SettingsObject->CanvasSize); + } +} + +void FImGuiModuleSettings::UpdateDPIScaleInfo() +{ + if (UImGuiSettings* SettingsObject = UImGuiSettings::Get()) + { SetDPIScaleInfo(SettingsObject->DPIScale); } } @@ -173,11 +217,8 @@ void FImGuiModuleSettings::SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasS void FImGuiModuleSettings::SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo) { - if (DPIScale != ScaleInfo) - { - DPIScale = ScaleInfo; - OnDPIScaleChangedDelegate.Broadcast(DPIScale); - } + DPIScale = ScaleInfo; + OnDPIScaleChangedDelegate.Broadcast(DPIScale); } #if WITH_EDITOR @@ -187,6 +228,11 @@ void FImGuiModuleSettings::OnPropertyChanged(class UObject* ObjectBeingModified, if (ObjectBeingModified == UImGuiSettings::Get()) { UpdateSettings(); + if (PropertyChangedEvent.MemberProperty + && (PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(FImGuiModuleSettings, DPIScale))) + { + UpdateDPIScaleInfo(); + } } } diff --git a/Source/ImGui/Private/ImGuiModuleSettings.h b/Source/ImGui/Private/ImGuiModuleSettings.h index 321bf67..bb88ca2 100644 --- a/Source/ImGui/Private/ImGuiModuleSettings.h +++ b/Source/ImGui/Private/ImGuiModuleSettings.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include @@ -111,24 +112,34 @@ protected: UPROPERTY(EditAnywhere, Category = "DPI Scale") EImGuiDPIScaleMethod ScalingMethod = EImGuiDPIScaleMethod::ImGui; - // Fixed scale. + // An optional scale to apply on top or instead of the curve-based scale. UPROPERTY(EditAnywhere, Category = "DPI Scale", meta = (ClampMin = 0, UIMin = 0)) float Scale = 1.f; + // Curve mapping resolution height to scale. + UPROPERTY(config, EditAnywhere, Category = "DPI Scale", meta = (XAxisName = "Resolution Height", YAxisName = "Scale", EditCondition = "bScaleWithCurve")) + FRuntimeFloatCurve DPICurve; + + // Whether to use curve-based scaling. If enabled, Scale will be multiplied by a value read from the DPICurve. + // If disabled, only the Scale property will be used. + UPROPERTY(config, EditAnywhere, Category = "DPI Scale") + bool bScaleWithCurve = true; + public: - float GetImGuiScale() const { return ShouldScaleInSlate() ? 1.f : Scale; } + FImGuiDPIScaleInfo(); - float GetSlateScale() const { return ShouldScaleInSlate() ? Scale : 1.f; } + float GetImGuiScale() const { return ShouldScaleInSlate() ? 1.f : CalculateScale(); } + + float GetSlateScale() const { return ShouldScaleInSlate() ? CalculateScale() : 1.f; } bool ShouldScaleInSlate() const { return ScalingMethod == EImGuiDPIScaleMethod::Slate; } - bool operator==(const FImGuiDPIScaleInfo& Other) const - { - return (Scale == Other.Scale) && (ScalingMethod == Other.ScalingMethod); - } +private: - bool operator!=(const FImGuiDPIScaleInfo& Other) const { return !(*this == Other); } + float CalculateScale() const { return Scale * CalculateResolutionBasedScale(); } + + float CalculateResolutionBasedScale() const; }; // UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface. @@ -262,7 +273,9 @@ public: private: + void InitializeAllSettings(); void UpdateSettings(); + void UpdateDPIScaleInfo(); void SetImGuiInputHandlerClass(const FStringClassReference& ClassReference); void SetShareKeyboardInput(bool bShare);