#482 Details视图定制   module     Slate     UE4     UMG     about a year ago (owner) Document
一个Actor或Property的Details信息的展示界面,可以定制。这项工作涉及几个基本的接口:
  • IDetailsView,其派生自SCompoundWidget。能看到的Details界面就是这个接口的实例
    • SDetailsView->SDetailsViewBase->IDetailsViewPrivate->IDetailsView
    • FPropertyEditorModule::CreateDetailView(const FDetailsViewArgs& DetailsViewArgs); // 用户填写参数后调用该函数拿到一个IDetailsView实例
  • IDetailLayoutBuilder接口是一个工具类,它定义了一套支持Category的显示控制、Property的显示控制、隐藏等等功能的接口。至于这些功能的实际表现由具体实现来完成
    • IDetailLayoutBuilder接口在UE4里有一个实现:FDetailLayoutBuilderImpl。这个实现按照一套确定的风格完成了上面说的功能概念,UE4里如上功能均由该实现来完成
    • UE4额外提供了一个IDetailCustomization接口,用户需要实现其CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)函数,目的是集中在这里将IDetailLayoutBuilder需要的数据输入给它。这也是通常用户要定制Details视图时唯一需要实现的接口
    • FPropertyEditorModule::RegisterCustomClassLayout()实现将IDetailCustomization信息提交给引擎的功能。
以上需要引用【PropertyEditor】模块。
代码示例:
针对特定Class类型的所有实例定制其Details面板的情形:
 StarupModule() {
	 FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(TEXT("PropertyEditor"));
	 // Custom Class Layouts
	 auto AddCustomClass = [this, InPropertyModule = &PropertyModule](FName Name, FOnGetDetailCustomizationInstance InstanceGetter)
	 {
		InPropertyModule->RegisterCustomClassLayout(Name, InstanceGetter);
		CustomClassLayoutNames.Add(Name);
	 };
	 AddCustomClass(ASURACameraDriver::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FSURACameraDriverDetailsCustomization::MakeInstance));
 }
 ShutdownModule() {
	 if (FModuleManager::Get().IsModuleLoaded("PropertyEditor"))
	 {
		FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
		for (FName ClassName : CustomClassLayoutNames)
		{
			PropertyModule.UnregisterCustomClassLayout(ClassName);
		}
		CustomClassLayoutNames.Reset();
	 }
 }
 // .h
 TArray<FName> CustomClassLayoutNames;
针对特定Class类型的某个实例定制Details面板。需要在该实例对应的IDetailsView中设置,详见代码 Customizations/SURACameraDriverDetailsCustomization代码
IDetailsView面板与UObject建立关联:
 TSharedRef<SWidget> SSURAAR_MainWnd::MakeSURACameraDriverDetails( )
 {
	FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>(TEXT("PropertyEditor"));
	FDetailsViewArgs Args;
        Args.bAllowSearch = false; // 隐藏Details面板的搜索框
	Args.NameAreaSettings = FDetailsViewArgs::HideNameArea; // 隐藏Details面板的角色名框
	TSharedRef<IDetailsView> View = PropertyModule.CreateDetailView(Args);
	View->RegisterInstancedCustomPropertyLayout(ASURACameraDriver::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FSURACameraDriverDetailsCustomization::MakeInstance));
	TArray<AActor*> OutActors;
	if (GWorld)
	{
		UGameplayStatics::GetAllActorsOfClass(GWorld, ASURACameraDriver::StaticClass(), OutActors);
	}
	if (OutActors.Num() > 0)
	{
		View->SetObject(OutActors[0], true);
	}
	return View;
 }