コード例 #1
0
void SDetailsViewBase::UpdatePropertyMap()
{
	// Reset everything
	ClassToPropertyMap.Empty();
	ClassesWithProperties.Empty();

	// We need to be able to create a new detail layout and properly clean up the old one in the process
	check(!DetailLayout.IsValid() || DetailLayout.IsUnique());

	RootTreeNodes.Empty();

	DetailLayout = MakeShareable(new FDetailLayoutBuilderImpl(ClassToPropertyMap, PropertyUtilities.ToSharedRef(), SharedThis(this)));


	auto RootPropertyNode = GetRootNode();
	check(RootPropertyNode.IsValid());
	// Currently object property nodes do not provide any useful information other than being a container for its children.  We do not draw anything for them.
	// When we encounter object property nodes, add their children instead of adding them to the tree.
	UpdatePropertyMapRecursive(*RootPropertyNode, *DetailLayout, NAME_None, RootPropertyNode.Get());

	CustomUpdatePropertyMap();

	// Ask for custom detail layouts, unless disabled. One reason for disabling custom layouts is that the custom layouts
	// inhibit our ability to find a single property's tree node. This is problematic for the diff and merge tools, that need
	// to display and highlight each changed property for the user. We could whitelist 'good' customizations here if 
	// we can make them work with the diff/merge tools.
	if( !bDisableCustomDetailLayouts )
	{
		QueryCustomDetailLayout(*DetailLayout);
	}
	
	DetailLayout->GenerateDetailLayout();

	UpdateFilteredDetails();
}
コード例 #2
0
void SDetailsViewBase::OnShowAllAdvancedClicked()
{
	CurrentFilter.bShowAllAdvanced = !CurrentFilter.bShowAllAdvanced;
	GetMutableDefault<UEditorStyleSettings>()->bShowAllAdvancedDetails = CurrentFilter.bShowAllAdvanced;
	GConfig->SetBool(TEXT("/Script/EditorStyle.EditorStyleSettings"), TEXT("bShowAllAdvancedDetails"), GetMutableDefault<UEditorStyleSettings>()->bShowAllAdvancedDetails, GEditorPerProjectIni);

	UpdateFilteredDetails();
}
コード例 #3
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();
}
コード例 #4
0
/** 
 * Hides or shows properties based on the passed in filter text
 * 
 * @param InFilterText	The filter text
 */
void SDetailsViewBase::FilterView(const FString& InFilterText)
{
	TArray<FString> CurrentFilterStrings;

	FString ParseString = InFilterText;
	// Remove whitespace from the front and back of the string
	ParseString.Trim();
	ParseString.TrimTrailing();
	ParseString.ParseIntoArray(CurrentFilterStrings, TEXT(" "), true);

	bHasActiveFilter = CurrentFilterStrings.Num() > 0;

	CurrentFilter.FilterStrings = CurrentFilterStrings;

	UpdateFilteredDetails();
}
コード例 #5
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();
	}
}
コード例 #6
0
void SDetailsViewBase::OnShowAllChildrenIfCategoryMatchesClicked()
{
	CurrentFilter.bShowAllChildrenIfCategoryMatches = !CurrentFilter.bShowAllChildrenIfCategoryMatches;

	UpdateFilteredDetails();
}
コード例 #7
0
void SDetailsViewBase::OnShowOnlyDifferingClicked()
{
	CurrentFilter.bShowOnlyDiffering = !CurrentFilter.bShowOnlyDiffering;

	UpdateFilteredDetails();
}
コード例 #8
0
void SDetailsViewBase::OnShowAllAdvancedClicked()
{
	CurrentFilter.bShowAllAdvanced = !CurrentFilter.bShowAllAdvanced;

	UpdateFilteredDetails();
}
コード例 #9
0
void SDetailsViewBase::OnShowOnlyModifiedClicked()
{
	CurrentFilter.bShowOnlyModifiedProperties = !CurrentFilter.bShowOnlyModifiedProperties;

	UpdateFilteredDetails();
}
コード例 #10
0
void SDetailsViewBase::RerunCurrentFilter()
{
	UpdateFilteredDetails();
}