void FDetailPropertyRow::GenerateChildrenForPropertyNode( TSharedPtr<FPropertyNode>& RootPropertyNode, FDetailNodeList& OutChildren ) { // Children should be disabled if we are disabled TAttribute<bool> ParentEnabledState = CustomIsEnabledAttrib; if( IsParentEnabled.IsBound() || HasEditCondition() ) { // Bind a delegate to the edit condition so our children will be disabled if the edit condition fails ParentEnabledState.Bind( this, &FDetailPropertyRow::GetEnabledState ); } if( PropertyTypeLayoutBuilder.IsValid() && bShowCustomPropertyChildren ) { const TArray< FDetailLayoutCustomization >& ChildRows = PropertyTypeLayoutBuilder->GetChildCustomizations(); for( int32 ChildIndex = 0; ChildIndex < ChildRows.Num(); ++ChildIndex ) { TSharedRef<FDetailItemNode> ChildNodeItem = MakeShareable( new FDetailItemNode( ChildRows[ChildIndex], ParentCategory.Pin().ToSharedRef(), ParentEnabledState ) ); ChildNodeItem->Initialize(); OutChildren.Add( ChildNodeItem ); } } else if (bShowCustomPropertyChildren || !CustomPropertyWidget.IsValid() ) { TSharedRef<FDetailCategoryImpl> ParentCategoryRef = ParentCategory.Pin().ToSharedRef(); IDetailLayoutBuilder& LayoutBuilder = ParentCategoryRef->GetParentLayout(); UProperty* ParentProperty = RootPropertyNode->GetProperty(); const bool bStructProperty = ParentProperty && ParentProperty->IsA<UStructProperty>(); for( int32 ChildIndex = 0; ChildIndex < RootPropertyNode->GetNumChildNodes(); ++ChildIndex ) { TSharedPtr<FPropertyNode> ChildNode = RootPropertyNode->GetChildNode(ChildIndex); if( ChildNode.IsValid() && ChildNode->HasNodeFlags( EPropertyNodeFlags::IsCustomized ) == 0 ) { if( ChildNode->AsObjectNode() ) { // Skip over object nodes and generate their children. Object nodes are not visible GenerateChildrenForPropertyNode( ChildNode, OutChildren ); } // Only struct children can have custom visibility that is different from their parent. else if ( !bStructProperty || LayoutBuilder.IsPropertyVisible( FPropertyAndParent(*ChildNode->GetProperty(), ParentProperty ) ) ) { FDetailLayoutCustomization Customization; Customization.PropertyRow = MakeShareable( new FDetailPropertyRow( ChildNode, ParentCategoryRef ) ); TSharedRef<FDetailItemNode> ChildNodeItem = MakeShareable( new FDetailItemNode( Customization, ParentCategoryRef, ParentEnabledState ) ); ChildNodeItem->Initialize(); OutChildren.Add( ChildNodeItem ); } } } } }
void FFloatPropertySection::GenerateSectionLayout(class ISectionLayoutBuilder& LayoutBuilder) const { UMovieSceneFloatSection* FloatSection = Cast<UMovieSceneFloatSection>(&SectionObject); TAttribute<TOptional<float>> ExternalValue; if (CanGetPropertyValue()) { ExternalValue.Bind(TAttribute<TOptional<float>>::FGetter::CreateLambda([&] { return GetPropertyValue<float>(); })); } TSharedRef<FFloatCurveKeyArea> KeyArea = MakeShareable( new FFloatCurveKeyArea(&FloatSection->GetFloatCurve(), ExternalValue, FloatSection)); LayoutBuilder.SetSectionAsKeyArea(KeyArea); }
void FFoliageTypePaintingCustomization::GetHiddenPropertyVisibility(const TSharedPtr<IPropertyHandle>& PropertyHandle, bool bHideInReapplyTool, TAttribute<EVisibility>& OutVisibility) const { TAttribute<EVisibility>::FGetter VisibilityGetter; FFoliageTypeCustomizationHelpers::BindHiddenPropertyVisibilityGetter(PropertyHandle, VisibilityGetter); if (bHideInReapplyTool) { // In addition to hiding it it behind the given property, only show this in the reapply tool OutVisibility = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateLambda([=] { if (!FoliageEditMode->UISettings.GetReapplyToolSelected() && VisibilityGetter.IsBound()) { const EVisibility ReturnVal = VisibilityGetter.Execute(); return ReturnVal; } return EVisibility::Collapsed; })); } else { OutVisibility.Bind(VisibilityGetter); } }
void FDetailPropertyRow::MakeValueWidget( FDetailWidgetRow& Row, const TSharedPtr<FDetailWidgetRow> InCustomRow, bool bAddWidgetDecoration ) const { EVerticalAlignment VerticalAlignment = VAlign_Center; EHorizontalAlignment HorizontalAlignment = HAlign_Left; TOptional<float> MinWidth; TOptional<float> MaxWidth; if( InCustomRow.IsValid() ) { VerticalAlignment = InCustomRow->ValueWidget.VerticalAlignment; HorizontalAlignment = InCustomRow->ValueWidget.HorizontalAlignment; } TAttribute<bool> IsEnabledAttrib = CustomIsEnabledAttrib; if( HasEditCondition() ) { IsEnabledAttrib.Bind( this, &FDetailPropertyRow::GetEnabledState ); } TSharedRef<SHorizontalBox> ValueWidget = SNew( SHorizontalBox ) .IsEnabled( IsEnabledAttrib ); if( InCustomRow.IsValid() ) { MinWidth = InCustomRow->ValueWidget.MinWidth; MaxWidth = InCustomRow->ValueWidget.MaxWidth; ValueWidget->AddSlot() [ InCustomRow->ValueWidget.Widget ]; } else { TSharedPtr<SPropertyValueWidget> PropertyValue; ValueWidget->AddSlot() .Padding( 0.0f, 0.0f, 4.0f, 0.0f ) [ SAssignNew( PropertyValue, SPropertyValueWidget, PropertyEditor, GetPropertyUtilities() ) .ShowPropertyButtons( false ) // We handle this ourselves ]; MinWidth = PropertyValue->GetMinDesiredWidth(); MaxWidth = PropertyValue->GetMaxDesiredWidth(); } if(bAddWidgetDecoration) { if( bShowPropertyButtons ) { TArray< TSharedRef<SWidget> > RequiredButtons; PropertyEditorHelpers::MakeRequiredPropertyButtons( PropertyEditor.ToSharedRef(), /*OUT*/RequiredButtons ); for( int32 ButtonIndex = 0; ButtonIndex < RequiredButtons.Num(); ++ButtonIndex ) { ValueWidget->AddSlot() .AutoWidth() .HAlign(HAlign_Left) .VAlign(VAlign_Center) .Padding(2.0f, 1.0f) [ RequiredButtons[ButtonIndex] ]; } } if (PropertyHandle->HasMetaData(TEXT("ConfigHierarchyEditable"))) { ValueWidget->AddSlot() .AutoWidth() .VAlign(VAlign_Center) .HAlign(HAlign_Left) .Padding(0.0f, 0.0f, 4.0f, 0.0f) [ PropertyCustomizationHelpers::MakeEditConfigHierarchyButton(FSimpleDelegate::CreateSP(PropertyEditor.ToSharedRef(), &FPropertyEditor::EditConfigHierarchy)) ]; } if (!PropertyHandle->HasMetaData(TEXT("NoResetToDefault"))) { ValueWidget->AddSlot() .Padding( 2.0f, 0.0f ) .AutoWidth() .VAlign(VAlign_Center) .HAlign(HAlign_Left) [ SNew( SResetToDefaultPropertyEditor, PropertyEditor.ToSharedRef() ) .IsEnabled( IsEnabledAttrib ) .CustomResetToDefault(CustomResetToDefault) ]; } } Row.ValueContent() .HAlign( HorizontalAlignment ) .VAlign( VerticalAlignment ) .MinDesiredWidth( MinWidth ) .MaxDesiredWidth( MaxWidth ) [ ValueWidget ]; }
void FDetailPropertyRow::MakeNameOrKeyWidget( FDetailWidgetRow& Row, const TSharedPtr<FDetailWidgetRow> InCustomRow ) const { EVerticalAlignment VerticalAlignment = VAlign_Center; EHorizontalAlignment HorizontalAlignment = HAlign_Fill; bool bHasKeyNode = PropertyNode->GetPropertyKeyNode().IsValid(); if( !bHasKeyNode && InCustomRow.IsValid() ) { VerticalAlignment = InCustomRow->NameWidget.VerticalAlignment; HorizontalAlignment = InCustomRow->NameWidget.HorizontalAlignment; } TAttribute<bool> IsEnabledAttrib = CustomIsEnabledAttrib; TSharedRef<SHorizontalBox> NameHorizontalBox = SNew( SHorizontalBox ); if( HasEditCondition() ) { IsEnabledAttrib.Bind( this, &FDetailPropertyRow::GetEnabledState ); NameHorizontalBox->AddSlot() .AutoWidth() .Padding( 0.0f, 0.0f ) .VAlign(VAlign_Center) [ SNew( SEditConditionWidget, PropertyEditor ) .CustomEditCondition( CustomEditCondition.IsValid() ? *CustomEditCondition : FCustomEditCondition() ) ]; } TSharedPtr<SWidget> NameWidget; // Key nodes will take precedence over custom rows. if (bHasKeyNode) { const TSharedRef<IPropertyUtilities> PropertyUtilities = ParentCategory.Pin()->GetParentLayoutImpl().GetPropertyUtilities(); NameWidget = SNew(SPropertyValueWidget, PropertyKeyEditor, PropertyUtilities) .IsEnabled(IsEnabledAttrib) .ShowPropertyButtons(false); } else if(InCustomRow.IsValid()) { NameWidget = SNew( SBox ) .IsEnabled( IsEnabledAttrib ) [ InCustomRow->NameWidget.Widget ]; } else { NameWidget = SNew( SPropertyNameWidget, PropertyEditor ) .IsEnabled( IsEnabledAttrib ) .DisplayResetToDefault( false ); } SHorizontalBox::FSlot& Slot = NameHorizontalBox->AddSlot() [ NameWidget.ToSharedRef() ]; if (bHasKeyNode) { Slot.Padding(0.0f, 0.0f, 20.0f, 0.0f); } else { Slot.AutoWidth(); } Row.NameContent() .HAlign( HorizontalAlignment ) .VAlign( VerticalAlignment ) [ NameHorizontalBox ]; }