vault backup: 2024-10-12 17:19:45

This commit is contained in:
2024-10-12 17:19:46 +08:00
parent ff94ddca61
commit 244c0c52f6
960 changed files with 31348 additions and 10 deletions

View File

@@ -0,0 +1,154 @@
# ForceInlineRow
- **功能描述:** 强制TMap属性里的结构key和其他Value合并到同一行来显示
- **使用位置:** UPROPERTY
- **元数据类型:** bool
- **关联项:** [EditInline](../EditInline/EditInline.md)
- **常用程度:** ★
强制TMap属性里的结构key和其他Value合并到同一行来显示。这里要注意的点是
- 本属性是TMap属性这样才有Key。TArray或TSet是没有用的。
- FStruct作为Key这样源码里的机制才能生效因为判断的就是Key Property
- 该FStruct有注册相关的IPropertyTypeCustomization这样才能自定义该结构的显示UI
- 该IPropertyTypeCustomization的ShouldInlineKey返回false默认就是否则true的话则不管有没有标ForceInlineRow都会合并成一行
## 测试代码:
```cpp
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TMap<FMyCommonStruct, int32> MyStructMap;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ForceInlineRow))
TMap<FMyCommonStruct, int32> MyStructMap_ForceInlineRow;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TMap<int32, FMyCommonStruct> MyStructMap2;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ForceInlineRow))
TMap<int32, FMyCommonStruct> MyStructMap_ForceInlineRow2;
void FMyCommonStructCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> PropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils)
{
HeaderRow.NameContent()[SNew(STextBlock).Text(INVTEXT("This is MyCommonStruct"))];
TSharedPtr<IPropertyHandle> IntPropertyHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FMyCommonStruct, MyInt));
TSharedPtr<IPropertyHandle> StringPropertyHandle = PropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FMyCommonStruct, MyString));
HeaderRow.ValueContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(5.0f, 0.0f).AutoWidth()
[
IntPropertyHandle->CreatePropertyNameWidget()
]
+ SHorizontalBox::Slot()
.Padding(5.0f, 0.0f).AutoWidth()
[
IntPropertyHandle->CreatePropertyValueWidget()
]
+ SHorizontalBox::Slot()
.Padding(5.0f, 0.0f).AutoWidth()
[
StringPropertyHandle->CreatePropertyNameWidget()
]
+ SHorizontalBox::Slot()
.Padding(5.0f, 0.0f).AutoWidth()
[
StringPropertyHandle->CreatePropertyValueWidget()
]
];
}
```
## 测试效果:
可以见到MyStructMap的数据项展示就分为了两行。而带有ForceInlineRow之后数据项UI就合并为一行显得更加的简洁。
在下面也特别观察到如果把FStruct作为Value则是没有这个区别的。
![Untitled](Untitled.png)
假如不注册FMyCommonStruct相应的IPropertyTypeCustomization的话则结构的属性UI采用默认方式显示则都是分为两行。
![Untitled](Untitled%201.png)
而假如FMyCommonStruct的IPropertyTypeCustomization的ShouldInlineKey返回true则会导致即使没有ForceInlineRow也会把该拥有该结构作为Key的属性给都合并为一行显示这个时候就失去ForceInlineRow的作用和区别了。
![Untitled](Untitled%202.png)
## 原理:
该部分逻辑也同样处于在FDetailPropertyRow的构造函数创建过程中判断是否有GetPropertyKeyNode则其实是在要求TMap属性。
接着作为Key的类型如果是UObject*则因为NeedsKeyNode一直返回false则无论如何都会进入MakePropertyEditor的分支。
因此此项测试的类型其实是Struct这样就必须依赖bInlineRow 和FoundPropertyCustomisation 的配合。这个时候就必须有IPropertyTypeCustomization才会进入分支而且如果IPropertyTypeCustomization::ShouldInlineKey()返回true则就不管属性上的ForceInlineRow如何都会进入分支。否则就靠属性上的ForceInlineRow这个时候才是这个Meta发挥作用的时候。
```cpp
FDetailPropertyRow::FDetailPropertyRow(TSharedPtr<FPropertyNode> InPropertyNode, TSharedRef<FDetailCategoryImpl> InParentCategory, TSharedPtr<FComplexPropertyNode> InExternalRootNode)
{
if (PropertyNode->GetPropertyKeyNode().IsValid())
{
TSharedPtr<IPropertyTypeCustomization> FoundPropertyCustomisation = GetPropertyCustomization(PropertyNode->GetPropertyKeyNode().ToSharedRef(), ParentCategory.Pin().ToSharedRef());
bool bInlineRow = FoundPropertyCustomisation != nullptr ? FoundPropertyCustomisation->ShouldInlineKey() : false;
static FName InlineKeyMeta("ForceInlineRow");
bInlineRow |= InPropertyNode->GetParentNode()->GetProperty()->HasMetaData(InlineKeyMeta);
// Only create the property editor if it's not a struct or if it requires to be inlined (and has customization)
if (!NeedsKeyNode(PropertyNodeRef, InParentCategory) || (bInlineRow && FoundPropertyCustomisation != nullptr))
{
CachedKeyCustomTypeInterface = FoundPropertyCustomisation;
MakePropertyEditor(PropertyNode->GetPropertyKeyNode().ToSharedRef(), Utilities, PropertyKeyEditor);
}
}
}
bool FDetailPropertyRow::NeedsKeyNode(TSharedRef<FPropertyNode> InPropertyNode, TSharedRef<FDetailCategoryImpl> InParentCategory)
{
FStructProperty* KeyStructProp = CastField<FStructProperty>(InPropertyNode->GetPropertyKeyNode()->GetProperty());
return KeyStructProp != nullptr;
}
```
源码里使用的例子:
在源码里搜索发现到该例子但实际上其实这里HLODSetups上的ForceInlineRow并不能起作用。
```cpp
USTRUCT()
struct FRuntimePartitionDesc
{
GENERATED_USTRUCT_BODY()
#if WITH_EDITORONLY_DATA
/** Partition class */
UPROPERTY(EditAnywhere, Category = RuntimeSettings)
TSubclassOf<URuntimePartition> Class;
/** Name for this partition, used to map actors to it through the Actor.RuntimeGrid property */
UPROPERTY(EditAnywhere, Category = RuntimeSettings, Meta = (EditCondition = "Class != nullptr", HideEditConditionToggle))
FName Name;
/** Main partition object */
UPROPERTY(VisibleAnywhere, Category = RuntimeSettings, Instanced, Meta = (EditCondition = "Class != nullptr", HideEditConditionToggle, NoResetToDefault, TitleProperty = "Name"))
TObjectPtr<URuntimePartition> MainLayer;
/** HLOD setups used by this partition, one for each layers in the hierarchy */
UPROPERTY(EditAnywhere, Category = RuntimeSettings, Meta = (EditCondition = "Class != nullptr", HideEditConditionToggle, ForceInlineRow))
TArray<FRuntimePartitionHLODSetup> HLODSetups;
#endif
#if WITH_EDITOR
void UpdateHLODPartitionLayers();
#endif
};
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB