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 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 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 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)
		];
}