This commit is contained in:
2025-04-21 20:25:53 +08:00
parent 7c33e9830c
commit df050170ce
3 changed files with 568 additions and 149 deletions

View File

@@ -20,6 +20,7 @@ const FName FDismembermentEditor::ViewportTabId(TEXT("DismembermentEditor_Viewpo
const FName FDismembermentEditor::DetailsTabId(TEXT("DismembermentEditor_Details"));
const FName FDismembermentEditor::LayerSystemTabId(TEXT("DismembermentEditor_LayerSystem"));
const FName FDismembermentEditor::PhysicsSettingsTabId(TEXT("DismembermentEditor_PhysicsSettings"));
const FName FDismembermentEditor::NodeTreeTabId(TEXT("DismembermentEditor_NodeTree"));
// Constructor
FDismembermentEditor::FDismembermentEditor()
@@ -104,11 +105,15 @@ void FDismembermentEditor::InitDismembermentEditor(const EToolkitMode::Type Mode
CreateEditorToolbar();
// Initialize the asset editor
InitAssetEditor(Mode, InitToolkitHost, FName("DismembermentEditorApp"),
FTabManager::FLayout::NullLayout,
FAssetEditorToolkit::InitAssetEditor(
Mode,
InitToolkitHost,
FName("DismembermentEditorApp"),
FTabManager::FLayout::NullLayout,
/*bCreateDefaultStandaloneMenu=*/ true,
/*bCreateDefaultToolbar=*/ true,
InSkeletalMesh);
InSkeletalMesh
);
// Register for undo/redo
GEditor->RegisterForUndo(this);
@@ -225,39 +230,28 @@ void FDismembermentEditor::CreateEditorLayout()
->AddArea
(
FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical)
// In UE5.5.4, toolbar is no longer a separate tab
// Skip the toolbar tab section and directly create the main content area
->Split
(
FTabManager::NewSplitter()->SetOrientation(Orient_Horizontal)->SetSizeCoefficient(0.9f)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.7f)
->SetSizeCoefficient(0.2f)
->AddTab(NodeTreeTabId, ETabState::OpenedTab)
)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.6f)
->AddTab(ViewportTabId, ETabState::OpenedTab)
)
->Split
(
FTabManager::NewSplitter()->SetOrientation(Orient_Vertical)
->SetSizeCoefficient(0.3f)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.4f)
->AddTab(DetailsTabId, ETabState::OpenedTab)
)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.3f)
->AddTab(LayerSystemTabId, ETabState::OpenedTab)
)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.3f)
->AddTab(PhysicsSettingsTabId, ETabState::OpenedTab)
)
FTabManager::NewStack()
->SetSizeCoefficient(0.2f)
->AddTab(DetailsTabId, ETabState::OpenedTab)
->AddTab(LayerSystemTabId, ETabState::OpenedTab)
->AddTab(PhysicsSettingsTabId, ETabState::OpenedTab)
)
)
);
@@ -302,20 +296,25 @@ void FDismembermentEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& In
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Viewports"));
InTabManager->RegisterTabSpawner(NodeTreeTabId, FOnSpawnTab::CreateSP(this, &FDismembermentEditor::SpawnTab_NodeTree))
.SetDisplayName(FText::FromString("Node Tree"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.BlueprintCore"));
InTabManager->RegisterTabSpawner(DetailsTabId, FOnSpawnTab::CreateSP(this, &FDismembermentEditor::SpawnTab_Details))
.SetDisplayName(FText::FromString("Details"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details"));
InTabManager->RegisterTabSpawner(LayerSystemTabId, FOnSpawnTab::CreateSP(this, &FDismembermentEditor::SpawnTab_LayerSystem))
.SetDisplayName(FText::FromString("Layer System"))
.SetDisplayName(FText::FromString("Anatomical Layer System"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Layers"));
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Layer"));
InTabManager->RegisterTabSpawner(PhysicsSettingsTabId, FOnSpawnTab::CreateSP(this, &FDismembermentEditor::SpawnTab_PhysicsSettings))
.SetDisplayName(FText::FromString("Physics Settings"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.WorldProperties"));
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.PhysicsAsset"));
UE_LOG(LogDismembermentEditor, Log, TEXT("Tab spawners registered successfully"));
}
@@ -337,6 +336,7 @@ void FDismembermentEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>&
FAssetEditorToolkit::UnregisterTabSpawners(InTabManager);
InTabManager->UnregisterTabSpawner(ViewportTabId);
InTabManager->UnregisterTabSpawner(NodeTreeTabId);
InTabManager->UnregisterTabSpawner(DetailsTabId);
InTabManager->UnregisterTabSpawner(LayerSystemTabId);
InTabManager->UnregisterTabSpawner(PhysicsSettingsTabId);
@@ -345,87 +345,563 @@ void FDismembermentEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>&
// Spawn the viewport tab
TSharedRef<SDockTab> FDismembermentEditor::SpawnTab_Viewport(const FSpawnTabArgs& Args)
{
// Create the viewport widget
ViewportWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Viewport will be implemented here"))
];
// Create the tab
return SNew(SDockTab)
.Label(FText::FromString("Viewport"))
.Label(FText::FromString("FLESH Viewport"))
[
ViewportWidget.ToSharedRef()
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Viewport implementation will be added here"))
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0, 0, 4, 0)
[
SNew(SButton)
.Text(FText::FromString("Boolean Cut"))
.ToolTipText(FText::FromString("Perform Boolean Cut Operation"))
.OnClicked_Lambda([this]() {
PerformBooleanCut();
return FReply::Handled();
})
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.Text(FText::FromString("Preview"))
.ToolTipText(FText::FromString("Preview Dismemberment Effects"))
.OnClicked_Lambda([this]() {
PreviewEffects();
return FReply::Handled();
})
]
]
];
}
// Spawn the node tree tab
TSharedRef<SDockTab> FDismembermentEditor::SpawnTab_NodeTree(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.Label(FText::FromString("Node Tree"))
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Node Tree"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Node tree implementation will be added here"))
]
]
]
];
}
// Spawn the details tab
TSharedRef<SDockTab> FDismembermentEditor::SpawnTab_Details(const FSpawnTabArgs& Args)
{
// Create the details view
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs DetailsViewArgs;
DetailsViewArgs.bUpdatesFromSelection = true;
DetailsViewArgs.bLockable = false;
DetailsViewArgs.bAllowSearch = true;
DetailsViewArgs.NameAreaSettings = FDetailsViewArgs::HideNameArea;
DetailsViewArgs.bHideSelectionTip = true;
DetailsWidget = PropertyEditorModule.CreateDetailView(DetailsViewArgs);
DetailsWidget->SetObject(SkeletalMesh);
// Create the tab
return SNew(SDockTab)
.Label(FText::FromString("Details"))
[
DetailsWidget.ToSharedRef()
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Details"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SExpandableArea)
.HeaderContent()
[
SNew(STextBlock)
.Text(FText::FromString("Display Settings"))
]
.BodyContent()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Draw when Selected"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Checked)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Draw when Parent Set"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Checked)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Draw when Children Set"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Checked)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Draw Always"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Unchecked)
]
]
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SExpandableArea)
.HeaderContent()
[
SNew(STextBlock)
.Text(FText::FromString("Editor Node"))
]
.BodyContent()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Enable Simulation"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Checked)
]
]
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SExpandableArea)
.HeaderContent()
[
SNew(STextBlock)
.Text(FText::FromString("Skinning Names"))
]
.BodyContent()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(STextBlock)
.Text(FText::FromString("Skinning names will be added here"))
]
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SExpandableArea)
.HeaderContent()
[
SNew(STextBlock)
.Text(FText::FromString("Debug"))
]
.BodyContent()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 2)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SNew(STextBlock)
.Text(FText::FromString("Debug Fixed Movement"))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SCheckBox)
.IsChecked(ECheckBoxState::Unchecked)
]
]
]
]
]
];
}
// Spawn the layer system tab
TSharedRef<SDockTab> FDismembermentEditor::SpawnTab_LayerSystem(const FSpawnTabArgs& Args)
{
// Create the layer system widget
LayerSystemWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Layer System will be implemented here"))
];
// Create the tab
return SNew(SDockTab)
.Label(FText::FromString("Layer System"))
.Label(FText::FromString("Anatomical Layer System"))
[
LayerSystemWidget.ToSharedRef()
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Anatomical Layer System"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Configure anatomical layers for the mesh"))
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Layer System implementation will be added here"))
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0, 0, 4, 0)
[
SNew(SButton)
.Text(FText::FromString("Add Layer"))
.OnClicked_Lambda([this]() {
AddNewLayer();
return FReply::Handled();
})
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.Text(FText::FromString("Remove Layer"))
.OnClicked_Lambda([this]() {
// TODO: Implement RemoveLayer
return FReply::Handled();
})
]
]
]
];
}
// Spawn the physics settings tab
TSharedRef<SDockTab> FDismembermentEditor::SpawnTab_PhysicsSettings(const FSpawnTabArgs& Args)
{
// Create the physics settings widget
PhysicsSettingsWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Physics Settings will be implemented here"))
];
// Create the tab
return SNew(SDockTab)
.Label(FText::FromString("Physics Settings"))
[
PhysicsSettingsWidget.ToSharedRef()
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Physics Settings"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(FText::FromString("Configure physics properties for dismemberment"))
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::FromString("Physics Settings implementation will be added here"))
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0, 0, 4, 0)
[
SNew(SButton)
.Text(FText::FromString("Apply Physics"))
.OnClicked_Lambda([this]() {
// TODO: Implement ApplyPhysics
return FReply::Handled();
})
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.Text(FText::FromString("Reset Physics"))
.OnClicked_Lambda([this]() {
// TODO: Implement ResetPhysics
return FReply::Handled();
})
]
]
]
];
}
// Create the editor toolbar
void FDismembermentEditor::CreateEditorToolbar()
{
// Create command list
TSharedRef<FUICommandList> CommandList = MakeShareable(new FUICommandList);
// Get the toolbar builder
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
ToolbarExtender->AddToolBarExtension(
"Asset",
EExtensionHook::After,
CommandList,
FToolBarExtensionDelegate::CreateLambda([this](FToolBarBuilder& ToolbarBuilder)
{
ToolbarBuilder.BeginSection("Dismemberment");
{
// Save button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(this, &FDismembermentEditor::SaveEdits)),
NAME_None,
FText::FromString("Save"),
FText::FromString("Save Dismemberment Settings"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "AssetEditor.SaveAsset"),
EUserInterfaceActionType::Button
);
// Browse button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Browse functionality
})),
NAME_None,
FText::FromString("Browse"),
FText::FromString("Browse Assets"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "ContentBrowser.AssetActions.Browse"),
EUserInterfaceActionType::Button
);
// Hide Mesh button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Hide Mesh functionality
})),
NAME_None,
FText::FromString("Hide Mesh"),
FText::FromString("Toggle Mesh Visibility"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "EditorViewport.ToggleRealTime"),
EUserInterfaceActionType::Button
);
// Preview Animation button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Preview Animation functionality
})),
NAME_None,
FText::FromString("Preview Animation"),
FText::FromString("Preview Animation"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "Persona.PreviewMesh"),
EUserInterfaceActionType::Button
);
// Play button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Play functionality
})),
NAME_None,
FText::FromString("Play"),
FText::FromString("Play Animation"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "MediaAsset.AssetActions.Play"),
EUserInterfaceActionType::Button
);
// Pause button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Pause functionality
})),
NAME_None,
FText::FromString("Pause"),
FText::FromString("Pause Animation"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "MediaAsset.AssetActions.Pause"),
EUserInterfaceActionType::Button
);
// Recompile button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Recompile functionality
})),
NAME_None,
FText::FromString("Recompile"),
FText::FromString("Recompile Dismemberment System"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "AssetEditor.ReimportAsset"),
EUserInterfaceActionType::Button
);
// Draw Flags button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Draw Flags functionality
})),
NAME_None,
FText::FromString("Draw Flags"),
FText::FromString("Toggle Draw Flags"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "EditorViewport.VisualizeBufferVisualizationMenu"),
EUserInterfaceActionType::Button
);
// Selection Flags button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Selection Flags functionality
})),
NAME_None,
FText::FromString("Selection Flags"),
FText::FromString("Toggle Selection Flags"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "EditorViewport.VisualizeNaniteVisualizationMenu"),
EUserInterfaceActionType::Button
);
// Draw Skinning button
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateLambda([this]() {
// TODO: Implement Draw Skinning functionality
})),
NAME_None,
FText::FromString("Draw Skinning"),
FText::FromString("Toggle Skinning Visualization"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "EditorViewport.VisualizeHLODColoration"),
EUserInterfaceActionType::Button
);
}
ToolbarBuilder.EndSection();
})
);
// Add the toolbar extender
AddToolbarExtender(ToolbarExtender);
}
// Perform a boolean cut operation
void FDismembermentEditor::PerformBooleanCut()
{
@@ -771,64 +1247,3 @@ void FDismembermentEditor::PreviewEffects()
FMessageDialog::Open(EAppMsgType::Ok, FText::FromString("Unknown exception occurred while previewing effects"));
}
}
// Create the editor toolbar
void FDismembermentEditor::CreateEditorToolbar()
{
// Create command list
TSharedPtr<FUICommandList> CommandList = MakeShareable(new FUICommandList);
// Get the toolbar builder
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
ToolbarExtender->AddToolBarExtension(
"Asset",
EExtensionHook::After,
CommandList,
FToolBarExtensionDelegate::CreateLambda([this](FToolBarBuilder& ToolbarBuilder)
{
ToolbarBuilder.BeginSection("Dismemberment");
{
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(this, &FDismembermentEditor::PerformBooleanCut)),
NAME_None,
FText::FromString("Boolean Cut"),
FText::FromString("Perform Boolean Cut Operation"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.CurveBase"),
EUserInterfaceActionType::Button
);
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(this, &FDismembermentEditor::AddNewLayer)),
NAME_None,
FText::FromString("Add Layer"),
FText::FromString("Add New Anatomical Layer"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Layer"),
EUserInterfaceActionType::Button
);
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(this, &FDismembermentEditor::PreviewEffects)),
NAME_None,
FText::FromString("Preview"),
FText::FromString("Preview Dismemberment Effects"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.ParticleSystem"),
EUserInterfaceActionType::Button
);
ToolbarBuilder.AddToolBarButton(
FUIAction(FExecuteAction::CreateSP(this, &FDismembermentEditor::SaveEdits)),
NAME_None,
FText::FromString("Save"),
FText::FromString("Save Dismemberment Settings"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "AssetEditor.SaveAsset"),
EUserInterfaceActionType::Button
);
}
ToolbarBuilder.EndSection();
})
);
// Add the extender
AddToolbarExtender(ToolbarExtender);
}

View File

@@ -23,15 +23,15 @@ DEFINE_LOG_CATEGORY(LogFLESHEditor);
#define LOCTEXT_NAMESPACE "FLESHEditor"
// Define static tab IDs
const FName FFLESHEditor::ViewportTabId(TEXT("Viewport"));
const FName FFLESHEditor::DetailsTabId(TEXT("Details"));
const FName FFLESHEditor::AssetBrowserTabId(TEXT("AssetBrowser"));
const FName FFLESHEditor::MatrixEditorTabId(TEXT("MatrixEditor"));
const FName FFLESHEditor::GraphEditorTabId(TEXT("GraphEditor"));
const FName FFLESHEditor::ToolbarTabId(TEXT("Toolbar"));
const FName FFLESHEditor::LayerSystemTabId(TEXT("LayerSystem"));
const FName FFLESHEditor::PhysicsSettingsTabId(TEXT("PhysicsSettings"));
const FName FFLESHEditor::DismembermentGraphTabId(TEXT("DismembermentGraph"));
const FName FFLESHEditor::ViewportTabId(TEXT("FLESHEditor_Viewport"));
const FName FFLESHEditor::DetailsTabId(TEXT("FLESHEditor_Details"));
const FName FFLESHEditor::AssetBrowserTabId(TEXT("FLESHEditor_AssetBrowser"));
const FName FFLESHEditor::MatrixEditorTabId(TEXT("FLESHEditor_MatrixEditor"));
const FName FFLESHEditor::GraphEditorTabId(TEXT("FLESHEditor_GraphEditor"));
const FName FFLESHEditor::ToolbarTabId(TEXT("FLESHEditor_Toolbar"));
const FName FFLESHEditor::LayerSystemTabId(TEXT("FLESHEditor_LayerSystem"));
const FName FFLESHEditor::PhysicsSettingsTabId(TEXT("FLESHEditor_PhysicsSettings"));
const FName FFLESHEditor::DismembermentGraphTabId(TEXT("FLESHEditor_DismembermentGraph"));
// Constructor
FFLESHEditor::FFLESHEditor()

View File

@@ -80,6 +80,9 @@ private:
/** Spawn physics settings tab */
TSharedRef<SDockTab> SpawnTab_PhysicsSettings(const FSpawnTabArgs& Args);
/** Spawn node tree tab */
TSharedRef<SDockTab> SpawnTab_NodeTree(const FSpawnTabArgs& Args);
/** Perform boolean cut operation */
void PerformBooleanCut();
@@ -128,4 +131,5 @@ private:
static const FName DetailsTabId;
static const FName LayerSystemTabId;
static const FName PhysicsSettingsTabId;
static const FName NodeTreeTabId;
};