Added ImGui.InputEnabled console variable to control when ImGui should receive inputs.

This commit is contained in:
Sebastian 2017-09-02 18:42:41 +01:00
parent 77bb73dbce
commit f7816ee1fd
2 changed files with 67 additions and 2 deletions

View File

@ -12,6 +12,15 @@
#include "Utilities/ScopeGuards.h" #include "Utilities/ScopeGuards.h"
namespace CVars
{
TAutoConsoleVariable<int> InputEnabled(TEXT("ImGui.InputEnabled"), 0,
TEXT("Allows to enable or disable ImGui input mode.\n")
TEXT("0: disabled (default)\n")
TEXT("1: enabled, input is routed to ImGui and with a few exceptions is consumed."),
ECVF_Default);
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SImGuiWidget::Construct(const FArguments& InArgs) void SImGuiWidget::Construct(const FArguments& InArgs)
{ {
@ -20,6 +29,9 @@ void SImGuiWidget::Construct(const FArguments& InArgs)
ContextIndex = InArgs._ContextIndex; ContextIndex = InArgs._ContextIndex;
ModuleManager->OnPostImGuiUpdate().AddRaw(this, &SImGuiWidget::OnPostImGuiUpdate); ModuleManager->OnPostImGuiUpdate().AddRaw(this, &SImGuiWidget::OnPostImGuiUpdate);
// Sync visibility with default input enabled state.
SetVisibilityFromInputEnabled();
} }
END_SLATE_FUNCTION_BUILD_OPTIMIZATION END_SLATE_FUNCTION_BUILD_OPTIMIZATION
@ -28,6 +40,15 @@ SImGuiWidget::~SImGuiWidget()
ModuleManager->OnPostImGuiUpdate().RemoveAll(this); ModuleManager->OnPostImGuiUpdate().RemoveAll(this);
} }
void SImGuiWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
Super::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
// Note: Moving that update to console variable sink or callback might seem like a better alternative but input
// setup in this function is better handled here.
UpdateInputEnabled();
}
FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
{ {
InputState.AddCharacter(CharacterEvent.GetCharacter()); InputState.AddCharacter(CharacterEvent.GetCharacter());
@ -154,6 +175,41 @@ void SImGuiWidget::CopyModifierKeys(const FPointerEvent& MouseEvent)
} }
} }
void SImGuiWidget::SetVisibilityFromInputEnabled()
{
// If we don't use input disable hit test to make this widget invisible for cursors hit detection.
SetVisibility(bInputEnabled ? EVisibility::Visible : EVisibility::HitTestInvisible);
}
void SImGuiWidget::UpdateInputEnabled()
{
const bool bEnabled = CVars::InputEnabled.GetValueOnGameThread() > 0;
if (bInputEnabled != bEnabled)
{
bInputEnabled = bEnabled;
SetVisibilityFromInputEnabled();
// Setup input to show cursor and take focus when we use input or clear state and pass focus back to viewport
// when we don't.
auto& Slate = FSlateApplication::Get();
if (bInputEnabled)
{
Slate.ResetToDefaultPointerInputSettings();
Slate.SetKeyboardFocus(SharedThis(this));
}
else
{
if (Slate.GetKeyboardFocusedWidget().Get() == this)
{
Slate.SetUserFocusToGameViewport(Slate.GetUserIndexForKeyboard());
}
UpdateInputMode(false, false);
}
}
}
void SImGuiWidget::UpdateInputMode(bool bNeedKeyboard, bool bNeedMouse) void SImGuiWidget::UpdateInputMode(bool bNeedKeyboard, bool bNeedMouse)
{ {
const EInputMode NewInputMode = const EInputMode NewInputMode =

View File

@ -36,7 +36,9 @@ public:
// SWidget overrides // SWidget overrides
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
virtual bool SupportsKeyboardFocus() const override { return true; } virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual bool SupportsKeyboardFocus() const override { return bInputEnabled; }
virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override; virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
@ -64,7 +66,7 @@ public:
private: private:
enum class EInputMode enum class EInputMode : uint8
{ {
None, None,
MouseOnly, MouseOnly,
@ -74,6 +76,12 @@ private:
FORCEINLINE void CopyModifierKeys(const FInputEvent& InputEvent); FORCEINLINE void CopyModifierKeys(const FInputEvent& InputEvent);
FORCEINLINE void CopyModifierKeys(const FPointerEvent& MouseEvent); FORCEINLINE void CopyModifierKeys(const FPointerEvent& MouseEvent);
// Update visibility based on input enabled state.
void SetVisibilityFromInputEnabled();
// Update input enabled state from console variable.
void UpdateInputEnabled();
// Determine new input mode based on requirement hints. // Determine new input mode based on requirement hints.
void UpdateInputMode(bool bNeedKeyboard, bool bNeedMouse); void UpdateInputMode(bool bNeedKeyboard, bool bNeedMouse);
@ -91,6 +99,7 @@ private:
int32 ContextIndex = 0; int32 ContextIndex = 0;
EInputMode InputMode = EInputMode::None; EInputMode InputMode = EInputMode::None;
bool bInputEnabled = false;
FImGuiInputState InputState; FImGuiInputState InputState;
}; };