diff --git a/Source/ImGui/Private/ImGuiContextProxy.cpp b/Source/ImGui/Private/ImGuiContextProxy.cpp index d110100..ee3c978 100644 --- a/Source/ImGui/Private/ImGuiContextProxy.cpp +++ b/Source/ImGui/Private/ImGuiContextProxy.cpp @@ -59,9 +59,9 @@ FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextInd // Set session data storage. IO.IniFilename = IniFilename.c_str(); - // Use pre-defined canvas size. - IO.DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT }; - DisplaySize = ImGuiInterops::ToVector2D(IO.DisplaySize); + // Start with the default canvas size. + ResetDisplaySize(); + IO.DisplaySize = { DisplaySize.X, DisplaySize.Y }; // Initialize key mapping, so context can correctly interpret input state. ImGuiInterops::SetUnrealKeyMap(IO); @@ -84,6 +84,11 @@ FImGuiContextProxy::~FImGuiContextProxy() } } +void FImGuiContextProxy::ResetDisplaySize() +{ + DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT }; +} + void FImGuiContextProxy::DrawEarlyDebug() { if (bIsFrameStarted && !bIsDrawEarlyDebugCalled) @@ -147,11 +152,6 @@ void FImGuiContextProxy::Tick(float DeltaSeconds) } } -void FImGuiContextProxy::SetAdaptiveCanvasSize(bool bAdaptive) -{ - bAdaptiveCanvasSize = bAdaptive; -} - void FImGuiContextProxy::BeginFrame(float DeltaTime) { if (!bIsFrameStarted) @@ -162,16 +162,7 @@ void FImGuiContextProxy::BeginFrame(float DeltaTime) ImGuiInterops::CopyInput(IO, InputState); InputState.ClearUpdateState(); - if (bAdaptiveCanvasSize) { - if (GEngine && GEngine->GameViewport) - { - GEngine->GameViewport->GetViewportSize(DisplaySize); - IO.DisplaySize = ImVec2(DisplaySize.X, DisplaySize.Y); - } - } else { - IO.DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT }; - DisplaySize = ImGuiInterops::ToVector2D(IO.DisplaySize); - } + IO.DisplaySize = { DisplaySize.X, DisplaySize.Y }; ImGui::NewFrame(); diff --git a/Source/ImGui/Private/ImGuiContextProxy.h b/Source/ImGui/Private/ImGuiContextProxy.h index 7297d13..47d562a 100644 --- a/Source/ImGui/Private/ImGuiContextProxy.h +++ b/Source/ImGui/Private/ImGuiContextProxy.h @@ -44,9 +44,15 @@ public: // Set this context as current ImGui context. void SetAsCurrent() { ImGui::SetCurrentContext(Context); } - // Context display size (read once per frame during context update). + // Get the desired context display size. const FVector2D& GetDisplaySize() const { return DisplaySize; } + // Set the desired context display size. + void SetDisplaySize(const FVector2D& Size) { DisplaySize = Size; } + + // Reset the desired context display size to default size. + void ResetDisplaySize(); + // Whether this context has an active item (read once per frame during context update). bool HasActiveItem() const { return bHasActiveItem; } @@ -68,9 +74,6 @@ public: // Tick to advance context to the next frame. Only one call per frame will be processed. void Tick(float DeltaSeconds); - // Set the adaptive canvas size configuration. - void SetAdaptiveCanvasSize(bool); - private: void BeginFrame(float DeltaTime = 1.f / 60.f); @@ -109,6 +112,4 @@ private: FSimpleMulticastDelegate* SharedDrawEvent = nullptr; std::string IniFilename; - - bool bAdaptiveCanvasSize = false; }; diff --git a/Source/ImGui/Private/ImGuiModuleManager.cpp b/Source/ImGui/Private/ImGuiModuleManager.cpp index e6a28a3..87e234b 100644 --- a/Source/ImGui/Private/ImGuiModuleManager.cpp +++ b/Source/ImGui/Private/ImGuiModuleManager.cpp @@ -175,7 +175,6 @@ void FImGuiModuleManager::AddWidgetToViewport(UGameViewportClient* GameViewport) // Make sure that we have a context for this viewport's world and get its index. int32 ContextIndex; auto& ContextProxy = ContextManager.GetWorldContextProxy(*GameViewport->GetWorld(), ContextIndex); - ContextProxy.SetAdaptiveCanvasSize(Settings.AdaptiveCanvasSize()); // Make sure that textures are loaded before the first Slate widget is created. LoadTextures(); diff --git a/Source/ImGui/Private/Widgets/SImGuiWidget.cpp b/Source/ImGui/Private/Widgets/SImGuiWidget.cpp index b63def3..404afac 100644 --- a/Source/ImGui/Private/Widgets/SImGuiWidget.cpp +++ b/Source/ImGui/Private/Widgets/SImGuiWidget.cpp @@ -84,6 +84,7 @@ void SImGuiWidget::Construct(const FArguments& InArgs) const auto& Settings = ModuleManager->GetSettings(); SetHideMouseCursor(Settings.UseSoftwareCursor()); CreateInputHandler(Settings.GetImGuiInputHandlerClass()); + SetAdaptiveCanvasSize(Settings.AdaptiveCanvasSize()); // Initialize state. UpdateVisibility(); @@ -125,6 +126,7 @@ void SImGuiWidget::Tick(const FGeometry& AllottedGeometry, const double InCurren UpdateInputState(); UpdateTransparentMouseInput(AllottedGeometry); HandleWindowFocusLost(); + UpdateCanvasSize(); } FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) @@ -496,9 +498,44 @@ void SImGuiWidget::HandleWindowFocusLost() } } +void SImGuiWidget::SetAdaptiveCanvasSize(bool bEnabled) +{ + if (bAdaptiveCanvasSize != bEnabled) + { + bAdaptiveCanvasSize = bEnabled; + bUpdateCanvasSize = true; + UpdateCanvasSize(); + } +} + +void SImGuiWidget::UpdateCanvasSize() +{ + if (bUpdateCanvasSize) + { + if (auto* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex)) + { + if (bAdaptiveCanvasSize) + { + if (GameViewport.IsValid()) + { + FVector2D DisplaySize; + GameViewport->GetViewportSize(DisplaySize); + ContextProxy->SetDisplaySize(DisplaySize); + } + } + else + { + ContextProxy->ResetDisplaySize(); + // No need for more updates, if we successfully processed fixed-canvas mode. + bUpdateCanvasSize = false; + } + } + } +} + void SImGuiWidget::UpdateCanvasControlMode(const FInputEvent& InputEvent) { - CanvasControlWidget->SetActive(InputEvent.IsLeftAltDown() && InputEvent.IsLeftShiftDown()); + CanvasControlWidget->SetActive(!bAdaptiveCanvasSize && InputEvent.IsLeftAltDown() && InputEvent.IsLeftShiftDown()); } void SImGuiWidget::OnPostImGuiUpdate() diff --git a/Source/ImGui/Private/Widgets/SImGuiWidget.h b/Source/ImGui/Private/Widgets/SImGuiWidget.h index 7239833..a36a1de 100644 --- a/Source/ImGui/Private/Widgets/SImGuiWidget.h +++ b/Source/ImGui/Private/Widgets/SImGuiWidget.h @@ -103,6 +103,9 @@ private: void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry); void HandleWindowFocusLost(); + void SetAdaptiveCanvasSize(bool bEnabled); + void UpdateCanvasSize(); + void UpdateCanvasControlMode(const FInputEvent& InputEvent); void OnPostImGuiUpdate(); @@ -135,6 +138,8 @@ private: bool bForegroundWindow = false; bool bHideMouseCursor = true; bool bTransparentMouseInput = false; + bool bAdaptiveCanvasSize = false; + bool bUpdateCanvasSize = false; TSharedPtr CanvasControlWidget; TWeakPtr PreviousUserFocusedWidget;