Replaced in ImGui Input Handler hard-coded assumptions about console open and stop play session shortcuts with values taken from input settings and input binding manager. Testing functions are available for inheriting classes.

This commit is contained in:
Sebastian 2018-07-10 20:21:35 +01:00
parent daa18fcf25
commit eabff7b839
3 changed files with 86 additions and 5 deletions

View File

@ -65,6 +65,7 @@ public class ImGui : ModuleRules
new string[] new string[]
{ {
"Settings", "Settings",
"UnrealEd",
} }
); );
} }

View File

@ -10,24 +10,64 @@
#include <Engine/Console.h> #include <Engine/Console.h>
#include <Input/Events.h> #include <Input/Events.h>
#if WITH_EDITOR
#include <Commands/InputBindingManager.h>
#include <Commands/InputChord.h>
#include <DebuggerCommands.h>
// Version 4.18 added support for dual key bindings.
#include <Runtime/Launch/Resources/Version.h>
#define WITH_SINGLE_KEY_BINDING (ENGINE_MAJOR_VERSION < 4 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 18))
#endif // WITH_EDITOR
DEFINE_LOG_CATEGORY_STATIC(LogImGuiInputHandler, Warning, All);
FImGuiInputResponse UImGuiInputHandler::OnKeyDown(const FKeyEvent& KeyEvent) FImGuiInputResponse UImGuiInputHandler::OnKeyDown(const FKeyEvent& KeyEvent)
{ {
// Ignore console open events, so we don't block it from opening. // Ignore console events, so we don't block it from opening.
if (KeyEvent.GetKey() == EKeys::Tilde) if (IsConsoleEvent(KeyEvent))
{ {
return FImGuiInputResponse{ false, false }; return FImGuiInputResponse{ false, false };
} }
// Ignore escape event, if they are not meant for ImGui control. #if WITH_EDITOR
if (KeyEvent.GetKey() == EKeys::Escape && !HasImGuiActiveItem()) // If there is no active ImGui control that would get precedence and this key event is bound to a stop play session
// command, then ignore that event and let the command execute.
if (!HasImGuiActiveItem() && IsStopPlaySessionEvent(KeyEvent))
{ {
return FImGuiInputResponse{ false, false }; return FImGuiInputResponse{ false, false };
} }
#endif // WITH_EDITOR
return DefaultResponse(); return DefaultResponse();
} }
bool UImGuiInputHandler::IsConsoleEvent(const FKeyEvent& KeyEvent) const
{
// Checking modifiers is based on console implementation.
const bool bModifierDown = KeyEvent.IsControlDown() || KeyEvent.IsShiftDown() || KeyEvent.IsAltDown() || KeyEvent.IsCommandDown();
return !bModifierDown && GetDefault<UInputSettings>()->ConsoleKeys.Contains(KeyEvent.GetKey());
}
#if WITH_EDITOR
bool UImGuiInputHandler::IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) const
{
if (StopPlaySessionCommandInfo.IsValid())
{
const FInputChord InputChord(KeyEvent.GetKey(), KeyEvent.IsShiftDown(), KeyEvent.IsControlDown(), KeyEvent.IsAltDown(), KeyEvent.IsCommandDown());
#if WITH_SINGLE_KEY_BINDING
const bool bHasActiveChord = (InputChord == StopPlaySessionCommandInfo->GetActiveChord().Get());
#else
const bool bHasActiveChord = StopPlaySessionCommandInfo->HasActiveChord(InputChord);
#endif
return bHasActiveChord && FPlayWorldCommands::GlobalPlayWorldActions->CanExecuteAction(StopPlaySessionCommandInfo.ToSharedRef());
}
return false;
}
#endif // WITH_EDITOR
bool UImGuiInputHandler::HasImGuiActiveItem() const bool UImGuiInputHandler::HasImGuiActiveItem() const
{ {
FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex); FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex);
@ -39,4 +79,13 @@ void UImGuiInputHandler::Initialize(FImGuiModuleManager* InModuleManager, UGameV
ModuleManager = InModuleManager; ModuleManager = InModuleManager;
GameViewport = InGameViewport; GameViewport = InGameViewport;
ContextIndex = InContextIndex; ContextIndex = InContextIndex;
#if WITH_EDITOR
StopPlaySessionCommandInfo = FInputBindingManager::Get().FindCommandInContext("PlayWorld", "StopPlaySession");
if (!StopPlaySessionCommandInfo.IsValid())
{
UE_LOG(LogImGuiInputHandler, Warning, TEXT("Couldn't find 'StopPlaySession' in context 'PlayWorld'. ")
TEXT("PIE feature allowing execution of stop command in ImGui input mode will be disabled."));
}
#endif // WITH_EDITOR
} }

View File

@ -15,6 +15,11 @@ struct FAnalogInputEvent;
struct FCharacterEvent; struct FCharacterEvent;
struct FKeyEvent; struct FKeyEvent;
#if WITH_EDITOR
class FUICommandInfo;
#endif // WITH_EDITOR
/** Response used by ImGui Input Handler to communicate input handling requests. */ /** Response used by ImGui Input Handler to communicate input handling requests. */
struct IMGUI_API FImGuiInputResponse struct IMGUI_API FImGuiInputResponse
{ {
@ -149,7 +154,29 @@ public:
protected: protected:
/** Checks whether corresponding ImGui context has an active item. */ /**
* Checks whether this is a key event that can open console.
*
* @param KeyEvent - Key event to test.
* @returns True, if this key event can open console.
*/
bool IsConsoleEvent(const FKeyEvent& KeyEvent) const;
#if WITH_EDITOR
/**
* Checks whether this is a key event that can stop PIE session.
*
* @param KeyEvent - Key event to test.
* @returns True, if this key event can stop PIE session.
*/
bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) const;
#endif
/**
* Checks whether corresponding ImGui context has an active item (holding cursor focus).
*
* @returns True, if corresponding context has an active item.
*/
bool HasImGuiActiveItem() const; bool HasImGuiActiveItem() const;
private: private:
@ -164,5 +191,9 @@ private:
int32 ContextIndex = -1; int32 ContextIndex = -1;
#if WITH_EDITOR
TSharedPtr<FUICommandInfo> StopPlaySessionCommandInfo;
#endif
friend class FImGuiInputHandlerFactory; friend class FImGuiInputHandlerFactory;
}; };