Files
FLESH/Source/FLESHEditor/Private/FLESHEditor.cpp
2025-04-21 20:08:05 +08:00

825 lines
28 KiB
C++

#include "FLESHEditor.h"
#include "FLESHEditorCommands.h"
#include "FLESHEditorStyle.h"
#include "MatrixInputWidget.h"
#include "DismembermentGraph/DismembermentGraphEditor.h"
#include "DismembermentEditor.h"
#include "AnatomicalStructureBrush.h"
#include "Widgets/Docking/SDockTab.h"
#include "PropertyEditorModule.h"
#include "Modules/ModuleManager.h"
#include "IDetailsView.h"
#include "Widgets/Layout/SBorder.h"
#include "Styling/AppStyle.h"
#include "Framework/Commands/UICommandList.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "ToolMenus.h"
#include "Misc/MessageDialog.h"
// Define log category
DEFINE_LOG_CATEGORY(LogFLESHEditor);
// Define localization namespace
#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"));
// Constructor
FFLESHEditor::FFLESHEditor()
: CommandList(MakeShareable(new FUICommandList))
, EditingObject(nullptr)
, bIsInitialized(false)
{
UE_LOG(LogFLESHEditor, Log, TEXT("FLESH Editor constructor called"));
}
// Destructor
FFLESHEditor::~FFLESHEditor()
{
// Unregister from any events
if (GEditor)
{
GEditor->UnregisterForUndo(this);
}
UE_LOG(LogFLESHEditor, Log, TEXT("FLESH Editor destructor called"));
}
// Initialize the editor
void FFLESHEditor::InitFLESHEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, UObject* InObject)
{
UE_LOG(LogFLESHEditor, Log, TEXT("Initializing FLESH Editor"));
try
{
// Set the object being edited
EditingObject = InObject;
if (!EditingObject)
{
HandleEditorError(LOCTEXT("InitNoObject", "Failed to initialize FLESH Editor: No object specified"));
return;
}
// Register commands
FFLESHEditorCommands::Register();
// Register for undo/redo
GEditor->RegisterForUndo(this);
// Create the layout
const TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout("Standalone_FLESHEditor_Layout_v1")
->AddArea
(
FTabManager::NewPrimaryArea()->SetOrientation(Orient_Vertical)
->Split
(
FTabManager::NewSplitter()->SetOrientation(Orient_Horizontal)->SetSizeCoefficient(0.9f)
->Split
(
FTabManager::NewStack()
->SetSizeCoefficient(0.7f)
->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)
)
)
)
);
// Initialize the asset editor
FAssetEditorToolkit::InitAssetEditor(
Mode,
InitToolkitHost,
FName("FLESHEditorApp"),
StandaloneDefaultLayout,
/*bCreateDefaultStandaloneMenu=*/ true,
/*bCreateDefaultToolbar=*/ true,
EditingObject
);
// Create the command list
CreateCommandList();
// Register tab spawners
RegisterTabSpawners(GetTabManager().ToSharedRef());
// Extend toolbar
ExtendToolbar();
// Set initialization flag
bIsInitialized = true;
UE_LOG(LogFLESHEditor, Log, TEXT("FLESH Editor initialized successfully"));
}
catch (const std::exception& e)
{
HandleEditorError(FText::Format(LOCTEXT("InitException", "Exception during FLESH Editor initialization: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))));
}
catch (...)
{
HandleEditorError(LOCTEXT("InitUnknownError", "Unknown exception during FLESH Editor initialization"));
}
}
// FEditorUndoClient interface
void FFLESHEditor::PostUndo(bool bSuccess)
{
if (bSuccess)
{
// Refresh the views
if (DetailsWidget.IsValid())
{
DetailsWidget->ForceRefresh();
}
}
}
void FFLESHEditor::PostRedo(bool bSuccess)
{
if (bSuccess)
{
// Refresh the views
if (DetailsWidget.IsValid())
{
DetailsWidget->ForceRefresh();
}
}
}
// Tab spawners
TSharedRef<SDockTab> FFLESHEditor::SpawnTab_Viewport(const FSpawnTabArgs& Args)
{
UE_LOG(LogFLESHEditor, Log, TEXT("Spawning Viewport tab"));
try
{
// Create the viewport widget
TSharedRef<SWidget> ViewportContent = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("ViewportTitle", "FLESH Viewport"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("ViewportImplementation", "Viewport implementation will be added here"))
.AutoWrapText(true)
]
]
];
// Create the tab
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("ViewportTab", "Viewport"))
[
ViewportContent
];
return NewTab;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception spawning Viewport tab: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("ViewportTabError", "Error spawning Viewport tab: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("ViewportTab", "Viewport"))
[
ErrorWidget
];
return NewTab;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception spawning Viewport tab"));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("ViewportTabUnknownError", "Unknown error spawning Viewport tab"))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("ViewportTab", "Viewport"))
[
ErrorWidget
];
return NewTab;
}
}
TSharedRef<SDockTab> FFLESHEditor::SpawnTab_Details(const FSpawnTabArgs& Args)
{
UE_LOG(LogFLESHEditor, Log, TEXT("Spawning Details tab"));
try
{
// Create the details widget
TSharedRef<SWidget> DetailsContent = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("DetailsTitle", "Details"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("DetailsImplementation", "Details implementation will be added here"))
.AutoWrapText(true)
]
]
];
// Create the tab
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("DetailsTab", "Details"))
[
DetailsContent
];
return NewTab;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception spawning Details tab: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("DetailsTabError", "Error spawning Details tab: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("DetailsTab", "Details"))
[
ErrorWidget
];
return NewTab;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception spawning Details tab"));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("DetailsTabUnknownError", "Unknown error spawning Details tab"))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("DetailsTab", "Details"))
[
ErrorWidget
];
return NewTab;
}
}
// DismembermentEditor related tab spawners
TSharedRef<SDockTab> FFLESHEditor::SpawnTab_LayerSystem(const FSpawnTabArgs& Args)
{
UE_LOG(LogFLESHEditor, Log, TEXT("Spawning Layer System tab"));
try
{
// Create the layer system widget
TSharedRef<SWidget> WidgetContent = CreateLayerSystemWidget();
// Create the tab
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("LayerSystemTab", "Layer System"))
[
WidgetContent
];
return NewTab;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception spawning Layer System tab: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("LayerSystemTabError", "Error spawning Layer System tab: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("LayerSystemTab", "Layer System"))
[
ErrorWidget
];
return NewTab;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception spawning Layer System tab"));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("LayerSystemTabUnknownError", "Unknown error spawning Layer System tab"))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("LayerSystemTab", "Layer System"))
[
ErrorWidget
];
return NewTab;
}
}
TSharedRef<SDockTab> FFLESHEditor::SpawnTab_PhysicsSettings(const FSpawnTabArgs& Args)
{
UE_LOG(LogFLESHEditor, Log, TEXT("Spawning Physics Settings tab"));
try
{
// Create the physics settings widget
TSharedRef<SWidget> WidgetContent = CreatePhysicsSettingsWidget();
// Create the tab
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("PhysicsSettingsTab", "Physics Settings"))
[
WidgetContent
];
return NewTab;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception spawning Physics Settings tab: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("PhysicsSettingsTabError", "Error spawning Physics Settings tab: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("PhysicsSettingsTab", "Physics Settings"))
[
ErrorWidget
];
return NewTab;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception spawning Physics Settings tab"));
// Create an error widget
TSharedRef<SWidget> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("PhysicsSettingsTabUnknownError", "Unknown error spawning Physics Settings tab"))
];
// Create the tab with the error widget
TSharedRef<SDockTab> NewTab = SNew(SDockTab)
.Label(LOCTEXT("PhysicsSettingsTab", "Physics Settings"))
[
ErrorWidget
];
return NewTab;
}
}
// Create DismembermentEditor related widgets
TSharedRef<SBorder> FFLESHEditor::CreateLayerSystemWidget()
{
UE_LOG(LogFLESHEditor, Log, TEXT("Creating Layer System widget"));
try
{
// Create a placeholder widget for now
TSharedRef<SBorder> Widget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("LayerSystemTitle", "Anatomical Layer System"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("LayerSystemDescription", "Configure anatomical layers for the mesh"))
.AutoWrapText(true)
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("LayerSystemImplementation", "Layer System implementation will be added here"))
.AutoWrapText(true)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SButton)
.Text(LOCTEXT("AddLayerButton", "Add Layer"))
.ToolTipText(LOCTEXT("AddLayerTooltip", "Add a new anatomical layer"))
.OnClicked_Lambda([]() { return FReply::Handled(); })
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SButton)
.Text(LOCTEXT("RemoveLayerButton", "Remove Layer"))
.ToolTipText(LOCTEXT("RemoveLayerTooltip", "Remove the selected anatomical layer"))
.OnClicked_Lambda([]() { return FReply::Handled(); })
]
];
// Store the widget in the class member
LayerSystemWidget = Widget;
return Widget;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception creating Layer System widget: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SBorder> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("LayerSystemWidgetError", "Error creating Layer System widget: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
.AutoWrapText(true)
];
return ErrorWidget;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception creating Layer System widget"));
// Create an error widget
TSharedRef<SBorder> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("LayerSystemWidgetUnknownError", "Unknown error creating Layer System widget"))
.AutoWrapText(true)
];
return ErrorWidget;
}
}
TSharedRef<SBorder> FFLESHEditor::CreatePhysicsSettingsWidget()
{
UE_LOG(LogFLESHEditor, Log, TEXT("Creating Physics Settings widget"));
try
{
// Create a placeholder widget for now
TSharedRef<SBorder> Widget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("PhysicsSettingsTitle", "Physics Settings"))
.Font(FCoreStyle::GetDefaultFontStyle("Bold", 12))
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 0, 0, 4)
[
SNew(STextBlock)
.Text(LOCTEXT("PhysicsSettingsDescription", "Configure physics properties for dismemberment"))
.AutoWrapText(true)
]
+ SVerticalBox::Slot()
.FillHeight(1.0f)
[
SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.DarkGroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("PhysicsSettingsImplementation", "Physics Settings implementation will be added here"))
.AutoWrapText(true)
]
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SButton)
.Text(LOCTEXT("ApplyPhysicsButton", "Apply Physics"))
.ToolTipText(LOCTEXT("ApplyPhysicsTooltip", "Apply physics settings to the mesh"))
.OnClicked_Lambda([]() { return FReply::Handled(); })
]
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 4, 0, 0)
[
SNew(SButton)
.Text(LOCTEXT("ResetPhysicsButton", "Reset Physics"))
.ToolTipText(LOCTEXT("ResetPhysicsTooltip", "Reset physics settings to default"))
.OnClicked_Lambda([]() { return FReply::Handled(); })
]
];
// Store the widget in the class member
PhysicsSettingsWidget = Widget;
return Widget;
}
catch (const std::exception& e)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Exception creating Physics Settings widget: %s"), UTF8_TO_TCHAR(e.what()));
// Create an error widget
TSharedRef<SBorder> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(FText::Format(LOCTEXT("PhysicsSettingsWidgetError", "Error creating Physics Settings widget: {0}"), FText::FromString(UTF8_TO_TCHAR(e.what()))))
.AutoWrapText(true)
];
return ErrorWidget;
}
catch (...)
{
UE_LOG(LogFLESHEditor, Error, TEXT("Unknown exception creating Physics Settings widget"));
// Create an error widget
TSharedRef<SBorder> ErrorWidget = SNew(SBorder)
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
.Padding(FMargin(4.0f))
[
SNew(STextBlock)
.Text(LOCTEXT("PhysicsSettingsWidgetUnknownError", "Unknown error creating Physics Settings widget"))
.AutoWrapText(true)
];
return ErrorWidget;
}
}
// Create command list
void FFLESHEditor::CreateCommandList()
{
UE_LOG(LogFLESHEditor, Log, TEXT("Creating command list"));
// Make sure the command list is valid
if (!CommandList.IsValid())
{
CommandList = MakeShareable(new FUICommandList);
}
// Bind commands
const FFLESHEditorCommands& Commands = FFLESHEditorCommands::Get();
// Example command binding
CommandList->MapAction(
Commands.OpenDismembermentGraphEditor,
FExecuteAction::CreateSP(this, &FFLESHEditor::OnOpenDismembermentGraphEditor),
FCanExecuteAction());
}
// Extend toolbar with custom buttons
void FFLESHEditor::ExtendToolbar()
{
UE_LOG(LogFLESHEditor, Log, TEXT("Extending toolbar"));
struct Local
{
static void FillToolbar(FToolBarBuilder& ToolbarBuilder)
{
ToolbarBuilder.BeginSection("FLESH");
{
ToolbarBuilder.AddToolBarButton(FFLESHEditorCommands::Get().OpenDismembermentGraphEditor,
NAME_None,
LOCTEXT("DismembermentGraphButtonLabel", "Dismemberment Graph"),
LOCTEXT("DismembermentGraphButtonTooltip", "Open the Dismemberment Graph Editor"),
FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Blueprint"));
}
ToolbarBuilder.EndSection();
}
};
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
ToolbarExtender->AddToolBarExtension(
"Asset",
EExtensionHook::After,
CommandList,
FToolBarExtensionDelegate::CreateStatic(&Local::FillToolbar)
);
AddToolbarExtender(ToolbarExtender);
}
// Command handlers
void FFLESHEditor::OnOpenDismembermentGraphEditor()
{
UE_LOG(LogFLESHEditor, Log, TEXT("Opening Dismemberment Graph Editor"));
// Implementation will be added in the future
}
// Error handling method
void FFLESHEditor::HandleEditorError(const FText& ErrorMessage)
{
UE_LOG(LogFLESHEditor, Error, TEXT("%s"), *ErrorMessage.ToString());
// Show a message dialog
FMessageDialog::Open(EAppMsgType::Ok, ErrorMessage);
}
// Check if editor is initialized
bool FFLESHEditor::IsEditorInitialized()
{
return bIsInitialized;
}
// FAssetEditorToolkit interface
void FFLESHEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::RegisterTabSpawners(InTabManager);
// Register viewport tab
InTabManager->RegisterTabSpawner(ViewportTabId, FOnSpawnTab::CreateSP(this, &FFLESHEditor::SpawnTab_Viewport))
.SetDisplayName(LOCTEXT("ViewportTab", "Viewport"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Viewports"));
// Register details tab
InTabManager->RegisterTabSpawner(DetailsTabId, FOnSpawnTab::CreateSP(this, &FFLESHEditor::SpawnTab_Details))
.SetDisplayName(LOCTEXT("DetailsTab", "Details"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details"));
// Register layer system tab
InTabManager->RegisterTabSpawner(LayerSystemTabId, FOnSpawnTab::CreateSP(this, &FFLESHEditor::SpawnTab_LayerSystem))
.SetDisplayName(LOCTEXT("LayerSystemTab", "Layer System"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Layers"));
// Register physics settings tab
InTabManager->RegisterTabSpawner(PhysicsSettingsTabId, FOnSpawnTab::CreateSP(this, &FFLESHEditor::SpawnTab_PhysicsSettings))
.SetDisplayName(LOCTEXT("PhysicsSettingsTab", "Physics Settings"))
.SetGroup(WorkspaceMenuCategory.ToSharedRef())
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.WorldSettings"));
}
void FFLESHEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
FAssetEditorToolkit::UnregisterTabSpawners(InTabManager);
// Unregister all tabs
InTabManager->UnregisterTabSpawner(ViewportTabId);
InTabManager->UnregisterTabSpawner(DetailsTabId);
InTabManager->UnregisterTabSpawner(LayerSystemTabId);
InTabManager->UnregisterTabSpawner(PhysicsSettingsTabId);
}
FName FFLESHEditor::GetToolkitFName() const
{
return FName("FLESHEditor");
}
FText FFLESHEditor::GetBaseToolkitName() const
{
return LOCTEXT("AppLabel", "FLESH Editor");
}
FString FFLESHEditor::GetWorldCentricTabPrefix() const
{
return LOCTEXT("WorldCentricTabPrefix", "FLESH ").ToString();
}
FLinearColor FFLESHEditor::GetWorldCentricTabColorScale() const
{
return FLinearColor(0.7f, 0.0f, 0.0f, 0.5f); // Dark red color
}
#undef LOCTEXT_NAMESPACE