// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "PropertyEditorDelegates.h" class IPropertyHandle; class IPropertyRowGenerator; class SWidget; struct FDisplayClusterDetailsDrawerState; /** Interface that allows detail data models to be generated for specific UObjects */ class IDisplayClusterDetailsDataModelGenerator : public TSharedFromThis { public: virtual ~IDisplayClusterDetailsDataModelGenerator() {} virtual void Initialize(const TSharedRef& DetailsDataModel, const TSharedRef& PropertyRowGenerator) = 0; virtual void Destroy(const TSharedRef& DetailsDataModel, const TSharedRef& PropertyRowGenerator) = 0; /** Called when the details data model should be generated by this generator */ virtual void GenerateDataModel(IPropertyRowGenerator& PropertyRowGenerator, class FDisplayClusterDetailsDataModel& OutDetailsDataModel) = 0; }; DECLARE_DELEGATE_RetVal(TSharedRef, FGetDetailsDataModelGenerator); /** * A data model that stores the details properties from a UObject, which determines which properties will be displayed in the details panel. */ class FDisplayClusterDetailsDataModel : public TSharedFromThis { public: /** Registers a new data model generator used to populate a details data model for the specified class */ template static void RegisterDetailsDataModelGenerator(FGetDetailsDataModelGenerator CreateGeneratorDelegate) { UClass* Class = T::StaticClass(); RegisteredDataModelGenerators.Add(Class, CreateGeneratorDelegate); } private: /** A list of data model generators, indexed by class name, that have been registered */ static TMap, FGetDetailsDataModelGenerator> RegisteredDataModelGenerators; public: /** Stores data used to generate a details subsection, which is a selectable element in a details section that modifies which properties are displayed in the section */ struct FDetailsSubsection { /** The display name of the subsection */ FText DisplayName; /** A delegate that creates the details customization for the details subsection */ FOnGetDetailCustomizationInstance DetailCustomizationDelegate; /** A list of categories to display in the detail subsection */ TArray Categories; }; /** Stores data used to generate a details section in the drawer, which displays a specific subset of properties from the selected objects */ struct FDetailsSection { /** The display name of the details section*/ FText DisplayName = FText::GetEmpty(); /** The handle of the property that controls the editing condition of the properties in the details group */ TSharedPtr EditConditionPropertyHandle = nullptr; /** A list of selectable subsections to display in the details view */ TArray Subsections; /** A delegate that creates the details customization for the details section */ FOnGetDetailCustomizationInstance DetailCustomizationDelegate; /** A list of categories to display in the detail subsection */ TArray Categories; }; DECLARE_MULTICAST_DELEGATE(FOnDataModelGenerated); public: FDisplayClusterDetailsDataModel(); /** Gets the property row generator that was used to generate this data model */ TSharedRef GetPropertyRowGenerator() const { return PropertyRowGenerator.ToSharedRef(); } /** Gets the list of objects from which the details properties were generated from */ TArray> GetObjects() const; /** Sets the objects from which the details properties will be generated */ void SetObjects(const TArray& InObjects); /** Gets whether the data model has objects of the specified class */ bool HasObjectOfType(const UClass* InClass) const; /** Resets the data model to be empty */ void Reset(); /** Adds the state of the data model to the specified drawer state */ void GetDrawerState(FDisplayClusterDetailsDrawerState& OutDrawerState); /** Sets the state of the data model from the specified drawer state */ void SetDrawerState(const FDisplayClusterDetailsDrawerState& InDrawerState); /** Gets the delegate that is raised when the data model is generated */ FOnDataModelGenerated& OnDataModelGenerated() { return OnDataModelGeneratedDelegate; } private: /** Initializes any needed data model generators for the specified class */ void InitializeDataModelGenerator(UClass* InClass); /** Attempts to find an instance of a data model generator that can be used for the specified class */ TSharedPtr GetDataModelGenerator(UClass* InClass) const; /** Callback that is raised when the property row generator the data model is generated from has been refreshed */ void OnPropertyRowGeneratorRefreshed(); public: /** A list of details sections in the details data model */ TArray DetailsSections; private: /** A list of data model generators that have been created to generate the data model for the current objects */ TMap, TSharedPtr> DataModelGeneratorInstances; /** The property row generator which manages the property handles of the details objects */ TSharedPtr PropertyRowGenerator; /** Delegate that is raised when the data model has been generated */ FOnDataModelGenerated OnDataModelGeneratedDelegate; };