From 1cecf93841f7198cb56ba1c666496c0eb6ba0668 Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Thu, 30 Jan 2025 13:15:25 -0500 Subject: [PATCH] CogWindow: simplify how CogWidgets are rendered Remove the need to specify the widgets width to be able to right them. Instead widgets are rendered in a table which left/center/right align automatically. --- Config/DefaultInput.ini | 1 + .../Private/CogEngineWindow_Cheats.cpp | 2 +- .../Private/CogEngineWindow_Inspector.cpp | 2 +- .../Private/CogEngineWindow_OutputLog.cpp | 2 +- .../Private/CogEngineWindow_Selection.cpp | 88 ++------ .../Private/CogEngineWindow_Skeleton.cpp | 2 +- .../Private/CogEngineWindow_Stats.cpp | 65 ++---- .../Public/CogEngineWindow_Selection.h | 4 +- .../CogEngine/Public/CogEngineWindow_Stats.h | 4 +- .../CogImgui/Private/CogImguiContext.cpp | 35 ++- .../CogImgui/Private/CogImguiWidget.cpp | 5 + .../Source/CogWindow/Private/CogWindow.cpp | 8 +- .../CogWindow/Private/CogWindowManager.cpp | 205 +++++++++--------- .../CogWindow/Private/CogWindowWidgets.cpp | 118 +++++++--- .../CogWindow/Private/CogWindow_Settings.cpp | 62 ++++++ .../Cog/Source/CogWindow/Public/CogWindow.h | 11 +- .../CogWindow/Public/CogWindowManager.h | 7 + .../CogWindow/Public/CogWindowWidgets.h | 12 +- .../CogWindow/Public/CogWindow_Settings.h | 15 ++ .../Source/ThirdParty/ImGui/imgui_widgets.cpp | 22 +- .../Private/CogAIWindow_BehaviorTree.cpp | 2 +- .../CogAI/Private/CogAIWindow_Blackboard.cpp | 2 +- .../Private/CogAbilityWindow_Abilities.cpp | 2 +- .../Private/CogAbilityWindow_Attributes.cpp | 4 +- .../Private/CogAbilityWindow_Cheats.cpp | 23 -- .../Private/CogAbilityWindow_Effects.cpp | 2 +- .../Private/CogAbilityWindow_Tags.cpp | 2 +- .../Private/CogAbilityWindow_Tasks.cpp | 2 +- 28 files changed, 386 insertions(+), 323 deletions(-) diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini index 5387297..65517ec 100644 --- a/Config/DefaultInput.ini +++ b/Config/DefaultInput.ini @@ -69,6 +69,7 @@ bCaptureMouseOnLaunch=True bEnableLegacyInputScales=True bEnableMotionControls=True bFilterInputByPlatformUser=False +bEnableInputDeviceSubsystem=True bShouldFlushPressedKeysOnViewportFocusLost=True bEnableDynamicComponentInputBinding=True bAlwaysShowTouchInterface=False diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Cheats.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Cheats.cpp index 2f00585..1a58fd5 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Cheats.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Cheats.cpp @@ -243,7 +243,7 @@ void FCogEngineWindow_Cheats::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp index 1faacd0..1c0785c 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Inspector.cpp @@ -256,7 +256,7 @@ void FCogEngineWindow_Inspector::RenderMenu() //----------------------------------- // Search //----------------------------------- - FCogWindowWidgets::SearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9); + FCogWindowWidgets::SearchBar("##Filter", Filter, -FCogWindowWidgets::GetFontWidth() * 9); //----------------------------------- // Options diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp index 219c087..06f105d 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_OutputLog.cpp @@ -184,7 +184,7 @@ void FCogEngineWindow_OutputLog::RenderContent() ImGui::EndCombo(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp index fe34328..dfde5c4 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp @@ -15,6 +15,7 @@ #include "GameFramework/Character.h" #include "HAL/IConsoleManager.h" #include "imgui.h" +#include "imgui_internal.h" #include "Kismet/GameplayStatics.h" FString FCogEngineWindow_Selection::ToggleSelectionModeCommand = TEXT("Cog.ToggleSelectionMode"); @@ -25,7 +26,7 @@ void FCogEngineWindow_Selection::Initialize() Super::Initialize(); bHasMenu = true; - bHasWidget = true; + bHasWidget = 2; ActorClasses = { AActor::StaticClass(), ACharacter::StaticClass() }; Config = GetConfig(); @@ -294,77 +295,30 @@ void FCogEngineWindow_Selection::TickSelectionMode() } //-------------------------------------------------------------------------------------------------------------------------- -float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) +void FCogEngineWindow_Selection::RenderMainMenuWidget() { - switch (SubWidgetIndex) + if (ImGui::MenuItem("Pick")) { - case 0: return FCogWindowWidgets::GetFontWidth() * 6; - case 1: return FMath::Min(FMath::Max(MaxWidth, FCogWindowWidgets::GetFontWidth() * 10), FCogWindowWidgets::GetFontWidth() * 30); - case 2: return FCogWindowWidgets::GetFontWidth() * 3; + GetOwner()->SetActivateSelectionMode(true); + HackWaitInputRelease(); } + RenderPickButtonTooltip(); - return -1.0f; -} - -//-------------------------------------------------------------------------------------------------------------------------- -void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, float Width) -{ - //----------------------------------- - // Pick Button - //----------------------------------- - if (SubWidgetIndex == 0) + //TODO: Could be replaced by a BeginMenu + + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); + AActor* NewSelection = nullptr; + if (FCogWindowWidgets::MenuActorsCombo( + "MenuActorSelection", + NewSelection, + *GetWorld(), + ActorClasses, + Config->SelectedClassIndex, + &Filter, + GetLocalPlayerPawn(), + [this](AActor& Actor) { RenderActorContextMenu(Actor); })) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); - ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); - - if (ImGui::Button("Pick", ImVec2(Width, 0))) - { - GetOwner()->SetActivateSelectionMode(true); - HackWaitInputRelease(); - } - RenderPickButtonTooltip(); - - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(2); - } - else if (SubWidgetIndex == 1) - { - ImGui::SetNextItemWidth(Width); - AActor* NewSelection = nullptr; - if (FCogWindowWidgets::MenuActorsCombo( - "MenuActorSelection", - NewSelection, - *GetWorld(), - ActorClasses, - Config->SelectedClassIndex, - &Filter, - GetLocalPlayerPawn(), - [this](AActor& Actor) { RenderActorContextMenu(Actor); })) - { - SetGlobalSelection(NewSelection); - } - } - else if (SubWidgetIndex == 2) - { - //----------------------------------- - // Reset Button - //----------------------------------- - { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); - if (ImGui::Button("X", ImVec2(Width, 0))) - { - SetGlobalSelection(nullptr); - ImGui::CloseCurrentPopup(); - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Reset the selection to the controlled actor."); - } - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(1); - } + SetGlobalSelection(NewSelection); } } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp index 9519c92..3a80c40 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Skeleton.cpp @@ -111,7 +111,7 @@ void FCogEngineWindow_Skeleton::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Stats.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Stats.cpp index 0b62bad..f4fe046 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Stats.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Stats.cpp @@ -17,7 +17,7 @@ void FCogEngineWindow_Stats::Initialize() { Super::Initialize(); - bHasWidget = true; + bHasWidget = 2; } //-------------------------------------------------------------------------------------------------------------------------- @@ -64,30 +64,14 @@ void FCogEngineWindow_Stats::RenderContent() } //-------------------------------------------------------------------------------------------------------------------------- -float FCogEngineWindow_Stats::GetMainMenuWidgetWidth(const int32 SubWidgetIndex, float MaxWidth) +void FCogEngineWindow_Stats::RenderMainMenuWidget() { const APlayerController* PlayerController = GetLocalPlayerController(); const UNetConnection* Connection = PlayerController != nullptr ? PlayerController->GetNetConnection() : nullptr; - - switch (SubWidgetIndex) - { - case 0: return FCogWindowWidgets::GetFontWidth() * 8; - case 1: return Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f; - case 2: return Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f; - } - - return -1; -} - -//-------------------------------------------------------------------------------------------------------------------------- -void FCogEngineWindow_Stats::RenderMainMenuWidget(const int32 SubWidgetIndex, const float Width) -{ - switch (SubWidgetIndex) - { - case 0: RenderMainMenuWidgetFramerate(Width); break; - case 1: RenderMainMenuWidgetPing(Width); break; - case 2: RenderMainMenuWidgetPacketLoss(Width); break; - } + + RenderMainMenuWidgetFramerate(FCogWindowWidgets::GetFontWidth() * 8); + RenderMainMenuWidgetPing(Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f); + RenderMainMenuWidgetPacketLoss(Connection != nullptr ? FCogWindowWidgets::GetFontWidth() * 7 : 0.0f); } //-------------------------------------------------------------------------------------------------------------------------- @@ -96,22 +80,12 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetFramerate(const float Width) extern ENGINE_API float GAverageFPS; const int32 Fps = (int32)GAverageFPS; - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); ImGui::PushStyleColor(ImGuiCol_Text, GetFpsColor(Fps)); - - if (ImGui::Button(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dfps###FramerateButton"), Fps)), ImVec2(Width, 0.0f))) - { - ImGui::OpenPopup("FrameratePopup"); - } - + const bool Open = ImGui::BeginMenu(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dfps###FramerateButton"), Fps))); ImGui::PopStyleColor(2); - ImGui::PopStyleVar(2); - ImGui::SetItemTooltip("Framerate"); - - if (ImGui::BeginPopup("FrameratePopup")) + if (Open) { ImGui::Text("Fps"); ImGui::SameLine(); @@ -123,8 +97,10 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetFramerate(const float Width) GEngine->SetMaxFPS(MaxFps); } - ImGui::EndPopup(); + ImGui::EndMenu(); } + + ImGui::SetItemTooltip("Framerate"); } //-------------------------------------------------------------------------------------------------------------------------- @@ -138,25 +114,15 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetPing(const float Width) } const float Ping = PlayerState->GetPingInMilliseconds(); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f)); ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0)); ImGui::PushStyleColor(ImGuiCol_Text, GetPingColor(Ping)); - - if (ImGui::Button(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dms###PingButton"), (int32)Ping)), ImVec2(Width, 0.0f))) - { - ImGui::OpenPopup("PingPopup"); - } - + const bool Open = ImGui::BeginMenu(TCHAR_TO_ANSI(*FString::Printf(TEXT("%3dms###PingButton"), (int32)Ping))); ImGui::PopStyleColor(2); - ImGui::PopStyleVar(2); - ImGui::SetItemTooltip("Ping"); #if DO_ENABLE_NET_TEST - if (ImGui::BeginPopup("PingPopup")) + if (Open) { - FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(GetWorld()); if (WorldContext.ActiveNetDrivers.Num() > 0) { @@ -171,9 +137,11 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetPing(const float Width) SelectedNetDriver->NetDriver->SetPacketSimulationSettings(Settings); } } - ImGui::EndPopup(); + + ImGui::EndMenu(); } #endif //DO_ENABLE_NET_TEST + } //-------------------------------------------------------------------------------------------------------------------------- @@ -208,7 +176,6 @@ void FCogEngineWindow_Stats::RenderMainMenuWidgetPacketLoss(const float Width) #if DO_ENABLE_NET_TEST if (ImGui::BeginPopup("PacketLossPopup")) { - FWorldContext& WorldContext = GEngine->GetWorldContextFromWorldChecked(GetWorld()); if (WorldContext.ActiveNetDrivers.Num() > 0) { diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h index 026b828..949c22e 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Selection.h @@ -45,9 +45,7 @@ protected: virtual void RenderContent() override; - virtual float GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) override; - - virtual void RenderMainMenuWidget(int32 SubWidgetIndex, float Width) override; + virtual void RenderMainMenuWidget() override; virtual bool DrawSelectionCombo(); diff --git a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Stats.h b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Stats.h index 6f5a341..6beee65 100644 --- a/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Stats.h +++ b/Plugins/Cog/Source/CogEngine/Public/CogEngineWindow_Stats.h @@ -23,9 +23,7 @@ protected: virtual void RenderContent() override; - virtual float GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) override; - - virtual void RenderMainMenuWidget(int32 SubWidgetIndex, float Width) override; + virtual void RenderMainMenuWidget() override; virtual void RenderMainMenuWidgetPacketLoss(float Width); diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp index 80ad99b..182ba5e 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiContext.cpp @@ -25,8 +25,8 @@ static UPlayerInput* GetPlayerInput(const UWorld* World); -FCogImGuiContextScope:: -FCogImGuiContextScope(FCogImguiContext& CogImguiContext) +//-------------------------------------------------------------------------------------------------------------------------- +FCogImGuiContextScope::FCogImGuiContextScope(FCogImguiContext& CogImguiContext) { PrevContext = ImGui::GetCurrentContext(); PrevPlotContext = ImPlot::GetCurrentContext(); @@ -35,8 +35,8 @@ FCogImGuiContextScope(FCogImguiContext& CogImguiContext) ImPlot::SetCurrentContext(CogImguiContext.PlotContext); } -FCogImGuiContextScope:: -FCogImGuiContextScope(ImGuiContext* GuiCtx, ImPlotContext* PlotCtx) +//-------------------------------------------------------------------------------------------------------------------------- +FCogImGuiContextScope::FCogImGuiContextScope(ImGuiContext* GuiCtx, ImPlotContext* PlotCtx) { PrevContext = ImGui::GetCurrentContext(); PrevPlotContext = ImPlot::GetCurrentContext(); @@ -45,8 +45,8 @@ FCogImGuiContextScope(ImGuiContext* GuiCtx, ImPlotContext* PlotCtx) ImPlot::SetCurrentContext(PlotCtx); } -FCogImGuiContextScope:: -~FCogImGuiContextScope() +//-------------------------------------------------------------------------------------------------------------------------- +FCogImGuiContextScope::~FCogImGuiContextScope() { ImGui::SetCurrentContext(PrevContext); ImPlot::SetCurrentContext(PrevPlotContext); @@ -298,11 +298,14 @@ bool FCogImguiContext::BeginFrame(float InDeltaTime) //------------------------------------------------------------------------------------------------------- // Refresh modifiers otherwise, when pressing ALT-TAB, the Alt modifier is always true //------------------------------------------------------------------------------------------------------- - FModifierKeysState ModifierKeys = FSlateApplication::Get().GetModifierKeys(); - if (ModifierKeys.IsControlDown() != IO.KeyCtrl) { IO.AddKeyEvent(ImGuiMod_Ctrl, ModifierKeys.IsControlDown()); } - if (ModifierKeys.IsShiftDown() != IO.KeyShift) { IO.AddKeyEvent(ImGuiMod_Shift, ModifierKeys.IsShiftDown()); } - if (ModifierKeys.IsAltDown() != IO.KeyAlt) { IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); } - if (ModifierKeys.IsCommandDown() != IO.KeySuper) { IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); } + if (bEnableInput) + { + FModifierKeysState ModifierKeys = FSlateApplication::Get().GetModifierKeys(); + if (ModifierKeys.IsControlDown() != IO.KeyCtrl) { IO.AddKeyEvent(ImGuiMod_Ctrl, ModifierKeys.IsControlDown()); } + if (ModifierKeys.IsShiftDown() != IO.KeyShift) { IO.AddKeyEvent(ImGuiMod_Shift, ModifierKeys.IsShiftDown()); } + if (ModifierKeys.IsAltDown() != IO.KeyAlt) { IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); } + if (ModifierKeys.IsCommandDown() != IO.KeySuper) { IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); } + } } //------------------------------------------------------------------------------------------------------- @@ -685,6 +688,8 @@ static UPlayerInput* GetPlayerInput(const UWorld* World) //-------------------------------------------------------------------------------------------------------------------------- void FCogImguiContext::SetEnableInput(bool Value) { + FCogImGuiContextScope ImGuiContextScope(ImGuiContext, PlotContext); + bEnableInput = Value; if (FSlateApplication::IsInitialized() == false) @@ -715,6 +720,14 @@ void FCogImguiContext::SetEnableInput(bool Value) { LocalPlayer->GetSlateOperations().CaptureMouse(GameViewport->GetGameViewportWidget().ToSharedRef()); } + + //--------------------------------------------------------------------------------- + // Make sure no keys stay down after disabling inputs + //--------------------------------------------------------------------------------- + ImGuiIO& IO = ImGui::GetIO(); + IO.ClearInputMouse(); + IO.ClearEventsQueue(); + IO.ClearInputKeys(); } RefreshMouseCursor(); diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp index 7052de0..c9ba3da 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp @@ -118,6 +118,11 @@ FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterE { FCogImGuiContextScope ImGuiContextScope(*Context); + if (Context->GetEnableInput() == false) + { + return FReply::Unhandled(); + } + ImGuiIO& IO = ImGui::GetIO(); IO.AddInputCharacter(FCogImguiInputHelper::CastInputChar(CharacterEvent.GetCharacter())); diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp index 045f886..0dddce3 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindow.cpp @@ -69,7 +69,7 @@ void FCogWindow::Render(float DeltaTime) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); } - + if (ImGui::Begin(TCHAR_TO_ANSI(*WindowTitle), &bIsVisible, WindowFlags)) { if (bNoPadding) @@ -205,3 +205,9 @@ UWorld* FCogWindow::GetWorld() const { return Owner->GetWorld(); } + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindow::IsWindowRenderedInMainMenu() +{ + return Owner->IsRenderingMainMenu(); +} diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index 5f4f98a..c69ef9f 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -235,7 +235,7 @@ void UCogWindowManager::Render(float DeltaTime) Window->Render(DeltaTime); } } - + if (bCompactSaved) { FCogWindowWidgets::PopStyleCompact(); @@ -370,6 +370,8 @@ void UCogWindowManager::RenderMainMenu() { const UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld()); + IsRenderingInMainMenu = true; + if (ImGui::BeginMainMenuBar()) { for (FMenu& Menu : MainMenu.SubMenus) @@ -402,116 +404,107 @@ void UCogWindowManager::RenderMainMenu() ImGui::EndMenu(); } - if (ImGui::BeginMenu("Widgets")) - { - for (int32 i = 0; i < Widgets.Num(); ++i) - { - FCogWindow* Window = Widgets[i]; - - ImGui::PushID(i); - - bool Visible = Window->GetIsWidgetVisible(); - if (ImGui::Checkbox(TCHAR_TO_ANSI(*Window->GetName()), &Visible)) - { - Window->SetIsWidgetVisible(Visible); - } - - if (ImGui::IsItemActive() && ImGui::IsItemHovered() == false) - { - const int iNext = i + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); - if (iNext >= 0 && iNext < Widgets.Num()) - { - Widgets[i] = Widgets[iNext]; - Widgets[iNext] = Window; - ImGui::ResetMouseDragDelta(); - } - } - - if (i == 0) - { - ImGui::SameLine(); - FCogWindowWidgets::HelpMarker("Drag and drop the widget names to reorder them."); - } - - ImGui::PopID(); - } - - ImGui::EndMenu(); - } - ImGui::EndMenu(); } - const float MinCursorX = ImGui::GetCursorPosX(); - float CursorX = ImGui::GetWindowWidth(); - - //------------------------------------------------------------ - // Render in reverse order because it makes more sense - // when looking at the widget ordered list in the UI. - //------------------------------------------------------------ - for (int32 WindowIndex = Widgets.Num() - 1; WindowIndex >= 0; WindowIndex--) - { - FCogWindow* Window = Widgets[WindowIndex]; - - if (Window->GetIsWidgetVisible() == false) - { - continue; - } - - TArray SubWidgetsWidths; - float SimCursorX = CursorX; - for (int32 SubWidgetIndex = 0; ; ++SubWidgetIndex) - { - const float MaxWidth = SimCursorX - MinCursorX; - float SubWidgetWidth = Window->GetMainMenuWidgetWidth(SubWidgetIndex, MaxWidth); - if (SubWidgetWidth == -1) - { - break; - } - - SimCursorX -= SubWidgetWidth; - SubWidgetsWidths.Add(SubWidgetWidth); - } - - bool Stop = false; - for (int32 SubWidgetIndex = SubWidgetsWidths.Num() - 1; SubWidgetIndex >= 0; SubWidgetIndex--) - { - const float SubWidgetWidth = SubWidgetsWidths[SubWidgetIndex]; - const float MaxWidth = CursorX - MinCursorX; - - //------------------------------------------- - // Bypass this subwidget if its width is 0 - //------------------------------------------- - if (SubWidgetWidth == 0) - { - continue; - } - - //------------------------------------------- - // Stop drawing if there is not enough room - //------------------------------------------- - if (SubWidgetWidth > MaxWidth) - { - Stop = true; - break; - } - - CursorX -= SubWidgetWidth; - ImGui::SetCursorPosX(CursorX); - - Window->RenderMainMenuWidget(SubWidgetIndex, SubWidgetWidth); - } - - if (Stop) - { - break; - } - - CursorX -= ImGui::GetStyle().ItemSpacing.x; - } + RenderWidgets(); ImGui::EndMainMenuBar(); } + + IsRenderingInMainMenu = false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +void UCogWindowManager::RenderWidgets() +{ + int32 numVisibleWidgets = 0; + for (int i = 0; i < Widgets.Num(); ++i) + { + FCogWindow* Window = Widgets[i]; + if (Window->GetIsWidgetVisible()) + { + numVisibleWidgets++; + } + } + + if (numVisibleWidgets == 0) + { return; } + + int32 numColumns = numVisibleWidgets; + + if (Settings->WidgetAlignment == ECogWidgetAlignment::Right) + { + numColumns++; + } + else if (Settings->WidgetAlignment == ECogWidgetAlignment::Center) + { + numColumns += 2; + } + + + ImGuiTableFlags Flags = ImGuiTableFlags_None; + if (Settings->ShowWidgetBorders) + { + Flags |= ImGuiTableFlags_BordersInnerV; + if (Settings->WidgetAlignment == ECogWidgetAlignment::Left) + { + Flags |= ImGuiTableFlags_BordersOuterV; + } + } + + if (Settings->WidgetAlignment == ECogWidgetAlignment::Manual) + { + Flags |= ImGuiTableFlags_Resizable; + if (Settings->ShowWidgetBorders == false) + { + Flags |= ImGuiTableFlags_NoBordersInBodyUntilResize; + } + } + + if (ImGui::BeginTable("Widgets", numColumns, Flags)) + { + if (Settings->WidgetAlignment == ECogWidgetAlignment::Right || Settings->WidgetAlignment == ECogWidgetAlignment::Center) + { + ImGui::TableSetupColumn("Stretch", ImGuiTableColumnFlags_WidthStretch); + } + + for (int i = 0; i < numVisibleWidgets; ++i) + { + ImGui::TableSetupColumn("Fixed", ImGuiTableColumnFlags_WidthFixed); + } + + if (Settings->WidgetAlignment == ECogWidgetAlignment::Center) + { + ImGui::TableSetupColumn("Stretch", ImGuiTableColumnFlags_WidthStretch); + } + + ImGui::TableNextRow(); + + if (Settings->WidgetAlignment == ECogWidgetAlignment::Right || Settings->WidgetAlignment == ECogWidgetAlignment::Center) + { + ImGui::TableNextColumn(); + } + + for (int i = 0; i < Widgets.Num(); ++i) + { + FCogWindow* Window = Widgets[i]; + if (Window->GetIsWidgetVisible() == false) + { continue; } + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 2); + Window->RenderMainMenuWidget(); + } + + if (Settings->WidgetAlignment == ECogWidgetAlignment::Center) + { + ImGui::TableNextColumn(); + } + + ImGui::EndTable(); + } } //-------------------------------------------------------------------------------------------------------------------------- @@ -553,7 +546,7 @@ void UCogWindowManager::RenderMenuItem(FCogWindow& Window, const char* MenuItemN { Window.SetIsVisible(!Window.GetIsVisible()); } - + RenderMenuItemHelp(Window); } else diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp index 7245582..692a302 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowWidgets.cpp @@ -41,15 +41,17 @@ void FCogWindowWidgets::EndTableTooltip() } //-------------------------------------------------------------------------------------------------------------------------- -void FCogWindowWidgets::ItemTooltipWrappedText(const char* InText) +bool FCogWindowWidgets::ItemTooltipWrappedText(const char* InText) { - if (ImGui::BeginItemTooltip()) - { - ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); - ImGui::TextUnformatted(InText); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } + bool result = ImGui::BeginItemTooltip(); + if (result == false) + { return false; } + + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(InText); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + return true; } //-------------------------------------------------------------------------------------------------------------------------- @@ -272,26 +274,19 @@ void FCogWindowWidgets::AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Po } //-------------------------------------------------------------------------------------------------------------------------- -void FCogWindowWidgets::SearchBar(ImGuiTextFilter& Filter, float Width /*= -1*/) +bool FCogWindowWidgets::SearchBar(const char* InLabel, ImGuiTextFilter& InFilter, float InWidth /*= -1*/) { - const ImGuiWindow* Window = FCogImguiHelper::GetCurrentWindow(); - const ImVec2 Pos1 = Window->DC.CursorPos; - Filter.Draw("##Filter", Width); - const ImVec2 Pos2 = Window->DC.CursorPosPrevLine; - - if (ImGui::IsItemActive() == false && Filter.Filters.empty()) + if (InWidth != 0.0f) { - static const char* Text = "Search"; - const float Height = ImGui::GetFrameHeight(); - const ImGuiContext& g = *ImGui::GetCurrentContext(); - const ImVec2 Min = Pos1 + ImVec2(g.Style.ItemSpacing.x, 0.0f); - const ImVec2 Max = Pos2 + ImVec2(-g.Style.ItemSpacing.x, Height); - const ImRect BB(Min, Max); - const ImVec2 TextSize = ImGui::CalcTextSize(Text, nullptr); - ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 128)); - ImGui::RenderTextClipped(Min, Max, Text, nullptr, &TextSize, ImVec2(0.0f, 0.5f), &BB); - ImGui::PopStyleColor(); + ImGui::SetNextItemWidth(InWidth); } + // + bool value_changed = ImGui::InputTextWithHint(InLabel, "Search", InFilter.InputBuf, IM_ARRAYSIZE(InFilter.InputBuf)); + if (value_changed) + { + InFilter.Build(); + } + return value_changed; } //-------------------------------------------------------------------------------------------------------------------------- @@ -859,7 +854,7 @@ bool FCogWindowWidgets::ActorsListWithFilters(AActor*& NewSelection, const UWorl if (Filter != nullptr) { ImGui::SameLine(); - SearchBar(*Filter); + SearchBar("##Filter", *Filter); AddSeparator = true; } @@ -1121,15 +1116,30 @@ void FCogWindowWidgets::SmallButton(const char* Text, const ImVec4& Color) } //-------------------------------------------------------------------------------------------------------------------------- -bool FCogWindowWidgets::InputText(const char* Text, FString& Value) +bool FCogWindowWidgets::InputText(const char* Text, FString& Value, ImGuiInputTextFlags InFlags, ImGuiInputTextCallback InCallback, void* InUserData) { - static char Buffer[256] = ""; - ImStrncpy(Buffer, TCHAR_TO_ANSI(*Value), IM_ARRAYSIZE(Buffer)); + static char ValueBuffer[256] = ""; + ImStrncpy(ValueBuffer, TCHAR_TO_ANSI(*Value), IM_ARRAYSIZE(ValueBuffer)); - bool result = ImGui::InputText(Text, Buffer, IM_ARRAYSIZE(Buffer)); + bool result = ImGui::InputText(Text, ValueBuffer, IM_ARRAYSIZE(ValueBuffer), InFlags, InCallback, InUserData); if (result) { - Value = FString(Buffer); + Value = FString(ValueBuffer); + } + + return result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FCogWindowWidgets::InputTextWithHint(const char* InText, const char* InHint, FString& InValue, ImGuiInputTextFlags InFlags, ImGuiInputTextCallback InCallback, void* InUserData) +{ + static char ValueBuffer[256] = ""; + ImStrncpy(ValueBuffer, TCHAR_TO_ANSI(*InValue), IM_ARRAYSIZE(ValueBuffer)); + + bool result = ImGui::InputTextWithHint(InText, InHint, ValueBuffer, IM_ARRAYSIZE(ValueBuffer), InFlags, InCallback, InUserData); + if (result) + { + InValue = FString(ValueBuffer); } return result; @@ -1142,6 +1152,7 @@ bool FCogWindowWidgets::BeginRightAlign(const char* Id) { ImGui::TableSetupColumn("a", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::TableNextColumn(); return true; @@ -1266,7 +1277,48 @@ bool FCogWindowWidgets::OpenObjectAssetButton(const UObject* InObject, const ImV } +//-------------------------------------------------------------------------------------------------------------------------- +void FCogWindowWidgets::RenderClosebutton(const ImVec2& InPos) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + // Tweak 1: Shrink hit-testing area if button covers an abnormally large proportion of the visible region. That's in order to facilitate moving the window away. (#3825) + // This may better be applied as a general hit-rect reduction mechanism for all widgets to ensure the area to move window is always accessible? + const ImRect bb(InPos, InPos + ImVec2(g.FontSize, g.FontSize)); + + ImU32 cross_col = ImGui::GetColorU32(ImGuiCol_Text); + ImVec2 cross_center = bb.GetCenter() - ImVec2(0.5f, 0.5f); + float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f; + window->DrawList->AddLine(cross_center + ImVec2(+cross_extent, +cross_extent), cross_center + ImVec2(-cross_extent, -cross_extent), cross_col, 1.0f); + window->DrawList->AddLine(cross_center + ImVec2(+cross_extent, -cross_extent), cross_center + ImVec2(-cross_extent, +cross_extent), cross_col, 1.0f); +} - - +// //-------------------------------------------------------------------------------------------------------------------------- +// bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiButtonFlags flags) +// { +// ImGuiContext& g = *GImGui; +// ImGuiWindow* window = GetCurrentWindow(); +// if (window->SkipItems) +// return false; +// +// const ImGuiID id = window->GetID(str_id); +// const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); +// const float default_size = GetFrameHeight(); +// ItemSize(size, (size.y >= default_size) ? g.Style.FramePadding.y : -1.0f); +// if (!ItemAdd(bb, id)) +// return false; +// +// bool hovered, held; +// bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); +// +// // Render +// const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); +// const ImU32 text_col = GetColorU32(ImGuiCol_Text); +// RenderNavCursor(bb, id); +// RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding); +// RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir); +// +// IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags); +// return pressed; +// } \ 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 b418747..d72949a 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindow_Settings.cpp @@ -173,6 +173,68 @@ void FCogWindow_Settings::RenderContent() } } + //------------------------------------------------------------------------------------------- + if (ImGui::CollapsingHeader("Widgets (?)", ImGuiTreeNodeFlags_DefaultOpen)) + { + FCogWindowWidgets::ItemTooltipWrappedText("Widgets appear in the main menu bar."); + + ImGui::Checkbox("Show Widget Borders", &Config->ShowWidgetBorders); + FCogWindowWidgets::ItemTooltipWrappedText("Should a border be visible between widgets."); + + FCogWindowWidgets::SetNextItemToShortWidth(); + FCogWindowWidgets::ComboboxEnum("Widgets Alignment", Config->WidgetAlignment); + FCogWindowWidgets::ItemTooltipWrappedText("How the widgets should be aligned in the main menu bar."); + + if (ImGui::BeginChild("Widgets", ImVec2(0, ImGui::GetFontSize() * 10), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY, ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + ImGui::TextUnformatted("Widgets visibility and ordering"); + ImGui::SameLine(); + FCogWindowWidgets::HelpMarker("Drag and drop the widget names to reorder them."); + ImGui::EndMenuBar(); + } + + TArray& Widgets = GetOwner()->Widgets; + for (int32 i = 0; i < Widgets.Num(); ++i) + { + FCogWindow* Window = Widgets[i]; + + ImGui::PushID(i); + + bool Visible = Window->GetIsWidgetVisible(); + if (ImGui::Checkbox("##Visibility", &Visible)) + { + Window->SetIsWidgetVisible(Visible); + } + + ImGui::SameLine(); + ImGui::Selectable(TCHAR_TO_ANSI(*Window->GetName()), false, ImGuiSelectableFlags_SpanAvailWidth); + { + Window->SetIsWidgetVisible(Visible); + } + if (ImGui::IsItemHovered()) + { + ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS); + } + + if (ImGui::IsItemActive() && ImGui::IsItemHovered() == false) + { + const int iNext = i + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); + if (iNext >= 0 && iNext < Widgets.Num()) + { + Widgets[i] = Widgets[iNext]; + Widgets[iNext] = Window; + ImGui::ResetMouseDragDelta(); + } + } + + ImGui::PopID(); + } + } + ImGui::EndChild(); + } + //------------------------------------------------------------------------------------------- if (ImGui::CollapsingHeader("Shortcuts", ImGuiTreeNodeFlags_DefaultOpen)) { diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindow.h b/Plugins/Cog/Source/CogWindow/Public/CogWindow.h index 78b0611..d22f185 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindow.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindow.h @@ -38,10 +38,7 @@ public: virtual void GameTick(float DeltaTime); /** */ - virtual float GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth) { return -1.0f; } - - /** */ - virtual void RenderMainMenuWidget(int32 SubWidgetIndex, float Width) {} + virtual void RenderMainMenuWidget() {} ImGuiID GetID() const { return ID; } @@ -61,7 +58,7 @@ public: void SetIsVisible(bool Value); - bool HasWidget() const { return bHasWidget; } + int32 HasWidget() const { return bHasWidget; } bool GetIsWidgetVisible() const { return bIsWidgetVisible; } @@ -107,6 +104,8 @@ protected: virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) {} + virtual bool IsWindowRenderedInMainMenu(); + APawn* GetLocalPlayerPawn() const; APlayerController* GetLocalPlayerController() const; @@ -123,7 +122,7 @@ protected: bool bIsVisible = false; - bool bHasWidget = false; + int32 bHasWidget = 0; bool bIsWidgetVisible = false; diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h index f5b197d..2b75475 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h @@ -75,12 +75,15 @@ public: FCogImguiContext& GetContext() { return Context; } + static void AddCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key); static void SortCommands(UPlayerInput* PlayerInput); void OnShortcutsDefined() const; + bool IsRenderingMainMenu() const { return IsRenderingInMainMenu; } + protected: friend class FCogWindow_Layouts; @@ -111,6 +114,8 @@ protected: virtual void HandleInputs(); + virtual void RenderWidgets(); + static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*); static void SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*); @@ -169,6 +174,8 @@ protected: bool bIsSelectionModeActive = false; bool IsInitialized = false; + + bool IsRenderingInMainMenu = false; }; //-------------------------------------------------------------------------------------------------------------------------- diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h index 1c234fb..1d9468e 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowWidgets.h @@ -27,7 +27,7 @@ public: static void EndTableTooltip(); - static void ItemTooltipWrappedText(const char* InText); + static bool ItemTooltipWrappedText(const char* InText); static bool BeginItemTableTooltip(); @@ -61,7 +61,7 @@ public: static void AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd = NULL); - static void SearchBar(ImGuiTextFilter& Filter, float Width = -1.0f); + static bool SearchBar(const char* InLabel, ImGuiTextFilter& InFilter, float InWidth = -1.0f); static void PushBackColor(const ImVec4& Color); @@ -90,7 +90,7 @@ public: 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); @@ -117,7 +117,9 @@ public: static void SmallButton(const char* Text, const ImVec4& Color); - static bool InputText(const char* Text, FString& Value); + static bool InputText(const char* Text, FString& Value, ImGuiInputTextFlags InFlags = 0, ImGuiInputTextCallback InCallback = nullptr, void* InUserData = nullptr); + + static bool InputTextWithHint(const char* InText, const char* InHint, FString& InValue, ImGuiInputTextFlags InFlags = 0, ImGuiInputTextCallback InCallback = nullptr, void* InUserData = nullptr); static bool BeginRightAlign(const char* Id); @@ -133,6 +135,8 @@ public: static bool OpenObjectAssetButton(const UObject* InObject, const ImVec2& InSize = ImVec2(0, 0)); + static void RenderClosebutton(const ImVec2& InPos); + }; template diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h index f2d08b4..893b340 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Settings.h @@ -37,6 +37,15 @@ protected: TObjectPtr Config = nullptr; }; +//-------------------------------------------------------------------------------------------------------------------------- +UENUM() +enum class ECogWidgetAlignment +{ + Left = 0, + Center = 1, + Right = 2, + Manual = 3 +}; //-------------------------------------------------------------------------------------------------------------------------- UCLASS(Config = Cog) @@ -85,6 +94,12 @@ public: UPROPERTY(Config) bool bDisableShortcutsWhenImGuiWantTextInput = false; + UPROPERTY(Config) + ECogWidgetAlignment WidgetAlignment = ECogWidgetAlignment::Right; + + UPROPERTY(Config) + bool ShowWidgetBorders = false; + UPROPERTY(Config) FCogImGuiKeyInfo ToggleImGuiInputShortcut = FCogImGuiKeyInfo(EKeys::F1); diff --git a/Plugins/Cog/Source/ThirdParty/ImGui/imgui_widgets.cpp b/Plugins/Cog/Source/ThirdParty/ImGui/imgui_widgets.cpp index 2cbef83..9550073 100644 --- a/Plugins/Cog/Source/ThirdParty/ImGui/imgui_widgets.cpp +++ b/Plugins/Cog/Source/ThirdParty/ImGui/imgui_widgets.cpp @@ -8757,21 +8757,33 @@ bool ImGui::BeginMainMenuBar() bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags); g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); - if (is_open) - BeginMenuBar(); - else + if (!is_open) + { End(); + return false; + } + + // Temporarily disable _NoSavedSettings, in the off-chance that tables or child windows submitted within the menu-bar may want to use settings. (#8356) + g.CurrentWindow->Flags &= ~ImGuiWindowFlags_NoSavedSettings; + BeginMenuBar(); return is_open; } void ImGui::EndMainMenuBar() { + ImGuiContext& g = *GImGui; + if (!g.CurrentWindow->DC.MenuBarAppending) + { + IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar + return; + } + EndMenuBar(); + g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356) // When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window // FIXME: With this strategy we won't be able to restore a NULL focus. - ImGuiContext& g = *GImGui; - if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest) + if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest && g.ActiveId == 0) FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild); End(); diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp index 278cdab..6d3f74a 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_BehaviorTree.cpp @@ -140,7 +140,7 @@ void FCogAIWindow_BehaviorTree::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp index 7453fa0..ef674fe 100644 --- a/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp +++ b/Plugins/CogAI/Source/CogAI/Private/CogAIWindow_Blackboard.cpp @@ -46,7 +46,7 @@ void FCogAIWindow_Blackboard::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp index 2788e86..5d017dc 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Abilities.cpp @@ -175,7 +175,7 @@ void FCogAbilityWindow_Abilities::RenderAbilitiesMenu(AActor* Selection) ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp index 69c00f7..3c25853 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Attributes.cpp @@ -108,7 +108,7 @@ void FCogAbilityWindow_Attributes::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } @@ -280,7 +280,7 @@ void FCogAbilityWindow_Attributes::RenderContent() { Selected = Index; - if (ImGui::IsMouseDoubleClicked(0)) + if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) { OpenAttributeDetails(Attribute); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp index fed189a..7deccd2 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp @@ -22,29 +22,6 @@ void FCogAbilityWindow_Cheats::Initialize() Asset = GetAsset(); Config = GetConfig(); AlignmentConfig = GetConfig(); - - FCogWindowConsoleCommandManager::RegisterWorldConsoleCommand( - TEXT("Cog.Cheat"), - TEXT("Apply a cheat to the selection. Cog.Cheat -Allies -Enemies -Controlled"), - GetWorld(), - FCogWindowConsoleCommandDelegate::CreateLambda([this](const TArray& InArgs, UWorld* InWorld) - { - if (InArgs.Num() > 0) - { - if (const FCogAbilityCheat* cheat = FindCheatByName(InArgs[0])) - { - const bool ApplyToEnemies = InArgs.Contains("-Enemies"); - const bool ApplyToAllies = InArgs.Contains("-Allies"); - const bool ApplyToControlled = InArgs.Contains("-Controlled"); - - RequestCheat(GetLocalPlayerPawn(), GetSelection(), *cheat, ApplyToEnemies, ApplyToAllies, ApplyToControlled); - } - else - { - UE_LOG(LogCogImGui, Warning, TEXT("Cog.Cheat %s | Cheat not found"), *InArgs[0]); - } - } - })); } //-------------------------------------------------------------------------------------------------------------------------- diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp index 2df399e..aae8194 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Effects.cpp @@ -74,7 +74,7 @@ void FCogAbilityWindow_Effects::RenderContent() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp index 6cf697f..f67424d 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tags.cpp @@ -67,7 +67,7 @@ void FCogAbilityWindow_Tags::RenderMenu() ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); } diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tasks.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tasks.cpp index bea5113..f02d27f 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tasks.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Tasks.cpp @@ -98,7 +98,7 @@ void FCogAbilityWindow_Tasks::RenderTaskMenu(AActor* Selection) ImGui::EndMenu(); } - FCogWindowWidgets::SearchBar(Filter); + FCogWindowWidgets::SearchBar("##Filter", Filter); ImGui::EndMenuBar(); }