예제 #1
0
FString FPropertyEditor::GetDisplayName() const
{
	FCategoryPropertyNode* CategoryNode = PropertyNode->AsCategoryNode();
	FItemPropertyNode* ItemPropertyNode = PropertyNode->AsItemPropertyNode();

	if ( CategoryNode != NULL )
	{
		return CategoryNode->GetDisplayName();
	}
	else if ( ItemPropertyNode != NULL )
	{
		return ItemPropertyNode->GetDisplayName();
	}
	else
	{
		FString DisplayName;
		PropertyNode->GetQualifiedName( DisplayName, true );

		return DisplayName;
	}
}
void SDetailsViewBase::UpdateSinglePropertyMapRecursive(FPropertyNode& InNode, FDetailLayoutData& LayoutData, FName CurCategory, FComplexPropertyNode* CurObjectNode, bool bEnableFavoriteSystem, bool bUpdateFavoriteSystemOnly)
{
	FDetailLayoutBuilderImpl& DetailLayout = *LayoutData.DetailLayout;

	UProperty* ParentProperty = InNode.GetProperty();
	UStructProperty* ParentStructProp = Cast<UStructProperty>(ParentProperty);
	for(int32 ChildIndex = 0; ChildIndex < InNode.GetNumChildNodes(); ++ChildIndex)
	{
		//Use the original value for each child
		bool LocalUpdateFavoriteSystemOnly = bUpdateFavoriteSystemOnly;

		TSharedPtr<FPropertyNode> ChildNodePtr = InNode.GetChildNode(ChildIndex);
		FPropertyNode& ChildNode = *ChildNodePtr;
		UProperty* Property = ChildNode.GetProperty();

		{
			FObjectPropertyNode* ObjNode = ChildNode.AsObjectNode();
			FCategoryPropertyNode* CategoryNode = ChildNode.AsCategoryNode();
			if(ObjNode)
			{
				// 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.
				UpdateSinglePropertyMapRecursive(ChildNode, LayoutData, CurCategory, ObjNode, bEnableFavoriteSystem, LocalUpdateFavoriteSystemOnly);
			}
			else if(CategoryNode)
			{
				if(!LocalUpdateFavoriteSystemOnly)
				{
					FName InstanceName = NAME_None;
					FName CategoryName = CurCategory;
					FString CategoryDelimiterString;
					CategoryDelimiterString.AppendChar(FPropertyNodeConstants::CategoryDelimiterChar);
					if(CurCategory != NAME_None && CategoryNode->GetCategoryName().ToString().Contains(CategoryDelimiterString))
					{
						// This property is child of another property so add it to the parent detail category
						FDetailCategoryImpl& CategoryImpl = DetailLayout.DefaultCategory(CategoryName);
						CategoryImpl.AddPropertyNode(ChildNodePtr.ToSharedRef(), InstanceName);
					}
				}

				// For category nodes, we just set the current category and recurse through the children
				UpdateSinglePropertyMapRecursive(ChildNode, LayoutData, CategoryNode->GetCategoryName(), CurObjectNode, bEnableFavoriteSystem, LocalUpdateFavoriteSystemOnly);
			}
			else
			{
				// Whether or not the property can be visible in the default detail layout
				bool bVisibleByDefault = IsVisibleStandaloneProperty(ChildNode, InNode);

				// Whether or not the property is a struct
				UStructProperty* StructProperty = Cast<UStructProperty>(Property);

				bool bIsStruct = StructProperty != NULL;

				static FName ShowOnlyInners("ShowOnlyInnerProperties");

				bool bIsChildOfCustomizedStruct = false;
				bool bIsCustomizedStruct = false;

				const UStruct* Struct = StructProperty ? StructProperty->Struct : NULL;
				const UStruct* ParentStruct = ParentStructProp ? ParentStructProp->Struct : NULL;
				if(Struct || ParentStruct)
				{
					FPropertyEditorModule& ParentPlugin = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
					if(Struct)
					{
						bIsCustomizedStruct = ParentPlugin.IsCustomizedStruct(Struct, SharedThis(this));
					}

					if(ParentStruct)
					{
						bIsChildOfCustomizedStruct = ParentPlugin.IsCustomizedStruct(ParentStruct, SharedThis(this));
					}
				}

				// Whether or not to push out struct properties to their own categories or show them inside an expandable struct 
				bool bPushOutStructProps = bIsStruct && !bIsCustomizedStruct && !ParentStructProp && Property->HasMetaData(ShowOnlyInners);

				// Is the property edit inline new 
				const bool bIsEditInlineNew = ChildNode.HasNodeFlags(EPropertyNodeFlags::ShowInnerObjectProperties) || SPropertyEditorEditInline::Supports(&ChildNode, ChildNode.GetArrayIndex());

				// Is this a property of a container property
				bool bIsChildOfContainer = PropertyEditorHelpers::IsChildOfArray(ChildNode) || PropertyEditorHelpers::IsChildOfSet(ChildNode) || PropertyEditorHelpers::IsChildOfMap(ChildNode);

				// Edit inline new properties should be visible by default
				bVisibleByDefault |= bIsEditInlineNew;

				// Children of arrays are not visible directly,
				bVisibleByDefault &= !bIsChildOfContainer;

				FPropertyAndParent PropertyAndParent(*Property, ParentProperty);
				const bool bIsUserVisible = IsPropertyVisible(PropertyAndParent);

				// Inners of customized in structs should not be taken into consideration for customizing.  They are not designed to be individually customized when their parent is already customized
				if(!bIsChildOfCustomizedStruct && !LocalUpdateFavoriteSystemOnly)
				{
					// Add any object classes with properties so we can ask them for custom property layouts later
					LayoutData.ClassesWithProperties.Add(Property->GetOwnerStruct());
				}

				// If there is no outer object then the class is the object root and there is only one instance
				FName InstanceName = NAME_None;
				if(CurObjectNode && CurObjectNode->GetParentNode())
				{
					InstanceName = CurObjectNode->GetParentNode()->GetProperty()->GetFName();
				}
				else if(ParentStructProp)
				{
					InstanceName = ParentStructProp->GetFName();
				}

				// Do not add children of customized in struct properties or arrays
				if(!bIsChildOfCustomizedStruct && !bIsChildOfContainer && !LocalUpdateFavoriteSystemOnly)
				{
					// Get the class property map
					FClassInstanceToPropertyMap& ClassInstanceMap = LayoutData.ClassToPropertyMap.FindOrAdd(Property->GetOwnerStruct()->GetFName());

					FPropertyNodeMap& PropertyNodeMap = ClassInstanceMap.FindOrAdd(InstanceName);

					if(!PropertyNodeMap.ParentProperty)
					{
						PropertyNodeMap.ParentProperty = CurObjectNode;
					}
					else
					{
						ensure(PropertyNodeMap.ParentProperty == CurObjectNode);
					}

					checkSlow(!PropertyNodeMap.Contains(Property->GetFName()));

					PropertyNodeMap.Add(Property->GetFName(), ChildNodePtr);
				}
				bool bCanDisplayFavorite = false;
				if(bVisibleByDefault && bIsUserVisible && !bPushOutStructProps)
				{
					FName CategoryName = CurCategory;
					// For properties inside a struct, add them to their own category unless they just take the name of the parent struct.  
					// In that case push them to the parent category
					FName PropertyCatagoryName = FObjectEditorUtils::GetCategoryFName(Property);
					if(!ParentStructProp || (PropertyCatagoryName != ParentStructProp->Struct->GetFName()))
					{
						CategoryName = PropertyCatagoryName;
					}

					if(!LocalUpdateFavoriteSystemOnly)
					{
						if(IsPropertyReadOnly(PropertyAndParent))
						{
							ChildNode.SetNodeFlags(EPropertyNodeFlags::IsReadOnly, true);
						}

						// Add a property to the default category
						FDetailCategoryImpl& CategoryImpl = DetailLayout.DefaultCategory(CategoryName);
						CategoryImpl.AddPropertyNode(ChildNodePtr.ToSharedRef(), InstanceName);
					}

					bCanDisplayFavorite = true;
					if(bEnableFavoriteSystem)
					{
						if(bIsCustomizedStruct)
						{
							bCanDisplayFavorite = false;
							//CustomizedStruct child are not categorize since they are under an object but we have to put them in favorite category if the user want to favorite them
							LocalUpdateFavoriteSystemOnly = true;
						}
						else if(ChildNodePtr->IsFavorite())
						{
							//Find or create the favorite category, we have to duplicate favorite property row under this category
							FString CategoryFavoritesName = TEXT("Favorites");
							FName CatFavName = *CategoryFavoritesName;
							FDetailCategoryImpl& CategoryFavImpl = DetailLayout.DefaultCategory(CatFavName);
							CategoryFavImpl.SetSortOrder(0);
							CategoryFavImpl.SetCategoryAsSpecialFavorite();

							//Add the property to the favorite
							FObjectPropertyNode *RootObjectParent = ChildNodePtr->FindRootObjectItemParent();
							FName RootInstanceName = NAME_None;
							if(RootObjectParent != nullptr)
							{
								RootInstanceName = RootObjectParent->GetObjectBaseClass()->GetFName();
							}

							if(LocalUpdateFavoriteSystemOnly)
							{
								if(IsPropertyReadOnly(PropertyAndParent))
								{
									ChildNode.SetNodeFlags(EPropertyNodeFlags::IsReadOnly, true);
								}
								else
								{
									//If the parent has a condition that is not met, make the child as readonly
									FDetailLayoutCustomization ParentTmpCustomization;
									ParentTmpCustomization.PropertyRow = MakeShareable(new FDetailPropertyRow(InNode.AsShared(), CategoryFavImpl.AsShared()));
									if(ParentTmpCustomization.PropertyRow->GetPropertyEditor()->IsPropertyEditingEnabled() == false)
									{
										ChildNode.SetNodeFlags(EPropertyNodeFlags::IsReadOnly, true);
									}
								}
							}

							//Duplicate the row
							CategoryFavImpl.AddPropertyNode(ChildNodePtr.ToSharedRef(), RootInstanceName);
						}

						if(bIsStruct)
						{
							LocalUpdateFavoriteSystemOnly = true;
						}
					}
				}
				ChildNodePtr->SetCanDisplayFavorite(bCanDisplayFavorite);

				bool bRecurseIntoChildren =
					!bIsChildOfCustomizedStruct // Don't recurse into built in struct children, we already know what they are and how to display them
					&&  !bIsCustomizedStruct // Don't recurse into customized structs
					&&	!bIsChildOfContainer // Do not recurse into containers, the children are drawn by the container property parent
					&&	!bIsEditInlineNew // Edit inline new children are not supported for customization yet
					&&	bIsUserVisible // Properties must be allowed to be visible by a user if they are not then their children are not visible either
					&& (!bIsStruct || bPushOutStructProps); //  Only recurse into struct properties if they are going to be displayed as standalone properties in categories instead of inside an expandable area inside a category

				if(bRecurseIntoChildren || LocalUpdateFavoriteSystemOnly)
				{
					// Built in struct properties or children of arras 
					UpdateSinglePropertyMapRecursive(ChildNode, LayoutData, CurCategory, CurObjectNode, bEnableFavoriteSystem, LocalUpdateFavoriteSystemOnly);
				}
			}
		}
	}
}
예제 #3
0
void SDetailsViewBase::UpdatePropertyMapRecursive(FPropertyNode& InNode, FDetailLayoutBuilderImpl& InDetailLayout, FName CurCategory, FComplexPropertyNode* CurObjectNode)
{
	UProperty* ParentProperty = InNode.GetProperty();
	UStructProperty* ParentStructProp = Cast<UStructProperty>(ParentProperty);

	for (int32 ChildIndex = 0; ChildIndex < InNode.GetNumChildNodes(); ++ChildIndex)
	{
		TSharedPtr<FPropertyNode> ChildNodePtr = InNode.GetChildNode(ChildIndex);
		FPropertyNode& ChildNode = *ChildNodePtr;
		UProperty* Property = ChildNode.GetProperty();

		{
			FObjectPropertyNode* ObjNode = ChildNode.AsObjectNode();
			FCategoryPropertyNode* CategoryNode = ChildNode.AsCategoryNode();
			if (ObjNode)
			{
				// 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(ChildNode, InDetailLayout, CurCategory, ObjNode);
			}
			else if (CategoryNode)
			{
				// For category nodes, we just set the current category and recurse through the children
				UpdatePropertyMapRecursive(ChildNode, InDetailLayout, CategoryNode->GetCategoryName(), CurObjectNode);
			}
			else
			{
				// Whether or not the property can be visible in the default detail layout
				bool bVisibleByDefault = IsVisibleStandaloneProperty(ChildNode, InNode);

				// Whether or not the property is a struct
				UStructProperty* StructProperty = Cast<UStructProperty>(Property);

				bool bIsStruct = StructProperty != NULL;

				static FName ShowOnlyInners("ShowOnlyInnerProperties");

				bool bIsChildOfCustomizedStruct = false;
				bool bIsCustomizedStruct = false;

				const UStruct* Struct = StructProperty ? StructProperty->Struct : NULL;
				const UStruct* ParentStruct = ParentStructProp ? ParentStructProp->Struct : NULL;
				if (Struct || ParentStruct)
				{
					FPropertyEditorModule& ParentPlugin = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
					if (Struct)
					{
						bIsCustomizedStruct = ParentPlugin.IsCustomizedStruct(Struct, SharedThis( this ) );
					}

					if (ParentStruct)
					{
						bIsChildOfCustomizedStruct = ParentPlugin.IsCustomizedStruct(ParentStruct, SharedThis( this ) );
					}
				}

				// Whether or not to push out struct properties to their own categories or show them inside an expandable struct 
				bool bPushOutStructProps = bIsStruct && !bIsCustomizedStruct && !ParentStructProp && Property->HasMetaData(ShowOnlyInners);

				// Is the property edit inline new 
				const bool bIsEditInlineNew = SPropertyEditorEditInline::Supports(&ChildNode, ChildNode.GetArrayIndex());

				// Is this a property of an array
				bool bIsChildOfArray = PropertyEditorHelpers::IsChildOfArray(ChildNode);

				// Edit inline new properties should be visible by default
				bVisibleByDefault |= bIsEditInlineNew;

				// Children of arrays are not visible directly,
				bVisibleByDefault &= !bIsChildOfArray;

				FPropertyAndParent PropertyAndParent(*Property, ParentProperty);
				const bool bIsUserVisible = IsPropertyVisible(PropertyAndParent);

				// Inners of customized in structs should not be taken into consideration for customizing.  They are not designed to be individually customized when their parent is already customized
				if (!bIsChildOfCustomizedStruct)
				{
					// Add any object classes with properties so we can ask them for custom property layouts later
					ClassesWithProperties.Add(Property->GetOwnerStruct());
				}

				// If there is no outer object then the class is the object root and there is only one instance
				FName InstanceName = NAME_None;
				if (CurObjectNode && CurObjectNode->GetParentNode())
				{
					InstanceName = CurObjectNode->GetParentNode()->GetProperty()->GetFName();
				}
				else if (ParentStructProp)
				{
					InstanceName = ParentStructProp->GetFName();
				}

				// Do not add children of customized in struct properties or arrays
				if (!bIsChildOfCustomizedStruct && !bIsChildOfArray)
				{
					// Get the class property map
					FClassInstanceToPropertyMap& ClassInstanceMap = ClassToPropertyMap.FindOrAdd(Property->GetOwnerStruct()->GetFName());

					FPropertyNodeMap& PropertyNodeMap = ClassInstanceMap.FindOrAdd(InstanceName);

					if (!PropertyNodeMap.ParentProperty)
					{
						PropertyNodeMap.ParentProperty = CurObjectNode;
					}
					else
					{
						ensure(PropertyNodeMap.ParentProperty == CurObjectNode);
					}

					checkSlow(!PropertyNodeMap.Contains(Property->GetFName()));

					PropertyNodeMap.Add(Property->GetFName(), ChildNodePtr);
				}

				if (bVisibleByDefault && bIsUserVisible && !bPushOutStructProps)
				{
					FName CategoryName = CurCategory;

					// For properties inside a struct, add them to their own category unless they just take the name of the parent struct.  
					// In that case push them to the parent category
					FName PropertyCatagoryName = FObjectEditorUtils::GetCategoryFName(Property);
					if (!ParentStructProp || (PropertyCatagoryName != ParentStructProp->Struct->GetFName()))
					{
						CategoryName = PropertyCatagoryName;
					}

					if (IsPropertyReadOnly(PropertyAndParent))
					{
						ChildNode.SetNodeFlags(EPropertyNodeFlags::IsReadOnly, true);
					}

					// Add a property to the default category
					FDetailCategoryImpl& CategoryImpl = InDetailLayout.DefaultCategory(CategoryName);
					CategoryImpl.AddPropertyNode(ChildNodePtr.ToSharedRef(), InstanceName);
				}

				bool bRecurseIntoChildren =
					!bIsChildOfCustomizedStruct // Don't recurse into built in struct children, we already know what they are and how to display them
					&&  !bIsCustomizedStruct // Don't recurse into customized structs
					&&	!bIsChildOfArray // Do not recurse into arrays, the children are drawn by the array property parent
					&&	!bIsEditInlineNew // Edit inline new children are not supported for customization yet
					&&	bIsUserVisible // Properties must be allowed to be visible by a user if they are not then their children are not visible either
					&& (!bIsStruct || bPushOutStructProps); //  Only recurse into struct properties if they are going to be displayed as standalone properties in categories instead of inside an expandable area inside a category

				if (bRecurseIntoChildren)
				{
					// Built in struct properties or children of arras 
					UpdatePropertyMapRecursive(ChildNode, InDetailLayout, CurCategory, CurObjectNode);
				}
			}
		}
	}
}
예제 #4
0
void FObjectPropertyNode::InternalInitChildNodes( FName SinglePropertyName )
{
	HiddenCategories.Empty();
	// Assemble a list of category names by iterating over all fields of BaseClass.

	// build a list of classes that we need to look at
	TSet<UClass*> ClassesToConsider;
	for( int32 i = 0; i < GetNumObjects(); ++i )
	{
		UObject* TempObject = GetUObject( i );
		if( TempObject )
		{
			ClassesToConsider.Add( TempObject->GetClass() );
		}
	}

	const bool bShouldShowHiddenProperties = !!HasNodeFlags(EPropertyNodeFlags::ShouldShowHiddenProperties);
	const bool bShouldShowDisableEditOnInstance = !!HasNodeFlags(EPropertyNodeFlags::ShouldShowDisableEditOnInstance);

	TSet<FName> Categories;
	for( TFieldIterator<UProperty> It(BaseClass.Get()); It; ++It )
	{
		bool bHidden = false;

		FName CategoryName = FObjectEditorUtils::GetCategoryFName(*It);

		for( UClass* Class : ClassesToConsider )
		{
			if( FEditorCategoryUtils::IsCategoryHiddenFromClass(Class, CategoryName.ToString()) )
			{
				HiddenCategories.Add( CategoryName );

				bHidden = true;
				break;
			}
		}

		bool bMetaDataAllowVisible = true;
		FString MetaDataVisibilityCheckString = It->GetMetaData(TEXT("bShowOnlyWhenTrue"));
		if (MetaDataVisibilityCheckString.Len())
		{
			//ensure that the metadata visibility string is actually set to true in order to show this property
			GConfig->GetBool(TEXT("UnrealEd.PropertyFilters"), *MetaDataVisibilityCheckString, bMetaDataAllowVisible, GEditorUserSettingsIni);
		}

		if (bMetaDataAllowVisible)
		{
			const bool bShowIfNonHiddenEditableProperty = (*It)->HasAnyPropertyFlags(CPF_Edit) && !bHidden;
			const bool bShowIfDisableEditOnInstance = !(*It)->HasAnyPropertyFlags(CPF_DisableEditOnInstance) || bShouldShowDisableEditOnInstance;
			if( bShouldShowHiddenProperties || (bShowIfNonHiddenEditableProperty && bShowIfDisableEditOnInstance) )
			{
				Categories.Add( CategoryName );
			}
		}
	}

	//////////////////////////////////////////
	// Add the category headers and the child items that belong inside of them.

	// Only show category headers if this is the top level object window and the parent window allows headers.
	if( HasNodeFlags(EPropertyNodeFlags::ShowCategories) )
	{
		FString CategoryDelimiterString;
		CategoryDelimiterString.AppendChar( FPropertyNodeConstants::CategoryDelimiterChar );

		TArray< FPropertyNode* > ParentNodesToSort;

		for( const FName& FullCategoryPath : Categories )
		{
			// Figure out the nesting level for this category
			TArray< FString > FullCategoryPathStrings;
			FullCategoryPath.ToString().ParseIntoArray( FullCategoryPathStrings, *CategoryDelimiterString, true );

			TSharedPtr<FPropertyNode> ParentLevelNode = SharedThis(this);
			FString CurCategoryPathString;
			for( int32 PathLevelIndex = 0; PathLevelIndex < FullCategoryPathStrings.Num(); ++PathLevelIndex )
			{
				// Build up the category path name for the current path level index
				if( CurCategoryPathString.Len() != 0 )
				{
					CurCategoryPathString += FPropertyNodeConstants::CategoryDelimiterChar;
				}
				CurCategoryPathString += FullCategoryPathStrings[ PathLevelIndex ];
				const FName CategoryName( *CurCategoryPathString );

				// Check to see if we've already created a category at the specified path level
				bool bFoundMatchingCategory = false;
				{
					for( int32 CurNodeIndex = 0; CurNodeIndex < ParentLevelNode->GetNumChildNodes(); ++CurNodeIndex )
					{
						TSharedPtr<FPropertyNode>& ChildNode = ParentLevelNode->GetChildNode( CurNodeIndex );
						check( ChildNode.IsValid() );

						// Is this a category node?
						FCategoryPropertyNode* ChildCategoryNode = ChildNode->AsCategoryNode();
						if( ChildCategoryNode != NULL )
						{
							// Does the name match?
							if( ChildCategoryNode->GetCategoryName() == CategoryName )
							{
								// Descend by using the child node as the new parent
								bFoundMatchingCategory = true;
								ParentLevelNode = ChildNode;
								break;
							}
						}
					}
				}

				// If we didn't find the category, then we'll need to create it now!
				if( !bFoundMatchingCategory )
				{
					// Create the category node and assign it to its parent node
					TSharedPtr<FCategoryPropertyNode> NewCategoryNode( new FCategoryPropertyNode );
					{
						NewCategoryNode->SetCategoryName( CategoryName );

						FPropertyNodeInitParams InitParams;
						InitParams.ParentNode = ParentLevelNode;
						InitParams.Property = NULL;
						InitParams.ArrayOffset = 0;
						InitParams.ArrayIndex = INDEX_NONE;
						InitParams.bAllowChildren = true;
						InitParams.bForceHiddenPropertyVisibility = bShouldShowHiddenProperties;
						InitParams.bCreateDisableEditOnInstanceNodes = bShouldShowDisableEditOnInstance;

						NewCategoryNode->InitNode( InitParams );

						// Recursively expand category properties if the category has been flagged for auto-expansion.
						if (BaseClass->IsAutoExpandCategory(*CategoryName.ToString())
							&&	!BaseClass->IsAutoCollapseCategory(*CategoryName.ToString()))
						{
							NewCategoryNode->SetNodeFlags(EPropertyNodeFlags::Expanded, true);
						}

						// Add this node to it's parent.  Note that no sorting happens here, so the parent's
						// list of child nodes will not be in the correct order.  We'll keep track of which
						// nodes we added children to so we can sort them after we're finished adding new nodes.
						ParentLevelNode->AddChildNode(NewCategoryNode);
						ParentNodesToSort.AddUnique( ParentLevelNode.Get() );
					}

					// Descend into the newly created category by using this node as the new parent
					ParentLevelNode = NewCategoryNode;
				}
			}
		}
	}
	else
	{
		// Iterate over all fields, creating items.
		for( TFieldIterator<UProperty> It(BaseClass.Get()); It; ++It )
		{
			const bool bShowIfNonHiddenEditableProperty = (*It)->HasAnyPropertyFlags(CPF_Edit) && !FEditorCategoryUtils::IsCategoryHiddenFromClass(BaseClass.Get(), FObjectEditorUtils::GetCategory(*It));
			const bool bShowIfDisableEditOnInstance = !(*It)->HasAnyPropertyFlags(CPF_DisableEditOnInstance) || bShouldShowDisableEditOnInstance;
			if (bShouldShowHiddenProperties || (bShowIfNonHiddenEditableProperty && bShowIfDisableEditOnInstance))
			{
				UProperty* CurProp = *It;
				if( SinglePropertyName == NAME_None || CurProp->GetFName() == SinglePropertyName )
				{
					TSharedPtr<FItemPropertyNode> NewItemNode( new FItemPropertyNode );

					FPropertyNodeInitParams InitParams;
					InitParams.ParentNode = SharedThis(this);
					InitParams.Property = CurProp;
					InitParams.ArrayOffset =  0;
					InitParams.ArrayIndex = INDEX_NONE;
					InitParams.bAllowChildren = SinglePropertyName == NAME_None;
					InitParams.bForceHiddenPropertyVisibility = bShouldShowHiddenProperties;
					InitParams.bCreateDisableEditOnInstanceNodes = bShouldShowDisableEditOnInstance;

					NewItemNode->InitNode( InitParams );

					AddChildNode(NewItemNode);

					if( SinglePropertyName != NAME_None )
					{
						// Generate no other children
						break;
					}
				}
			}
		}
	}

}