// Copyright Epic Games, Inc. All Rights Reserved. #include "DataVisualizations/PCGDataVisualizationHelpers.h" #include "Widgets/SPCGEditorGraphAttributeListView.h" #include "Metadata/PCGAttributePropertySelector.h" #include "Metadata/PCGMetadata.h" #include "Metadata/Accessors/PCGAttributeAccessorHelpers.h" #define LOCTEXT_NAMESPACE "PCGDataVisualizationHelpers" namespace PCGDataVisualizationConstants { const FString NoneAttributeId = TEXT("@None"); /** Labels of the columns. */ const FText TEXT_Index = LOCTEXT("Index", "$Index"); } namespace PCGDataVisualizationHelpers { void AddColumnInfo(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { FPCGTableVisualizerColumnInfo& ColumnInfo = OutInfo.ColumnInfos.Emplace_GetRef(); ColumnInfo.Accessor = Overrides.CreateAccessorFuncOverride ? Overrides.CreateAccessorFuncOverride() : TSharedPtr(PCGAttributeAccessorHelpers::CreateConstAccessor(Data, InSelector).Release()); ColumnInfo.AccessorKeys = Overrides.CreateAccessorKeysFuncOverride ? Overrides.CreateAccessorKeysFuncOverride() : TSharedPtr(PCGAttributeAccessorHelpers::CreateConstKeys(Data, InSelector).Release()); if (ensure(ColumnInfo.Accessor)) { const uint16 Type = Overrides.TypeOverride == EPCGMetadataTypes::Unknown ? ColumnInfo.Accessor->GetUnderlyingType() : static_cast(Overrides.TypeOverride); if (Overrides.bAddTypeToTooltip && !Overrides.TooltipOverride.IsEmpty()) { ColumnInfo.Tooltip = FText::Format(INVTEXT("{0} ({1})"), Overrides.TooltipOverride, PCG::Private::GetTypeNameText(Type)); } else if (!Overrides.TooltipOverride.IsEmpty()) { ColumnInfo.Tooltip = Overrides.TooltipOverride; } else { ColumnInfo.Tooltip = PCG::Private::GetTypeNameText(Type); } if (PCG::Private::IsOfTypes(Type)) { ColumnInfo.CellAlignment = EPCGTableVisualizerCellAlignment::Left; ColumnInfo.Width = PCGEditorGraphAttributeListView::MaxColumnWidth; } if (!Overrides.LabelOverride.IsEmpty()) { ColumnInfo.Label = Overrides.LabelOverride; } else if (InSelector.GetName() == NAME_None) { ColumnInfo.Label = FText::Format(LOCTEXT("NoneLabelFormat", "{1} ({0})"), UEnum::GetDisplayValueAsText(static_cast(ColumnInfo.Accessor->GetUnderlyingType())), InSelector.GetDisplayText(/*bSkipDomain=*/true)); } else { ColumnInfo.Label = InSelector.GetDisplayText(/*bSkipDomain=*/true); } ColumnInfo.Id = *ColumnInfo.Label.ToString(); } } void AddColumnInfoExtraNames(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& BaseSelector, const TArray& AllExtraNames, const FColumnInfoOverrides& Overrides) { FPCGAttributePropertySelector SelectorCopy = BaseSelector; FString& SelectorExtraName = SelectorCopy.GetExtraNamesMutable().Emplace_GetRef(); for (const FString& ExtraName : AllExtraNames) { SelectorExtraName = ExtraName; AddColumnInfo(OutInfo, Data, SelectorCopy, Overrides); } } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { AddColumnInfoExtraNames(OutInfo, Data, InSelector, {TEXT("X"), TEXT("Y")}, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { AddColumnInfoExtraNames(OutInfo, Data, InSelector, {TEXT("X"), TEXT("Y"), TEXT("Z")}, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { AddColumnInfoExtraNames(OutInfo, Data, InSelector, {TEXT("X"), TEXT("Y"), TEXT("Z"), TEXT("W")}, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { AddColumnInfoExtraNames(OutInfo, Data, InSelector, {TEXT("R"), TEXT("G"), TEXT("B"), TEXT("A")}, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { return AddTypedColumnInfo(OutInfo, Data, InSelector, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { AddColumnInfoExtraNames(OutInfo, Data, InSelector, {TEXT("Roll"), TEXT("Pitch"), TEXT("Yaw")}, Overrides); } template <> void AddTypedColumnInfo_Impl(FPCGTableVisualizerInfo& OutInfo, const UPCGData* Data, const FPCGAttributePropertySelector& InSelector, const FColumnInfoOverrides& Overrides) { FPCGAttributePropertySelector SelectorCopy = InSelector; FString& SelectorExtraName = SelectorCopy.GetExtraNamesMutable().Emplace_GetRef(); SelectorExtraName = TEXT("Position"); AddTypedColumnInfo(OutInfo, Data, SelectorCopy, Overrides); SelectorExtraName = TEXT("Rotation"); AddTypedColumnInfo(OutInfo, Data, SelectorCopy, Overrides); SelectorExtraName = TEXT("Scale"); AddTypedColumnInfo(OutInfo, Data, SelectorCopy, Overrides); } void CreateMetadataColumnInfos(const UPCGData* Data, FPCGTableVisualizerInfo& OutInfo, const FPCGMetadataDomainID& DomainID) { const UPCGMetadata* Metadata = Data->ConstMetadata(); if (!Metadata) { return; } const FPCGMetadataDomain* MetadataDomain = Metadata->GetConstMetadataDomain(DomainID); if (!MetadataDomain) { return; } TArray AttributeNames; TArray AttributeTypes; MetadataDomain->GetAttributes(AttributeNames, AttributeTypes); // Domain is constant for all the attributes FPCGAttributePropertySelector Selector{}; Data->SetDomainFromDomainID(DomainID, Selector); auto AddInfo = [Data, &OutInfo, &Selector](T, const FName AttributeName) { Selector.SetAttributeName(AttributeName); AddTypedColumnInfo(OutInfo, Data, Selector); }; for (int32 I = 0; I < AttributeNames.Num(); I++) { PCGMetadataAttribute::CallbackWithRightType(static_cast(AttributeTypes[I]), AddInfo, AttributeNames[I]); } } FPCGTableVisualizerInfo CreateDefaultMetadataColumnInfos(const UPCGData* Data, const FPCGMetadataDomainID& DomainID) { check(Data); const UPCGMetadata* Metadata = Data->ConstMetadata(); const FPCGMetadataDomain* MetadataDomain = Metadata ? Metadata->GetConstMetadataDomain(DomainID) : nullptr; if (!MetadataDomain) { return {}; } FPCGTableVisualizerInfo Info; Info.Data = Data; FPCGAttributePropertySelector IndexSelector = FPCGAttributePropertySelector::CreateExtraPropertySelector(EPCGExtraProperties::Index); Data->SetDomainFromDomainID(DomainID, IndexSelector); AddColumnInfo(Info, Data, IndexSelector); Info.SortingColumn = Info.ColumnInfos.Last().Id; // Add Metadata Columns CreateMetadataColumnInfos(Data, Info, DomainID); return Info; } } #undef LOCTEXT_NAMESPACE