mirror of
				https://github.com/kevinporetti/UnrealImGui.git
				synced 2025-11-03 23:33:16 +00:00 
			
		
		
		
	Added ImGui Input Handler and ImGui Settings:
- Added ImGui Input Handler class that allows to customize handling of the keyboard and gamepad input. - Added ImGui Settings to allow specify custom input handler implementation. - Added editor support for ImGui Settings. - Input handling in ImGui Widget is divided for querying the handler (more customizable) and actual input processing based on the handler’s response (fixed and simplified). - Removed a need for checking console state in different input handling functions in ImGui Widget by suppressing keyboard focus support when console is opened.
This commit is contained in:
		
							parent
							
								
									6ddc7f2805
								
							
						
					
					
						commit
						5968c3ce84
					
				@ -12,6 +12,12 @@ public class ImGui : ModuleRules
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_FORWARDED_MODULE_RULES_CTOR
 | 
				
			||||||
 | 
							bool bBuildEditor = Target.bBuildEditor;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							bool bBuildEditor = (Target.Type == TargetRules.TargetType.Editor);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PublicIncludePaths.AddRange(
 | 
							PublicIncludePaths.AddRange(
 | 
				
			||||||
			new string[] {
 | 
								new string[] {
 | 
				
			||||||
				"ImGui/Public",
 | 
									"ImGui/Public",
 | 
				
			||||||
@ -53,6 +59,17 @@ public class ImGui : ModuleRules
 | 
				
			|||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (bBuildEditor)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								PrivateDependencyModuleNames.AddRange(
 | 
				
			||||||
 | 
									new string[]
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"Settings",
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DynamicallyLoadedModuleNames.AddRange(
 | 
							DynamicallyLoadedModuleNames.AddRange(
 | 
				
			||||||
			new string[]
 | 
								new string[]
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										106
									
								
								Source/ImGui/Private/Editor/ImGuiEditor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								Source/ImGui/Private/Editor/ImGuiEditor.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiPrivatePCH.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiEditor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiSettings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ISettingsModule.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LOCTEXT_NAMESPACE "ImGuiEditor"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SETTINGS_CONTAINER TEXT("Project"), TEXT("Plugins"), TEXT("ImGui")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ISettingsModule* GetSettingsModule()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return FModuleManager::GetModulePtr<ISettingsModule>("Settings");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FImGuiEditor::FImGuiEditor()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Register();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// As a side effect of being part of the ImGui module, we need to support deferred registration (only executed if
 | 
				
			||||||
 | 
						// module is loaded manually at the very early stage).
 | 
				
			||||||
 | 
						if (!IsRegistrationCompleted())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							CreateRegistrator();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FImGuiEditor::~FImGuiEditor()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Unregister();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FImGuiEditor::Register()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Only register after UImGuiSettings class is initialized (necessary to check in early loading stages).
 | 
				
			||||||
 | 
						if (!bSettingsRegistered && UImGuiSettings::StaticClass()->IsValidLowLevelFast())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (ISettingsModule* SettingsModule = GetSettingsModule())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								bSettingsRegistered = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								SettingsModule->RegisterSettings(SETTINGS_CONTAINER,
 | 
				
			||||||
 | 
									LOCTEXT("ImGuiSettingsName", "ImGui"),
 | 
				
			||||||
 | 
									LOCTEXT("ImGuiSettingsDescription", "Configure the Unreal ImGui plugin."),
 | 
				
			||||||
 | 
									GetMutableDefault<UImGuiSettings>());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FImGuiEditor::Unregister()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (bSettingsRegistered)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							bSettingsRegistered = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ISettingsModule* SettingsModule = GetSettingsModule())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SettingsModule->UnregisterSettings(SETTINGS_CONTAINER);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FImGuiEditor::CreateRegistrator()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!RegistratorHandle.IsValid())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							RegistratorHandle = FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (Reason == EModuleChangeReason::ModuleLoaded)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Register();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (IsRegistrationCompleted())
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ReleaseRegistrator();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FImGuiEditor::ReleaseRegistrator()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (RegistratorHandle.IsValid())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FModuleManager::Get().OnModulesChanged().Remove(RegistratorHandle);
 | 
				
			||||||
 | 
							RegistratorHandle.Reset();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef SETTINGS_CONTAINER
 | 
				
			||||||
 | 
					#undef LOCTEXT_NAMESPACE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WITH_EDITOR
 | 
				
			||||||
							
								
								
									
										30
									
								
								Source/ImGui/Private/Editor/ImGuiEditor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Source/ImGui/Private/Editor/ImGuiEditor.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Registers module's settings in editor (due to a small size of this code we don't use a separate editor module).
 | 
				
			||||||
 | 
					class FImGuiEditor
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FImGuiEditor();
 | 
				
			||||||
 | 
						~FImGuiEditor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool IsRegistrationCompleted() const { return bSettingsRegistered; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Register();
 | 
				
			||||||
 | 
						void Unregister();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void CreateRegistrator();
 | 
				
			||||||
 | 
						void ReleaseRegistrator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FDelegateHandle RegistratorHandle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bSettingsRegistered = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WITH_EDITOR
 | 
				
			||||||
							
								
								
									
										42
									
								
								Source/ImGui/Private/ImGuiInputHandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								Source/ImGui/Private/ImGuiInputHandler.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiPrivatePCH.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiInputHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiContextProxy.h"
 | 
				
			||||||
 | 
					#include "ImGuiModuleManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Engine/Console.h>
 | 
				
			||||||
 | 
					#include <Input/Events.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FImGuiInputResponse UImGuiInputHandler::OnKeyDown(const FKeyEvent& KeyEvent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// Ignore console open events, so we don't block it from opening.
 | 
				
			||||||
 | 
						if (KeyEvent.GetKey() == EKeys::Tilde)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return FImGuiInputResponse{ false, false };
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ignore escape event, if they are not meant for ImGui control.
 | 
				
			||||||
 | 
						if (KeyEvent.GetKey() == EKeys::Escape && !HasImGuiActiveItem())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return FImGuiInputResponse{ false, false };
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return DefaultResponse();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool UImGuiInputHandler::HasImGuiActiveItem() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex);
 | 
				
			||||||
 | 
						return ContextProxy && ContextProxy->HasActiveItem();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UImGuiInputHandler::Initialize(FImGuiModuleManager* InModuleManager, UGameViewportClient* InGameViewport, int32 InContextIndex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ModuleManager = InModuleManager;
 | 
				
			||||||
 | 
						GameViewport = InGameViewport;
 | 
				
			||||||
 | 
						ContextIndex = InContextIndex;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										55
									
								
								Source/ImGui/Private/ImGuiInputHandlerFactory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Source/ImGui/Private/ImGuiInputHandlerFactory.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiPrivatePCH.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiInputHandlerFactory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiInputHandler.h"
 | 
				
			||||||
 | 
					#include "ImGuiSettings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFINE_LOG_CATEGORY_STATIC(LogImGuiInputHandlerFactory, Warning, All);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UImGuiInputHandler* FImGuiInputHandlerFactory::NewHandler(FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UClass* HandlerClass = nullptr;
 | 
				
			||||||
 | 
						if (UImGuiSettings* Settings = GetMutableDefault<UImGuiSettings>())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							const auto& HandlerClassReference = Settings->GetImGuiInputHandlerClass();
 | 
				
			||||||
 | 
							if (HandlerClassReference.IsValid())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								HandlerClass = HandlerClassReference.TryLoadClass<UImGuiInputHandler>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!HandlerClass)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									UE_LOG(LogImGuiInputHandlerFactory, Error, TEXT("Couldn't load ImGui Input Handler class '%s'."), *HandlerClassReference.ToString());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!HandlerClass)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							HandlerClass = UImGuiInputHandler::StaticClass();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UImGuiInputHandler* Handler = NewObject<UImGuiInputHandler>(GameViewport, HandlerClass);
 | 
				
			||||||
 | 
						if (Handler)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Handler->Initialize(ModuleManager, GameViewport, ContextIndex);
 | 
				
			||||||
 | 
							Handler->AddToRoot();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							UE_LOG(LogImGuiInputHandlerFactory, Error, TEXT("Failed attempt to create Input Handler: HandlerClass = %s."), *GetNameSafe(HandlerClass));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Handler;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FImGuiInputHandlerFactory::ReleaseHandler(UImGuiInputHandler* Handler)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (Handler)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Handler->RemoveFromRoot();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								Source/ImGui/Private/ImGuiInputHandlerFactory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Source/ImGui/Private/ImGuiInputHandlerFactory.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FImGuiModuleManager;
 | 
				
			||||||
 | 
					class UGameViewportClient;
 | 
				
			||||||
 | 
					class UImGuiInputHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FImGuiInputHandlerFactory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static UImGuiInputHandler* NewHandler(FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void ReleaseHandler(UImGuiInputHandler* Handler);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -6,6 +6,10 @@
 | 
				
			|||||||
#include "Utilities/WorldContext.h"
 | 
					#include "Utilities/WorldContext.h"
 | 
				
			||||||
#include "Utilities/WorldContextIndex.h"
 | 
					#include "Utilities/WorldContextIndex.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					#include "Editor/ImGuiEditor.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <IPluginManager.h>
 | 
					#include <IPluginManager.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,6 +36,10 @@ struct EDelegateCategory
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static FImGuiModuleManager* ModuleManager = nullptr;
 | 
					static FImGuiModuleManager* ModuleManager = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					static FImGuiEditor* ModuleEditor = nullptr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if WITH_EDITOR
 | 
					#if WITH_EDITOR
 | 
				
			||||||
FImGuiDelegateHandle FImGuiModule::AddEditorImGuiDelegate(const FImGuiDelegate& Delegate)
 | 
					FImGuiDelegateHandle FImGuiModule::AddEditorImGuiDelegate(const FImGuiDelegate& Delegate)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -91,17 +99,28 @@ void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void FImGuiModule::StartupModule()
 | 
					void FImGuiModule::StartupModule()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	checkf(!ModuleManager, TEXT("Instance of Module Manager already exists. Instance should be created only during module startup."));
 | 
						// Create managers that implements module logic.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create module manager that implements modules logic.
 | 
						checkf(!ModuleManager, TEXT("Instance of the Module Manager already exists. Instance should be created only during module startup."));
 | 
				
			||||||
	ModuleManager = new FImGuiModuleManager();
 | 
						ModuleManager = new FImGuiModuleManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
						checkf(!ModuleEditor, TEXT("Instance of the Module Editor already exists. Instance should be created only during module startup."));
 | 
				
			||||||
 | 
						ModuleEditor = new FImGuiEditor();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FImGuiModule::ShutdownModule()
 | 
					void FImGuiModule::ShutdownModule()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	checkf(ModuleManager, TEXT("Null Module Manager. Manager instance should be deleted during module shutdown."));
 | 
						// Before we shutdown we need to delete managers that will do all the necessary cleanup.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Before we shutdown we need to delete manager that will do all necessary cleanup.
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
						checkf(ModuleEditor, TEXT("Null Module Editor. Module editor instance should be deleted during module shutdown."));
 | 
				
			||||||
 | 
						delete ModuleEditor;
 | 
				
			||||||
 | 
						ModuleEditor = nullptr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						checkf(ModuleManager, TEXT("Null Module Manager. Module manager instance should be deleted during module shutdown."));
 | 
				
			||||||
	delete ModuleManager;
 | 
						delete ModuleManager;
 | 
				
			||||||
	ModuleManager = nullptr;
 | 
						ModuleManager = nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										51
									
								
								Source/ImGui/Private/ImGuiSettings.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Source/ImGui/Private/ImGuiSettings.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiPrivatePCH.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiSettings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UImGuiSettings::UImGuiSettings()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
						RegisterPropertyChangedDelegate();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UImGuiSettings::~UImGuiSettings()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
						UnregisterPropertyChangedDelegate();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UImGuiSettings::RegisterPropertyChangedDelegate()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!FCoreUObjectDelegates::OnObjectPropertyChanged.IsBoundToObject(this))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FCoreUObjectDelegates::OnObjectPropertyChanged.AddUObject(this, &UImGuiSettings::OnPropertyChanged);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UImGuiSettings::UnregisterPropertyChangedDelegate()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FCoreUObjectDelegates::OnObjectPropertyChanged.RemoveAll(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void UImGuiSettings::OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (ObjectBeingModified == this)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							static const FName ImGuiInputHandlerPropertyName = GET_MEMBER_NAME_CHECKED(UImGuiSettings, ImGuiInputHandlerClass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const FName UpdatedPropertyName = PropertyChangedEvent.MemberProperty ? PropertyChangedEvent.MemberProperty->GetFName() : NAME_None;
 | 
				
			||||||
 | 
							if (UpdatedPropertyName == ImGuiInputHandlerPropertyName)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								OnImGuiInputHandlerClassChanged.Broadcast();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WITH_EDITOR
 | 
				
			||||||
							
								
								
									
										56
									
								
								Source/ImGui/Private/ImGuiSettings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Source/ImGui/Private/ImGuiSettings.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiInputHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Delegates/Delegate.h>
 | 
				
			||||||
 | 
					#include <UObject/Object.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Select right soft class reference header to avoid warning (new header contains FSoftClassPath to FStringClassReference
 | 
				
			||||||
 | 
					// typedef, so we will use that as a common denominator).
 | 
				
			||||||
 | 
					#include <Runtime/Launch/Resources/Version.h>
 | 
				
			||||||
 | 
					#if (ENGINE_MAJOR_VERSION < 4 || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 18))
 | 
				
			||||||
 | 
					#include <StringClassReference.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <UObject/SoftObjectPath.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiSettings.generated.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Settings for ImGui module.
 | 
				
			||||||
 | 
					UCLASS(config=ImGui, defaultconfig)
 | 
				
			||||||
 | 
					class UImGuiSettings : public UObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GENERATED_BODY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UImGuiSettings();
 | 
				
			||||||
 | 
						~UImGuiSettings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Path to custom implementation of ImGui Input Handler.
 | 
				
			||||||
 | 
						const FStringClassReference& GetImGuiInputHandlerClass() const { return ImGuiInputHandlerClass; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Delegate raised when ImGuiInputHandlerClass property has changed.
 | 
				
			||||||
 | 
						FSimpleMulticastDelegate OnImGuiInputHandlerClassChanged;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Path to own implementation of ImGui Input Handler allowing to customize handling of keyboard and gamepad input.
 | 
				
			||||||
 | 
						// If not set then default handler is used.
 | 
				
			||||||
 | 
						UPROPERTY(EditAnywhere, config, Category = "Input", meta = (MetaClass = "ImGuiInputHandler"))
 | 
				
			||||||
 | 
						FStringClassReference ImGuiInputHandlerClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if WITH_EDITOR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RegisterPropertyChangedDelegate();
 | 
				
			||||||
 | 
						void UnregisterPropertyChangedDelegate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WITH_EDITOR
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -7,8 +7,11 @@
 | 
				
			|||||||
#include "ImGuiContextManager.h"
 | 
					#include "ImGuiContextManager.h"
 | 
				
			||||||
#include "ImGuiContextProxy.h"
 | 
					#include "ImGuiContextProxy.h"
 | 
				
			||||||
#include "ImGuiImplementation.h"
 | 
					#include "ImGuiImplementation.h"
 | 
				
			||||||
 | 
					#include "ImGuiInputHandler.h"
 | 
				
			||||||
 | 
					#include "ImGuiInputHandlerFactory.h"
 | 
				
			||||||
#include "ImGuiInteroperability.h"
 | 
					#include "ImGuiInteroperability.h"
 | 
				
			||||||
#include "ImGuiModuleManager.h"
 | 
					#include "ImGuiModuleManager.h"
 | 
				
			||||||
 | 
					#include "ImGuiSettings.h"
 | 
				
			||||||
#include "TextureManager.h"
 | 
					#include "TextureManager.h"
 | 
				
			||||||
#include "Utilities/Arrays.h"
 | 
					#include "Utilities/Arrays.h"
 | 
				
			||||||
#include "Utilities/ScopeGuards.h"
 | 
					#include "Utilities/ScopeGuards.h"
 | 
				
			||||||
@ -106,11 +109,19 @@ void SImGuiWidget::Construct(const FArguments& InArgs)
 | 
				
			|||||||
	checkf(ContextProxy, TEXT("Missing context during widget construction: ContextIndex = %d"), ContextIndex);
 | 
						checkf(ContextProxy, TEXT("Missing context during widget construction: ContextIndex = %d"), ContextIndex);
 | 
				
			||||||
	ContextProxy->OnDraw().AddRaw(this, &SImGuiWidget::OnDebugDraw);
 | 
						ContextProxy->OnDraw().AddRaw(this, &SImGuiWidget::OnDebugDraw);
 | 
				
			||||||
	ContextProxy->SetInputState(&InputState);
 | 
						ContextProxy->SetInputState(&InputState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create ImGui Input Handler.
 | 
				
			||||||
 | 
						CreateInputHandler();
 | 
				
			||||||
 | 
						RegisterInputHandlerChangedDelegate();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
 | 
					END_SLATE_FUNCTION_BUILD_OPTIMIZATION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SImGuiWidget::~SImGuiWidget()
 | 
					SImGuiWidget::~SImGuiWidget()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						// Release ImGui Input Handler.
 | 
				
			||||||
 | 
						UnregisterInputHandlerChangedDelegate();
 | 
				
			||||||
 | 
						ReleaseInputHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Remove binding between this widget and its context proxy.
 | 
						// Remove binding between this widget and its context proxy.
 | 
				
			||||||
	if (auto* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex))
 | 
						if (auto* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -142,16 +153,23 @@ void SImGuiWidget::Tick(const FGeometry& AllottedGeometry, const double InCurren
 | 
				
			|||||||
	UpdateInputEnabled();
 | 
						UpdateInputEnabled();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (IsConsoleOpened())
 | 
						FReply ToSlateReply(const FImGuiInputResponse& HandlingResponse)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return FReply::Unhandled();
 | 
							return HandlingResponse.HasConsumeRequest() ? FReply::Handled() : FReply::Unhandled();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FReply SImGuiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const FImGuiInputResponse Response = InputHandler->OnKeyChar(CharacterEvent);
 | 
				
			||||||
 | 
						if (Response.HasProcessingRequest())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		InputState.AddCharacter(CharacterEvent.GetCharacter());
 | 
							InputState.AddCharacter(CharacterEvent.GetCharacter());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return FReply::Handled();
 | 
						return ToSlateReply(Response);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
 | 
					FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
 | 
				
			||||||
@ -159,10 +177,14 @@ FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& Key
 | 
				
			|||||||
	if (KeyEvent.GetKey().IsGamepadKey())
 | 
						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 FReply::Handled();
 | 
								return ToSlateReply(Response);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -171,17 +193,16 @@ FReply SImGuiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& Key
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (IsConsoleOpened() || IgnoreKeyEvent(KeyEvent))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return FReply::Unhandled();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		InputState.SetKeyDown(KeyEvent, true);
 | 
					 | 
				
			||||||
		CopyModifierKeys(KeyEvent);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		UpdateCanvasMapMode(KeyEvent);
 | 
							UpdateCanvasMapMode(KeyEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return WithMouseLockRequests(FReply::Handled());
 | 
							const FImGuiInputResponse Response = InputHandler->OnKeyDown(KeyEvent);
 | 
				
			||||||
 | 
							if (Response.HasProcessingRequest())
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								InputState.SetKeyDown(KeyEvent, true);
 | 
				
			||||||
 | 
								CopyModifierKeys(KeyEvent);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return WithMouseLockRequests(ToSlateReply(Response));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -191,9 +212,10 @@ FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEv
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		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 FReply::Handled();
 | 
								return ToSlateReply(InputHandler->OnGamepadKeyUp(KeyEvent));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@ -202,25 +224,27 @@ FReply SImGuiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEv
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Even if we don't send new keystrokes to ImGui, we still handle key up events, to make sure that we clear keys
 | 
							UpdateCanvasMapMode(KeyEvent);
 | 
				
			||||||
		// pressed before suppressing keyboard input.
 | 
					
 | 
				
			||||||
 | 
							// 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);
 | 
							CopyModifierKeys(KeyEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		UpdateCanvasMapMode(KeyEvent);
 | 
							return WithMouseLockRequests(ToSlateReply(InputHandler->OnKeyUp(KeyEvent)));
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// If console is opened we notify key change but we also let event trough, so it can be handled by console.
 | 
					 | 
				
			||||||
		return IsConsoleOpened() ? FReply::Unhandled() : WithMouseLockRequests(FReply::Handled());
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FReply SImGuiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent)
 | 
					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 FReply::Handled();
 | 
							return ToSlateReply(Response);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -275,24 +299,6 @@ FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEve
 | 
				
			|||||||
	return FReply::Handled();
 | 
						return FReply::Handled();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FCursorReply SImGuiWidget::OnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	EMouseCursor::Type MouseCursor = EMouseCursor::None;
 | 
					 | 
				
			||||||
	if (MouseCursorOverride != EMouseCursor::None)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		MouseCursor = MouseCursorOverride;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (CVars::DrawMouseCursor.GetValueOnGameThread() <= 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			MouseCursor = ContextProxy->GetMouseCursor();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return FCursorReply::Cursor(MouseCursor);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
 | 
					FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (bCanvasMapMode)
 | 
						if (bCanvasMapMode)
 | 
				
			||||||
@ -365,6 +371,66 @@ void SImGuiWidget::OnMouseLeave(const FPointerEvent& MouseEvent)
 | 
				
			|||||||
	UpdateInputMode(HasKeyboardFocus() && GameViewport->Viewport->IsForegroundWindow(), false);
 | 
						UpdateInputMode(HasKeyboardFocus() && GameViewport->Viewport->IsForegroundWindow(), false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FCursorReply SImGuiWidget::OnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						EMouseCursor::Type MouseCursor = EMouseCursor::None;
 | 
				
			||||||
 | 
						if (MouseCursorOverride != EMouseCursor::None)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							MouseCursor = MouseCursorOverride;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (CVars::DrawMouseCursor.GetValueOnGameThread() <= 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								MouseCursor = ContextProxy->GetMouseCursor();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return FCursorReply::Cursor(MouseCursor);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SImGuiWidget::CreateInputHandler()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!InputHandler.IsValid())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							InputHandler = FImGuiInputHandlerFactory::NewHandler(ModuleManager, GameViewport.Get(), ContextIndex);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SImGuiWidget::ReleaseInputHandler()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (InputHandler.IsValid())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							FImGuiInputHandlerFactory::ReleaseHandler(InputHandler.Get());
 | 
				
			||||||
 | 
							InputHandler.Reset();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SImGuiWidget::RecreateInputHandler()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ReleaseInputHandler();
 | 
				
			||||||
 | 
						CreateInputHandler();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SImGuiWidget::RegisterInputHandlerChangedDelegate()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (UImGuiSettings* Settings = GetMutableDefault<UImGuiSettings>())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (!Settings->OnImGuiInputHandlerClassChanged.IsBoundToObject(this))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Settings->OnImGuiInputHandlerClassChanged.AddRaw(this, &SImGuiWidget::RecreateInputHandler);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SImGuiWidget::UnregisterInputHandlerChangedDelegate()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (UImGuiSettings* Settings = GetMutableDefault<UImGuiSettings>())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Settings->OnImGuiInputHandlerClassChanged.RemoveAll(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FReply SImGuiWidget::WithMouseLockRequests(FReply&& Reply)
 | 
					FReply SImGuiWidget::WithMouseLockRequests(FReply&& Reply)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const bool bNeedMouseLock = bCanvasDragging || bFrameDragging;
 | 
						const bool bNeedMouseLock = bCanvasDragging || bFrameDragging;
 | 
				
			||||||
@ -404,27 +470,6 @@ bool SImGuiWidget::IsConsoleOpened() const
 | 
				
			|||||||
	return GameViewport->ViewportConsole && GameViewport->ViewportConsole->ConsoleState != NAME_None;
 | 
						return GameViewport->ViewportConsole && GameViewport->ViewportConsole->ConsoleState != NAME_None;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SImGuiWidget::IgnoreKeyEvent(const FKeyEvent& KeyEvent) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	// Ignore console open/close events.
 | 
					 | 
				
			||||||
	if (KeyEvent.GetKey() == EKeys::Tilde)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Ignore escape keys unless they are needed to cancel operations in ImGui.
 | 
					 | 
				
			||||||
	if (KeyEvent.GetKey() == EKeys::Escape)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		auto* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex);
 | 
					 | 
				
			||||||
		if (!ContextProxy || !ContextProxy->HasActiveItem())
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void SImGuiWidget::SetMouseCursorOverride(EMouseCursor::Type InMouseCursorOverride)
 | 
					void SImGuiWidget::SetMouseCursorOverride(EMouseCursor::Type InMouseCursorOverride)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (MouseCursorOverride != InMouseCursorOverride)
 | 
						if (MouseCursorOverride != InMouseCursorOverride)
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FImGuiModuleManager;
 | 
					class FImGuiModuleManager;
 | 
				
			||||||
 | 
					class UImGuiInputHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Slate widget for rendering ImGui output and storing Slate inputs.
 | 
					// Slate widget for rendering ImGui output and storing Slate inputs.
 | 
				
			||||||
class SImGuiWidget : public SLeafWidget
 | 
					class SImGuiWidget : public SLeafWidget
 | 
				
			||||||
@ -45,7 +46,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
 | 
						virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual bool SupportsKeyboardFocus() const override { return bInputEnabled; }
 | 
						virtual bool SupportsKeyboardFocus() const override { return bInputEnabled && !IsConsoleOpened(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
 | 
						virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -63,8 +64,6 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
 | 
						virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual FCursorReply OnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) const override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
 | 
						virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
 | 
						virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
 | 
				
			||||||
@ -75,6 +74,8 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
 | 
						virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual FCursorReply OnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum class EInputMode : uint8
 | 
						enum class EInputMode : uint8
 | 
				
			||||||
@ -86,6 +87,13 @@ private:
 | 
				
			|||||||
		Full
 | 
							Full
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void CreateInputHandler();
 | 
				
			||||||
 | 
						void ReleaseInputHandler();
 | 
				
			||||||
 | 
						void RecreateInputHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RegisterInputHandlerChangedDelegate();
 | 
				
			||||||
 | 
						void UnregisterInputHandlerChangedDelegate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If needed, add to event reply a mouse lock or unlock request.
 | 
						// If needed, add to event reply a mouse lock or unlock request.
 | 
				
			||||||
	FORCEINLINE FReply WithMouseLockRequests(FReply&& Reply);
 | 
						FORCEINLINE FReply WithMouseLockRequests(FReply&& Reply);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -94,8 +102,6 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool IsConsoleOpened() const;
 | 
						bool IsConsoleOpened() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool IgnoreKeyEvent(const FKeyEvent& KeyEvent) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void SetMouseCursorOverride(EMouseCursor::Type InMouseCursorOverride);
 | 
						void SetMouseCursorOverride(EMouseCursor::Type InMouseCursorOverride);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update visibility based on input enabled state.
 | 
						// Update visibility based on input enabled state.
 | 
				
			||||||
@ -147,6 +153,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	FImGuiModuleManager* ModuleManager = nullptr;
 | 
						FImGuiModuleManager* ModuleManager = nullptr;
 | 
				
			||||||
	TWeakObjectPtr<UGameViewportClient> GameViewport;
 | 
						TWeakObjectPtr<UGameViewportClient> GameViewport;
 | 
				
			||||||
 | 
						TWeakObjectPtr<UImGuiInputHandler> InputHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutable TArray<FSlateVertex> VertexBuffer;
 | 
						mutable TArray<FSlateVertex> VertexBuffer;
 | 
				
			||||||
	mutable TArray<SlateIndex> IndexBuffer;
 | 
						mutable TArray<SlateIndex> IndexBuffer;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										168
									
								
								Source/ImGui/Public/ImGuiInputHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								Source/ImGui/Public/ImGuiInputHandler.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <CoreMinimal.h>
 | 
				
			||||||
 | 
					#include <UObject/Object.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ImGuiInputHandler.generated.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class FImGuiModuleManager;
 | 
				
			||||||
 | 
					class UGameViewportClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct FAnalogInputEvent;
 | 
				
			||||||
 | 
					struct FCharacterEvent;
 | 
				
			||||||
 | 
					struct FKeyEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Response used by ImGui Input Handler to communicate input handling requests. */
 | 
				
			||||||
 | 
					struct IMGUI_API FImGuiInputResponse
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/** Create empty response with no requests. */
 | 
				
			||||||
 | 
						FImGuiInputResponse() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Create response with custom request configuration.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param bInProcess - State of the processing request.
 | 
				
			||||||
 | 
						 * @param bInConsume - State of the consume request.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						FImGuiInputResponse(bool bInProcess, bool bInConsume)
 | 
				
			||||||
 | 
							: bProcess(bInProcess)
 | 
				
			||||||
 | 
							, bConsume(bInConsume)
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Check whether this response contains processing request.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns True, if processing was requested and false otherwise.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						FORCEINLINE bool HasProcessingRequest() const { return bProcess; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Check whether this response contains consume request.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns True, if consume was requested and false otherwise.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						FORCEINLINE bool HasConsumeRequest() const { return bConsume; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Set the processing request.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param bInProcess - True, to request input processing (implicit) and false otherwise.
 | 
				
			||||||
 | 
						 * @returns Reference to this response (for chaining requests).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						FORCEINLINE FImGuiInputResponse& RequestProcessing(bool bInProcess = true) { bProcess = bInProcess; return *this; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Set the consume request.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param bInConsume - True, to request input consume (implicit) and false otherwise.
 | 
				
			||||||
 | 
						 * @returns Reference to this response (for chaining requests).
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						FORCEINLINE FImGuiInputResponse& RequestConsume(bool bInConsume = true) { bConsume = bInConsume; return *this; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bProcess = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool bConsume = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Defines behaviour when handling input events. It allows to customize handling of the keyboard and gamepad input,
 | 
				
			||||||
 | 
					 * primarily to support shortcuts in ImGui input mode. Since mouse is not really needed for this functionality and
 | 
				
			||||||
 | 
					 * mouse pointer state and focus are closely connected to input mode, mouse events are left out of this interface.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When receiving keyboard and gamepad events ImGui Widget calls input handler to query expected behaviour. By default,
 | 
				
			||||||
 | 
					 * with a few exceptions (see @ OnKeyDown) all events are expected to be processed and consumed. Custom implementations
 | 
				
			||||||
 | 
					 * may tweak that behaviour and/or inject custom code.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Note that returned response is only treated as a hint. In current implementation all consume requests are respected
 | 
				
			||||||
 | 
					 * but to protect from locking ImGui input states, key up events are always processed. Decision about blocking certain
 | 
				
			||||||
 | 
					 * inputs can be taken during key down events and processing corresponding key up events should not make difference.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Also note that input handler functions are only called when ImGui Widget is receiving input events, what can be for
 | 
				
			||||||
 | 
					 * instance suppressed by opening console.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See @ Project Settings/Plugins/ImGui/Input/ImGuiInputHandlerClass property to set custom implementation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					UCLASS()
 | 
				
			||||||
 | 
					class IMGUI_API UImGuiInputHandler : public UObject
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GENERATED_BODY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling character events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to process
 | 
				
			||||||
 | 
						 * and consume this event.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnKeyChar(const struct FCharacterEvent& CharacterEvent) { return DefaultResponse(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling keyboard key down events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to process
 | 
				
			||||||
 | 
						 * and consume most of the key, but unlike other cases it requests to ignore certain events, like those that are
 | 
				
			||||||
 | 
						 * needed to open console or close PIE session in editor.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnKeyDown(const FKeyEvent& KeyEvent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling keyboard key up events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Note that regardless of returned response, key up events are always processed by ImGui Widget.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to consume
 | 
				
			||||||
 | 
						 * this event.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnKeyUp(const FKeyEvent& KeyEvent) { return DefaultResponse(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling gamepad key down events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to process
 | 
				
			||||||
 | 
						 * and consume this event.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnGamepadKeyDown(const FKeyEvent& GamepadKeyEvent) { return DefaultResponse(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling gamepad key up events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * Note that regardless of returned response, key up events are always processed by ImGui Widget.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to consume
 | 
				
			||||||
 | 
						 * this event.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnGamepadKeyUp(const FKeyEvent& GamepadKeyEvent) { return DefaultResponse(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Called when handling gamepad analog events.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @returns Response with rules how input should be handled. Default implementation contains requests to process
 | 
				
			||||||
 | 
						 * and consume this event.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						virtual FImGuiInputResponse OnGamepadAxis(const FAnalogInputEvent& GamepadAxisEvent) { return DefaultResponse(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Checks whether corresponding ImGui context has an active item. */
 | 
				
			||||||
 | 
						bool HasImGuiActiveItem() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Initialize(FImGuiModuleManager* InModuleManager, UGameViewportClient* InGameViewport, int32 InContextIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FORCEINLINE FImGuiInputResponse DefaultResponse() { return FImGuiInputResponse{ true, true }; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						FImGuiModuleManager* ModuleManager = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TWeakObjectPtr<UGameViewportClient> GameViewport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32 ContextIndex = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						friend class FImGuiInputHandlerFactory;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user