mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-18 08:20:32 +00:00
Moved input state from SImGuiWidget to FImGuiContextProxy and modified implementation of FImGuiInputState reset functionality.
Moving input state to context proxy decouples it a bit from a particular input source and although not used right now, it allows multiple sources to send input in parallel.
This commit is contained in:
parent
22c5b42387
commit
852a501022
@ -151,10 +151,8 @@ void FImGuiContextProxy::BeginFrame(float DeltaTime)
|
||||
ImGuiIO& IO = ImGui::GetIO();
|
||||
IO.DeltaTime = DeltaTime;
|
||||
|
||||
if (InputState)
|
||||
{
|
||||
ImGuiInterops::CopyInput(IO, *InputState);
|
||||
}
|
||||
ImGuiInterops::CopyInput(IO, InputState);
|
||||
InputState.ClearUpdateState();
|
||||
|
||||
ImGui::NewFrame();
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ImGuiDrawData.h"
|
||||
|
||||
#include "ImGuiInputState.h"
|
||||
#include "Utilities/WorldContextIndex.h"
|
||||
|
||||
#include <ICursor.h>
|
||||
@ -13,8 +13,6 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
class FImGuiInputState;
|
||||
|
||||
// Represents a single ImGui context. All the context updates should be done through this proxy. During update it
|
||||
// broadcasts draw events to allow listeners draw their controls. After update it stores draw data.
|
||||
class FImGuiContextProxy
|
||||
@ -58,13 +56,8 @@ public:
|
||||
const TArray<FImGuiDrawList>& GetDrawData() const { return DrawLists; }
|
||||
|
||||
// Get input state used by this context.
|
||||
const FImGuiInputState* GetInputState() const { return InputState; }
|
||||
|
||||
// Set input state to be used by this context.
|
||||
void SetInputState(const FImGuiInputState* SourceInputState) { InputState = SourceInputState; }
|
||||
|
||||
// If context is currently using input state to remove then remove that binding.
|
||||
void RemoveInputState(const FImGuiInputState* InputStateToRemove) { if (InputState == InputStateToRemove) InputState = nullptr; }
|
||||
FImGuiInputState& GetInputState() { return InputState; }
|
||||
const FImGuiInputState& GetInputState() const { return InputState; }
|
||||
|
||||
// Is this context the current ImGui context.
|
||||
bool IsCurrentContext() const { return ImGui::GetCurrentContext() == Context.Get(); }
|
||||
@ -117,7 +110,7 @@ private:
|
||||
bool bIsDrawEarlyDebugCalled = false;
|
||||
bool bIsDrawDebugCalled = false;
|
||||
|
||||
const FImGuiInputState* InputState = nullptr;
|
||||
FImGuiInputState InputState;
|
||||
|
||||
TArray<FImGuiDrawList> DrawLists;
|
||||
|
||||
|
@ -46,7 +46,7 @@ namespace
|
||||
|
||||
FImGuiInputState::FImGuiInputState()
|
||||
{
|
||||
ResetState();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void FImGuiInputState::AddCharacter(TCHAR Char)
|
||||
@ -82,31 +82,6 @@ void FImGuiInputState::SetMouseDown(uint32 MouseIndex, bool bIsDown)
|
||||
}
|
||||
}
|
||||
|
||||
void FImGuiInputState::Reset(bool bKeyboard, bool bMouse, bool bNavigation)
|
||||
{
|
||||
if (bKeyboard)
|
||||
{
|
||||
ClearCharacters();
|
||||
ClearKeys();
|
||||
}
|
||||
|
||||
if (bMouse)
|
||||
{
|
||||
ClearMouseButtons();
|
||||
ClearMouseAnalogue();
|
||||
}
|
||||
|
||||
if (bKeyboard && bMouse)
|
||||
{
|
||||
ClearModifierKeys();
|
||||
}
|
||||
|
||||
if (bNavigation)
|
||||
{
|
||||
ClearNavigationInputs();
|
||||
}
|
||||
}
|
||||
|
||||
void FImGuiInputState::ClearUpdateState()
|
||||
{
|
||||
if (InputCharactersNum > 0)
|
||||
@ -132,7 +107,7 @@ void FImGuiInputState::ClearKeys()
|
||||
using std::fill;
|
||||
fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false);
|
||||
|
||||
// Expand update range because keys array has been updated.
|
||||
// Mark the whole array as dirty because potentially each entry could be affected.
|
||||
KeysUpdateRange.SetFull();
|
||||
}
|
||||
|
||||
@ -141,7 +116,7 @@ void FImGuiInputState::ClearMouseButtons()
|
||||
using std::fill;
|
||||
fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
|
||||
|
||||
// Expand update range because mouse buttons array has been updated.
|
||||
// Mark the whole array as dirty because potentially each entry could be affected.
|
||||
MouseButtonsUpdateRange.SetFull();
|
||||
}
|
||||
|
||||
|
@ -151,17 +151,34 @@ public:
|
||||
// @param bInHasGamepad - True, if gamepad is attached
|
||||
void SetGamepad(bool bInHasGamepad) { bHasGamepad = bInHasGamepad; }
|
||||
|
||||
// Reset the whole state and mark as dirty.
|
||||
void ResetState() { Reset(true, true, true); }
|
||||
// Reset the whole input state and mark it as dirty.
|
||||
void Reset()
|
||||
{
|
||||
ResetKeyboard();
|
||||
ResetMouse();
|
||||
ResetGamepadNavigation();
|
||||
}
|
||||
|
||||
// Reset keyboard state and mark as dirty.
|
||||
void ResetKeyboardState() { Reset(true, false, false); }
|
||||
// Reset the keyboard input state and mark it as dirty.
|
||||
void ResetKeyboard()
|
||||
{
|
||||
ClearCharacters();
|
||||
ClearKeys();
|
||||
ClearModifierKeys();
|
||||
}
|
||||
|
||||
// Reset mouse state and mark as dirty.
|
||||
void ResetMouseState() { Reset(false, true, false); }
|
||||
// Reset the mouse input state and mark it as dirty.
|
||||
void ResetMouse()
|
||||
{
|
||||
ClearMouseButtons();
|
||||
ClearMouseAnalogue();
|
||||
}
|
||||
|
||||
// Reset navigation state.
|
||||
void ResetNavigationState() { Reset(false, false, true); }
|
||||
// Reset the gamepad navigation state.
|
||||
void ResetGamepadNavigation()
|
||||
{
|
||||
ClearNavigationInputs();
|
||||
}
|
||||
|
||||
// Clear part of the state that is meant to be updated in every frame like: accumulators, buffers, navigation data
|
||||
// and information about dirty parts of keys or mouse buttons arrays.
|
||||
@ -172,8 +189,6 @@ private:
|
||||
void SetKeyDown(uint32 KeyIndex, bool bIsDown);
|
||||
void SetMouseDown(uint32 MouseIndex, bool IsDown);
|
||||
|
||||
void Reset(bool bKeyboard, bool bMouse, bool bNavigation);
|
||||
|
||||
void ClearCharacters();
|
||||
void ClearKeys();
|
||||
void ClearMouseButtons();
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "ImGuiImplementation.h"
|
||||
#include "ImGuiInputHandler.h"
|
||||
#include "ImGuiInputHandlerFactory.h"
|
||||
#include "ImGuiInputState.h"
|
||||
#include "ImGuiInteroperability.h"
|
||||
#include "ImGuiModuleManager.h"
|
||||
#include "ImGuiModuleSettings.h"
|
||||
@ -83,7 +84,7 @@ void SImGuiWidget::Construct(const FArguments& InArgs)
|
||||
#if IMGUI_WIDGET_DEBUG
|
||||
ContextProxy->OnDraw().AddRaw(this, &SImGuiWidget::OnDebugDraw);
|
||||
#endif // IMGUI_WIDGET_DEBUG
|
||||
ContextProxy->SetInputState(&InputState);
|
||||
InputState = &ContextProxy->GetInputState();
|
||||
|
||||
// Register for settings change.
|
||||
RegisterImGuiSettingsDelegates();
|
||||
@ -119,7 +120,6 @@ SImGuiWidget::~SImGuiWidget()
|
||||
#if IMGUI_WIDGET_DEBUG
|
||||
ContextProxy->OnDraw().RemoveAll(this);
|
||||
#endif // IMGUI_WIDGET_DEBUG
|
||||
ContextProxy->RemoveInputState(&InputState);
|
||||
}
|
||||
|
||||
// Unregister from post-update notifications.
|
||||
@ -148,7 +148,7 @@ FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEven
|
||||
const FImGuiInputResponse Response = InputHandler->OnKeyChar(CharacterEvent);
|
||||
if (Response.HasProcessingRequest())
|
||||
{
|
||||
InputState.AddCharacter(CharacterEvent.GetCharacter());
|
||||
InputState->AddCharacter(CharacterEvent.GetCharacter());
|
||||
}
|
||||
|
||||
return ToSlateReply(Response);
|
||||
@ -158,12 +158,12 @@ FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& Key
|
||||
{
|
||||
if (KeyEvent.GetKey().IsGamepadKey())
|
||||
{
|
||||
if (InputState.IsGamepadNavigationEnabled())
|
||||
if (InputState->IsGamepadNavigationEnabled())
|
||||
{
|
||||
const FImGuiInputResponse Response = InputHandler->OnGamepadKeyDown(KeyEvent);
|
||||
if (Response.HasProcessingRequest())
|
||||
{
|
||||
InputState.SetGamepadNavigationKey(KeyEvent, true);
|
||||
InputState->SetGamepadNavigationKey(KeyEvent, true);
|
||||
}
|
||||
|
||||
return ToSlateReply(Response);
|
||||
@ -180,7 +180,7 @@ FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& Key
|
||||
const FImGuiInputResponse Response = InputHandler->OnKeyDown(KeyEvent);
|
||||
if (Response.HasProcessingRequest())
|
||||
{
|
||||
InputState.SetKeyDown(KeyEvent, true);
|
||||
InputState->SetKeyDown(KeyEvent, true);
|
||||
CopyModifierKeys(KeyEvent);
|
||||
}
|
||||
|
||||
@ -192,10 +192,10 @@ FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEv
|
||||
{
|
||||
if (KeyEvent.GetKey().IsGamepadKey())
|
||||
{
|
||||
if (InputState.IsGamepadNavigationEnabled())
|
||||
if (InputState->IsGamepadNavigationEnabled())
|
||||
{
|
||||
// Always handle key up events to protect from leaving accidental keys not cleared in ImGui input state.
|
||||
InputState.SetGamepadNavigationKey(KeyEvent, false);
|
||||
InputState->SetGamepadNavigationKey(KeyEvent, false);
|
||||
|
||||
return ToSlateReply(InputHandler->OnGamepadKeyUp(KeyEvent));
|
||||
}
|
||||
@ -209,7 +209,7 @@ FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEv
|
||||
UpdateCanvasControlMode(KeyEvent);
|
||||
|
||||
// Always handle key up events to protect from leaving accidental keys not cleared in ImGui input state.
|
||||
InputState.SetKeyDown(KeyEvent, false);
|
||||
InputState->SetKeyDown(KeyEvent, false);
|
||||
CopyModifierKeys(KeyEvent);
|
||||
|
||||
return ToSlateReply(InputHandler->OnKeyUp(KeyEvent));
|
||||
@ -218,12 +218,12 @@ FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEv
|
||||
|
||||
FReply SImGuiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent)
|
||||
{
|
||||
if (AnalogInputEvent.GetKey().IsGamepadKey() && InputState.IsGamepadNavigationEnabled())
|
||||
if (AnalogInputEvent.GetKey().IsGamepadKey() && InputState->IsGamepadNavigationEnabled())
|
||||
{
|
||||
const FImGuiInputResponse Response = InputHandler->OnGamepadAxis(AnalogInputEvent);
|
||||
if (Response.HasProcessingRequest())
|
||||
{
|
||||
InputState.SetGamepadNavigationAxis(AnalogInputEvent, AnalogInputEvent.GetAnalogValue());
|
||||
InputState->SetGamepadNavigationAxis(AnalogInputEvent, AnalogInputEvent.GetAnalogValue());
|
||||
}
|
||||
|
||||
return ToSlateReply(Response);
|
||||
@ -236,32 +236,32 @@ FReply SImGuiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAn
|
||||
|
||||
FReply SImGuiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
InputState.SetMouseDown(MouseEvent, true);
|
||||
InputState->SetMouseDown(MouseEvent, true);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SImGuiWidget::OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
InputState.SetMouseDown(MouseEvent, true);
|
||||
InputState->SetMouseDown(MouseEvent, true);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SImGuiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
InputState.SetMouseDown(MouseEvent, false);
|
||||
InputState->SetMouseDown(MouseEvent, false);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
InputState.AddMouseWheelDelta(MouseEvent.GetWheelDelta());
|
||||
InputState->AddMouseWheelDelta(MouseEvent.GetWheelDelta());
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||
{
|
||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(MyGeometry.GetAccumulatedRenderTransform());
|
||||
InputState.SetMousePosition(ImGuiToScreen.Inverse().TransformPoint(MouseEvent.GetScreenSpacePosition()));
|
||||
InputState->SetMousePosition(ImGuiToScreen.Inverse().TransformPoint(MouseEvent.GetScreenSpacePosition()));
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
@ -300,7 +300,7 @@ void SImGuiWidget::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent
|
||||
{
|
||||
for (const FKey& Button : { EKeys::LeftMouseButton, EKeys::MiddleMouseButton, EKeys::RightMouseButton, EKeys::ThumbMouseButton, EKeys::ThumbMouseButton2 })
|
||||
{
|
||||
InputState.SetMouseDown(Button, MouseEvent.IsMouseButtonDown(Button));
|
||||
InputState->SetMouseDown(Button, MouseEvent.IsMouseButtonDown(Button));
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,9 +375,9 @@ void SImGuiWidget::UnregisterImGuiSettingsDelegates()
|
||||
|
||||
void SImGuiWidget::CopyModifierKeys(const FInputEvent& InputEvent)
|
||||
{
|
||||
InputState.SetControlDown(InputEvent.IsControlDown());
|
||||
InputState.SetShiftDown(InputEvent.IsShiftDown());
|
||||
InputState.SetAltDown(InputEvent.IsAltDown());
|
||||
InputState->SetControlDown(InputEvent.IsControlDown());
|
||||
InputState->SetShiftDown(InputEvent.IsShiftDown());
|
||||
InputState->SetAltDown(InputEvent.IsAltDown());
|
||||
}
|
||||
|
||||
bool SImGuiWidget::IsConsoleOpened() const
|
||||
@ -493,10 +493,10 @@ void SImGuiWidget::UpdateInputEnabled()
|
||||
|
||||
if (bInputEnabled)
|
||||
{
|
||||
InputState.SetKeyboardNavigationEnabled(ModuleManager && ModuleManager->GetProperties().IsKeyboardNavigationEnabled());
|
||||
InputState.SetGamepadNavigationEnabled(ModuleManager && ModuleManager->GetProperties().IsGamepadNavigationEnabled());
|
||||
InputState->SetKeyboardNavigationEnabled(ModuleManager && ModuleManager->GetProperties().IsKeyboardNavigationEnabled());
|
||||
InputState->SetGamepadNavigationEnabled(ModuleManager && ModuleManager->GetProperties().IsGamepadNavigationEnabled());
|
||||
const auto& Application = FSlateApplication::Get().GetPlatformApplication();
|
||||
InputState.SetGamepad(Application.IsValid() && Application->IsGamepadAttached());
|
||||
InputState->SetGamepad(Application.IsValid() && Application->IsGamepadAttached());
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,18 +516,18 @@ void SImGuiWidget::UpdateInputMode(bool bHasKeyboardFocus, bool bHasMousePointer
|
||||
// mouse-only input mode.
|
||||
if (NewInputMode == EInputMode::None)
|
||||
{
|
||||
InputState.ResetState();
|
||||
InputState->Reset();
|
||||
}
|
||||
else if (InputMode == EInputMode::Full)
|
||||
{
|
||||
InputState.ResetKeyboardState();
|
||||
InputState.ResetNavigationState();
|
||||
InputState->ResetKeyboard();
|
||||
InputState->ResetGamepadNavigation();
|
||||
}
|
||||
|
||||
InputMode = NewInputMode;
|
||||
}
|
||||
|
||||
InputState.SetMousePointer(bUseSoftwareCursor && bHasMousePointer);
|
||||
InputState->SetMousePointer(bUseSoftwareCursor && bHasMousePointer);
|
||||
}
|
||||
|
||||
void SImGuiWidget::UpdateCanvasControlMode(const FInputEvent& InputEvent)
|
||||
@ -537,11 +537,6 @@ void SImGuiWidget::UpdateCanvasControlMode(const FInputEvent& InputEvent)
|
||||
|
||||
void SImGuiWidget::OnPostImGuiUpdate()
|
||||
{
|
||||
if (InputMode != EInputMode::None)
|
||||
{
|
||||
InputState.ClearUpdateState();
|
||||
}
|
||||
|
||||
ImGuiRenderTransform = ImGuiTransform;
|
||||
}
|
||||
|
||||
@ -780,7 +775,7 @@ void SImGuiWidget::OnDebugDraw()
|
||||
{
|
||||
TwoColumns::Value("Input Enabled", bInputEnabled);
|
||||
TwoColumns::Value("Input Mode", TEXT_INPUT_MODE(InputMode));
|
||||
TwoColumns::Value("Input Has Mouse Pointer", InputState.HasMousePointer());
|
||||
TwoColumns::Value("Input Has Mouse Pointer", InputState->HasMousePointer());
|
||||
});
|
||||
|
||||
TwoColumns::CollapsingGroup("Widget", [&]()
|
||||
@ -837,7 +832,7 @@ void SImGuiWidget::OnDebugDraw()
|
||||
{
|
||||
const FKey& Key = Keys[Idx];
|
||||
const uint32 KeyIndex = ImGuiInterops::GetKeyIndex(Key);
|
||||
Styles::TextHighlight(InputState.GetKeys()[KeyIndex], [&]()
|
||||
Styles::TextHighlight(InputState->GetKeys()[KeyIndex], [&]()
|
||||
{
|
||||
TwoColumns::Value(*Key.GetDisplayName().ToString(), KeyIndex);
|
||||
});
|
||||
@ -852,9 +847,9 @@ void SImGuiWidget::OnDebugDraw()
|
||||
|
||||
Columns::CollapsingGroup("Modifier Keys", 4, [&]()
|
||||
{
|
||||
Styles::TextHighlight(InputState.IsShiftDown(), [&]() { ImGui::Text("Shift"); }); ImGui::NextColumn();
|
||||
Styles::TextHighlight(InputState.IsControlDown(), [&]() { ImGui::Text("Control"); }); ImGui::NextColumn();
|
||||
Styles::TextHighlight(InputState.IsAltDown(), [&]() { ImGui::Text("Alt"); }); ImGui::NextColumn();
|
||||
Styles::TextHighlight(InputState->IsShiftDown(), [&]() { ImGui::Text("Shift"); }); ImGui::NextColumn();
|
||||
Styles::TextHighlight(InputState->IsControlDown(), [&]() { ImGui::Text("Control"); }); ImGui::NextColumn();
|
||||
Styles::TextHighlight(InputState->IsAltDown(), [&]() { ImGui::Text("Alt"); }); ImGui::NextColumn();
|
||||
ImGui::NextColumn();
|
||||
});
|
||||
|
||||
@ -877,7 +872,7 @@ void SImGuiWidget::OnDebugDraw()
|
||||
{
|
||||
const FKey& Button = Buttons[Idx];
|
||||
const uint32 MouseIndex = ImGuiInterops::GetMouseIndex(Button);
|
||||
Styles::TextHighlight(InputState.GetMouseButtons()[MouseIndex], [&]()
|
||||
Styles::TextHighlight(InputState->GetMouseButtons()[MouseIndex], [&]()
|
||||
{
|
||||
TwoColumns::Value(*Button.GetDisplayName().ToString(), MouseIndex);
|
||||
});
|
||||
@ -892,9 +887,9 @@ void SImGuiWidget::OnDebugDraw()
|
||||
|
||||
Columns::CollapsingGroup("Mouse Axes", 4, [&]()
|
||||
{
|
||||
TwoColumns::Value("Position X", InputState.GetMousePosition().X);
|
||||
TwoColumns::Value("Position Y", InputState.GetMousePosition().Y);
|
||||
TwoColumns::Value("Wheel Delta", InputState.GetMouseWheelDelta());
|
||||
TwoColumns::Value("Position X", InputState->GetMousePosition().X);
|
||||
TwoColumns::Value("Position Y", InputState->GetMousePosition().Y);
|
||||
TwoColumns::Value("Wheel Delta", InputState->GetMouseWheelDelta());
|
||||
ImGui::NextColumn(); ImGui::NextColumn();
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ImGuiInputState.h"
|
||||
#include "ImGuiModuleDebug.h"
|
||||
#include "ImGuiModuleSettings.h"
|
||||
|
||||
@ -12,6 +11,7 @@
|
||||
// Hide ImGui Widget debug in non-developer mode.
|
||||
#define IMGUI_WIDGET_DEBUG IMGUI_MODULE_DEVELOPER
|
||||
|
||||
class FImGuiInputState;
|
||||
class FImGuiModuleManager;
|
||||
class SImGuiCanvasControl;
|
||||
class UImGuiInputHandler;
|
||||
@ -37,9 +37,6 @@ public:
|
||||
// Get index of the context that this widget is targeting.
|
||||
int32 GetContextIndex() const { return ContextIndex; }
|
||||
|
||||
// Get input state associated with this widget.
|
||||
const FImGuiInputState& GetInputState() const { return InputState; }
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// SWidget overrides
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@ -137,7 +134,7 @@ private:
|
||||
|
||||
int32 ContextIndex = 0;
|
||||
|
||||
FImGuiInputState InputState;
|
||||
FImGuiInputState* InputState;
|
||||
|
||||
EInputMode InputMode = EInputMode::None;
|
||||
bool bInputEnabled = false;
|
||||
|
Loading…
Reference in New Issue
Block a user