// Copyright Epic Games, Inc. All Rights Reserved. #include "LiveLinkSubjectRepresentationDetailCustomization.h" #include "DetailWidgetRow.h" #include "IDetailChildrenBuilder.h" #include "IPropertyUtilities.h" #define LOCTEXT_NAMESPACE "LiveLinkSubjectRepresentationDetailCustomization" TSharedRef FLiveLinkSubjectRepresentationDetailCustomization::MakeInstance() { return MakeShareable(new FLiveLinkSubjectRepresentationDetailCustomization); } void FLiveLinkSubjectRepresentationDetailCustomization::CustomizeHeader(TSharedRef InPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils) { StructPropertyHandle = InPropertyHandle; TSharedPtr PropertyUtils = CustomizationUtils.GetPropertyUtilities(); check(CastFieldChecked(StructPropertyHandle->GetProperty())->Struct == FLiveLinkSubjectRepresentation::StaticStruct()); HeaderRow.NameContent() [ StructPropertyHandle->CreatePropertyNameWidget() ] .ValueContent() .MinDesiredWidth(125.f) .MaxDesiredWidth(400.f) [ SNew(SLiveLinkSubjectRepresentationPicker) .ShowRole(true) .Font(CustomizationUtils.GetRegularFont()) .HasMultipleValues(this, &FLiveLinkSubjectRepresentationDetailCustomization::HasMultipleValues) .Value(this, &FLiveLinkSubjectRepresentationDetailCustomization::GetValue) .OnValueChanged(this, &FLiveLinkSubjectRepresentationDetailCustomization::SetValue) ].IsEnabled(MakeAttributeLambda([=] { return !InPropertyHandle->IsEditConst() && PropertyUtils->IsPropertyEditingEnabled(); })); } void FLiveLinkSubjectRepresentationDetailCustomization::CustomizeChildren(TSharedRef PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils) { TSharedPtr PropertyUtils = CustomizationUtils.GetPropertyUtilities(); uint32 NumberOfChild; if (PropertyHandle->GetNumChildren(NumberOfChild) == FPropertyAccess::Success) { for (uint32 Index = 0; Index < NumberOfChild; ++Index) { TSharedRef ChildPropertyHandle = PropertyHandle->GetChildHandle(Index).ToSharedRef(); ChildBuilder.AddProperty(ChildPropertyHandle) .ShowPropertyButtons(true) .IsEnabled(MakeAttributeLambda([=] { return !PropertyHandle->IsEditConst() && PropertyUtils->IsPropertyEditingEnabled(); })); } } } SLiveLinkSubjectRepresentationPicker::FLiveLinkSourceSubjectRole FLiveLinkSubjectRepresentationDetailCustomization::GetValue() const { TArray RawData; StructPropertyHandle->AccessRawData(RawData); for (const void* RawPtr : RawData) { if (RawPtr) { return SLiveLinkSubjectRepresentationPicker::FLiveLinkSourceSubjectRole(*reinterpret_cast(RawPtr)); } } return SLiveLinkSubjectRepresentationPicker::FLiveLinkSourceSubjectRole(); } void FLiveLinkSubjectRepresentationDetailCustomization::SetValue(SLiveLinkSubjectRepresentationPicker::FLiveLinkSourceSubjectRole NewValue) { FStructProperty* StructProperty = CastFieldChecked(StructPropertyHandle->GetProperty()); TArray RawData; StructPropertyHandle->AccessRawData(RawData); FLiveLinkSubjectRepresentation* PreviousValue = reinterpret_cast(RawData[0]); FLiveLinkSubjectRepresentation NewSubRep = NewValue.ToSubjectRepresentation(); FString TextValue; StructProperty->Struct->ExportText(TextValue, &NewSubRep, PreviousValue, nullptr, EPropertyPortFlags::PPF_None, nullptr); ensure(StructPropertyHandle->SetValueFromFormattedString(TextValue, EPropertyValueSetFlags::DefaultFlags) == FPropertyAccess::Result::Success); } bool FLiveLinkSubjectRepresentationDetailCustomization::HasMultipleValues() const { TArray RawData; StructPropertyHandle->AccessRawData(RawData); TOptional CompareAgainst; for (const void* RawPtr : RawData) { if (RawPtr == nullptr) { if (CompareAgainst.IsSet()) { return false; } } else { FLiveLinkSubjectRepresentation ThisValue = *reinterpret_cast(RawPtr); if (!CompareAgainst.IsSet()) { CompareAgainst = ThisValue; } else if (!(ThisValue == CompareAgainst.GetValue())) { return true; } } } return false; } #undef LOCTEXT_NAMESPACE