如何优雅的向DataTable上方ToolBar区域新增功能按钮
近期终于抽出空来把之前做的一些小东西整理出来,希望能对你有帮助
- 问题背景:只要是大量使用DT的项目我想都会遇到想要"一键处理XXX"的需求,比如是一键打开表格配置的蓝图,一键运行表格配置合法性检查等等。问题随之而来,如何优雅的扩展增加按钮,总不能是来个需求都往引擎源码里加,这有点痛苦,而且还要求对如何扩展引擎编辑器有基本的了解。
基础思路
- 朴素的想法是不同表格有不同的需求,那么最好按钮由每张表格自己决定
- 最好加按钮的人不需要了解引擎如何扩展,不需要改引擎代码,只在对应表格代码中处理相关逻辑
说干就干
-
引擎中新增一个扩展按钮信息结构体
// 在DataTable.h新增 USTRUCT(BlueprintType) struct FDTExtendToolBarBtnInfo {GENERATED_BODY() public:FDTExtendToolBarBtnInfo() = default;FDTExtendToolBarBtnInfo(FString InLabel, FString InFuncType, FString InToolTip): Label(InLabel), FuncType(InFuncType), ToolTip(InToolTip){}bool operator==(const FDTExtendToolBarBtnInfo& Other) const{return Label == Other.Label && FuncType == Other.FuncType;}UPROPERTY()FString Label = "TestExtendBtn";UPROPERTY()FString FuncType = "Test";UPROPERTY()FString ToolTip = "ToolBar tool tip";UPROPERTY()FString IconStyleSet = "EditorStyle";UPROPERTY()FString IconStyle = "ContentBrowser.ImportPackage"; }; -
从 GetLifetimeReplicatedProps() 得到灵感,在TableRowBase表行基类结构体中增加虚函数,从子类表行中获取要增加的扩展按钮信息
// DataTable.h中 FTableRowBase 中增加虚函数 #if WITH_EDITOR // 这里新增虚函数,由子类各自塞入扩展信息 virtual void GetExtendToolBars(TArray<FDTExtendToolBarBtnInfo>& OutExtendToolBars) { }; // 按钮回调事件 virtual void OnExtendToolBarBtnClicked(const FString InBtnType) { }; #endif // WITH_EDITOR -
由DataTableEditor获取到之后统一注册扩展,绑定回调函数到对应的表行,去执行不同的处理逻辑
// DataTable.h中 FDataTableEditor::FillToolbar(FToolBarBuilder& ToolbarBuilder)函数中统一注册增加当前表格的扩展按钮 // 自定义增加ToolBar按钮 ToolbarBuilder.BeginSection("CustomDTCommands"); {const UDataTable* ViewTable = GetDataTable();if (ViewTable && HighlightedRowName.IsValid()){auto RowData = ViewTable->FindRow<FTableRowBase>(HighlightedRowName, "");if (!RowData){return;}TArray<FDTExtendToolBarBtnInfo> ExtendBtnInfos;RowData->GetExtendToolBars(ExtendBtnInfos); // 从子类获取for (const auto& BtnInfo : ExtendBtnInfos){FString FuncType = BtnInfo.FuncType;ToolbarBuilder.AddToolBarButton(FUIAction(FExecuteAction::CreateLambda([this, FuncType]() {const UDataTable* ViewTable = GetDataTable();if (ViewTable && HighlightedRowName.IsValid()){auto RowData = ViewTable->FindRow<FTableRowBase>(HighlightedRowName, "");if (RowData){RowData->OnExtendToolBarBtnClicked(FuncType); // 回调到子类}}})),NAME_None,TAttribute(FText::FromString(BtnInfo.Label)),TAttribute(FText::FromString(BtnInfo.ToolTip)),FSlateIcon(FName(BtnInfo.IconStyleSet), FName(BtnInfo.IconStyle)));}} } ToolbarBuilder.EndSection();牛刀小试
- 我们随意找一个表行结构体来试验,扩展一个按钮仅需要几行代码,添加按钮的代码是简单而固定的。对于执行同学来说,只需要关注回调函数中自己的处理逻辑即可。


- 引擎内效果

- 我们随意找一个表行结构体来试验,扩展一个按钮仅需要几行代码,添加按钮的代码是简单而固定的。对于执行同学来说,只需要关注回调函数中自己的处理逻辑即可。