diff --git a/Source/FlowEditor/Private/DetailCustomizations/FlowComponentDetails.cpp b/Source/FlowEditor/Private/DetailCustomizations/FlowComponentDetails.cpp new file mode 100644 index 00000000..5f4f260e --- /dev/null +++ b/Source/FlowEditor/Private/DetailCustomizations/FlowComponentDetails.cpp @@ -0,0 +1,52 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DetailCustomizations/FlowComponentDetails.h" +#include "FlowComponent.h" + +#include "DetailCategoryBuilder.h" +#include "DetailLayoutBuilder.h" +#include "GameplayTagsManager.h" +#include "Graph/FlowGraphSettings.h" + +FFlowComponentDetails::~FFlowComponentDetails() +{ + UGameplayTagsManager::Get().OnGetCategoriesMetaFromPropertyHandle.RemoveAll(this); +} + +void FFlowComponentDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) +{ + const UFlowGraphSettings* Settings = GetDefault(); + UGameplayTagsManager::Get().OnGetCategoriesMetaFromPropertyHandle.AddSP(this, &FFlowComponentDetails::ResolveCategoriesMeta); + + + IdentityTagsHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UFlowComponent, IdentityTags)); + + const ECategoryPriority::Type Priority = Settings->bMarkFlowCategoryImportant ? ECategoryPriority::Important : ECategoryPriority::Default; + IDetailCategoryBuilder& Category = DetailBuilder.EditCategory("Flow", FText::GetEmpty(), Priority); + + Category.AddProperty(IdentityTagsHandle); +} + +void FFlowComponentDetails::ResolveCategoriesMeta(TSharedPtr PropertyHandle, FString& MetaString) const +{ + if (PropertyHandle->IsSamePropertyNode(IdentityTagsHandle)) + { + const UFlowGraphSettings* Settings = GetDefault(); + + if (Settings->ComponentClassIdentityTagCategories.IsEmpty()) + { + MetaString = FString::JoinBy(Settings->DefaultIdentityTagCategories, TEXT(","), [](const FGameplayTag& Tag) { return Tag.ToString(); }); + } + else + { + for (const UClass* Class = IdentityTagsHandle->GetOuterBaseClass(); Class; Class = Class->GetSuperClass()) + { + if (const FGameplayTagContainer* Tags = Settings->ComponentClassIdentityTagCategories.Find(Class)) + { + MetaString = FString::JoinBy(*Tags, TEXT(","), [](const FGameplayTag& Tag) { return Tag.ToString(); }); + }; + } + } + } +} diff --git a/Source/FlowEditor/Private/FlowEditorModule.cpp b/Source/FlowEditor/Private/FlowEditorModule.cpp index 09906bf8..e98ff50c 100644 --- a/Source/FlowEditor/Private/FlowEditorModule.cpp +++ b/Source/FlowEditor/Private/FlowEditorModule.cpp @@ -31,8 +31,10 @@ #include "DetailCustomizations/FlowAssetParamsPtrCustomization.h" #include "DetailCustomizations/FlowDataPinValueOwnerCustomizations.h" #include "DetailCustomizations/FlowDataPinValueStandardCustomizations.h" +#include "DetailCustomizations/FlowComponentDetails.h" #include "FlowAsset.h" +#include "FlowComponent.h" #include "AddOns/FlowNodeAddOn.h" #include "Asset/FlowAssetParamsTypes.h" #include "Find/FindInFlow.h" @@ -254,6 +256,7 @@ void FFlowEditorModule::RegisterDetailCustomizations() RegisterCustomClassLayout(UFlowNode_CustomOutput::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FFlowNode_CustomOutputDetails::MakeInstance)); RegisterCustomClassLayout(UFlowNode_PlayLevelSequence::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FFlowNode_PlayLevelSequenceDetails::MakeInstance)); RegisterCustomClassLayout(UFlowNode_SubGraph::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FFlowNode_SubGraphDetails::MakeInstance)); + RegisterCustomClassLayout(UFlowComponent::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FFlowComponentDetails::MakeInstance)); RegisterCustomStructLayout(*FFlowActorOwnerComponentRef::StaticStruct(), FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FFlowActorOwnerComponentRefCustomization::MakeInstance)); RegisterCustomStructLayout(*FFlowPin::StaticStruct(), FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FFlowPinCustomization::MakeInstance)); RegisterCustomStructLayout(*FFlowNamedDataPinProperty::StaticStruct(), FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FFlowNamedDataPinPropertyCustomization::MakeInstance)); diff --git a/Source/FlowEditor/Public/DetailCustomizations/FlowComponentDetails.h b/Source/FlowEditor/Public/DetailCustomizations/FlowComponentDetails.h new file mode 100644 index 00000000..470942e5 --- /dev/null +++ b/Source/FlowEditor/Public/DetailCustomizations/FlowComponentDetails.h @@ -0,0 +1,26 @@ +// Copyright https://github.com/MothCocoon/FlowGraph/graphs/contributors +#pragma once + +#include "IDetailCustomization.h" + + +class FFlowComponentDetails : public IDetailCustomization +{ +public: + static TSharedRef MakeInstance() + { + return MakeShareable(new FFlowComponentDetails()); + } + + virtual ~FFlowComponentDetails() override; + + // IDetailCustomization + virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; + // -- + +protected: + virtual void ResolveCategoriesMeta(TSharedPtr PropertyHandle, FString& MetaString) const; + +private: + TSharedPtr IdentityTagsHandle; +}; \ No newline at end of file diff --git a/Source/FlowEditor/Public/Graph/FlowGraphSettings.h b/Source/FlowEditor/Public/Graph/FlowGraphSettings.h index 1c264284..6dcfa96a 100644 --- a/Source/FlowEditor/Public/Graph/FlowGraphSettings.h +++ b/Source/FlowEditor/Public/Graph/FlowGraphSettings.h @@ -9,6 +9,7 @@ #include "Graph/FlowGraphNodesPolicy.h" #include "FlowGraphSettings.generated.h" +class UFlowComponent; class UFlowNodeBase; USTRUCT() @@ -181,7 +182,19 @@ class FLOWEDITOR_API UFlowGraphSettings : public UDeveloperSettings UPROPERTY(EditAnywhere, config, Category = "Wires", meta = (ClampMin = 0.0f)) float SelectedWireThickness; - + + + /** FlowComponent only. Move category Flow to the top of details panel */ + UPROPERTY(EditAnywhere, config, Category = "Details") + bool bMarkFlowCategoryImportant = true; + + /** Use these tags If identity Categories are no overriden */ + UPROPERTY(EditAnywhere, config, Category = "Details") + TArray DefaultIdentityTagCategories; + + /** Per component class categories. Overrides DefaultIdentityTagCategories */ + UPROPERTY(EditAnywhere, config, Category = "Details") + TMap, FGameplayTagContainer> ComponentClassIdentityTagCategories; public: virtual FName GetCategoryName() const override { return FName("Flow Graph"); } virtual FText GetSectionText() const override { return INVTEXT("Graph Settings"); }