From 1b5d63b0af4f0a938789bcb2ee41abe0800587f0 Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Thu, 19 Oct 2023 17:28:42 -0400 Subject: [PATCH] Rework how ImGui input toggle is triggered Add a new window CommandBindings to configure the shortcuts of console commands The first time it is created, this window add the bindings to control cog: [Tab] Cog.ToggleInput [F1] Cog.LoadLayout 1 [F2] Cog.LoadLayout 2 [F3] Cog.LoadLayout 3 [F4] Cog.LoadLayout 4 [F5] Cog.ToggleSelectionMode The selection window can now uses the Actor Label instead of Name (simpler to read) Fix Blackboard sorting --- .../Cog/Source/CogEngine/CogEngine.Build.cs | 21 +- .../CogEngineWindow_CommandBindings.cpp | 172 ++++++++++++++++ .../Private/CogEngineWindow_Selection.cpp | 63 ++++-- .../Public/CogEngineWindow_CommandBindings.h | 37 ++++ .../Public/CogEngineWindow_Selection.h | 27 ++- .../CogImgui/Private/CogImguiInputHelper.cpp | 150 ++++++++++++-- .../CogImgui/Private/CogImguiWidget.cpp | 38 ++-- .../CogImgui/Public/CogImguiInputHelper.h | 13 +- .../Source/CogImgui/Public/CogImguiModule.h | 5 - .../CogWindow/Private/CogWindowManager.cpp | 31 ++- .../CogWindow/Private/CogWindowWidgets.cpp | 194 +++++++++++++++++- .../CogWindow/Private/CogWindow_Settings.cpp | 52 ----- .../CogWindow/Public/CogWindowManager.h | 9 +- .../CogWindow/Public/CogWindowWidgets.h | 13 ++ .../CogWindow/Public/CogWindow_Settings.h | 3 +- .../CogAI/Private/CogAIWindow_Blackboard.cpp | 2 +- Source/CogSample/CogSampleGameState.cpp | 34 +-- Source/CogSample/CogSampleGameState.h | 6 +- 18 files changed, 705 insertions(+), 165 deletions(-) create mode 100644 Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp create mode 100644 Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CommandBindings.h diff --git a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs index 4a66a02..9109015 100644 --- a/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs +++ b/Plugins/Cog/Source/CogEngine/CogEngine.Build.cs @@ -7,13 +7,15 @@ public class CogEngine : ModuleRules PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; PublicIncludePaths.AddRange( - new string[] { + new string[] + { } ); PrivateIncludePaths.AddRange( - new string[] { + new string[] + { } ); @@ -21,11 +23,6 @@ public class CogEngine : ModuleRules PublicDependencyModuleNames.AddRange( new string[] { - "Core", - "CogCommon", - "CogImgui", - "CogDebug", - "CogWindow", } ); @@ -33,11 +30,17 @@ public class CogEngine : ModuleRules PrivateDependencyModuleNames.AddRange( new string[] { - "CoreUObject", + "CogCommon", + "CogDebug", + "CogImgui", + "CogWindow", + "Core", + "CoreUObject", "Engine", + "InputCore", + "NetCore", "Slate", "SlateCore", - "NetCore", } ); diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp new file mode 100644 index 0000000..0abf2d3 --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp @@ -0,0 +1,172 @@ +#include "CogEngineWindow_CommandBindings.h" + +#include "CogWindowWidgets.h" +#include "GameFramework/PlayerInput.h" +#include "imgui.h" + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_CommandBindings::RenderHelp() +{ + ImGui::Text( + "This window can be used to configure the command bindings. " + "Bindings are used to trigger console commands from a keyboard shortcuts. " + ); +} + +//-------------------------------------------------------------------------------------------------------------------------- +UCogEngineWindow_CommandBindings::UCogEngineWindow_CommandBindings() +{ +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_CommandBindings::PostInitProperties() +{ + Super::PostInitProperties(); + + if (bRegisterDefaultCommands) + { + if (RegisterDefaultCommands()) + { + bRegisterDefaultCommands = false; + } + } +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_CommandBindings::RenderContent() +{ + Super::RenderContent(); + + APlayerController* PlayerController = GetLocalPlayerController(); + if (PlayerController == nullptr) + { + return; + } + + UPlayerInput* PlayerInput = PlayerController->PlayerInput; + if (PlayerInput == nullptr) + { + return; + } + + int32 Index = 0; + int32 IndexToRemove = INDEX_NONE; + + if (FCogWindowWidgets::ButtonWithTooltip("Add", "Add a new item in the array")) + { + PlayerInput->DebugExecBindings.AddDefaulted(); + PlayerInput->SaveConfig(); + } + + ImGui::SameLine(); + if (FCogWindowWidgets::ButtonWithTooltip("Sort", "Sort the array")) + { + Sort(PlayerInput); + PlayerInput->SaveConfig(); + } + + ImGui::SameLine(); + if (FCogWindowWidgets::ButtonWithTooltip( + "Register Default Commands", + "Register the default commands used to control Cog:\n\n" + "[Tab] Cog.ToggleInput\n" + "[F1] Cog.LoadLayout 1\n" + "[F2] Cog.LoadLayout 2\n" + "[F3] Cog.LoadLayout 3\n" + "[F4] Cog.LoadLayout 4\n" + "[F5] Cog.ToggleSelectionMode\n" + )) + { + RegisterDefaultCommands(); + } + + for (FKeyBind& KeyBind : PlayerInput->DebugExecBindings) + { + ImGui::PushID(Index); + + if (FCogWindowWidgets::KeyBind(KeyBind)) + { + PlayerInput->SaveConfig(); + } + + ImGui::SameLine(); + if (FCogWindowWidgets::DeleteArrayItemButton()) + { + IndexToRemove = Index; + } + + ImGui::PopID(); + Index++; + } + + if (IndexToRemove != INDEX_NONE) + { + PlayerInput->DebugExecBindings.RemoveAt(IndexToRemove); + PlayerInput->SaveConfig(); + } +} + + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_CommandBindings::Sort(UPlayerInput* PlayerInput) +{ + PlayerInput->DebugExecBindings.Sort([](const FKeyBind& Key1, const FKeyBind& Key2) + { + return Key1.Command.Compare(Key2.Command) < 0; + }); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool UCogEngineWindow_CommandBindings::RegisterDefaultCommands() +{ + APlayerController* PlayerController = GetLocalPlayerController(); + if (PlayerController == nullptr) + { + return false; + } + + UPlayerInput* PlayerInput = PlayerController->PlayerInput; + if (PlayerInput == nullptr) + { + return false; + } + + AddCogCommand(PlayerInput, "Cog.ToggleInput", EKeys::Tab); + AddCogCommand(PlayerInput, "Cog.LoadLayout 1", EKeys::F1); + AddCogCommand(PlayerInput, "Cog.LoadLayout 2", EKeys::F2); + AddCogCommand(PlayerInput, "Cog.LoadLayout 3", EKeys::F3); + AddCogCommand(PlayerInput, "Cog.LoadLayout 4", EKeys::F4); + AddCogCommand(PlayerInput, "Cog.ToggleSelectionMode", EKeys::F5); + + Sort(PlayerInput); + PlayerInput->SaveConfig(); + + return true; +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogEngineWindow_CommandBindings::AddCogCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key) +{ + for (FKeyBind& KeyBind : PlayerInput->DebugExecBindings) + { + if (KeyBind.Key == Key && KeyBind.Command != Command) + { + KeyBind.Control = true; + KeyBind.bIgnoreCtrl = false; + } + } + + FKeyBind* ExistingKeyBind = PlayerInput->DebugExecBindings.FindByPredicate([Command](const FKeyBind& KeyBind){ return KeyBind.Command == Command; }); + if (ExistingKeyBind == nullptr) + { + ExistingKeyBind = &PlayerInput->DebugExecBindings.AddDefaulted_GetRef(); + } + + FKeyBind CogKeyBind; + CogKeyBind.Command = Command; + CogKeyBind.Control = false; + CogKeyBind.bIgnoreCtrl = true; + CogKeyBind.Key = Key; + + *ExistingKeyBind = CogKeyBind; +} \ No newline at end of file diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp index 91c9de8..0f2dc6f 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp @@ -1,12 +1,14 @@ #include "CogEngineWindow_Selection.h" #include "CogDebugDraw.h" +#include "CogDebugSettings.h" #include "CogEngineReplicator.h" #include "CogImguiModule.h" #include "CogWindowManager.h" #include "CogWindowWidgets.h" #include "EngineUtils.h" #include "GameFramework/Character.h" +#include "HAL/IConsoleManager.h" #include "imgui.h" #include "Kismet/GameplayStatics.h" @@ -26,14 +28,24 @@ UCogEngineWindow_Selection::UCogEngineWindow_Selection() { bHasMenu = true; ActorClasses = { AActor::StaticClass(), ACharacter::StaticClass() }; -} + ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand( + TEXT("Cog.ToggleSelectionMode"), + TEXT("Toggle the actor selection mode"), + FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray& Args) { ToggleSelectionMode(); }), + ECVF_Cheat)); +} //-------------------------------------------------------------------------------------------------------------------------- void UCogEngineWindow_Selection::ResetConfig() { Super::ResetConfig(); + for (IConsoleObject* ConsoleCommand : ConsoleCommands) + { + IConsoleManager::Get().UnregisterConsoleObject(ConsoleCommand); + } + SelectedClassIndex = 0; SelectionName = FString(); bReapplySelection = true; @@ -169,7 +181,7 @@ void UCogEngineWindow_Selection::RenderTick(float DeltaTime) { if (Actor != GetLocalPlayerPawn()) { - DrawActorFrame(Actor); + DrawActorFrame(*Actor); } } } @@ -250,8 +262,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo() ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255)); bool bIsSelected = Actor == FCogDebugSettings::GetSelection(); - const FString ActorName = GetNameSafe(Actor); - if (ImGui::Selectable(TCHAR_TO_ANSI(*ActorName), bIsSelected)) + if (ImGui::Selectable(TCHAR_TO_ANSI(*GetActorName(*Actor)), bIsSelected)) { SetGlobalSelection(Actor); SelectionChanged = true; @@ -266,7 +277,7 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo() //------------------------ if (ImGui::IsItemHovered()) { - DrawActorFrame(Actor); + DrawActorFrame(*Actor); } if (bIsSelected) @@ -281,6 +292,31 @@ bool UCogEngineWindow_Selection::DrawSelectionCombo() return SelectionChanged; } +//-------------------------------------------------------------------------------------------------------------------------- +FString UCogEngineWindow_Selection::GetActorName(const AActor* Actor) const +{ + if (Actor == nullptr) + { + return FString("none"); + } + + return GetActorName(*Actor); +} + +//-------------------------------------------------------------------------------------------------------------------------- +FString UCogEngineWindow_Selection::GetActorName(const AActor& Actor) const +{ +#if WITH_EDITOR + + return bDisplayActorLabel ? Actor.GetActorLabel() : Actor.GetName(); + +#else //WITH_EDITOR + + return Actor.GetName(); + +#endif //WITH_EDITOR +} + //-------------------------------------------------------------------------------------------------------------------------- void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor) { @@ -333,6 +369,7 @@ void UCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor) ImGui::Separator(); ImGui::Checkbox("Save selection", &bReapplySelection); + ImGui::Checkbox("Display Actor Label", &bDisplayActorLabel); ImGui::EndPopup(); } @@ -387,7 +424,7 @@ void UCogEngineWindow_Selection::TickSelectionMode() if (HoveredActor != nullptr) { - DrawActorFrame(HoveredActor); + DrawActorFrame(*HoveredActor); } if (bSelectionModeActive) @@ -412,7 +449,7 @@ void UCogEngineWindow_Selection::TickSelectionMode() } //-------------------------------------------------------------------------------------------------------------------------- -void UCogEngineWindow_Selection::DrawActorFrame(const AActor* Actor) +void UCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor) { APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); if (PlayerController == nullptr) @@ -427,14 +464,14 @@ void UCogEngineWindow_Selection::DrawActorFrame(const AActor* Actor) bool PrimitiveFound = false; FBox Bounds(ForceInit); - if (const UPrimitiveComponent* PrimitiveComponent = Cast(Actor->GetRootComponent())) + if (const UPrimitiveComponent* PrimitiveComponent = Cast(Actor.GetRootComponent())) { PrimitiveFound = true; Bounds += PrimitiveComponent->Bounds.GetBox(); } else { - Actor->ForEachComponent(true, [&](const UPrimitiveComponent* InPrimComp) + Actor.ForEachComponent(true, [&](const UPrimitiveComponent* InPrimComp) { if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled()) { @@ -450,16 +487,16 @@ void UCogEngineWindow_Selection::DrawActorFrame(const AActor* Actor) } else { - BoxOrigin = Actor->GetActorLocation(); + BoxOrigin = Actor.GetActorLocation(); BoxExtent = FVector(50.f, 50.f, 50.f); } FVector2D ScreenPosMin, ScreenPosMax; if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax)) { - const ImU32 Color = (Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128); + const ImU32 Color = (&Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128); DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin), FCogImguiHelper::ToImVec2(ScreenPosMax), Color, 0.0f, 0, 1.0f); - FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)), Color, TCHAR_TO_ANSI(*Actor->GetName())); + FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)), Color, TCHAR_TO_ANSI(*GetActorName(Actor))); } } @@ -563,7 +600,7 @@ void UCogEngineWindow_Selection::RenderMainMenuWidget(bool Draw, float& Width) ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); ImGui::SameLine(); - FString CurrentSelectionName = GetNameSafe(GlobalSelection); + FString CurrentSelectionName = GetActorName(GlobalSelection); if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(SelectionButtonWidth, 0))) { diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CommandBindings.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CommandBindings.h new file mode 100644 index 0000000..0102def --- /dev/null +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_CommandBindings.h @@ -0,0 +1,37 @@ +#pragma once + +#include "CoreMinimal.h" +#include "CogWindow.h" +#include "CogEngineWindow_CommandBindings.generated.h" + +class UPlayerInput; +struct FKeyBind; + +UCLASS(Config = Cog) +class COGENGINE_API UCogEngineWindow_CommandBindings : public UCogWindow +{ + GENERATED_BODY() + +public: + + UCogEngineWindow_CommandBindings(); + +protected: + + virtual void PostInitProperties() override; + + virtual void RenderHelp() override; + + virtual void RenderContent() override; + + virtual bool RegisterDefaultCommands(); + +private: + + UPROPERTY(Config) + bool bRegisterDefaultCommands = true; + + void Sort(UPlayerInput* PlayerInput); + + void AddCogCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key); +}; diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h index 01facad..d5de7c5 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h @@ -5,6 +5,8 @@ #include "CogWindow.h" #include "CogEngineWindow_Selection.generated.h" +class IConsoleObject; + UCLASS(Config = Cog) class COGENGINE_API UCogEngineWindow_Selection : public UCogWindow { @@ -24,10 +26,16 @@ public: void SetTraceType(ETraceTypeQuery Value) { TraceType = Value; } - void TryReapplySelection() const; + virtual void ActivateSelectionMode(); + + virtual void DeactivateSelectionMode(); + + virtual void ToggleSelectionMode(); protected: + virtual void TryReapplySelection() const; + virtual void ResetConfig() override; virtual void PreSaveConfig() override; @@ -46,8 +54,6 @@ protected: virtual void DrawActorContextMenu(AActor* Actor); - virtual void ActivateSelectionMode(); - virtual void HackWaitInputRelease(); virtual void SetGlobalSelection(AActor* Value) const; @@ -58,19 +64,22 @@ private: TSubclassOf GetSelectedActorClass() const; + FString GetActorName(const AActor* Actor) const; + + FString GetActorName(const AActor& Actor) const; + void TickSelectionMode(); - void ToggleSelectionMode(); - - void DeactivateSelectionMode(); - - void DrawActorFrame(const AActor* Actor); + void DrawActorFrame(const AActor& Actor); bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max); UPROPERTY(Config) bool bReapplySelection = true; + UPROPERTY(Config) + bool bDisplayActorLabel = true; + UPROPERTY(Config) FString SelectionName; @@ -88,4 +97,6 @@ private: TArray> ActorClasses; ETraceTypeQuery TraceType = TraceTypeQuery1; + + TArray ConsoleCommands; }; diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp index be8440c..28066db 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp @@ -31,29 +31,59 @@ APlayerController* FCogImguiInputHelper::GetFirstLocalPlayerController(UWorld& W } //-------------------------------------------------------------------------------------------------------------------------- -bool FCogImguiInputHelper::IsKeyEventHandled(const FKeyEvent& KeyEvent) +bool FCogImguiInputHelper::IsKeyEventHandled(UWorld* World, const FKeyEvent& KeyEvent) { + //------------------------------------------------------------------------------------------------ + // Do not handle the input if imgui input is disabled + //------------------------------------------------------------------------------------------------ if (FCogImguiModule::Get().GetEnableInput() == false) { return false; } + //------------------------------------------------------------------------------------------------ + // We want the user to control the character with its gamepad even when imgui has the input. + //------------------------------------------------------------------------------------------------ if (KeyEvent.GetKey().IsGamepadKey()) { return false; } + //------------------------------------------------------------------------------------------------ + // We want the user to be able to open the console command when imgui has the input. + //------------------------------------------------------------------------------------------------ if (IsConsoleEvent(KeyEvent)) { return false; } + //------------------------------------------------------------------------------------------------ + // We want the user to be able to stop its session by pressing Esc, even when imgui has the input + //------------------------------------------------------------------------------------------------ if (IsStopPlaySessionEvent(KeyEvent)) { return false; } - if (IsImGuiToggleInputEvent(KeyEvent)) + //------------------------------------------------------------------------------------------------ + // If we receive a key modifier, we want to let others systems know about it. + // Otherwise, the console command bindings that are bound to something like CTRL+Key + // won't work, even if we let the KeyEvent pass with 'IsKeyBoundToCommand' below. + // It seems the command binings system needs to know about the modifier key press event itself, + // and not the Key+Modifier event. + // We update ImGui modifier keys in SCogImguiWidget::TickKeyModifiers(). + //------------------------------------------------------------------------------------------------ + if (KeyEvent.GetKey().IsModifierKey()) + { + return false; + } + + //------------------------------------------------------------------------------------------------ + // We want the user to be able to use command bingings, even when imgui has the input. + // We actually use a console command to toggle the input from the game to imgui, and other + // windows command such as LoadLayout. + //------------------------------------------------------------------------------------------------ + if (IsKeyBoundToCommand(World, KeyEvent)) { return false; } @@ -80,6 +110,73 @@ bool FCogImguiInputHelper::IsKeyEventMatchingKeyInfo(const FKeyEvent& KeyEvent, return Result; } +//-------------------------------------------------------------------------------------------------------------------------- +#define BREAK_CHECKBOX_STATE(CheckBoxState, RequireValue, IgnoreValue) \ +{ \ + if (CheckBoxState == ECheckBoxState::Checked) \ + { \ + RequireValue = true; \ + IgnoreValue = false; \ + } \ + else if (CheckBoxState == ECheckBoxState::Unchecked) \ + { \ + RequireValue = false; \ + IgnoreValue = true; \ + } \ + else if (CheckBoxState == ECheckBoxState::Undetermined) \ + { \ + RequireValue = false; \ + IgnoreValue = false; \ + } \ +} \ + + +//-------------------------------------------------------------------------------------------------------------------------- +ECheckBoxState FCogImguiInputHelper::MakeCheckBoxState(uint8 RequireValue, uint8 IgnoreValue) +{ + if (RequireValue) + { + return ECheckBoxState::Checked; + } + + if (IgnoreValue) + { + return ECheckBoxState::Unchecked; + } + + return ECheckBoxState::Undetermined; +} + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogImguiInputHelper::KeyBindToKeyInfo(const FKeyBind& KeyBind, FCogImGuiKeyInfo& KeyInfo) +{ + KeyInfo.Key = KeyBind.Key; + KeyInfo.Shift = MakeCheckBoxState(KeyBind.Shift, KeyBind.bIgnoreShift); + KeyInfo.Ctrl = MakeCheckBoxState(KeyBind.Control, KeyBind.bIgnoreCtrl); + KeyInfo.Alt = MakeCheckBoxState(KeyBind.Alt, KeyBind.bIgnoreAlt); + KeyInfo.Alt = MakeCheckBoxState(KeyBind.Cmd, KeyBind.bIgnoreCmd); +} + + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogImguiInputHelper::KeyInfoToKeyBind(const FCogImGuiKeyInfo& KeyInfo, FKeyBind& KeyBind) +{ + KeyBind.Key = KeyInfo.Key; + BREAK_CHECKBOX_STATE(KeyInfo.Shift, KeyBind.Shift, KeyBind.bIgnoreShift); + BREAK_CHECKBOX_STATE(KeyInfo.Ctrl, KeyBind.Control, KeyBind.bIgnoreCtrl); + BREAK_CHECKBOX_STATE(KeyInfo.Alt, KeyBind.Alt, KeyBind.bIgnoreAlt); + BREAK_CHECKBOX_STATE(KeyInfo.Cmd, KeyBind.Cmd, KeyBind.bIgnoreCmd); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogImguiInputHelper::IsKeyEventMatchingKeyBind(const FKeyEvent& KeyEvent, const FKeyBind& KeyBind) +{ + FCogImGuiKeyInfo KeyInfo; + KeyBindToKeyInfo(KeyBind, KeyInfo); + const bool Result = IsKeyEventMatchingKeyInfo(KeyEvent, KeyInfo); + return Result; +} + //-------------------------------------------------------------------------------------------------------------------------- bool FCogImguiInputHelper::WasKeyInfoJustPressed(APlayerController& PlayerController, const FCogImGuiKeyInfo& KeyInfo) { @@ -99,6 +196,38 @@ bool FCogImguiInputHelper::WasKeyInfoJustPressed(APlayerController& PlayerContro return false; } +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogImguiInputHelper::IsKeyBoundToCommand(UWorld* World, const FKeyEvent& KeyEvent) +{ + if (World == nullptr) + { + return false; + } + + APlayerController* Controller = GetFirstLocalPlayerController(*World); + if (Controller == nullptr) + { + return false; + } + + UPlayerInput* PlayerInput = Controller->PlayerInput; + if (PlayerInput == nullptr) + { + return false; + } + + for (const FKeyBind& KeyBind : PlayerInput->DebugExecBindings) + { + if (IsKeyEventMatchingKeyBind(KeyEvent, KeyBind)) + { + return true; + } + } + + return false; +} + + //-------------------------------------------------------------------------------------------------------------------------- bool FCogImguiInputHelper::IsConsoleEvent(const FKeyEvent& KeyEvent) { @@ -124,13 +253,6 @@ bool FCogImguiInputHelper::IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) return false; } -//-------------------------------------------------------------------------------------------------------------------------- -bool FCogImguiInputHelper::IsImGuiToggleInputEvent(const FKeyEvent& KeyEvent) -{ - const bool Result = IsKeyEventMatchingKeyInfo(KeyEvent, FCogImguiModule::Get().GetToggleInputKey()); - return Result; -} - //-------------------------------------------------------------------------------------------------------------------------- ImGuiKey FCogImguiInputHelper::KeyEventToImGuiKey(const FKeyEvent& KeyEvent) { @@ -150,11 +272,11 @@ ImGuiKey FCogImguiInputHelper::KeyEventToImGuiKey(const FKeyEvent& KeyEvent) //-------------------------------------------------------------------------------------------------------------------------- uint32 FCogImguiInputHelper::MouseButtonToImGuiMouseButton(const FKey& MouseButton) { - if (MouseButton == EKeys::LeftMouseButton) { return 0; } - if (MouseButton == EKeys::RightMouseButton) { return 1; } - if (MouseButton == EKeys::MiddleMouseButton) { return 2; } - if (MouseButton == EKeys::ThumbMouseButton) { return 3; } - if (MouseButton == EKeys::ThumbMouseButton2) { return 4; } + if (MouseButton == EKeys::LeftMouseButton) { return 0; } + if (MouseButton == EKeys::RightMouseButton) { return 1; } + if (MouseButton == EKeys::MiddleMouseButton) { return 2; } + if (MouseButton == EKeys::ThumbMouseButton) { return 3; } + if (MouseButton == EKeys::ThumbMouseButton2) { return 4; } return -1; } diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp index c12ec3a..a510798 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp @@ -121,17 +121,6 @@ void SCogImguiWidget::TickFocus() { FCogImguiModule& Module = FCogImguiModule::Get(); - if (UWorld* World = GameViewport->GetWorld()) - { - if (APlayerController* Controller = FCogImguiInputHelper::GetFirstLocalPlayerController(*World)) - { - if (FCogImguiInputHelper::WasKeyInfoJustPressed(*Controller, Module.GetToggleInputKey())) - { - Module.ToggleEnableInput(); - } - } - } - const bool bShouldEnableInput = Module.GetEnableInput(); if (bEnableInput != bShouldEnableInput) { @@ -264,18 +253,19 @@ FVector2D SCogImguiWidget::ComputeDesiredSize(float Scale) const //-------------------------------------------------------------------------------------------------------------------------- ULocalPlayer* SCogImguiWidget::GetLocalPlayer() const { - if (GameViewport.IsValid()) - { - if (UWorld* World = GameViewport->GetWorld()) - { - if (ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController()) - { - return World->GetFirstLocalPlayerFromController(); - } - } + if (GameViewport.IsValid() == false) + { + return nullptr; } - - return nullptr; + + UWorld* World = GameViewport->GetWorld(); + if (World == nullptr) + { + return nullptr; + } + + ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController(); + return LocalPlayer; } //-------------------------------------------------------------------------------------------------------------------------- @@ -358,7 +348,7 @@ FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterE //-------------------------------------------------------------------------------------------------------------------------- FReply SCogImguiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) { - if (FCogImguiInputHelper::IsKeyEventHandled(KeyEvent) == false) + if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false) { return FReply::Unhandled(); } @@ -377,7 +367,7 @@ FReply SCogImguiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& //-------------------------------------------------------------------------------------------------------------------------- FReply SCogImguiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) { - if (FCogImguiInputHelper::IsKeyEventHandled(KeyEvent) == false) + if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false) { return FReply::Unhandled(); } diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h index 8a289df..44f9793 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h @@ -5,6 +5,7 @@ #include "imgui.h" struct FCogImGuiKeyInfo; +struct FKeyBind; class COGIMGUI_API FCogImguiInputHelper { @@ -12,7 +13,7 @@ public: static APlayerController* GetFirstLocalPlayerController(UWorld& World); - static bool IsKeyEventHandled(const FKeyEvent& KeyEvent); + static bool IsKeyEventHandled(UWorld* World, const FKeyEvent& KeyEvent); static bool WasKeyInfoJustPressed(APlayerController& PlayerController, const FCogImGuiKeyInfo& KeyInfo); @@ -20,9 +21,17 @@ public: static bool IsKeyEventMatchingKeyInfo(const FKeyEvent& KeyEvent, const FCogImGuiKeyInfo& InputChord); + static bool IsKeyEventMatchingKeyBind(const FKeyEvent& KeyEvent, const FKeyBind& KeyBind); + + static ECheckBoxState MakeCheckBoxState(uint8 RequireValue, uint8 IgnoreValue); + + static void KeyBindToKeyInfo(const FKeyBind& KeyBind, FCogImGuiKeyInfo& KeyInfo); + + static void KeyInfoToKeyBind(const FCogImGuiKeyInfo& KeyInfo, FKeyBind& KeyBind); + static bool IsConsoleEvent(const FKeyEvent& KeyEvent); - static bool IsImGuiToggleInputEvent(const FKeyEvent& KeyEvent); + static bool IsKeyBoundToCommand(UWorld* World, const FKeyEvent& KeyEvent); static bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent); diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiModule.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiModule.h index 504bd4c..7151032 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiModule.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiModule.h @@ -35,10 +35,6 @@ public: void ToggleEnableInput() { bEnabledInput = !bEnabledInput; } - const FCogImGuiKeyInfo& GetToggleInputKey() const { return ToggleInputKey; } - - void SetToggleInputKey(const FCogImGuiKeyInfo& Value) { ToggleInputKey = Value; } - private: void Initialize(); @@ -47,5 +43,4 @@ private: ImFontAtlas DefaultFontAtlas; bool bEnabledInput = true; bool bIsInitialized = false; - FCogImGuiKeyInfo ToggleInputKey; }; diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index c92c104..3b1ef24 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -3,10 +3,11 @@ #include "CogDebugDrawImGui.h" #include "CogImguiModule.h" #include "CogImguiWidget.h" -#include "CogWindow_Spacing.h" #include "CogWindow_Settings.h" +#include "CogWindow_Spacing.h" #include "CogWindowWidgets.h" #include "Engine/Engine.h" +#include "HAL/IConsoleManager.h" #include "imgui_internal.h" //-------------------------------------------------------------------------------------------------------------------------- @@ -36,6 +37,25 @@ void UCogWindowManager::InitializeInternal() SpaceWindows.Add(CreateWindow("Spacing 4", false)); SettingsWindow = CreateWindow("Window.Settings", false); + + ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand( + TEXT("Cog.ToggleInput"), + TEXT("Toggle the input focus between the Game and ImGui"), + FConsoleCommandWithArgsDelegate::CreateLambda([](const TArray& Args) { FCogImguiModule::Get().ToggleEnableInput(); }), + ECVF_Cheat)); + + ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand( + TEXT("Cog.LoadLayout"), + TEXT("Load the layout. Cog.LoadLayout "), + FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray& Args) { if (Args.Num() > 0) { LoadLayout(FCString::Atoi(*Args[0])); }}), + ECVF_Cheat)); + + ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand( + TEXT("Cog.SaveLayout"), + TEXT("Save the layout. Cog.SaveLayout "), + FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray& Args) { if (Args.Num() > 0) { SaveLayout(FCString::Atoi(*Args[0])); }}), + ECVF_Cheat)); + } //-------------------------------------------------------------------------------------------------------------------------- @@ -47,6 +67,11 @@ void UCogWindowManager::Shutdown() Window->SaveConfig(); } + for (IConsoleObject* ConsoleCommand : ConsoleCommands) + { + IConsoleManager::Get().UnregisterConsoleObject(ConsoleCommand); + } + SaveConfig(); } @@ -190,7 +215,7 @@ void UCogWindowManager::CloseAllWindows() } //-------------------------------------------------------------------------------------------------------------------------- -void UCogWindowManager::LoadLayout(int LayoutIndex) +void UCogWindowManager::LoadLayout(int32 LayoutIndex) { for (UCogWindow* Window : Windows) { @@ -201,7 +226,7 @@ void UCogWindowManager::LoadLayout(int LayoutIndex) } //-------------------------------------------------------------------------------------------------------------------------- -void UCogWindowManager::SaveLayout(int LayoutIndex) +void UCogWindowManager::SaveLayout(int32 LayoutIndex) { FString Filename = *FCogImguiHelper::GetIniFilePath(FString::Printf(TEXT("imgui_layout_%d"), LayoutIndex)); ImGui::SaveIniSettingsToDisk(TCHAR_TO_ANSI(*Filename)); diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp index 7611cfe..ff84e2f 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp @@ -1,9 +1,12 @@ #include "CogWindowWidgets.h" #include "CogImguiHelper.h" -#include "Kismet/KismetMathLibrary.h" +#include "CogImGuiKeyInfo.h" +#include "CogImguiInputHelper.h" #include "imgui.h" #include "imgui_internal.h" +#include "InputCoreTypes.h" +#include "Kismet/KismetMathLibrary.h" //-------------------------------------------------------------------------------------------------------------------------- void FCogWindowWidgets::BeginTableTooltip() @@ -283,4 +286,193 @@ bool FCogWindowWidgets::ComboboxEnum(const char* Label, UEnum* Enum, int64 Curre } return HasChanged; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::CheckBoxState(const char* Label, ECheckBoxState& State) +{ + const char* TooltipText = nullptr; + ImVec4 ButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button); + ImVec4 TextColor = ImGui::GetStyleColorVec4(ImGuiCol_Text); + + switch (State) + { + case ECheckBoxState::Checked: + { + TooltipText = "Checked"; + break; + } + + case ECheckBoxState::Unchecked: + { + ButtonColor.w = 0.5f; + TextColor.w = 0.5f; + TooltipText = "Unchecked"; + break; + } + + case ECheckBoxState::Undetermined: + { + ButtonColor.w = 0.1f; + TextColor.w = 0.1f; + TooltipText = "Undetermined"; + break; + } + } + + ImGui::PushStyleColor(ImGuiCol_Text, TextColor); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(ButtonColor.x, ButtonColor.y, ButtonColor.z, ButtonColor.w * 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(ButtonColor.x, ButtonColor.y, ButtonColor.z, ButtonColor.w * 0.8f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(ButtonColor.x, ButtonColor.y, ButtonColor.z, ButtonColor.w * 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); + + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + + const bool Pressed = ImGui::Button(Label); + + if (State == ECheckBoxState::Unchecked) + { + ImVec2 Pos = ImGui::GetItemRectMin(); + ImVec2 Size = ImGui::GetItemRectSize(); + + ImGui::GetWindowDrawList()->AddLine(ImVec2(Pos.x, Pos.y + Size.y * 0.5f), ImVec2(Pos.x + Size.x, Pos.y + Size.y * 0.5f), IM_COL32(255, 255, 255, 255), 0.0f); + } + + ImGui::PopStyleVar(); + + ImGui::PopStyleColor(5); + + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + { + ImGui::SetTooltip(TooltipText); + } + + if (Pressed) + { + switch (State) + { + case ECheckBoxState::Checked: State = ECheckBoxState::Unchecked; break; + case ECheckBoxState::Unchecked: State = ECheckBoxState::Undetermined; break; + case ECheckBoxState::Undetermined: State = ECheckBoxState::Checked; break; + } + } + + return Pressed; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::InputKey(const char* Label, FCogImGuiKeyInfo& KeyInfo) +{ + ImGui::PushID(Label); + + ImGui::AlignTextToFramePadding(); + ImGui::TextUnformatted(Label); + + const bool HasChanged = InputKey(KeyInfo); + + ImGui::PopID(); + + return HasChanged; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::InputKey(FCogImGuiKeyInfo& KeyInfo) +{ + static TArray AllKeys; + if (AllKeys.IsEmpty()) + { + EKeys::GetAllKeys(AllKeys); + } + + bool HasKeyChanged = false; + + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 6); + if (ImGui::BeginCombo("##Key", TCHAR_TO_ANSI(*KeyInfo.Key.ToString()), ImGuiComboFlags_HeightLarge)) + { + for (int32 i = 0; i < AllKeys.Num(); ++i) + { + const FKey Key = AllKeys[i]; + if (Key.IsDigital() == false || Key.IsDeprecated() || Key.IsBindableToActions() == false || Key.IsMouseButton() || Key.IsTouch() || Key.IsGamepadKey()) + { + continue; + } + + bool IsSelected = KeyInfo.Key == Key; + if (ImGui::Selectable(TCHAR_TO_ANSI(*Key.ToString()), IsSelected)) + { + KeyInfo.Key = Key; + HasKeyChanged = true; + } + } + ImGui::EndCombo(); + } + + ImGui::SameLine(); + HasKeyChanged |= CheckBoxState("Ctrl", KeyInfo.Ctrl); + + ImGui::SameLine(); + HasKeyChanged |= CheckBoxState("Shift", KeyInfo.Shift); + + ImGui::SameLine(); + HasKeyChanged |= CheckBoxState("Alt", KeyInfo.Alt); + + ImGui::SameLine(); + HasKeyChanged |= CheckBoxState("Cmd", KeyInfo.Cmd); + + return HasKeyChanged; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::KeyBind(FKeyBind& KeyBind) +{ + static char Buffer[256] = ""; + + const char* Str = TCHAR_TO_ANSI(*KeyBind.Command); + ImStrncpy(Buffer, Str, IM_ARRAYSIZE(Buffer)); + + bool HasChanged = false; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); + if (ImGui::InputText("##Command", Buffer, IM_ARRAYSIZE(Buffer))) + { + KeyBind.Command = FString(Buffer); + HasChanged = true; + } + + FCogImGuiKeyInfo KeyInfo; + FCogImguiInputHelper::KeyBindToKeyInfo(KeyBind, KeyInfo); + + ImGui::SameLine(); + if (InputKey(KeyInfo)) + { + HasChanged = true; + FCogImguiInputHelper::KeyInfoToKeyBind(KeyInfo, KeyBind); + } + + return HasChanged; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::ButtonWithTooltip(const char* Text, const char* Tooltip) +{ + bool IsPressed = ImGui::Button(Text); + + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + { + ImGui::SetTooltip(Tooltip); + } + + return IsPressed; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::DeleteArrayItemButton() +{ + bool IsPressed = ImGui::Button("x"); + + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + { + ImGui::SetTooltip("Delete Item"); + } + + return IsPressed; } \ No newline at end of file diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp index fc4fb73..be57177 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp @@ -9,18 +9,12 @@ UCogWindow_Settings::UCogWindow_Settings() { bHasMenu = false; - ToggleInputKey.Key = EKeys::Tab; } //-------------------------------------------------------------------------------------------------------------------------- void UCogWindow_Settings::PostInitProperties() { Super::PostInitProperties(); - - if (ToggleInputKey.Key != EKeys::Invalid) - { - FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey); - } } //-------------------------------------------------------------------------------------------------------------------------- @@ -49,52 +43,6 @@ void UCogWindow_Settings::RenderContent() ImGui::Separator(); - ImGui::Text("Toggle Input Key"); - - TArray Keys; - EKeys::GetAllKeys(Keys); - - bool HasKeyChanged = false; - FCogWindowWidgets::SetNextItemToShortWidth(); - if (ImGui::BeginCombo("Key", TCHAR_TO_ANSI(*ToggleInputKey.Key.ToString()))) - { - for (int32 i = 0; i < Keys.Num(); ++i) - { - const FKey Key = Keys[i]; - if (Key.IsDigital() == false || Key.IsDeprecated()) - { - continue; - } - - bool IsSelected = ToggleInputKey.Key == Key; - if (ImGui::Selectable(TCHAR_TO_ANSI(*Key.ToString()), IsSelected)) - { - ToggleInputKey.Key = Key; - HasKeyChanged = true; - } - } - ImGui::EndCombo(); - } - - FCogWindowWidgets::SetNextItemToShortWidth(); - HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Ctrl", ToggleInputKey.Ctrl); - - FCogWindowWidgets::SetNextItemToShortWidth(); - HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Shift", ToggleInputKey.Shift); - - FCogWindowWidgets::SetNextItemToShortWidth(); - HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Alt", ToggleInputKey.Alt); - - FCogWindowWidgets::SetNextItemToShortWidth(); - HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Cmd", ToggleInputKey.Cmd); - - if (HasKeyChanged) - { - FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey); - } - - ImGui::Separator(); - ImGui::Spacing(); ImGui::Spacing(); if (ImGui::Button("Reset All Windows Config")) diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h index cf27a8a..a3f0edf 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h @@ -5,10 +5,11 @@ #include "imgui.h" #include "CogWindowManager.generated.h" +class IConsoleObject; +class SCogImguiWidget; class UCogWindow; class UCogWindow_Settings; class UWorld; -class SCogImguiWidget; struct ImGuiSettingsHandler; struct ImGuiTextBuffer; @@ -48,9 +49,9 @@ public: void ResetLayout(); - void LoadLayout(int LayoutIndex); + void LoadLayout(int32 LayoutIndex); - void SaveLayout(int LayoutIndex); + void SaveLayout(int32 LayoutIndex); bool GetHideAllWindows() const { return bHideAllWindows; } @@ -147,4 +148,6 @@ protected: bool bHideAllWindows = false; bool bRefreshDPIScale = false; + + TArray ConsoleCommands; }; diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h index 9cb1bf4..c6fbd3f 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h @@ -6,6 +6,7 @@ class UEnum; class FEnumProperty; +struct FCogImGuiKeyInfo; class COGWINDOW_API FCogWindowWidgets { @@ -51,6 +52,18 @@ public: static bool ComboboxEnum(const char* Label, const FEnumProperty* EnumProperty, uint8* PointerToEnumValue); + static bool CheckBoxState(const char* Label, ECheckBoxState& State); + + static bool InputKey(const char* Label, FCogImGuiKeyInfo& KeyInfo); + + static bool InputKey(FCogImGuiKeyInfo& KeyInfo); + + static bool KeyBind(FKeyBind& KeyBind); + + static bool ButtonWithTooltip(const char* Text, const char* Tooltip); + + static bool DeleteArrayItemButton(); + }; template diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h index 28a473d..a427e20 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h @@ -5,6 +5,7 @@ #include "CogImGuiKeyInfo.h" #include "CogWindow_Settings.generated.h" + UCLASS(Config = Cog) class COGWINDOW_API UCogWindow_Settings : public UCogWindow { @@ -22,6 +23,4 @@ protected: private: - UPROPERTY(Config) - FCogImGuiKeyInfo ToggleInputKey; }; diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp index 700787a..caef3ef 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp @@ -100,7 +100,7 @@ void UCogAIWindow_Blackboard::RenderContent() { Keys.Sort([](const FBlackboardEntry& Key1, const FBlackboardEntry& Key2) { - return Key1.EntryName.Compare(Key1.EntryName) < 0; + return Key1.EntryName.Compare(Key2.EntryName) < 0; }); } diff --git a/Source/CogSample/CogSampleGameState.cpp b/Source/CogSample/CogSampleGameState.cpp index 31a7690..27119ae 100644 --- a/Source/CogSample/CogSampleGameState.cpp +++ b/Source/CogSample/CogSampleGameState.cpp @@ -25,13 +25,14 @@ #include "CogEngineDataAsset.h" #include "CogEngineModule.h" #include "CogEngineWindow_Collisions.h" +#include "CogEngineWindow_CommandBindings.h" #include "CogEngineWindow_DebugSettings.h" #include "CogEngineWindow_ImGui.h" #include "CogEngineWindow_Inspector.h" #include "CogEngineWindow_LogCategories.h" +#include "CogEngineWindow_Metrics.h" #include "CogEngineWindow_NetEmulation.h" #include "CogEngineWindow_OutputLog.h" -#include "CogEngineWindow_Metrics.h" #include "CogEngineWindow_Plots.h" #include "CogEngineWindow_Scalability.h" #include "CogEngineWindow_Selection.h" @@ -43,6 +44,7 @@ #include "CogInputDataAsset.h" #include "CogInputWindow_Actions.h" #include "CogInputWindow_Gamepad.h" +#include "CogSampleLogCategories.h" #include "CogWindowManager.h" #include "GameFramework/GameUserSettings.h" @@ -94,6 +96,7 @@ void ACogSampleGameState::EndPlay(const EEndPlayReason::Type EndPlayReason) Super::EndPlay(EndPlayReason); #if ENABLE_COG + if (CogWindowManager != nullptr) { CogWindowManager->Shutdown(); @@ -123,9 +126,6 @@ void ACogSampleGameState::Tick(float DeltaSeconds) //-------------------------------------------------------------------------------------------------------------------------- void ACogSampleGameState::InitializeCog() { - FCogImguiModule::Get().SetToggleInputKey(FCogImGuiKeyInfo(EKeys::Tab)); - RegisterCommand(TEXT("Cog.ToggleInput"), TEXT(""), FConsoleCommandWithArgsDelegate::CreateUObject(this, &ACogSampleGameState::CogToggleInput)); - CogWindowManager = NewObject(this); CogWindowManagerRef = CogWindowManager; @@ -137,6 +137,8 @@ void ACogSampleGameState::InitializeCog() UCogEngineWindow_Collisions* CollisionsWindow = CogWindowManager->CreateWindow("Engine.Collision"); CollisionsWindow->SetAsset(EngineAsset); + CogWindowManager->CreateWindow("Engine.Command Bindings"); + CogWindowManager->CreateWindow("Engine.Debug Settings"); CogWindowManager->CreateWindow("Engine.ImGui"); @@ -150,9 +152,6 @@ void ACogSampleGameState::InitializeCog() } }); - - - CogWindowManager->CreateWindow("Engine.Log Categories"); CogWindowManager->CreateWindow("Engine.Net Emulation"); @@ -163,7 +162,7 @@ void ACogSampleGameState::InitializeCog() CogWindowManager->CreateWindow("Engine.Plots"); - UCogEngineWindow_Selection* SelectionWindow = CogWindowManager->CreateWindow("Engine.Selection"); + SelectionWindow = CogWindowManager->CreateWindow("Engine.Selection"); SelectionWindow->SetActorClasses({ ACharacter::StaticClass(), AActor::StaticClass(), AGameModeBase::StaticClass(), AGameStateBase::StaticClass() }); SelectionWindow->SetTraceType(UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Pawn)); @@ -223,25 +222,8 @@ void ACogSampleGameState::InitializeCog() //--------------------------------------- // Main Menu Widget //--------------------------------------- - CogWindowManager->AddMainMenuWidget(SelectionWindow); + CogWindowManager->AddMainMenuWidget(SelectionWindow.Get()); CogWindowManager->AddMainMenuWidget(StatsWindow); } -//-------------------------------------------------------------------------------------------------------------------------- -void ACogSampleGameState::RegisterCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command) -{ - IConsoleManager& ConsoleManager = IConsoleManager::Get(); - if (!ConsoleManager.FindConsoleObject(Name)) - { - ConsoleManager.RegisterConsoleCommand(Name, Help, Command, ECVF_Cheat); - } -} - -//-------------------------------------------------------------------------------------------------------------------------- -void ACogSampleGameState::CogToggleInput(const TArray& Args) -{ - FCogImguiModule::Get().ToggleEnableInput(); -} - - #endif //ENABLE_COG diff --git a/Source/CogSample/CogSampleGameState.h b/Source/CogSample/CogSampleGameState.h index c3af6a7..cf7d7a5 100644 --- a/Source/CogSample/CogSampleGameState.h +++ b/Source/CogSample/CogSampleGameState.h @@ -6,6 +6,7 @@ #include "CogSampleGameState.generated.h" class UCogWindowManager; +class UCogEngineWindow_Selection; UCLASS() class ACogSampleGameState : public AGameStateBase @@ -32,11 +33,12 @@ private: void InitializeCog(); - void RegisterCommand(const TCHAR* Name, const TCHAR* Help, const FConsoleCommandWithArgsDelegate& Command); + void RegisterCommands(); - void CogToggleInput(const TArray& Args); + void UnregisterCommands(); TObjectPtr CogWindowManager = nullptr; + TObjectPtr SelectionWindow = nullptr; #endif //ENABLE_COG };