使用 IDetailCustomization 自定义属性面板

使用 IDetailCustomization 的方式可以给 UE 的属性面板添加特殊的东西,比如按钮。

以给 F 的结构的 Detail 添加按钮的方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
// ReleaseSettingsDetails.h
#pragma once
#include "IDetailCustomization.h"

class FReleaseSettingsDetails : public IDetailCustomization
{
public:
/** Makes a new instance of this detail layout class for a specific detail view requesting it */
static TSharedRef<IDetailCustomization> MakeInstance();

/** IDetailCustomization interface */
virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
};

.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// ReleaseSettingsDetails.cpp
#include "CreatePatch/ReleaseSettingsDetails.h"
#include "CreatePatch/FExportReleaseSettings.h"

// engine header
#include "DetailLayoutBuilder.h"
#include "DetailCategoryBuilder.h"
#include "DetailWidgetRow.h"
#include "Widgets/Input/SButton.h"

#define LOCTEXT_NAMESPACE "ReleaseSettingsDetails"

TSharedRef<IDetailCustomization> FReleaseSettingsDetails::MakeInstance()
{
return MakeShareable(new FReleaseSettingsDetails());
}

void FReleaseSettingsDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
TArray< TSharedPtr<FStructOnScope> > StructBeingCustomized;
DetailBuilder.GetStructsBeingCustomized(StructBeingCustomized);
check(StructBeingCustomized.Num() == 1);

FExportReleaseSettings* ReleaseSettingsIns = (FExportReleaseSettings*)StructBeingCustomized[0].Get()->GetStructMemory();

IDetailCategoryBuilder& VersionCategory = DetailBuilder.EditCategory("Version",FText::GetEmpty(),ECategoryPriority::Default);
VersionCategory.SetShowAdvanced(true);

VersionCategory.AddCustomRow(LOCTEXT("ImportPakLists", "Import Pak Lists"),true)
.ValueContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(0)
.AutoWidth()
[
SNew(SButton)
.Text(LOCTEXT("Import", "Import"))
.ToolTipText(LOCTEXT("ImportPakLists_Tooltip", "Import Pak Lists"))
.IsEnabled_Lambda([this,ReleaseSettingsIns]()->bool
{
return ReleaseSettingsIns->IsByPakList();
})
.OnClicked_Lambda([this, ReleaseSettingsIns]()
{
if (ReleaseSettingsIns)
{
ReleaseSettingsIns->ImportPakLists();
}
return(FReply::Handled());
})
]
+ SHorizontalBox::Slot()
.Padding(5,0,0,0)
.AutoWidth()
[
SNew(SButton)
.Text(LOCTEXT("Clear", "Clear"))
.ToolTipText(LOCTEXT("ClearPakLists_Tooltip", "Clear Pak Lists"))
.IsEnabled_Lambda([this,ReleaseSettingsIns]()->bool
{
return ReleaseSettingsIns->IsByPakList();
})
.OnClicked_Lambda([this, ReleaseSettingsIns]()
{
if (ReleaseSettingsIns)
{
ReleaseSettingsIns->ClearImportedPakList();
}
return(FReply::Handled());
})
]
];
}
#undef LOCTEXT_NAMESPACE

这里我们只是定义了一个 IDetailCustomization 的类,其中的 CustomizeDetails 是对 FExportReleaseSettings 添加的细节。

该类在创建 DetailView 时使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void SHotPatcherExportRelease::CreateExportFilterListView()
{
// Create a property view
FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked<FPropertyEditorModule>("PropertyEditor");

FDetailsViewArgs DetailsViewArgs;
{
DetailsViewArgs.bAllowSearch = true;
DetailsViewArgs.bHideSelectionTip = true;
DetailsViewArgs.bLockable = false;
DetailsViewArgs.bSearchInitialKeyFocus = true;
DetailsViewArgs.bUpdatesFromSelection = false;
DetailsViewArgs.NotifyHook = nullptr;
DetailsViewArgs.bShowOptions = true;
DetailsViewArgs.bShowModifiedPropertiesOption = false;
DetailsViewArgs.bShowScrollBar = false;
DetailsViewArgs.bShowOptions = true;
DetailsViewArgs.bUpdatesFromSelection= true;
}

FStructureDetailsViewArgs StructureViewArgs;
{
StructureViewArgs.bShowObjects = true;
StructureViewArgs.bShowAssets = true;
StructureViewArgs.bShowClasses = true;
StructureViewArgs.bShowInterfaces = true;
}

SettingsView = EditModule.CreateStructureDetailView(DetailsViewArgs, StructureViewArgs, nullptr);
FStructOnScope* Struct = new FStructOnScope(FExportReleaseSettings::StaticStruct(), (uint8*)ExportReleaseSettings.Get());
SettingsView->GetOnFinishedChangingPropertiesDelegate().AddRaw(ExportReleaseSettings.Get(),&FExportReleaseSettings::OnFinishedChangingProperties);
SettingsView->GetDetailsView()->RegisterInstancedCustomPropertyLayout(FExportReleaseSettings::StaticStruct(),FOnGetDetailCustomizationInstance::CreateStatic(&FReleaseSettingsDetails::MakeInstance));
SettingsView->SetStructureData(MakeShareable(Struct));
}

使用 RegisterInstancedCustomPropertyLayout 把所写的 FReleaseSettingsDetails 实例注册到 DetailView 中。注意调用时机要在 SetStructureData 之前。
然后就可以看到添加的两个按钮了: