Retake the focus when loosing it while ImGui has the input

This commit is contained in:
Arnaud Jamin
2025-02-13 00:51:44 -05:00
parent 2906837026
commit 30ecbefd10
5 changed files with 44 additions and 8 deletions
@@ -52,7 +52,7 @@ void FCogEngineWindow_Slate::RenderContent()
void FCogEngineWindow_Slate::RenderUser(FSlateUser& User)
{
if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders))
if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable))
{
constexpr ImVec4 LabelColor(1.0f, 1.0f, 1.0f, 0.5f);
@@ -206,6 +206,17 @@ void FCogImguiContext::Shutdown()
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::OnImGuiWidgetFocusLost()
{
FCogImGuiContextScope ImGuiContextScope(Context, PlotContext);
if (bEnableInput && GameViewport->GetGameViewportWidget()->HasUserFocus(0))
{
bRetakeFocus = true;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMetrics) const
{
@@ -238,7 +249,7 @@ void FCogImguiContext::OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMet
bool FCogImguiContext::BeginFrame(float InDeltaTime)
{
FCogImGuiContextScope ImGuiContextScope(Context, PlotContext);
//-------------------------------------------------------------------------------------------------------
// Skip the first frame, to let the main widget update its TickSpaceGeometry which is returned by the
// platform callback ImGui_GetWindowPos. When using viewports Imgui needs to know the main viewport
@@ -250,6 +261,16 @@ bool FCogImguiContext::BeginFrame(float InDeltaTime)
return false;
}
//-------------------------------------------------------------------------------------------------------
// Sometime the game can retake unaware that ImGui want to keep the focus and mouse unlock.
// This typically happens when switching level.
//-------------------------------------------------------------------------------------------------------
if (bRetakeFocus)
{
SetEnableInput(true);
bRetakeFocus = false;
}
ImGuiIO& IO = ImGui::GetIO();
IO.DeltaTime = InDeltaTime;
@@ -696,16 +717,14 @@ static APlayerController* GetLocalPlayerController(const UWorld* World)
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::SetEnableInput(bool Value)
void FCogImguiContext::SetEnableInput(const bool InValue)
{
FCogImGuiContextScope ImGuiContextScope(Context, PlotContext);
bEnableInput = Value;
bEnableInput = InValue;
if (FSlateApplication::IsInitialized() == false)
{
return;
}
{ return; }
if (bEnableInput)
{
@@ -277,6 +277,17 @@ FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocu
return Super::OnFocusReceived(MyGeometry, FocusEvent);
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::OnFocusLost(const FFocusEvent& InFocusEvent)
{
SLeafWidget::OnFocusLost(InFocusEvent);
if (Context != nullptr)
{
Context->OnImGuiWidgetFocusLost();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::RefreshVisibility()
{
@@ -47,7 +47,7 @@ public:
bool GetEnableInput() const { return bEnableInput; }
void SetEnableInput(bool Value);
void SetEnableInput(bool InValue);
bool GetWantCaptureMouse() const { return bWantCaptureMouse; }
@@ -81,6 +81,8 @@ public:
TSharedPtr<const SCogImguiWidget> GetMainWidget() const { return MainWidget; }
void OnImGuiWidgetFocusLost();
static bool GetIsNetImguiInitialized() { return bIsNetImGuiInitialized; }
private:
@@ -179,6 +181,8 @@ private:
bool bSkipRendering = false;
bool bRetakeFocus = false;
static bool bIsNetImGuiInitialized;
};
@@ -51,6 +51,8 @@ public:
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
virtual void OnFocusLost(const FFocusEvent& InFocusEvent) override;
void SetDrawData(const ImDrawData* InDrawData);