diff --git a/Source/ImGui/Private/ImGuiContextManager.cpp b/Source/ImGui/Private/ImGuiContextManager.cpp index 5e4f5d1..523c13a 100644 --- a/Source/ImGui/Private/ImGuiContextManager.cpp +++ b/Source/ImGui/Private/ImGuiContextManager.cpp @@ -152,7 +152,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetEditorContextData() if (UNLIKELY(!Data)) { - Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, OnDrawMultiContext, FontAtlas, -1 }); + Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, OnDrawMultiContext, FontAtlas, DPIScale, -1 }); OnContextProxyCreated.Broadcast(Utilities::EDITOR_CONTEXT_INDEX, *Data->ContextProxy); } @@ -167,7 +167,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetStandaloneWorldCont if (UNLIKELY(!Data)) { - Data = &Contexts.Emplace(Utilities::STANDALONE_GAME_CONTEXT_INDEX, FContextData{ GetWorldContextName(), Utilities::STANDALONE_GAME_CONTEXT_INDEX, OnDrawMultiContext, FontAtlas }); + Data = &Contexts.Emplace(Utilities::STANDALONE_GAME_CONTEXT_INDEX, FContextData{ GetWorldContextName(), Utilities::STANDALONE_GAME_CONTEXT_INDEX, OnDrawMultiContext, FontAtlas, DPIScale }); OnContextProxyCreated.Broadcast(Utilities::STANDALONE_GAME_CONTEXT_INDEX, *Data->ContextProxy); } @@ -209,7 +209,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co #if WITH_EDITOR if (UNLIKELY(!Data)) { - Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, OnDrawMultiContext, FontAtlas, WorldContext->PIEInstance }); + Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, OnDrawMultiContext, FontAtlas, DPIScale, WorldContext->PIEInstance }); OnContextProxyCreated.Broadcast(Index, *Data->ContextProxy); } else @@ -220,7 +220,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co #else if (UNLIKELY(!Data)) { - Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, OnDrawMultiContext, FontAtlas }); + Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, OnDrawMultiContext, FontAtlas, DPIScale }); OnContextProxyCreated.Broadcast(Index, *Data->ContextProxy); } #endif @@ -232,38 +232,6 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co return *Data; } -struct FGuardContext -{ - FGuardContext() - : OldContext(ImGui::GetCurrentContext()) - { - } - - ~FGuardContext() - { - if (bRestore) - { - ImGui::SetCurrentContext(OldContext); - } - } - - FGuardContext(FGuardContext&& Other) - : OldContext(MoveTemp(Other.OldContext)) - { - Other.bRestore = false; - } - - FGuardContext& operator=(FGuardContext&&) = delete; - - FGuardContext(const FGuardContext&) = delete; - FGuardContext& operator=(const FGuardContext&) = delete; - -private: - - ImGuiContext* OldContext = nullptr; - bool bRestore = true; -}; - void FImGuiContextManager::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo) { const float Scale = ScaleInfo.GetImGuiScale(); @@ -281,12 +249,7 @@ void FImGuiContextManager::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo) { if (Pair.Value.ContextProxy) { - ImGuiStyle NewStyle = ImGuiStyle(); - NewStyle.ScaleAllSizes(DPIScale); - - FGuardContext GuardContext; - Pair.Value.ContextProxy->SetAsCurrent(); - ImGui::GetStyle() = MoveTemp(NewStyle); + Pair.Value.ContextProxy->SetDPIScale(DPIScale); } } } diff --git a/Source/ImGui/Private/ImGuiContextManager.h b/Source/ImGui/Private/ImGuiContextManager.h index e28f97e..6afff21 100644 --- a/Source/ImGui/Private/ImGuiContextManager.h +++ b/Source/ImGui/Private/ImGuiContextManager.h @@ -74,9 +74,9 @@ private: struct FContextData { - FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, int32 InPIEInstance = -1) + FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, float DPIScale, int32 InPIEInstance = -1) : PIEInstance(InPIEInstance) - , ContextProxy(new FImGuiContextProxy(ContextName, ContextIndex, &SharedDrawEvent, &FontAtlas)) + , ContextProxy(new FImGuiContextProxy(ContextName, ContextIndex, &SharedDrawEvent, &FontAtlas, DPIScale)) { } diff --git a/Source/ImGui/Private/ImGuiContextProxy.cpp b/Source/ImGui/Private/ImGuiContextProxy.cpp index f500d4b..97e73aa 100644 --- a/Source/ImGui/Private/ImGuiContextProxy.cpp +++ b/Source/ImGui/Private/ImGuiContextProxy.cpp @@ -39,9 +39,41 @@ namespace static FString SaveDirectory = GetSaveDirectory(); return FPaths::Combine(SaveDirectory, Name + TEXT(".ini")); } + + struct FGuardCurrentContext + { + FGuardCurrentContext() + : OldContext(ImGui::GetCurrentContext()) + { + } + + ~FGuardCurrentContext() + { + if (bRestore) + { + ImGui::SetCurrentContext(OldContext); + } + } + + FGuardCurrentContext(FGuardCurrentContext&& Other) + : OldContext(MoveTemp(Other.OldContext)) + { + Other.bRestore = false; + } + + FGuardCurrentContext& operator=(FGuardCurrentContext&&) = delete; + + FGuardCurrentContext(const FGuardCurrentContext&) = delete; + FGuardCurrentContext& operator=(const FGuardCurrentContext&) = delete; + + private: + + ImGuiContext* OldContext = nullptr; + bool bRestore = true; + }; } -FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas) +FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas, float InDPIScale) : Name(InName) , ContextIndex(InContextIndex) , SharedDrawEvent(InSharedDrawEvent) @@ -63,6 +95,9 @@ FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextInd ResetDisplaySize(); IO.DisplaySize = { DisplaySize.X, DisplaySize.Y }; + // Set the initial DPI scale. + SetDPIScale(InDPIScale); + // Initialize key mapping, so context can correctly interpret input state. ImGuiInterops::SetUnrealKeyMap(IO); @@ -89,6 +124,21 @@ void FImGuiContextProxy::ResetDisplaySize() DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT }; } +void FImGuiContextProxy::SetDPIScale(float Scale) +{ + if (DPIScale != Scale) + { + DPIScale = Scale; + + ImGuiStyle NewStyle = ImGuiStyle(); + NewStyle.ScaleAllSizes(Scale); + + FGuardCurrentContext GuardContext; + SetAsCurrent(); + ImGui::GetStyle() = MoveTemp(NewStyle); + } +} + void FImGuiContextProxy::DrawEarlyDebug() { if (bIsFrameStarted && !bIsDrawEarlyDebugCalled) diff --git a/Source/ImGui/Private/ImGuiContextProxy.h b/Source/ImGui/Private/ImGuiContextProxy.h index 47d562a..338432c 100644 --- a/Source/ImGui/Private/ImGuiContextProxy.h +++ b/Source/ImGui/Private/ImGuiContextProxy.h @@ -19,7 +19,7 @@ class FImGuiContextProxy { public: - FImGuiContextProxy(const FString& Name, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas); + FImGuiContextProxy(const FString& Name, int32 InContextIndex, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas, float InDPIScale); ~FImGuiContextProxy(); FImGuiContextProxy(const FImGuiContextProxy&) = delete; @@ -53,6 +53,12 @@ public: // Reset the desired context display size to default size. void ResetDisplaySize(); + // Get the DPI scale set for this context. + float GetDPIScale() const { return DPIScale; } + + // Set the DPI scale for this context. + void SetDPIScale(float Scale); + // Whether this context has an active item (read once per frame during context update). bool HasActiveItem() const { return bHasActiveItem; } @@ -90,6 +96,7 @@ private: ImGuiContext* Context; FVector2D DisplaySize = FVector2D::ZeroVector; + float DPIScale = 1.f; EMouseCursor::Type MouseCursor = EMouseCursor::None; bool bHasActiveItem = false;