Merge pull request #22 from arnaud-jamin/new-windows

New windows
This commit is contained in:
Arnaud Jamin
2024-01-08 01:41:57 -05:00
committed by GitHub
31 changed files with 649 additions and 463 deletions
@@ -19,7 +19,7 @@ void FCogDebug::Reset()
//--------------------------------------------------------------------------------------------------------------------------
bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject)
{
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
const UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
if (World == nullptr)
{
return true;
@@ -30,7 +30,7 @@ bool FCogDebug::IsDebugActiveForObject(const UObject* WorldContextObject)
return true;
}
bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection.Get(), Settings.bIsFilteringBySelection);
const bool Result = IsDebugActiveForObject_Internal(WorldContextObject, Selection.Get(), Settings.bIsFilteringBySelection);
return Result;
}
@@ -92,7 +92,7 @@ AActor* FCogDebug::GetSelection()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogDebug::SetSelection(UWorld* World, AActor* Value)
void FCogDebug::SetSelection(const UWorld* World, AActor* Value)
{
Selection = Value;
@@ -2,7 +2,6 @@
#include "CogDebug.h"
#include "Components/LineBatchComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Engine/Engine.h"
#include "DrawDebugHelpers.h"
#include "Components/BoxComponent.h"
@@ -423,7 +423,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
InOutTransform.SetLocation(NewLocation);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
//DrawDebugPoint(World, InitialTransform.GetTranslation(), 5.0f, FColor::White);
@@ -453,7 +453,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
InOutTransform.SetLocation(NewLocation);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f %0.1f"), SnappedDeltaU, SnappedDeltaV);
const FString Text = FString::Printf(TEXT("%+0.1f %+0.1f"), SnappedDeltaU, SnappedDeltaV);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
//DrawDebugPoint(World, InitialTransform.GetTranslation(), 5.0f, FColor::White);
@@ -474,7 +474,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
InOutTransform.SetRotation(NewRot);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedAngle);
const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedAngle);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
break;
@@ -490,7 +490,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
InOutTransform.SetScale3D(NewScale);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
break;
@@ -505,7 +505,7 @@ bool FCogDebug_Gizmo::Draw(const char* Id, const APlayerController& InPlayerCont
InOutTransform.SetScale3D(NewScale);
Result = true;
const FString Text = FString::Printf(TEXT("%0.1f"), SnappedDelta);
const FString Text = FString::Printf(TEXT("%+0.1f"), SnappedDelta);
DrawGizmoText(FCogImguiHelper::ToImVec2(Center2D), FCogImguiHelper::ToImU32(Settings.GizmoTextColor), StringCast<ANSICHAR>(*Text).Get());
break;
@@ -24,9 +24,9 @@ ACogDebugReplicator* ACogDebugReplicator::Spawn(APlayerController* Controller)
}
//--------------------------------------------------------------------------------------------------------------------------
ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(UWorld& World)
ACogDebugReplicator* ACogDebugReplicator::GetLocalReplicator(const UWorld& World)
{
for (TActorIterator<ACogDebugReplicator> It(&World, ACogDebugReplicator::StaticClass()); It; ++It)
for (TActorIterator<ACogDebugReplicator> It(&World, StaticClass()); It; ++It)
{
ACogDebugReplicator* Replicator = *It;
return Replicator;
@@ -61,6 +61,9 @@ struct FCogDebugSettings
UPROPERTY(Config)
float TextSize = 1.0f;
UPROPERTY(Config)
bool ActorNameUseLabel = true;
UPROPERTY(Config)
float GizmoScale = 1.0f;
@@ -363,7 +366,7 @@ public:
static AActor* GetSelection();
static void SetSelection(UWorld* World, AActor* Value);
static void SetSelection(const UWorld* World, AActor* Value);
static bool GetIsFilteringBySelection();
@@ -61,7 +61,7 @@ public:
static ACogDebugReplicator* Spawn(APlayerController* Controller);
static ACogDebugReplicator* GetLocalReplicator(UWorld& World);
static ACogDebugReplicator* GetLocalReplicator(const UWorld& World);
static void GetRemoteReplicators(UWorld& World, TArray<ACogDebugReplicator*>& Replicators);
+13 -27
View File
@@ -4,32 +4,16 @@ public class CogEngine : ModuleRules
{
public CogEngine(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[]
{
}
);
PrivateIncludePaths.AddRange(
new string[]
{
}
);
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(
new string[]
new []
{
"CogDebug",
}
);
});
PrivateDependencyModuleNames.AddRange(
new string[]
new []
{
"CogCommon",
"CogImgui",
@@ -41,14 +25,16 @@ public class CogEngine : ModuleRules
"NetCore",
"Slate",
"SlateCore",
}
);
});
DynamicallyLoadedModuleNames.AddRange(
new string[]
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.AddRange(
new []
{
}
);
"AssetTools"
});
}
}
}
@@ -0,0 +1,68 @@
#include "CogEngineHelper.h"
#include "CogEngineReplicator.h"
#include "CogWindowHelper.h"
#include "CogWindowWidgets.h"
#include "imgui.h"
#if WITH_EDITOR
#include "IAssetTools.h"
#endif
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineHelper::ActorContextMenu(AActor& Actor)
{
FCogWindowWidgets::ThinSeparatorText("Object");
#if WITH_EDITOR
const UObject* DefaultObject = Actor.GetClass()->GetDefaultObject();
if (DefaultObject == nullptr)
{
ImGui::BeginDisabled();
}
if (ImGui::Button("Browse To Asset", ImVec2(-1, 0)))
{
IAssetTools::Get().SyncBrowserToAssets({ DefaultObject });
}
if (DefaultObject == nullptr)
{
ImGui::EndDisabled();
}
#endif
if (ImGui::Button("Delete", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld()))
{
Replicator->Server_DeleteActor(&Actor);
}
}
if (APawn* Pawn = Cast<APawn>(&Actor))
{
FCogWindowWidgets::ThinSeparatorText("Pawn");
if (ImGui::Button("Possess", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld()))
{
Replicator->Server_Possess(Pawn);
}
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Possess this pawn.");
}
if (ImGui::Button("Reset Possession", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*Actor.GetWorld()))
{
Replicator->Server_ResetPossession();
}
}
}
}
@@ -207,3 +207,16 @@ void ACogEngineReplicator::Server_ResetPossession_Implementation()
#endif // !UE_BUILD_SHIPPING
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogEngineReplicator::Server_DeleteActor_Implementation(AActor* Actor)
{
#if !UE_BUILD_SHIPPING
if (Actor != nullptr)
{
GetWorld()->DestroyActor(Actor);
}
#endif // !UE_BUILD_SHIPPING
}
@@ -43,38 +43,17 @@ void FCogEngineWindow_CollisionTester::RenderContent()
//-------------------------------------------------
if (ImGui::BeginMenuBar())
{
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
if (ImGui::ArrowButton("SelectPrev", ImGuiDir_Left))
{
}
if (ImGui::BeginItemTooltip())
{
ImGui::SetTooltip("Select previous collision tester");
ImGui::EndTooltip();
}
ImGui::SameLine();
if (ImGui::ArrowButton("SelectNext", ImGuiDir_Right))
{
}
if (ImGui::BeginItemTooltip())
{
ImGui::SetTooltip("Select next collision tester");
ImGui::EndTooltip();
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(1);
if (ImGui::MenuItem("Spawn"))
{
const FActorSpawnParameters SpawnInfo;
const FTransform Transform = GetSelection() ? GetSelection()->GetActorTransform() : FTransform::Identity;
ACogEngineCollisionTester* Actor = GetWorld()->SpawnActor<ACogEngineCollisionTester>(ACogEngineCollisionTester::StaticClass(), Transform, SpawnInfo);
FCogDebug::SetSelection(GetWorld(), Actor);
ACogEngineCollisionTester* NewActor = GetWorld()->SpawnActor<ACogEngineCollisionTester>(ACogEngineCollisionTester::StaticClass(), Transform, SpawnInfo);
#if WITH_EDITOR
NewActor->SetActorLabel(NewActor->GetName().Replace(TEXT("CogEngine"), TEXT("")));
#endif
FCogDebug::SetSelection(GetWorld(), NewActor);
}
if (ImGui::BeginItemTooltip())
{
@@ -102,12 +81,17 @@ void FCogEngineWindow_CollisionTester::RenderContent()
ImGui::EndDisabled();
}
ImGui::SetNextItemWidth(-1);
FCogWindowWidgets::MenuActorsCombo("CollisionTesters", *GetWorld(), ACogEngineCollisionTester::StaticClass());
ImGui::EndMenuBar();
}
if (CollisionTester == nullptr)
{
ImGui::TextDisabled("Spawn or select a Collision Tester actor");
ImGui::PushTextWrapPos(0.0f);
ImGui::TextDisabled("Select or spawn a Collision Tester actor");
ImGui::PopTextWrapPos();
return;
}
@@ -224,19 +208,19 @@ void FCogEngineWindow_CollisionTester::RenderContent()
}
}
ImGui::Separator();
//-------------------------------------------------
// Channels
//-------------------------------------------------
if (CollisionTester->By == ECogEngine_CollisionQueryBy::Profile)
{
ImGui::Separator();
ImGui::BeginDisabled();
FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery);
ImGui::EndDisabled();
}
else if (CollisionTester->By == ECogEngine_CollisionQueryBy::ObjectType)
{
ImGui::Separator();
FCogWindowWidgets::CollisionProfileChannels(CollisionTester->ObjectTypesToQuery);
}
}
@@ -91,6 +91,12 @@ void FCogEngineWindow_DebugSettings::RenderContent()
ImGui::SetTooltip("Make debug draw always persist");
}
ImGui::Checkbox("Actor Name Use Label", &Settings.ActorNameUseLabel);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
{
ImGui::SetTooltip("Use the actor label when displaying the actor name.");
}
ImGui::Checkbox("Text Shadow", &Settings.TextShadow);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
{
@@ -250,7 +250,7 @@ void FCogEngineWindow_Inspector::RenderMenu()
//-----------------------------------
// Search
//-----------------------------------
FCogWindowWidgets::MenuSearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9);
FCogWindowWidgets::SearchBar(Filter, -FCogWindowWidgets::GetFontWidth() * 9);
//-----------------------------------
// Options
@@ -171,7 +171,7 @@ void FCogEngineWindow_OutputLog::RenderContent()
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 9);
if (ImGui::BeginCombo("##Verbosity", FCogDebugHelper::VerbosityToString((ELogVerbosity::Type)Config->VerbosityFilter)))
{
for (int32 i = (int32)ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
for (int32 i = ELogVerbosity::Error; i <= (int32)ELogVerbosity::VeryVerbose; ++i)
{
const bool IsSelected = i == Config->VerbosityFilter;
const ELogVerbosity::Type Verbosity = (ELogVerbosity::Type)i;
@@ -184,7 +184,7 @@ void FCogEngineWindow_OutputLog::RenderContent()
ImGui::EndCombo();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -1,8 +1,8 @@
#include "CogEngineWindow_Selection.h"
#include "CogDebugDraw.h"
#include "CogDebug.h"
#include "CogEngineReplicator.h"
#include "CogEngineHelper.h"
#include "CogEngineWindow_ImGui.h"
#include "CogImguiHelper.h"
#include "CogImguiInputHelper.h"
#include "CogWindowManager.h"
@@ -75,7 +75,7 @@ void FCogEngineWindow_Selection::PreSaveConfig()
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::TryReapplySelection() const
{
UWorld* World = GetWorld();
const UWorld* World = GetWorld();
if (World == nullptr)
{
return;
@@ -91,14 +91,14 @@ void FCogEngineWindow_Selection::TryReapplySelection() const
return;
}
TSubclassOf<AActor> SelectedClass = GetSelectedActorClass();
const TSubclassOf<AActor> SelectedClass = GetSelectedActorClass();
if (SelectedClass == nullptr)
{
return;
}
TArray<AActor*> Actors;
for (TActorIterator<AActor> It(World, SelectedClass); It; ++It)
for (TActorIterator It(World, SelectedClass); It; ++It)
{
AActor* Actor = *It;
if (GetNameSafe(Actor) == Config->SelectionName)
@@ -155,9 +155,9 @@ void FCogEngineWindow_Selection::DeactivateSelectionMode()
bSelectionModeActive = false;
//--------------------------------------------------------------------------------------------
// We can enter selection mode by a command, and imgui might not have the input focus
// When in selection mode we need imgui to have the input focus
// When leaving selection mode we want to leave it as is was before
// We can enter selection mode by a command, and ImGui might not have the input focus
// When in selection mode we need ImGui to have the input focus
// When leaving selection mode we want to leave it as it was before
//--------------------------------------------------------------------------------------------
GetOwner()->GetContext().SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
@@ -179,11 +179,11 @@ void FCogEngineWindow_Selection::RenderTick(float DeltaTime)
TickSelectionMode();
}
if (AActor* Actor = GetSelection())
if (const AActor* Actor = GetSelection())
{
if (Actor != GetLocalPlayerPawn())
{
DrawActorFrame(*Actor);
FCogWindowWidgets::ActorFrame(*Actor);
}
}
}
@@ -198,8 +198,16 @@ void FCogEngineWindow_Selection::RenderContent()
if (ImGui::MenuItem("Pick"))
{
ActivateSelectionMode();
HackWaitInputRelease();
//HackWaitInputRelease();
}
if (ImGui::BeginMenu("Options"))
{
ImGui::Checkbox("Save selection", &Config->bReapplySelection);
ImGui::Checkbox("Actor Name Use Label", &FCogDebug::Settings.ActorNameUseLabel);
ImGui::EndMenu();
}
RenderPickButtonTooltip();
ImGui::EndMenuBar();
@@ -211,171 +219,7 @@ void FCogEngineWindow_Selection::RenderContent()
//--------------------------------------------------------------------------------------------------------------------------
bool FCogEngineWindow_Selection::DrawSelectionCombo()
{
bool SelectionChanged = false;
APawn* LocalPlayerPawn = GetLocalPlayerPawn();
//------------------------
// Actor Class Combo
//------------------------
TSubclassOf<AActor> SelectedClass = GetSelectedActorClass();
ImGui::SetNextItemWidth(-1);
if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedClass))))
{
for (int32 i = 0; i < ActorClasses.Num(); ++i)
{
TSubclassOf<AActor> SubClass = ActorClasses[i];
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(SubClass)), false))
{
Config->SelectedClassIndex = i;
SelectedClass = SubClass;
}
}
ImGui::EndCombo();
}
ImGui::Separator();
//------------------------
// Actor List
//------------------------
ImGui::BeginChild("ActorList", ImVec2(-1, -1), false);
TArray<AActor*> Actors;
for (TActorIterator<AActor> It(GetWorld(), SelectedClass); It; ++It)
{
AActor* Actor = *It;
Actors.Add(Actor);
}
ImGuiListClipper Clipper;
Clipper.Begin(Actors.Num());
while (Clipper.Step())
{
for (int32 i = Clipper.DisplayStart; i < Clipper.DisplayEnd; i++)
{
AActor* Actor = Actors[i];
if (Actor == nullptr)
{
continue;
}
ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255));
bool bIsSelected = Actor == FCogDebug::GetSelection();
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetActorName(*Actor)), bIsSelected))
{
SetGlobalSelection(Actor);
SelectionChanged = true;
}
ImGui::PopStyleColor(1);
DrawActorContextMenu(Actor);
//------------------------
// Draw Frame
//------------------------
if (ImGui::IsItemHovered())
{
DrawActorFrame(*Actor);
}
if (bIsSelected)
{
ImGui::SetItemDefaultFocus();
}
}
}
Clipper.End();
ImGui::EndChild();
return SelectionChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogEngineWindow_Selection::GetActorName(const AActor* Actor) const
{
if (Actor == nullptr)
{
return FString("none");
}
return GetActorName(*Actor);
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogEngineWindow_Selection::GetActorName(const AActor& Actor) const
{
#if WITH_EDITOR
return Config->bDisplayActorLabel ? Actor.GetActorLabel() : Actor.GetName();
#else //WITH_EDITOR
return Actor.GetName();
#endif //WITH_EDITOR
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::DrawActorContextMenu(AActor* Actor)
{
//------------------------
// ContextMenu
//------------------------
ImGui::SetNextWindowSize(ImVec2(FCogWindowWidgets::GetFontWidth() * 30, 0));
if (ImGui::BeginPopupContextItem())
{
if (ImGui::Button("Reset Selection", ImVec2(-1, 0)))
{
ImGui::CloseCurrentPopup();
SetGlobalSelection(GetLocalPlayerPawn());
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Reset the selection to the controlled actor.");
}
if (APawn* Pawn = Cast<APawn>(Actor))
{
if (ImGui::Button("Possess", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_Possess(Pawn);
}
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Possess this pawn.");
}
if (ImGui::Button("Reset Possession", ImVec2(-1, 0)))
{
if (ACogEngineReplicator* Replicator = ACogEngineReplicator::GetLocalReplicator(*GetWorld()))
{
Replicator->Server_ResetPossession();
}
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Reset pawn.");
}
}
ImGui::Separator();
ImGui::Checkbox("Save selection", &Config->bReapplySelection);
ImGui::Checkbox("Display Actor Label", &Config->bDisplayActorLabel);
ImGui::EndPopup();
}
return FCogWindowWidgets::ActorsListWithFilters(*GetWorld(), ActorClasses, Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn());
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -439,7 +283,7 @@ void FCogEngineWindow_Selection::TickSelectionMode()
if (HoveredActor != nullptr)
{
DrawActorFrame(*HoveredActor);
FCogWindowWidgets::ActorFrame(*HoveredActor);
}
if (bSelectionModeActive)
@@ -463,107 +307,6 @@ void FCogEngineWindow_Selection::TickSelectionMode()
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor)
{
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
if (PlayerController == nullptr)
{
return;
}
ImGuiViewport* Viewport = ImGui::GetMainViewport();
if (Viewport == nullptr)
{
return;
}
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
FVector BoxOrigin, BoxExtent;
bool PrimitiveFound = false;
FBox Bounds(ForceInit);
if (const UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(Actor.GetRootComponent()))
{
PrimitiveFound = true;
Bounds += PrimitiveComponent->Bounds.GetBox();
}
else
{
Actor.ForEachComponent<UPrimitiveComponent>(true, [&](const UPrimitiveComponent* InPrimComp)
{
if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled())
{
Bounds += InPrimComp->Bounds.GetBox();
PrimitiveFound = true;
}
});
}
if (PrimitiveFound)
{
Bounds.GetCenterAndExtents(BoxOrigin, BoxExtent);
}
else
{
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);
DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin) + Viewport->Pos, FCogImguiHelper::ToImVec2(ScreenPosMax) + Viewport->Pos, Color, 0.0f, 0, 1.0f);
FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)) + Viewport->Pos, Color, TCHAR_TO_ANSI(*GetActorName(Actor)));
}
}
//-----------------------------------------------------------------------------------------
bool FCogEngineWindow_Selection::ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max)
{
FVector Corners[8];
Corners[0].Set(-Extent.X, -Extent.Y, -Extent.Z); // - - -
Corners[1].Set(Extent.X, -Extent.Y, -Extent.Z); // + - -
Corners[2].Set(-Extent.X, Extent.Y, -Extent.Z); // - + -
Corners[3].Set(-Extent.X, -Extent.Y, Extent.Z); // - - +
Corners[4].Set(Extent.X, Extent.Y, -Extent.Z); // + + -
Corners[5].Set(Extent.X, -Extent.Y, Extent.Z); // + - +
Corners[6].Set(-Extent.X, Extent.Y, Extent.Z); // - + +
Corners[7].Set(Extent.X, Extent.Y, Extent.Z); // + + +
Min.X = FLT_MAX;
Min.Y = FLT_MAX;
Max.X = -FLT_MAX;
Max.Y = -FLT_MAX;
for (int i = 0; i < 8; ++i)
{
FVector2D ScreenLocation;
if (PlayerController->ProjectWorldLocationToScreen(Origin + Corners[i], ScreenLocation, false) == false)
{
return false;
}
Min.X = FMath::Min(ScreenLocation.X, Min.X);
Min.Y = FMath::Min(ScreenLocation.Y, Min.Y);
Max.X = FMath::Max(ScreenLocation.X, Max.X);
Max.Y = FMath::Max(ScreenLocation.Y, Max.Y);
}
// Prevent getting large values when the camera get close to the target
ImVec2 DisplaySize = ImGui::GetIO().DisplaySize;
Min.X = FMath::Max(-DisplaySize.x, Min.X);
Min.Y = FMath::Max(-DisplaySize.y, Min.Y);
Max.X = FMath::Min(DisplaySize.x * 2, Max.X);
Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y);
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, float MaxWidth)
{
@@ -577,7 +320,6 @@ float FCogEngineWindow_Selection::GetMainMenuWidgetWidth(int32 SubWidgetIndex, f
return -1.0f;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, float Width)
{
@@ -602,44 +344,8 @@ void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, floa
}
else if (SubWidgetIndex == 1)
{
if (ImGui::BeginPopup("SelectionPopup"))
{
ImGui::BeginChild("Popup", ImVec2(Width, FCogWindowWidgets::GetFontWidth() * 40), false);
if (DrawSelectionCombo())
{
ImGui::CloseCurrentPopup();
}
ImGui::EndChild();
ImGui::EndPopup();
}
AActor* GlobalSelection = FCogDebug::GetSelection();
//-----------------------------------
// Selection
//-----------------------------------
{
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));
FString CurrentSelectionName = GetActorName(GlobalSelection);
if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(Width, 0.0f)))
{
ImGui::OpenPopup("SelectionPopup");
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*CurrentSelectionName));
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(2);
DrawActorContextMenu(GlobalSelection);
}
ImGui::SetNextItemWidth(Width);
FCogWindowWidgets::MenuActorsCombo("MenuActorSelection", *GetWorld(), ActorClasses, Config->SelectedClassIndex, &Filter, GetLocalPlayerPawn(), [this](AActor& Actor) { RenderActorContextMenu(Actor); });
}
else if (SubWidgetIndex == 2)
{
@@ -664,6 +370,12 @@ void FCogEngineWindow_Selection::RenderMainMenuWidget(int32 SubWidgetIndex, floa
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::RenderActorContextMenu(AActor& Actor)
{
FCogEngineHelper::ActorContextMenu(Actor);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Selection::SetGlobalSelection(AActor* Value) const
{
@@ -111,7 +111,7 @@ void FCogEngineWindow_Skeleton::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -0,0 +1,11 @@
#pragma once
#include "CoreMinimal.h"
class COGENGINE_API FCogEngineHelper
{
public:
static void ActorContextMenu(AActor& Actor);
};
@@ -10,7 +10,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogCogEngine, Verbose, All);
class APlayerController;
using FCogEnineSpawnFunction = TFunction<void(const FCogEngineSpawnEntry& SpawnEntry)>;
using FCogEngineSpawnFunction = TFunction<void(const FCogEngineSpawnEntry& SpawnEntry)>;
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(NotBlueprintable, NotBlueprintType, notplaceable, noteditinlinenew, hidedropdown, Transient)
@@ -30,9 +30,9 @@ public:
APlayerController* GetPlayerController() const { return OwnerPlayerController.Get(); }
FCogEnineSpawnFunction GetSpawnFunction() const { return SpawnFunction; }
FCogEngineSpawnFunction GetSpawnFunction() const { return SpawnFunction; }
void SetSpawnFunction(FCogEnineSpawnFunction Value) { SpawnFunction = Value; }
void SetSpawnFunction(FCogEngineSpawnFunction Value) { SpawnFunction = Value; }
UFUNCTION(Server, Reliable)
void Server_Spawn(const FCogEngineSpawnEntry& SpawnEntry);
@@ -47,6 +47,9 @@ public:
UFUNCTION(Server, Reliable)
void Server_ResetPossession();
UFUNCTION(Server, Reliable)
void Server_DeleteActor(AActor* Actor);
protected:
UFUNCTION(Server, Reliable)
@@ -65,5 +68,5 @@ private:
UPROPERTY(ReplicatedUsing = OnRep_TimeDilation)
float TimeDilation = 1.0f;
FCogEnineSpawnFunction SpawnFunction;
FCogEngineSpawnFunction SpawnFunction;
};
@@ -59,26 +59,18 @@ protected:
virtual bool DrawSelectionCombo();
virtual void DrawActorContextMenu(AActor* Actor);
virtual void HackWaitInputRelease();
virtual void SetGlobalSelection(AActor* Value) const;
virtual void RenderPickButtonTooltip();
virtual void RenderActorContextMenu(AActor& Actor);
TSubclassOf<AActor> GetSelectedActorClass() const;
FString GetActorName(const AActor* Actor) const;
FString GetActorName(const AActor& Actor) const;
void TickSelectionMode();
void DrawActorFrame(const AActor& Actor);
bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max);
FVector LastSelectedActorLocation = FVector::ZeroVector;
bool bSelectionModeActive = false;
@@ -94,6 +86,8 @@ protected:
TArray<IConsoleObject*> ConsoleCommands;
TObjectPtr<UCogEngineConfig_Selection> Config;
ImGuiTextFilter Filter;
};
//--------------------------------------------------------------------------------------------------------------------------
@@ -107,9 +101,6 @@ public:
UPROPERTY(Config)
bool bReapplySelection = true;
UPROPERTY(Config)
bool bDisplayActorLabel = true;
UPROPERTY(Config)
FString SelectionName;
@@ -121,7 +112,6 @@ public:
Super::Reset();
bReapplySelection = true;
bDisplayActorLabel = true;
SelectionName.Reset();
SelectedClassIndex = 0;
}
@@ -32,6 +32,25 @@ ImGuiWindow* FCogImguiHelper::GetCurrentWindow()
return Context.CurrentWindow;
}
//--------------------------------------------------------------------------------------------------------------------------
float FCogImguiHelper::GetNextItemWidth()
{
float Width;
const ImGuiContext& g = *GImGui;
if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth)
{
Width = g.NextItemData.Width;
}
else
{
const ImGuiWindow* Window = GetCurrentWindow();
Width = Window->DC.ItemWidth;
}
return Width;
}
//--------------------------------------------------------------------------------------------------------------------------
FColor FCogImguiHelper::ToFColor(ImU32 Color)
{
@@ -24,6 +24,8 @@ public:
static ImGuiWindow* GetCurrentWindow();
static float GetNextItemWidth();
static FColor ToFColor(ImU32 Color);
static FSlateRect ToSlateRect(const ImVec4& Value);
@@ -0,0 +1,90 @@
#include "CogWindowHelper.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "CogDebug.h"
//----------------------------------------------------------------------------------------------------------------------
const UObject* FCogWindowHelper::GetFirstAssetByClass(const TSubclassOf<UObject> AssetClass)
{
const IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")).Get();
TArray<FAssetData> Assets;
AssetRegistry.GetAssetsByClass(AssetClass->GetClassPathName(), Assets, true);
if (Assets.Num() == 0)
{
return nullptr;
}
const UObject* Asset = Assets[0].GetAsset();
return Asset;
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogWindowHelper::GetActorName(const AActor* Actor)
{
if (Actor == nullptr)
{
return FString("none");
}
return GetActorName(*Actor);
}
//--------------------------------------------------------------------------------------------------------------------------
FString FCogWindowHelper::GetActorName(const AActor& Actor)
{
#if WITH_EDITOR
const FCogDebugSettings& Settings = FCogDebug::Settings;
return Settings.ActorNameUseLabel ? Actor.GetActorLabel() : Actor.GetName();
#else //WITH_EDITOR
return Actor.GetName();
#endif //WITH_EDITOR
}
//-----------------------------------------------------------------------------------------
bool FCogWindowHelper::ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max)
{
FVector Corners[8];
Corners[0].Set(-Extent.X, -Extent.Y, -Extent.Z); // - - -
Corners[1].Set(Extent.X, -Extent.Y, -Extent.Z); // + - -
Corners[2].Set(-Extent.X, Extent.Y, -Extent.Z); // - + -
Corners[3].Set(-Extent.X, -Extent.Y, Extent.Z); // - - +
Corners[4].Set(Extent.X, Extent.Y, -Extent.Z); // + + -
Corners[5].Set(Extent.X, -Extent.Y, Extent.Z); // + - +
Corners[6].Set(-Extent.X, Extent.Y, Extent.Z); // - + +
Corners[7].Set(Extent.X, Extent.Y, Extent.Z); // + + +
Min.X = FLT_MAX;
Min.Y = FLT_MAX;
Max.X = -FLT_MAX;
Max.Y = -FLT_MAX;
for (int i = 0; i < 8; ++i)
{
FVector2D ScreenLocation;
if (PlayerController->ProjectWorldLocationToScreen(Origin + Corners[i], ScreenLocation, false) == false)
{
return false;
}
Min.X = FMath::Min(ScreenLocation.X, Min.X);
Min.Y = FMath::Min(ScreenLocation.Y, Min.Y);
Max.X = FMath::Max(ScreenLocation.X, Max.X);
Max.Y = FMath::Max(ScreenLocation.Y, Max.Y);
}
// Prevent getting large values when the camera get close to the target
ImVec2 DisplaySize = ImGui::GetIO().DisplaySize;
Min.X = FMath::Max(-DisplaySize.x, Min.X);
Min.Y = FMath::Max(-DisplaySize.y, Min.Y);
Max.X = FMath::Min(DisplaySize.x * 2, Max.X);
Max.Y = FMath::Min(DisplaySize.y * 2, Max.Y);
return true;
}
@@ -2,12 +2,14 @@
#include "CogDebug.h"
#include "CogImguiHelper.h"
#include "CogImguiKeyInfo.h"
#include "CogImguiInputHelper.h"
#include "CogImguiKeyInfo.h"
#include "CogWindowHelper.h"
#include "EngineUtils.h"
#include "GameFramework/PlayerInput.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "InputCoreTypes.h"
#include "GameFramework/PlayerInput.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::BeginTableTooltip()
@@ -26,6 +28,18 @@ void FCogWindowWidgets::EndTableTooltip()
ImGui::PopStyleVar(2);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ThinSeparatorText(const char* Label)
{
ImGui::PushStyleVar(ImGuiStyleVar_SeparatorTextBorderSize, 2);
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(100, 100, 100, 255));
ImGui::SeparatorText(Label);
ImGui::PopStyleColor();
ImGui::PopStyleVar();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay)
{
@@ -208,25 +222,24 @@ void FCogWindowWidgets::AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Po
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::MenuSearchBar(ImGuiTextFilter& Filter, float Width /*= -1*/)
void FCogWindowWidgets::SearchBar(ImGuiTextFilter& Filter, float Width /*= -1*/)
{
ImGuiWindow* Window = FCogImguiHelper::GetCurrentWindow();
ImGui::SameLine();
ImVec2 Pos1 = Window->DC.CursorPos;
Filter.Draw("", Width);
ImVec2 Pos2 = Window->DC.CursorPos;
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())
{
static const char* Text = "Search";
const float Height = ImGui::GetFrameHeight();
ImGuiContext& g = *ImGui::GetCurrentContext();
ImVec2 Min = Pos1 + ImVec2(g.Style.ItemSpacing.x, 0.0f);
ImVec2 Max = Pos2 + ImVec2(-g.Style.ItemSpacing.x, Height);
ImRect BB(Min, Max);
ImVec2 TextSize = ImGui::CalcTextSize(Text, NULL);
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, NULL, &TextSize, ImVec2(0.0f, 0.5f), &BB);
ImGui::RenderTextClipped(Min, Max, Text, nullptr, &TextSize, ImVec2(0.0f, 0.5f), &BB);
ImGui::PopStyleColor();
}
}
@@ -716,4 +729,292 @@ bool FCogWindowWidgets::CollisionProfileChannels(int32& Channels)
}
return Result;
}
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::ActorsListWithFilters(const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction)
{
TSubclassOf<AActor> SelectedClass = AActor::StaticClass();
if (ActorClasses.IsValidIndex(SelectedActorClassIndex))
{
SelectedClass = ActorClasses[SelectedActorClassIndex];
}
bool AddSeparator = false;
//------------------------
// Actor Class Combo
//------------------------
if (ActorClasses.Num() > 1)
{
ImGui::SetNextItemWidth(18 * GetFontWidth());
if (ImGui::BeginCombo("##SelectionType", TCHAR_TO_ANSI(*GetNameSafe(SelectedClass))))
{
for (int32 i = 0; i < ActorClasses.Num(); ++i)
{
TSubclassOf<AActor> SubClass = ActorClasses[i];
if (ImGui::Selectable(TCHAR_TO_ANSI(*GetNameSafe(SubClass)), false))
{
SelectedActorClassIndex = i;
SelectedClass = SubClass;
}
}
ImGui::EndCombo();
}
AddSeparator = true;
}
if (Filter != nullptr)
{
ImGui::SameLine();
SearchBar(*Filter);
AddSeparator = true;
}
if (AddSeparator)
{
ImGui::Separator();
}
//------------------------
// Actor List
//------------------------
ImGui::BeginChild("ActorsList", ImVec2(-1, -1), false);
const bool SelectionChanged = ActorsList(World, SelectedClass, Filter, LocalPlayerPawn, ContextMenuFunction);
ImGui::EndChild();
return SelectionChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::ActorsList(const UWorld& World, const TSubclassOf<AActor> ActorClass, const ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction)
{
TArray<AActor*> Actors;
for (TActorIterator It(&World, ActorClass); It; ++It)
{
AActor* Actor = *It;
bool AddActor = true;
if (Filter != nullptr && Filter->IsActive())
{
const char* ActorName = TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(*Actor));
if (Filter != nullptr && Filter->PassFilter(ActorName) == false)
{
AddActor = false;
}
}
if (AddActor)
{
Actors.Add(Actor);
}
}
const AActor* OldSelection = FCogDebug::GetSelection();
const AActor* NewSelection = OldSelection;
ImGuiListClipper Clipper;
Clipper.Begin(Actors.Num());
while (Clipper.Step())
{
for (int32 i = Clipper.DisplayStart; i < Clipper.DisplayEnd; i++)
{
AActor* Actor = Actors[i];
if (Actor == nullptr)
{
continue;
}
ImGui::PushStyleColor(ImGuiCol_Text, Actor == LocalPlayerPawn ? IM_COL32(255, 255, 0, 255) : IM_COL32(255, 255, 255, 255));
const bool bIsSelected = Actor == FCogDebug::GetSelection();
if (ImGui::Selectable(TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(*Actor)), bIsSelected))
{
FCogDebug::SetSelection(&World, Actor);
NewSelection = Actor;
}
ImGui::PopStyleColor(1);
ActorContextMenu(*Actor, ContextMenuFunction);
//------------------------
// Draw Frame
//------------------------
if (ImGui::IsItemHovered())
{
ActorFrame(*Actor);
}
if (bIsSelected)
{
ImGui::SetItemDefaultFocus();
}
}
}
Clipper.End();
return NewSelection != OldSelection;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::MenuActorsCombo(const char* StrID, const UWorld& World, TSubclassOf<AActor> ActorClass, const FCogWindowActorContextMenuFunction& ContextMenuFunction)
{
int32 SelectedActorClassIndex = 0;
const TArray ActorClasses = { ActorClass };
AActor* Actor = nullptr;
return MenuActorsCombo(StrID, World, ActorClasses, SelectedActorClassIndex, nullptr, nullptr, ContextMenuFunction);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::MenuActorsCombo(const char* StrID, const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction)
{
bool Result = false;
ImGui::PushID(StrID);
const ImVec2 Pos1 = ImGui::GetCursorScreenPos();
const float Width = FCogImguiHelper::GetNextItemWidth();
//-----------------------------------
// Combo button
//-----------------------------------
{
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));
TSubclassOf<AActor> SelectedClass = AActor::StaticClass();
if (ActorClasses.IsValidIndex(SelectedActorClassIndex))
{
SelectedClass = ActorClasses[SelectedActorClassIndex];
}
AActor* Selection = FCogDebug::GetSelection();
if (Selection != nullptr && Selection->IsA(SelectedClass) == false)
{
Selection = nullptr;
}
const FString CurrentSelectionName = FCogWindowHelper::GetActorName(Selection);
if (ImGui::Button(TCHAR_TO_ANSI(*CurrentSelectionName), ImVec2(Width, 0.0f)))
{
ImGui::OpenPopup("ActorListPopup");
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Current Selection: %s", TCHAR_TO_ANSI(*CurrentSelectionName));
}
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(2);
if (Selection != nullptr)
{
ActorContextMenu(*Selection, ContextMenuFunction);
}
}
//-----------------------------------
// Popup
//-----------------------------------
const ImVec2 Pos2 = ImGui::GetCursorScreenPos();
ImGui::SetNextWindowPos(ImVec2(Pos1.x, Pos1.y + ImGui::GetFrameHeight()));
if (ImGui::BeginPopup("ActorListPopup"))
{
ImGui::BeginChild("Child", ImVec2(Pos2.x - Pos1.x, GetFontWidth() * 40), false);
Result = ActorsListWithFilters(World, ActorClasses, SelectedActorClassIndex, Filter, LocalPlayerPawn, ContextMenuFunction);
if (Result)
{
ImGui::CloseCurrentPopup();
}
ImGui::EndChild();
ImGui::EndPopup();
}
ImGui::PopID();
return Result;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ActorContextMenu(AActor& Selection, const FCogWindowActorContextMenuFunction& ContextMenuFunction)
{
if (ContextMenuFunction == nullptr)
{
return;
}
ImGui::SetNextWindowSize(ImVec2(GetFontWidth() * 30, 0));
if (ImGui::BeginPopupContextItem())
{
ContextMenuFunction(Selection);
ImGui::EndPopup();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ActorFrame(const AActor& Actor)
{
const APlayerController* PlayerController = Actor.GetWorld()->GetFirstPlayerController();
if (PlayerController == nullptr)
{
return;
}
ImGuiViewport* Viewport = ImGui::GetMainViewport();
if (Viewport == nullptr)
{
return;
}
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
FVector BoxOrigin, BoxExtent;
bool PrimitiveFound = false;
FBox Bounds(ForceInit);
if (const UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(Actor.GetRootComponent()))
{
PrimitiveFound = true;
Bounds += PrimitiveComponent->Bounds.GetBox();
}
else
{
Actor.ForEachComponent<UPrimitiveComponent>(true, [&](const UPrimitiveComponent* InPrimComp)
{
if (InPrimComp->IsRegistered() && InPrimComp->IsCollisionEnabled())
{
Bounds += InPrimComp->Bounds.GetBox();
PrimitiveFound = true;
}
});
}
if (PrimitiveFound)
{
Bounds.GetCenterAndExtents(BoxOrigin, BoxExtent);
}
else
{
BoxOrigin = Actor.GetActorLocation();
BoxExtent = FVector::ZeroVector;
}
FVector2D ScreenPosMin, ScreenPosMax;
if (FCogWindowHelper::ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax))
{
const ImU32 Color = (&Actor == FCogDebug::GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128);
if (ScreenPosMin != ScreenPosMax)
{
DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin) + Viewport->Pos, FCogImguiHelper::ToImVec2(ScreenPosMax) + Viewport->Pos, Color, 0.0f, 0, 1.0f);
}
AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)) + Viewport->Pos, Color, TCHAR_TO_ANSI(*FCogWindowHelper::GetActorName(Actor)));
}
}
@@ -1,8 +1,6 @@
#pragma once
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "CoreMinimal.h"
#include "Templates/SubclassOf.h"
@@ -11,26 +9,21 @@ class COGWINDOW_API FCogWindowHelper
{
public:
//----------------------------------------------------------------------------------------------------------------------
static FString GetActorName(const AActor* Actor);
static FString GetActorName(const AActor& Actor);
static bool ComputeBoundingBoxScreenPosition(const APlayerController* PlayerController, const FVector& Origin, const FVector& Extent, FVector2D& Min, FVector2D& Max);
template<typename T>
static const T* GetFirstAssetByClass()
{
return Cast<T>(GetFirstAssetByClass(T::StaticClass()));
}
static const T* GetFirstAssetByClass();
//----------------------------------------------------------------------------------------------------------------------
static const UObject* GetFirstAssetByClass(const TSubclassOf<UObject> AssetClass)
{
const IAssetRegistry& AssetRegistry = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")).Get();
TArray<FAssetData> Assets;
AssetRegistry.GetAssetsByClass(AssetClass->GetClassPathName(), Assets, true);
if (Assets.Num() == 0)
{
return nullptr;
}
const UObject* Asset = Assets[0].GetAsset();
return Asset;
}
static const UObject* GetFirstAssetByClass(const TSubclassOf<UObject> AssetClass);
};
//----------------------------------------------------------------------------------------------------------------------
template<typename T>
const T* FCogWindowHelper::GetFirstAssetByClass()
{
return Cast<T>(GetFirstAssetByClass(T::StaticClass()));
}
@@ -12,6 +12,8 @@ struct FCogImGuiKeyInfo;
struct FKeyBind;
struct FKeyBind;
using FCogWindowActorContextMenuFunction = TFunction<void(AActor& Actor)>;
class COGWINDOW_API FCogWindowWidgets
{
public:
@@ -20,6 +22,8 @@ public:
static void EndTableTooltip();
static void ThinSeparatorText(const char* Label);
static void ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay);
static bool ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor);
@@ -44,7 +48,7 @@ public:
static void AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd = NULL);
static void MenuSearchBar(ImGuiTextFilter& Filter, float Width = -1.0f);
static void SearchBar(ImGuiTextFilter& Filter, float Width = -1.0f);
static void PushBackColor(const ImVec4& Color);
@@ -86,6 +90,17 @@ public:
static bool CollisionProfileChannels(int32& Channels);
static bool MenuActorsCombo(const char* StrID, const UWorld& World, TSubclassOf<AActor> ActorClass, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool MenuActorsCombo(const char* StrID, const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool ActorsListWithFilters(const UWorld& World, const TArray<TSubclassOf<AActor>>& ActorClasses, int32& SelectedActorClassIndex, ImGuiTextFilter* Filter, const APawn* LocalPlayerPawn, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static bool ActorsList(const UWorld& World, const TSubclassOf<AActor> ActorClass, const ImGuiTextFilter* Filter = nullptr, const APawn* LocalPlayerPawn = nullptr, const FCogWindowActorContextMenuFunction& ContextMenuFunction = nullptr);
static void ActorContextMenu(AActor& Selection, const FCogWindowActorContextMenuFunction& ContextMenuFunction);
static void ActorFrame(const AActor& Actor);
};
template<typename EnumType>
@@ -140,7 +140,7 @@ void FCogAIWindow_BehaviorTree::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -46,7 +46,7 @@ void FCogAIWindow_Blackboard::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -172,7 +172,7 @@ void FCogAbilityWindow_Abilities::RenderAbiltiesMenu(AActor* Selection)
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -73,7 +73,7 @@ void FCogAbilityWindow_Attributes::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -73,7 +73,7 @@ void FCogAbilityWindow_Effects::RenderContent()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
@@ -67,7 +67,7 @@ void FCogAbilityWindow_Tags::RenderMenu()
ImGui::EndMenu();
}
FCogWindowWidgets::MenuSearchBar(Filter);
FCogWindowWidgets::SearchBar(Filter);
ImGui::EndMenuBar();
}
-9
View File
@@ -1,15 +1,12 @@
#include "CogSampleGameState.h"
#include "CogSampleAbilitySystemComponent.h"
#include "CogSampleFunctionLibrary_Tag.h"
#include "GameFramework/Character.h"
#include "GameFramework/GameMode.h"
#include "GameFramework/GameState.h"
#include "Modules/ModuleManager.h"
#if ENABLE_COG
#include "CogAbilityDataAsset.h"
#include "CogAbilityModule.h"
#include "CogAbilityWindow_Abilities.h"
#include "CogAbilityWindow_Attributes.h"
#include "CogAbilityWindow_Cheats.h"
@@ -19,10 +16,7 @@
#include "CogAbilityWindow_Tweaks.h"
#include "CogAIWindow_BehaviorTree.h"
#include "CogAIWindow_Blackboard.h"
#include "CogDebugDrawImGui.h"
#include "CogDebugPlot.h"
#include "CogEngineDataAsset.h"
#include "CogEngineModule.h"
#include "CogEngineWindow_CollisionTester.h"
#include "CogEngineWindow_CollisionViewer.h"
#include "CogEngineWindow_CommandBindings.h"
@@ -42,11 +36,8 @@
#include "CogEngineWindow_Stats.h"
#include "CogEngineWindow_TimeScale.h"
#include "CogEngineWindow_Transform.h"
#include "CogImguiModule.h"
#include "CogInputDataAsset.h"
#include "CogInputWindow_Actions.h"
#include "CogInputWindow_Gamepad.h"
#include "CogSampleLogCategories.h"
#include "CogSampleWindow_Team.h"
#include "CogWindowManager.h"