diff --git a/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp b/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp new file mode 100644 index 00000000..c5cc1522 --- /dev/null +++ b/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp @@ -0,0 +1,57 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DetailCustomizations/FlowActorDetails.h" +#include "ActorDetailsDelegates.h" +#include "DetailCategoryBuilder.h" +#include "DetailLayoutBuilder.h" +#include "FlowComponent.h" +#include "Graph/FlowGraphSettings.h" + + +FFlowActorDetails::~FFlowActorDetails() +{ + OnExtendActorDetails.RemoveAll(this); +} + +void FFlowActorDetails::Register() +{ + if (GetDefault()->bShowFlowTagsInActorDetails) + { + OnExtendActorDetails.AddSP(this, &FFlowActorDetails::AddFlowCategory); + } +} + +void FFlowActorDetails::AddFlowCategory(class IDetailLayoutBuilder& Details, const FGetSelectedActors& GetSelectedActors) +{ + if (GetSelectedActors.IsBound()) + { + TArray Components; + const TArray>& SelectedActors = GetSelectedActors.Execute(); + for (auto& WeakActor : SelectedActors) + { + if (const AActor* Actor = WeakActor.Get()) + { + TInlineComponentArray FlowComps(Actor); + Components.Append(FlowComps); + } + } + + if (!Components.IsEmpty()) + { + const ECategoryPriority::Type Priority = GetDefault()->bMarkFlowCategoryImportant ? ECategoryPriority::Important : ECategoryPriority::Default; + + const FText CategoryName = FText::Format(NSLOCTEXT("FlowDetails", "FlowCategoryFormat", "Flow Components: {0} "), FText::AsNumber(Components.Num())); + const FString Tooltip = FString::JoinBy(Components, LINE_TERMINATOR, [](const UObject* Object) + { + const UActorComponent* Component = CastChecked(Object); + const FString Actor = Component->GetOwner() ? Component->GetOwner()->GetActorNameOrLabel() : TEXT("None"); + return FString(Actor + TEXT(".") + Object->GetName()); + }); + + IDetailCategoryBuilder& Category = Details.EditCategory(TEXT("_FlowDetails"), CategoryName, Priority); + Category.SetToolTip(FText::FromString(Tooltip)); + Category.AddExternalObjectProperty(Components, GET_MEMBER_NAME_CHECKED(UFlowComponent, IdentityTags)); + } + } +} diff --git a/Source/FlowEditor/Private/FlowEditorModule.cpp b/Source/FlowEditor/Private/FlowEditorModule.cpp index 09906bf8..3d8410d8 100644 --- a/Source/FlowEditor/Private/FlowEditorModule.cpp +++ b/Source/FlowEditor/Private/FlowEditorModule.cpp @@ -31,6 +31,7 @@ #include "DetailCustomizations/FlowAssetParamsPtrCustomization.h" #include "DetailCustomizations/FlowDataPinValueOwnerCustomizations.h" #include "DetailCustomizations/FlowDataPinValueStandardCustomizations.h" +#include "DetailCustomizations/FlowActorDetails.h" #include "FlowAsset.h" #include "AddOns/FlowNodeAddOn.h" @@ -90,6 +91,9 @@ void FFlowEditorModule::StartupModule() FlowTrackCreateEditorHandle = SequencerModule.RegisterTrackEditor(FOnCreateTrackEditor::CreateStatic(&FFlowTrackEditor::CreateTrackEditor)); RegisterDetailCustomizations(); + + ActorDetails = MakeShared(); + ActorDetails->Register(); // register asset indexers if (FModuleManager::Get().IsModuleLoaded(AssetSearchModuleName)) @@ -120,6 +124,8 @@ void FFlowEditorModule::ShutdownModule() UnregisterDetailCustomizations(); UnregisterAssets(); + + ActorDetails.Reset(); // unregister track editors ISequencerModule& SequencerModule = FModuleManager::Get().LoadModuleChecked("Sequencer"); diff --git a/Source/FlowEditor/Public/DetailCustomizations/FlowActorDetails.h b/Source/FlowEditor/Public/DetailCustomizations/FlowActorDetails.h new file mode 100644 index 00000000..c555f930 --- /dev/null +++ b/Source/FlowEditor/Public/DetailCustomizations/FlowActorDetails.h @@ -0,0 +1,17 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "ActorDetailsDelegates.h" + +/** + * + */ +class FLOWEDITOR_API FFlowActorDetails : public TSharedFromThis +{ +public: + virtual ~FFlowActorDetails(); + virtual void Register(); + virtual void AddFlowCategory(class IDetailLayoutBuilder& Details, const FGetSelectedActors& GetSelectedActors); +}; diff --git a/Source/FlowEditor/Public/FlowEditorModule.h b/Source/FlowEditor/Public/FlowEditorModule.h index b6ce4e18..55b123c1 100644 --- a/Source/FlowEditor/Public/FlowEditorModule.h +++ b/Source/FlowEditor/Public/FlowEditorModule.h @@ -32,6 +32,7 @@ class FLOWEDITOR_API FFlowEditorModule : public IModuleInterface bool bIsRegisteredForAssetChanges = false; + TSharedPtr ActorDetails; public: virtual void StartupModule() override; virtual void ShutdownModule() override; diff --git a/Source/FlowEditor/Public/Graph/FlowGraphSettings.h b/Source/FlowEditor/Public/Graph/FlowGraphSettings.h index 1c264284..5e14a6dc 100644 --- a/Source/FlowEditor/Public/Graph/FlowGraphSettings.h +++ b/Source/FlowEditor/Public/Graph/FlowGraphSettings.h @@ -181,6 +181,14 @@ class FLOWEDITOR_API UFlowGraphSettings : public UDeveloperSettings UPROPERTY(EditAnywhere, config, Category = "Wires", meta = (ClampMin = 0.0f)) float SelectedWireThickness; + + + UPROPERTY(EditAnywhere, config, Category = "Details", meta = (ConfigRestartRequired = true)) + bool bShowFlowTagsInActorDetails = true; + + /** FlowComponent only. Move category Flow to the top of details panel */ + UPROPERTY(EditAnywhere, config, Category = "Details") + bool bMarkFlowCategoryImportant = true; public: virtual FName GetCategoryName() const override { return FName("Flow Graph"); }