void FReplaceVectorWithLinearColorBuilder::GeneratePropertyContent(const TSharedRef<IPropertyHandle>& Handle, IDetailChildrenBuilder& ChildrenBuilder) { // Add to the current builder, depending on the property type. uint32 NumChildren = 0; ensure(Handle->GetNumChildren(NumChildren) == FPropertyAccess::Success); bool bHasChildren = (NumChildren > 0); bool bIsArray = Handle->AsArray().IsValid(); if (bIsArray) { // Arrays need special handling and will create an array builder TSharedRef<FDetailArrayBuilder> ArrayBuilder = MakeShareable(new FDetailArrayBuilder(Handle)); ArrayBuilder->OnGenerateArrayElementWidget(FOnGenerateArrayElementWidget::CreateSP(this, &FReplaceVectorWithLinearColorBuilder::OnGenerateArrayElementWidget)); ChildrenBuilder.AddChildCustomBuilder(ArrayBuilder); } else if (bHasChildren) { // If there are children, we invoke a new instance of our custom builder for recursive handling // Note, if this is an FVector, it will be handled specially by the implementation of the IDetailCustomNodeBuilder interface. TSharedRef<FReplaceVectorWithLinearColorBuilder> StructBuilder = MakeShareable(new FReplaceVectorWithLinearColorBuilder(Handle)); ChildrenBuilder.AddChildCustomBuilder(StructBuilder); } else { // No children - just add the property. ChildrenBuilder.AddChildProperty(Handle); } }
void FRawDistributionVectorStructCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { // Determine from the metadata whether we should treat vectors as FLinearColors or not bool bTreatAsColor = StructPropertyHandle->HasMetaData("TreatAsColor"); uint32 NumChildren; ensure(StructPropertyHandle->GetNumChildren(NumChildren) == FPropertyAccess::Success); // Now recurse through all children, creating a custom builder for each which will either add the default property row, or // a property row exposing a FLinearColor type customization which maps directly to the elements of the original FVector. for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ChildIndex++) { TSharedPtr<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle(ChildIndex); check(ChildHandle.IsValid()); if (bTreatAsColor) { TSharedRef<FReplaceVectorWithLinearColorBuilder> CustomBuilder = MakeShareable(new FReplaceVectorWithLinearColorBuilder(ChildHandle.ToSharedRef())); StructBuilder.AddChildCustomBuilder(CustomBuilder); } else { StructBuilder.AddChildProperty(ChildHandle.ToSharedRef()); } } }
void FLandscapeEditorStructCustomization_FGizmoImportLayer::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { TSharedRef<IPropertyHandle> PropertyHandle_LayerFilename = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FGizmoImportLayer, LayerFilename)).ToSharedRef(); ChildBuilder.AddChildProperty(PropertyHandle_LayerFilename) .CustomWidget() .NameContent() [ PropertyHandle_LayerFilename->CreatePropertyNameWidget() ] .ValueContent() .MinDesiredWidth(250.0f) .MaxDesiredWidth(0) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() [ PropertyHandle_LayerFilename->CreatePropertyValueWidget() ] + SHorizontalBox::Slot() .AutoWidth() //.Padding(0,0,12,0) // Line up with the other properties due to having no reset to default button [ SNew(SButton) .ContentPadding(FMargin(4, 0)) .Text(NSLOCTEXT("UnrealEd", "GenericOpenDialog", "...")) .OnClicked_Static(&FLandscapeEditorStructCustomization_FGizmoImportLayer::OnGizmoImportLayerFilenameButtonClicked, PropertyHandle_LayerFilename) ] ]; TSharedRef<IPropertyHandle> PropertyHandle_LayerName = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FGizmoImportLayer, LayerName)).ToSharedRef(); ChildBuilder.AddChildProperty(PropertyHandle_LayerName); }
void FReplaceVectorWithLinearColorBuilder::AddColorChildProperty(const TSharedPtr<IPropertyHandle>& StructHandle, const FText& Text, int32 ElementIndex, IDetailChildrenBuilder& ChildrenBuilder) { ChildrenBuilder.AddChildContent(LOCTEXT("Color", "Color")) .NameContent() [ SNew(STextBlock) .Text(Text) .Font(IPropertyTypeCustomizationUtils::GetRegularFont()) ] .ValueContent() .MinDesiredWidth(100.0f) .MaxDesiredWidth(100.0f) [ SNew(SNumericEntryBox<float>) .Font(IPropertyTypeCustomizationUtils::GetRegularFont()) .Value(this, &FReplaceVectorWithLinearColorBuilder::OnGetColorElementValue, StructHandle, ElementIndex) .OnValueCommitted(this, &FReplaceVectorWithLinearColorBuilder::OnColorElementValueCommitted, StructHandle, ElementIndex) .OnValueChanged(this, &FReplaceVectorWithLinearColorBuilder::OnColorElementValueChanged, StructHandle, ElementIndex) .OnBeginSliderMovement(this, &FReplaceVectorWithLinearColorBuilder::OnBeginSliderMovement) .OnEndSliderMovement(this, &FReplaceVectorWithLinearColorBuilder::OnEndSliderMovement) .AllowSpin(true) .MinSliderValue(0.0f) .MaxSliderValue(1.0f) ]; }
void FActionMappingsNodeBuilder::GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) { RebuildGroupedMappings(); for (int32 Index = 0; Index < GroupedMappings.Num(); ++Index) { FMappingSet& MappingSet = GroupedMappings[Index]; FString GroupNameString(TEXT("ActionMappings.")); MappingSet.SharedName.AppendString(GroupNameString); FName GroupName(*GroupNameString); IDetailGroup& ActionMappingGroup = ChildrenBuilder.AddChildGroup(GroupName, FText::FromName(MappingSet.SharedName)); MappingSet.DetailGroup = &ActionMappingGroup; TSharedRef<SWidget> AddButton = PropertyCustomizationHelpers::MakeAddButton(FSimpleDelegate::CreateSP(this, &FActionMappingsNodeBuilder::AddActionMappingToGroupButton_OnClick, MappingSet), LOCTEXT("AddActionMappingToGroupToolTip", "Adds Action Mapping to Group")); TSharedRef<SWidget> RemoveButton = PropertyCustomizationHelpers::MakeDeleteButton(FSimpleDelegate::CreateSP(this, &FActionMappingsNodeBuilder::RemoveActionMappingGroupButton_OnClick, MappingSet), LOCTEXT("RemoveActionMappingGroupToolTip", "Removes Action Mapping Group")); ActionMappingGroup.HeaderRow() [ SNew( SHorizontalBox ) + SHorizontalBox::Slot() .AutoWidth() [ SNew(SBox) .WidthOverride( InputConstants::TextBoxWidth ) [ SNew(SEditableTextBox) .Padding(2.0f) .Text(FText::FromName(MappingSet.SharedName)) .OnTextCommitted(FOnTextCommitted::CreateSP(this, &FActionMappingsNodeBuilder::OnActionMappingNameCommitted, MappingSet)) .Font(IDetailLayoutBuilder::GetDetailFont()) ] ] +SHorizontalBox::Slot() .Padding(InputConstants::PropertyPadding) .HAlign(HAlign_Center) .VAlign(VAlign_Center) .AutoWidth() [ AddButton ] +SHorizontalBox::Slot() .Padding(InputConstants::PropertyPadding) .HAlign(HAlign_Center) .VAlign(VAlign_Center) .AutoWidth() [ RemoveButton ] ]; for (int32 MappingIndex = 0; MappingIndex < MappingSet.Mappings.Num(); ++MappingIndex) { ActionMappingGroup.AddPropertyRow(MappingSet.Mappings[MappingIndex]).ShowPropertyButtons(false); } } }
void FSpriteDetailsCustomization::GenerateAdditionalTextureWidget(TSharedRef<IPropertyHandle> PropertyHandle, int32 ArrayIndex, IDetailChildrenBuilder& ChildrenBuilder) { IDetailPropertyRow& TextureRow = ChildrenBuilder.AddChildProperty(PropertyHandle); FText ExtraText; if (FText* pExtraText = AdditionalTextureLabels.Find(ArrayIndex)) { ExtraText = *pExtraText; } FNumberFormattingOptions NoCommas; NoCommas.UseGrouping = false; const FText SlotDesc = FText::Format(LOCTEXT("AdditionalTextureSlotIndex", "Slot #{0}"), FText::AsNumber(ArrayIndex, &NoCommas)); TextureRow.DisplayName(SlotDesc); TextureRow.ShowPropertyButtons(false); TextureRow.CustomWidget(false) .NameContent() [ CreateTextureNameWidget(PropertyHandle, ExtraText) ] .ValueContent() .MaxDesiredWidth(TOptional<float>()) [ PropertyHandle->CreatePropertyValueWidget() ]; }
void FMoviePlayerSettingsDetails::GenerateArrayElementWidget(TSharedRef<IPropertyHandle> PropertyHandle, int32 ArrayIndex, IDetailChildrenBuilder& ChildrenBuilder) { IDetailPropertyRow& FilePathRow = ChildrenBuilder.AddChildProperty( PropertyHandle ); { FilePathRow.CustomWidget(false) .NameContent() [ PropertyHandle->CreatePropertyNameWidget() ] .ValueContent() .MaxDesiredWidth(0.0f) .MinDesiredWidth(125.0f) [ SNew(SFilePathPicker) .BrowseButtonImage(FEditorStyle::GetBrush("PropertyWindow.Button_Ellipsis")) .BrowseButtonStyle(FEditorStyle::Get(), "HoverHintOnly") .BrowseButtonToolTip(LOCTEXT("FileButtonToolTipText", "Choose a file from this computer")) .BrowseDirectory(FEditorDirectories::Get().GetLastDirectory(ELastDirectory::GENERIC_OPEN)) .BrowseTitle(LOCTEXT("PropertyEditorTitle", "File picker...")) .FilePath(this, &FMoviePlayerSettingsDetails::HandleFilePathPickerFilePath, PropertyHandle) .FileTypeFilter(TEXT("MPEG-4 Movie (*.mp4)|*.mp4")) .OnPathPicked(this, &FMoviePlayerSettingsDetails::HandleFilePathPickerPathPicked, PropertyHandle) ]; } };
void FDialogueContextMappingNodeBuilder::GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) { if( ContextMappingPropertyHandle->IsValidHandle() ) { const TSharedPtr<IPropertyHandle> SoundwavePropertyHandle = ContextMappingPropertyHandle->GetChildHandle("Soundwave"); ChildrenBuilder.AddChildProperty(SoundwavePropertyHandle.ToSharedRef()); } }
void FFormatTextLayout::GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) { Children.Empty(); for (int32 ArgIdx = 0; ArgIdx < TargetNode->GetArgumentCount(); ++ArgIdx) { TSharedRef<class FFormatTextArgumentLayout> ArgumentIndexLayout = MakeShareable(new FFormatTextArgumentLayout(TargetNode, ArgIdx) ); ChildrenBuilder.AddChildCustomBuilder(ArgumentIndexLayout); Children.Add(ArgumentIndexLayout); } }
void FNiagaraEmitterPropertiesDetails::OnGenerateScalarConstantEntry(TSharedRef<IPropertyHandle> ElementProperty, int32 ElementIndex, IDetailChildrenBuilder& ChildrenBuilder) { TSharedPtr<IPropertyHandle> ValueProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraConstants_Float, Value)); TSharedPtr<IPropertyHandle> NameProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraConstants_Float, Name)); FName DisplayName; NameProperty->GetValue(DisplayName); //Don't display system constants if (UNiagaraComponent::GetSystemConstants().Find(FNiagaraVariableInfo(DisplayName, ENiagaraDataType::Scalar)) == INDEX_NONE) { ChildrenBuilder.AddChildProperty(ValueProperty.ToSharedRef()).DisplayName(FText::FromName(DisplayName)); } }
void FLightmapCustomNodeBuilder::GenerateChildContent(IDetailChildrenBuilder& ChildrenBuilder) { RefreshLightmapItems(); for(TSharedPtr<FLightmapItem>& Item : LightmapItems) { ChildrenBuilder.AddChildContent(LOCTEXT("LightMapsFilter", "Lightmaps")) .ValueContent() .HAlign(HAlign_Fill) [ MakeLightMapList(Item) ]; } }
void FLightmapCustomNodeBuilder::GenerateChildContent(IDetailChildrenBuilder& ChildrenBuilder) { RefreshLightmapItems(); ChildrenBuilder.AddChildContent(LOCTEXT("LightMapsFilter", "Lightmaps")) .ValueContent() .HAlign(HAlign_Fill) [ SAssignNew(LightmapListView, SListView<TSharedPtr<FLightmapItem>>) .ListItemsSource(&LightmapItems) .OnGenerateRow(this, &FLightmapCustomNodeBuilder::MakeLightMapListViewWidget) .OnContextMenuOpening(this, &FLightmapCustomNodeBuilder::OnGetLightMapContextMenuContent) .OnMouseButtonDoubleClick(this, &FLightmapCustomNodeBuilder::OnLightMapListMouseButtonDoubleClick) ]; }
void FAbcCompressionSettingsCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { Settings = UAbcImportSettings::Get(); uint32 NumChildren; StructPropertyHandle->GetNumChildren(NumChildren); for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex) { TSharedRef<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle(ChildIndex).ToSharedRef(); IDetailPropertyRow& Property = StructBuilder.AddChildProperty(ChildHandle); static const FName EditConditionName = "EnumCondition"; int32 EnumCondition = ChildHandle->GetINTMetaData(EditConditionName); Property.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FAbcCompressionSettingsCustomization::ArePropertiesVisible, EnumCondition))); } }
void FWidgetNavigationCustomization::MakeNavRow(TWeakPtr<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder, EUINavigation Nav, FText NavName) { ChildBuilder.AddChildContent(NavName) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(NavName) ] .ValueContent() .MaxDesiredWidth(300) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() [ SNew(SComboButton) .HAlign(HAlign_Center) .ButtonContent() [ SNew(STextBlock) .Text(this, &FWidgetNavigationCustomization::GetNavigationText, PropertyHandle, Nav) ] .ContentPadding(FMargin(2.0f, 1.0f)) .MenuContent() [ MakeNavMenu(PropertyHandle, Nav) ] ] // Explicit Navigation Widget + SHorizontalBox::Slot() .FillWidth(1.0f) [ SNew(SEditableTextBox) .HintText(LOCTEXT("WidgetName", "Widget Name?")) .Text(this, &FWidgetNavigationCustomization::GetExplictWidget, PropertyHandle, Nav) .OnTextCommitted(this, &FWidgetNavigationCustomization::OnCommitExplictWidgetText, PropertyHandle, Nav) .Font(IDetailLayoutBuilder::GetDetailFont()) .Visibility(this, &FWidgetNavigationCustomization::GetExplictWidgetFieldVisibility, PropertyHandle, Nav) ] ]; }
void FNiagaraEmitterPropertiesDetails::OnGenerateEventReceiverEntry(TSharedRef<IPropertyHandle> ElementProperty, int32 ElementIndex, IDetailChildrenBuilder& ChildrenBuilder) { TSharedPtr<IPropertyHandle> NameProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraEventReceiverProperties, Name)); FName DisplayName; NameProperty->GetValue(DisplayName); // ChildrenBuilder.AddChildProperty(ElementProperty).DisplayName(FText::FromName(DisplayName)); IDetailGroup& Group = ChildrenBuilder.AddChildGroup(DisplayName, FText::FromName(DisplayName)); uint32 NumChildren = 0; if (ElementProperty->GetNumChildren(NumChildren) == FPropertyAccess::Success) { for (uint32 i = 0; i < NumChildren; ++i) { TSharedPtr<IPropertyHandle> Child = ElementProperty->GetChildHandle(i); //Dont add the ID. We just grab it's name for the name region of this property. if (Child.IsValid() && Child->GetProperty()->GetName() != GET_MEMBER_NAME_CHECKED(FNiagaraEventReceiverProperties, Name).ToString()) { TSharedPtr<SWidget> NameWidget; TSharedPtr<SWidget> ValueWidget; FDetailWidgetRow DefaultDetailRow; IDetailPropertyRow& Row = Group.AddPropertyRow(Child.ToSharedRef()); Row.GetDefaultWidgets(NameWidget, ValueWidget, DefaultDetailRow); Row.CustomWidget(true) .NameContent() [ NameWidget.ToSharedRef() ] .ValueContent() [ ValueWidget.ToSharedRef() ]; } } } }
void FNiagaraEmitterPropertiesDetails::OnGenerateEventGeneratorEntry(TSharedRef<IPropertyHandle> ElementProperty, int32 ElementIndex, IDetailChildrenBuilder& ChildrenBuilder) { TSharedPtr<IPropertyHandle> IDProperty = ElementProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraEventGeneratorProperties, ID)); TSharedPtr<IPropertyHandle> NameProperty = IDProperty->GetChildHandle(GET_MEMBER_NAME_CHECKED(FNiagaraDataSetID, Name)); FName DisplayName; NameProperty->GetValue(DisplayName); //IDetailPropertyRow& Row = ChildrenBuilder.AddChildProperty(ElementProperty).DisplayName(FText::FromName(DisplayName)); IDetailGroup& GenGroup = ChildrenBuilder.AddChildGroup(DisplayName, FText::FromName(DisplayName)); uint32 NumChildren = 0; if (ElementProperty->GetNumChildren(NumChildren) == FPropertyAccess::Success) { for (uint32 i = 0; i < NumChildren; ++i) { TSharedPtr<IPropertyHandle> Child = ElementProperty->GetChildHandle(i); //Dont add the ID. We just grab it's name for the name region of this property. if (Child.IsValid() && Child->GetProperty()->GetName() != GET_MEMBER_NAME_CHECKED(FNiagaraEventGeneratorProperties, ID).ToString()) { GenGroup.AddPropertyRow(Child.ToSharedRef()); } } } }
void FAttributeBasedFloatDetails::CustomizeChildren(TSharedRef<IPropertyHandle> StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { uint32 NumChildrenProps = 0; StructPropertyHandle->GetNumChildren(NumChildrenProps); AttributeCalculationTypePropertyHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FAttributeBasedFloat, AttributeCalculationType)); const TSharedPtr<IPropertyHandle> FinalChannelHandle = StructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FAttributeBasedFloat, FinalChannel)); if (ensure(FinalChannelHandle.IsValid()) && ensure(FinalChannelHandle->IsValidHandle()) && ensure(AttributeCalculationTypePropertyHandle.IsValid()) && ensure(AttributeCalculationTypePropertyHandle->IsValidHandle())) { for (uint32 ChildIdx = 0; ChildIdx < NumChildrenProps; ++ChildIdx) { TSharedPtr<IPropertyHandle> ChildHandle = StructPropertyHandle->GetChildHandle(ChildIdx); if (ChildHandle.IsValid() && ChildHandle->IsValidHandle()) { IDetailPropertyRow& NewPropRow = StructBuilder.AddChildProperty(ChildHandle.ToSharedRef()); if (ChildHandle->GetProperty() == FinalChannelHandle->GetProperty()) { NewPropRow.Visibility(TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateSP(this, &FAttributeBasedFloatDetails::GetFinalChannelVisibility))); } } } } }
void FVehicleTransmissionDataCustomization::CreateGearUIDelegate(TSharedRef<IPropertyHandle> GearProperty, int32 GearIdx, IDetailChildrenBuilder& ChildrenBuilder) { FText Label = FText::Format(LOCTEXT("TransmissionGear", "Gear {0}"), FText::AsNumber(GearIdx + 1)); CreateGearUIHelper(ChildrenBuilder.AddChildContent(Label), Label, GearProperty, ForwardGear); }
void FCurveColorCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { uint32 NumChildren = 0; StructPropertyHandle->GetNumChildren(NumChildren); for( uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex ) { TSharedPtr<IPropertyHandle> Child = StructPropertyHandle->GetChildHandle( ChildIndex ); if( Child->GetProperty()->GetName() == TEXT("ExternalCurve") ) { ExternalCurveHandle = Child; FSimpleDelegate OnCurveChangedDelegate = FSimpleDelegate::CreateSP( this, &FCurveColorCustomization::OnExternalCurveChanged, InStructPropertyHandle ); Child->SetOnPropertyValueChanged(OnCurveChangedDelegate); StructBuilder.AddChildContent(LOCTEXT("ExternalCurveLabel", "ExternalCurve")) .NameContent() [ Child->CreatePropertyNameWidget() ] .ValueContent() [ SNew(SVerticalBox) +SVerticalBox::Slot() .AutoHeight() [ SNew(SHorizontalBox) +SHorizontalBox::Slot() [ Child->CreatePropertyValueWidget() ] +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(1,0) [ SNew(SButton) .ButtonStyle( FEditorStyle::Get(), "NoBorder" ) .ContentPadding(1.f) .ToolTipText(LOCTEXT("ConvertInternalCurveTooltip", "Convert to Internal Color Curve")) .OnClicked(this, &FCurveColorCustomization::OnConvertButtonClicked) .IsEnabled(this, &FCurveColorCustomization::IsConvertButtonEnabled) [ SNew(SImage) .Image( FEditorStyle::GetBrush(TEXT("PropertyWindow.Button_Clear")) ) ] ] ] +SVerticalBox::Slot() .AutoHeight() [ SNew(SButton) .HAlign(HAlign_Center) .Text( LOCTEXT( "CreateAssetButton", "Create External Curve" ) ) .ToolTipText(LOCTEXT( "CreateAssetTooltip", "Create a new Color Curve asset from this curve") ) .OnClicked(this, &FCurveColorCustomization::OnCreateButtonClicked) .IsEnabled(this, &FCurveColorCustomization::IsCreateButtonEnabled) ] ]; } else { StructBuilder.AddChildProperty(Child.ToSharedRef()); } } }
void FAssetImportDataCustomization::CustomizeChildren( TSharedRef<IPropertyHandle> InPropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils ) { PropertyHandle = InPropertyHandle; FAssetImportInfo* Info = GetEditStruct(); if (!Info) { return; } auto Font = IDetailLayoutBuilder::GetDetailFont(); const FText SourceFileText = LOCTEXT("SourceFile", "Source File"); for (int32 Index = 0; Index < Info->SourceFiles.Num(); ++Index) { ChildBuilder.AddChildContent(SourceFileText) .NameContent() [ SNew(STextBlock) .Text(SourceFileText) .Font(Font) ] .ValueContent() .HAlign(HAlign_Fill) .MaxDesiredWidth(TOptional<float>()) [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SHorizontalBox) + SHorizontalBox::Slot() [ SNew(SEditableText) .IsReadOnly(true) .Text(this, &FAssetImportDataCustomization::GetFilenameText, Index) .ToolTipText(this, &FAssetImportDataCustomization::GetFilenameText, Index) .Font(Font) ] +SHorizontalBox::Slot() .AutoWidth() [ SNew(SButton) .OnClicked(this, &FAssetImportDataCustomization::OnChangePathClicked, Index) .ToolTipText(LOCTEXT("ChangePath_Tooltip", "Browse for a new source file path")) [ SNew(STextBlock) .Text(LOCTEXT("...", "...")) .Font(Font) ] ] +SHorizontalBox::Slot() .AutoWidth() [ SNew(SButton) .VAlign(VAlign_Center) .HAlign(HAlign_Center) .ButtonStyle(FEditorStyle::Get(), "HoverHintOnly") .OnClicked(this, &FAssetImportDataCustomization::OnClearPathClicked, Index) .ToolTipText(LOCTEXT("ClearPath_Tooltip", "Clear this source file information from the asset")) [ SNew(SImage) .Image(FEditorStyle::GetBrush("Cross")) ] ] ] + SVerticalBox::Slot() .AutoHeight() [ SNew(SEditableText) .IsReadOnly(true) .Text(this, &FAssetImportDataCustomization::GetTimestampText, Index) .Font(Font) ] ]; } }
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION void FTextureLODGroupLayout::GenerateChildContent(IDetailChildrenBuilder& ChildrenBuilder) { // Min and Max LOD properties { ChildrenBuilder.AddChildContent(LOCTEXT("MinLODSize", "Min LOD Size")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("MinLODSize", "Min LOD Size")) ] .ValueContent() [ SNew(SSpinBox<uint32>) .Font(IDetailLayoutBuilder::GetDetailFont()) .MinValue(2) .MaxValue(4096) .Value(this, &FTextureLODGroupLayout::GetMinLODSize) .OnValueChanged(this, &FTextureLODGroupLayout::OnMinLODSizeChanged) .OnValueCommitted(this, &FTextureLODGroupLayout::OnMinLODSizeCommitted) ]; } { ChildrenBuilder.AddChildContent(LOCTEXT("MaxLODSize", "Max LOD Size")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("MaxLODSize", "Max LOD Size")) ] .ValueContent() [ SNew(SSpinBox<uint32>) .Font(IDetailLayoutBuilder::GetDetailFont()) .MinValue(2) .MaxValue(4096) .Value(this, &FTextureLODGroupLayout::GetMaxLODSize) .OnValueChanged(this, &FTextureLODGroupLayout::OnMaxLODSizeChanged) .OnValueCommitted(this, &FTextureLODGroupLayout::OnMaxLODSizeCommitted) ]; } // LOD Bias { ChildrenBuilder.AddChildContent(LOCTEXT("LODBias", "LOD Bias")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("LODBias", "LOD Bias")) ] .ValueContent() [ SNew(SSpinBox<uint32>) .Font(IDetailLayoutBuilder::GetDetailFont()) .MinValue(1) .MaxValue(100) .Value(this, &FTextureLODGroupLayout::GetLODBias) .OnValueChanged(this, &FTextureLODGroupLayout::OnLODBiasChanged) .OnValueCommitted(this, &FTextureLODGroupLayout::OnLODBiasCommitted) ]; } // Filter properties TSharedPtr<FName> NamePointPtr = MakeShareable(new FName(NAME_Point)); FilterComboList.Add(NamePointPtr); TSharedPtr<FName> NameLinearPtr = MakeShareable(new FName(NAME_Linear)); FilterComboList.Add(NameLinearPtr); TSharedPtr<FName> NameAnisoPtr = MakeShareable(new FName(NAME_Aniso)); FilterComboList.Add(NameAnisoPtr); { ChildrenBuilder.AddChildContent(LOCTEXT("MinMagFilter", "MinMag Filter")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("MinMagFilter", "MinMag Filter")) ] .ValueContent() [ SNew(SComboBox< TSharedPtr<FName> >) .OptionsSource(&FilterComboList) .OnGenerateWidget(this, &FTextureLODGroupLayout::MakeMinMagFilterComboWidget) .OnSelectionChanged(this, &FTextureLODGroupLayout::OnMinMagFilterChanged) .InitiallySelectedItem(FilterComboList[0]) .ContentPadding(0) .Content() [ SNew(STextBlock) .Text(this, &FTextureLODGroupLayout::GetMinMagFilterComboBoxContent) .Font(IDetailLayoutBuilder::GetDetailFont()) .ToolTipText(this, &FTextureLODGroupLayout::GetMinMagFilterComboBoxToolTip) ] ]; } { ChildrenBuilder.AddChildContent(LOCTEXT("MipFilter", "Mip Filter")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("MipFilter", "Mip Filter")) ] .ValueContent() [ SNew(SComboBox< TSharedPtr<FName> >) .OptionsSource(&FilterComboList) .OnGenerateWidget(this, &FTextureLODGroupLayout::MakeMipFilterComboWidget) .OnSelectionChanged(this, &FTextureLODGroupLayout::OnMipFilterChanged) .InitiallySelectedItem(FilterComboList[0]) .ContentPadding(0) .Content() [ SNew(STextBlock) .Text(this, &FTextureLODGroupLayout::GetMipFilterComboBoxContent) .Font(IDetailLayoutBuilder::GetDetailFont()) .ToolTipText(this, &FTextureLODGroupLayout::GetMipFilterComboBoxToolTip) ] ]; } // Mip Gen Settings { ChildrenBuilder.AddChildContent(LOCTEXT("MipGenSettings", "Mip Gen Settings")) .NameContent() [ SNew(STextBlock) .Font(IDetailLayoutBuilder::GetDetailFont()) .Text(LOCTEXT("MipGenSettings", "Mip Gen Settings")) ] .ValueContent() [ SNew(SComboBox< TSharedPtr<TextureMipGenSettings> >) .OptionsSource(&MipGenSettingsComboList) .OnGenerateWidget(this, &FTextureLODGroupLayout::MakeMipGenSettingsComboWidget) .OnSelectionChanged(this, &FTextureLODGroupLayout::OnMipGenSettingsChanged) .InitiallySelectedItem(MipGenSettingsComboList[0]) .ContentPadding(0) .Content() [ SNew(STextBlock) .Text(this, &FTextureLODGroupLayout::GetMipGenSettingsComboBoxContent) .Font(IDetailLayoutBuilder::GetDetailFont()) .ToolTipText(this, &FTextureLODGroupLayout::GetMipGenSettingsComboBoxToolTip) ] ]; } }
void FRemeshingSettingsLayout::GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) { //Use MassiveLOD ChildrenBuilder.AddChildContent(LOCTEXT("UseMassiveLOD", "Use MassiveLOD") ) .Visibility(RemeshingSettingsVisisbility) .NameContent() [ SNew( STextBlock ) .Font( IDetailLayoutBuilder::GetDetailFont() ) .Text( LOCTEXT("AsParent", "As Parent") ) ] .ValueContent() [ SNew(SCheckBox) .IsChecked(this, &FRemeshingSettingsLayout::GetUseMassiveLODState) .OnCheckStateChanged(this, &FRemeshingSettingsLayout::OnUseMassiveLODChanged) ]; //Size On Screen ChildrenBuilder.AddChildContent( LOCTEXT("SizeOnScreen", "Size On Screen") ) .Visibility(RemeshingSettingsVisisbility) .NameContent() [ SNew( STextBlock ) .Font( IDetailLayoutBuilder::GetDetailFont() ) .Text( LOCTEXT("SizeOnScreen", "Size On Screen") ) ] .ValueContent() [ SNew(SSpinBox<int32>) .Font( IDetailLayoutBuilder::GetDetailFont() ) .MinValue(1) .MaxValue(5000) .Value(this, &FRemeshingSettingsLayout::GetSizeOnScreen) .OnValueChanged(this, &FRemeshingSettingsLayout::OnSizeOnScreenChanged) .OnValueCommitted(this, &FRemeshingSettingsLayout::OnSizeOnScreenCommitted) ]; //Merge Distance ChildrenBuilder.AddChildContent( LOCTEXT("MergeDistance", "Merge Distance") ) .Visibility(RemeshingSettingsVisisbility) .NameContent() [ SNew( STextBlock ) .Font( IDetailLayoutBuilder::GetDetailFont() ) .Text( LOCTEXT("MergeDistance", "Merge Distance") ) ] .ValueContent() [ SNew(SSpinBox<int32>) .Font( IDetailLayoutBuilder::GetDetailFont() ) .MinValue(0) .MaxValue(5000) .Value(this, &FRemeshingSettingsLayout::GetMergeDistance) .OnValueChanged(this, &FRemeshingSettingsLayout::OnMergeDistanceChanged) .OnValueCommitted(this, &FRemeshingSettingsLayout::OnMergeDistanceCommitted) ]; //Recalculate Normals /*ChildrenBuilder.AddChildContent( LOCTEXT("RecalculateNormals", "Recalculate Normals") ) .Visibility(RemeshingSettingsVisisbility) .NameContent() [ SNew( STextBlock ) .Font( IDetailLayoutBuilder::GetDetailFontBold() ) .Text( LOCTEXT("RecalculateNormals", "Recalculate Normals").ToString() ) ];*/ ChildrenBuilder.AddChildContent( LOCTEXT("HardAngle", "Hard Angle") ) .Visibility(RemeshingSettingsVisisbility) .NameContent() [ SNew(SBox) .Content() [ SNew( STextBlock ) .Font( IDetailLayoutBuilder::GetDetailFont() ) .Text( LOCTEXT("HardAngle", "Hard Angle") ) ] ] .ValueContent() [ SNew(SSpinBox<float>) .Font( IDetailLayoutBuilder::GetDetailFont() ) .MinValue(0.0f) .MaxValue(180.0f) .Value(this, &FRemeshingSettingsLayout::GetHardAngle) .OnValueChanged(this, &FRemeshingSettingsLayout::OnHardAngleChanged) .OnValueCommitted(this, &FRemeshingSettingsLayout::OnHardAngleCommitted) ]; }