Ejemplo n.º 1
0
/** Called at the end of SetObjectArray after we change the objects being observed */
void SDetailsView::PostSetObject()
{
	DestroyColorPicker();
	ColorPropertyNode = nullptr;

	FPropertyNodeInitParams InitParams;
	InitParams.ParentNode = nullptr;
	InitParams.Property = nullptr;
	InitParams.ArrayOffset = 0;
	InitParams.ArrayIndex = INDEX_NONE;
	InitParams.bAllowChildren = true;
	InitParams.bForceHiddenPropertyVisibility =  FPropertySettings::Get().ShowHiddenProperties();

	switch ( DetailsViewArgs.DefaultsOnlyVisibility )
	{
	case FDetailsViewArgs::EEditDefaultsOnlyNodeVisibility::Hide:
		InitParams.bCreateDisableEditOnInstanceNodes = false;
		break;
	case FDetailsViewArgs::EEditDefaultsOnlyNodeVisibility::Show:
		InitParams.bCreateDisableEditOnInstanceNodes = true;
		break;
	case FDetailsViewArgs::EEditDefaultsOnlyNodeVisibility::Automatic:
		InitParams.bCreateDisableEditOnInstanceNodes = HasClassDefaultObject();
		break;
	default:
		check(false);
	}

	for( TSharedPtr<FComplexPropertyNode>& ComplexRootNode : RootPropertyNodes )
	{
		FObjectPropertyNode* RootPropertyNode = ComplexRootNode->AsObjectNode();

		RootPropertyNode->InitNode( InitParams );

		// Restore existing expanded items
		RestoreExpandedItems(ComplexRootNode.ToSharedRef());
	}

	UpdatePropertyMaps();

	for( auto ExternalRootNode : ExternalRootPropertyNodes )
	{
		if( ExternalRootNode.IsValid() )
		{
			RestoreExpandedItems( ExternalRootNode.Pin().ToSharedRef() );
		}
	}

	UpdateFilteredDetails();
}
Ejemplo n.º 2
0
/** Called at the end of SetObjectArray after we change the objects being observed */
void SDetailsView::PostSetObject()
{
	DestroyColorPicker();
	ColorPropertyNode = NULL;

	FPropertyNodeInitParams InitParams;
	InitParams.ParentNode = NULL;
	InitParams.Property = NULL;
	InitParams.ArrayOffset = 0;
	InitParams.ArrayIndex = INDEX_NONE;
	InitParams.bAllowChildren = true;
	InitParams.bForceHiddenPropertyVisibility =  FPropertySettings::Get().ShowHiddenProperties();

	RootPropertyNode->InitNode( InitParams );

	bool bInitiallySeen = true;
	bool bParentAllowsVisible = true;
	// Restore existing expanded items
	RestoreExpandedItems();

	UpdatePropertyMap();
}
Ejemplo n.º 3
0
void SSingleProperty::SetObject( UObject* InObject )
{
	DestroyColorPicker();

	if( !RootPropertyNode.IsValid() )
	{
		RootPropertyNode = MakeShareable( new FObjectPropertyNode );
	}

	RootPropertyNode->RemoveAllObjects();
	ValueNode.Reset();

	if( InObject )
	{
		RootPropertyNode->AddObject( InObject );
	}


	FPropertyNodeInitParams InitParams;
	InitParams.ParentNode = NULL;
	InitParams.Property = NULL;
	InitParams.ArrayOffset = 0;
	InitParams.ArrayIndex = INDEX_NONE;
	// we'll generate the children
	InitParams.bAllowChildren = false;
	InitParams.bForceHiddenPropertyVisibility = false;

	RootPropertyNode->InitNode( InitParams );

	ValueNode = RootPropertyNode->GenerateSingleChild( PropertyName );

	bool bIsAcceptableProperty = false;
	// valid criteria for standalone properties 
	if( ValueNode.IsValid() )
	{
		UProperty* Property = ValueNode->GetProperty();

		bIsAcceptableProperty = true;
		// not an array property (dynamic or static)
		bIsAcceptableProperty &= !( Property->IsA( UArrayProperty::StaticClass() ) || (Property->ArrayDim > 1 && ValueNode->GetArrayIndex() == INDEX_NONE) );
		// not a struct property unless its a built in type like a vector
		bIsAcceptableProperty &= ( !Property->IsA( UStructProperty::StaticClass() ) || PropertyEditorHelpers::IsBuiltInStructProperty( Property ) );
	}

	if( bIsAcceptableProperty )
	{
		ValueNode->RebuildChildren();

		TSharedRef< FPropertyEditor > PropertyEditor = FPropertyEditor::Create( ValueNode.ToSharedRef(), TSharedPtr< IPropertyUtilities >( PropertyUtilities ).ToSharedRef() );
		ValueNode->SetDisplayNameOverride( NameOverride );

		TSharedPtr<SHorizontalBox> HorizontalBox;

		ChildSlot
		[
			SAssignNew( HorizontalBox, SHorizontalBox )
		];

		if( NamePlacement != EPropertyNamePlacement::Hidden )
		{
			HorizontalBox->AddSlot()
			.Padding( 2.0f, 0.0f, 2.0f, 4.0f )
			.AutoWidth()
			.VAlign( VAlign_Center )
			[
				SNew( SPropertyNameWidget, PropertyEditor )
				.DisplayResetToDefault( false )
			];
		}

		HorizontalBox->AddSlot()
		.Padding( 0.0f, 2.0f, 0.0f, 2.0f )
		.FillWidth(1.0f)
		.VAlign( VAlign_Center )
		[
			SNew( SPropertyValueWidget, PropertyEditor, PropertyUtilities.ToSharedRef() )
		];

		HorizontalBox->AddSlot()
		.Padding( 2.0f )
		.AutoWidth()
		.VAlign( VAlign_Center )
		[
			SNew( SResetToDefaultPropertyEditor,  PropertyEditor )
		];
	}
	else
	{
		ChildSlot
		[
			SNew(STextBlock)
			.Font(PropertyFont)
			.Text(NSLOCTEXT("PropertyEditor", "SinglePropertyInvalidType", "Cannot Edit Inline"))
			.ToolTipText(NSLOCTEXT("PropertyEditor", "SinglePropertyInvalidType_Tooltip", "Properties of this type cannot be edited inline; edit it elsewhere"))
		];

		// invalid or missing property
		RootPropertyNode->RemoveAllObjects();
		ValueNode.Reset();
		RootPropertyNode.Reset();
	}
}
Ejemplo n.º 4
0
/** Ticks the property view.  This function performs a data consistency check */
void SDetailsViewBase::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime )
{
	for (int32 i = 0; i < CustomizationClassInstancesPendingDelete.Num(); ++i)
	{
		ensure(CustomizationClassInstancesPendingDelete[i].IsUnique());
	}

	if (RootNodePendingKill.IsValid())
	{
		RootNodePendingKill->Disconnect();
		RootNodePendingKill.Reset();
	}

	// Empty all the customization instances that need to be deleted
	CustomizationClassInstancesPendingDelete.Empty();

	auto RootPropertyNode = GetRootNode();
	check(RootPropertyNode.IsValid());

	// Purge any objects that are marked pending kill from the object list
	if (auto ObjectRoot = RootPropertyNode->AsObjectNode())
	{
		ObjectRoot->PurgeKilledObjects();
	}

	if (DeferredActions.Num() > 0)
	{
		// Any deferred actions are likely to cause the node  tree to be at least partially rebuilt
		// Save the expansion state of existing nodes so we can expand them later
		SaveExpandedItems();

		// Execute any deferred actions
		for (int32 ActionIndex = 0; ActionIndex < DeferredActions.Num(); ++ActionIndex)
		{
			DeferredActions[ActionIndex].ExecuteIfBound();
		}
		DeferredActions.Empty();
	}

	if( RootPropertyNode == RootNodePendingKill )
	{
		// Reaquire the root property node.  It may have been changed by the deferred actions if something like a blueprint editor forcefully resets a details panel during a posteditchange
		RootPropertyNode = GetRootNode();

		RestoreExpandedItems();
	}


	bool bValidateExternalNodes = true;
	FPropertyNode::DataValidationResult Result = RootPropertyNode->EnsureDataIsValid();
	if (Result == FPropertyNode::PropertiesChanged || Result == FPropertyNode::EditInlineNewValueChanged)
	{
		RestoreExpandedItems();
		UpdatePropertyMap();
	}
	else if (Result == FPropertyNode::ArraySizeChanged)
	{
		RestoreExpandedItems();
		UpdateFilteredDetails();
	}
	else if (Result == FPropertyNode::ObjectInvalid)
	{
		ForceRefresh();

		// All objects are being reset, no need to validate external nodes
		bValidateExternalNodes = false;
	}

	if (bValidateExternalNodes)
	{
		for (int32 NodeIndex = 0; NodeIndex < ExternalRootPropertyNodes.Num(); ++NodeIndex)
		{
			TSharedPtr<FPropertyNode> PropertyNode = ExternalRootPropertyNodes[NodeIndex].Pin();

			if (PropertyNode.IsValid())
			{
				Result = PropertyNode->EnsureDataIsValid();
				if (Result == FPropertyNode::PropertiesChanged || Result == FPropertyNode::EditInlineNewValueChanged)
				{
					RestoreExpandedItems(PropertyNode);
					UpdatePropertyMap();
					// Note this will invalidate all the external root nodes so there is no need to continue
					ExternalRootPropertyNodes.Empty();
					break;
				}
				else if (Result == FPropertyNode::ArraySizeChanged)
				{
					RestoreExpandedItems(PropertyNode);
					UpdateFilteredDetails();
				}
			}
			else
			{
				// Remove the current node if it is no longer valid
				ExternalRootPropertyNodes.RemoveAt(NodeIndex);
				--NodeIndex;
			}
		}
	}

	if (DetailLayout.IsValid())
	{
		DetailLayout->Tick(InDeltaTime);
	}

	if (!ColorPropertyNode.IsValid() && bHasOpenColorPicker)
	{
		// Destroy the color picker window if the color property node has become invalid
		DestroyColorPicker();
		bHasOpenColorPicker = false;
	}


	if (FilteredNodesRequestingExpansionState.Num() > 0)
	{
		// change expansion state on the nodes that request it
		for (TMap<TSharedRef<IDetailTreeNode>, bool >::TConstIterator It(FilteredNodesRequestingExpansionState); It; ++It)
		{
			DetailTree->SetItemExpansion(It.Key(), It.Value());
		}

		FilteredNodesRequestingExpansionState.Empty();
	}
}