From a41f71e04e83e550d49977e26fc979584c94382f Mon Sep 17 00:00:00 2001 From: Vasilii Bulgakov Date: Mon, 13 Apr 2026 15:54:30 +0700 Subject: [PATCH 1/2] Actor details can show flow tags in selected actors --- .../DetailCustomizations/FlowActorDetails.cpp | 57 +++++++++++++++++++ .../FlowEditor/Private/FlowEditorModule.cpp | 6 ++ .../DetailCustomizations/FlowActorDetails.h | 17 ++++++ Source/FlowEditor/Public/FlowEditorModule.h | 1 + .../Public/Graph/FlowGraphSettings.h | 8 +++ 5 files changed, 89 insertions(+) create mode 100644 Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp create mode 100644 Source/FlowEditor/Public/DetailCustomizations/FlowActorDetails.h diff --git a/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp b/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp new file mode 100644 index 00000000..565c8cc2 --- /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("Flow"), 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"); } From 901ab68171f8d27718529573480eab32ed83f745 Mon Sep 17 00:00:00 2001 From: Vasilii Bulgakov Date: Mon, 13 Apr 2026 16:37:39 +0700 Subject: [PATCH 2/2] Better category name to avoid conflicts --- .../Private/DetailCustomizations/FlowActorDetails.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp b/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp index 565c8cc2..c5cc1522 100644 --- a/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp +++ b/Source/FlowEditor/Private/DetailCustomizations/FlowActorDetails.cpp @@ -49,7 +49,7 @@ void FFlowActorDetails::AddFlowCategory(class IDetailLayoutBuilder& Details, con return FString(Actor + TEXT(".") + Object->GetName()); }); - IDetailCategoryBuilder& Category = Details.EditCategory(TEXT("Flow"), CategoryName, Priority); + IDetailCategoryBuilder& Category = Details.EditCategory(TEXT("_FlowDetails"), CategoryName, Priority); Category.SetToolTip(FText::FromString(Tooltip)); Category.AddExternalObjectProperty(Components, GET_MEMBER_NAME_CHECKED(UFlowComponent, IdentityTags)); }