/** * @file * * @author Mamadou Babaei * * @section LICENSE * * (The MIT License) * * Copyright (c) 2020 - 2024 SenseGlove * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * @section DESCRIPTION * * */ #include "SGEditor/SGSkeletalMeshEditor.h" #include "Framework/MultiBox/MultiBoxExtender.h" #include "ISkeletalMeshEditor.h" #include "ISkeletalMeshEditorModule.h" #include "Modules/ModuleManager.h" #include "SGEditor/SGAssetTypeActions_SkeletalMesh.h" #include "SGEditor/SGPluginStyle.h" #include "SGEditor/SGSkeletalMeshEditorCommands.h" #define LOCTEXT_NAMESPACE "SkeletalMeshEditor" struct FSGSkeletalMeshEditor::FImpl { /************************ * Member variables ************************/ TSharedPtr AssetActions; TSharedPtr EditorCommands; TSharedPtr MenuExtender; TSharedPtr ToolbarExtender; /************************ * Owner object ************************/ FSGSkeletalMeshEditor* Owner; /************************ * Constructor / Destructor ************************/ explicit FImpl(FSGSkeletalMeshEditor* InOwner); ~FImpl(); /************************ * Default copy constructor & copy assignment operator ************************/ FImpl(const FImpl& Rhs) = default; FImpl& operator=(const FImpl& Rhs) = default; }; TSharedRef FSGSkeletalMeshEditor::GetInstance() { static TSharedPtr Instance{MakeShared()}; return Instance.ToSharedRef(); } FSGSkeletalMeshEditor::FSGSkeletalMeshEditor() : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { } FSGSkeletalMeshEditor::~FSGSkeletalMeshEditor() = default; void FSGSkeletalMeshEditor::Initialize() const { //RegisterAssetTypeActions(); RegisterCommands(); ExtendMenu(); ExtendToolbar(); } void FSGSkeletalMeshEditor::Deinitialize() const { UnregisterCommands(); } void FSGSkeletalMeshEditor::RegisterAssetTypeActions() const { if (Pimpl->AssetActions.IsValid()) { Pimpl->AssetActions.Reset(); } Pimpl->AssetActions = MakeShared(); IAssetTools& AssetTools = FModuleManager::LoadModuleChecked("AssetTools").Get(); AssetTools.RegisterAssetTypeActions(Pimpl->AssetActions.ToSharedRef()); } void FSGSkeletalMeshEditor::RegisterCommands() const { if (Pimpl->EditorCommands.IsValid()) { Pimpl->EditorCommands.Reset(); } Pimpl->EditorCommands = MakeShared(); Pimpl->EditorCommands->RegisterCommands(); } void FSGSkeletalMeshEditor::UnregisterCommands() const { if (!Pimpl->EditorCommands.IsValid()) { return; } Pimpl->EditorCommands->Unregister(); } void FSGSkeletalMeshEditor::ExtendMenu() const { if (Pimpl->MenuExtender.IsValid()) { Pimpl->MenuExtender.Reset(); } Pimpl->MenuExtender = MakeShared(); ISkeletalMeshEditorModule& SkeletonEditorModule{ FModuleManager::LoadModuleChecked("SkeletalMeshEditor") }; const TSharedPtr ExtensibilityManager{ SkeletonEditorModule.GetMenuExtensibilityManager() }; if (!ensureAlwaysMsgf(ExtensibilityManager.IsValid(), TEXT("Invalid ExtensibilityManager!"))) { return; } Pimpl->MenuExtender->AddMenuExtension( FName{TEXT("AssetEditorActions")}, EExtensionHook::After, Pimpl->EditorCommands->CommandList, FMenuExtensionDelegate::CreateLambda([&](FMenuBuilder MenuBuilder)-> void { MenuBuilder.BeginSection(FName{TEXT("SenseGlove")}, LOCTEXT("SenseGloveHeading", "SenseGlove")); { MenuBuilder.AddMenuEntry( Pimpl->EditorCommands->AddSenseGloveSockets, NAME_None, LOCTEXT("AddSenseGloveSocketsLabel", "Add SenseGlove Sockets"), LOCTEXT( "AddSenseGloveSocketsToolTip", "Adds and sets up the SenseGlove grab and touch sockets"), FSlateIcon{FSGPluginStyle::GetStyleSetIcon()}, NAME_None); } MenuBuilder.EndSection(); })); ExtensibilityManager->AddExtender(Pimpl->MenuExtender); } void FSGSkeletalMeshEditor::ExtendToolbar() const { if (Pimpl->ToolbarExtender.IsValid()) { Pimpl->ToolbarExtender.Reset(); } Pimpl->ToolbarExtender = MakeShared(); ISkeletalMeshEditorModule& SkeletalMeshEditorModule{ FModuleManager::LoadModuleChecked("SkeletalMeshEditor") }; const TSharedPtr ExtensibilityManager{ SkeletalMeshEditorModule.GetToolBarExtensibilityManager() }; if (!ensureAlwaysMsgf(ExtensibilityManager.IsValid(), TEXT("Invalid ExtensibilityManager!"))) { return; } Pimpl->ToolbarExtender->AddToolBarExtension( FName{TEXT("SkeletalMesh")}, EExtensionHook::After, Pimpl->EditorCommands->CommandList, FToolBarExtensionDelegate::CreateLambda([&](FToolBarBuilder& ToolbarBuilder)-> void { ToolbarBuilder.BeginSection(FName{TEXT("SenseGlove")}); { ToolbarBuilder.AddToolBarButton( Pimpl->EditorCommands->AddSenseGloveSockets, NAME_None, LOCTEXT("AddSenseGloveSocketsLabel", "Add SenseGlove Sockets"), LOCTEXT( "AddSenseGloveSocketsToolTip", "Adds and sets up the SenseGlove grab and touch sockets"), FSGPluginStyle::GetStyleSetIcon(), NAME_None, FNewMenuDelegate{} ); } ToolbarBuilder.EndSection(); })); ExtensibilityManager->AddExtender(Pimpl->ToolbarExtender); } FSGSkeletalMeshEditor::FImpl::FImpl(FSGSkeletalMeshEditor* InOwner) : Owner(InOwner) { } FSGSkeletalMeshEditor::FImpl::~FImpl() = default; void FSGSkeletalMeshEditor::FImplDeleter::operator()(const FImpl* P) const { delete P; } #undef LOCTEXT_NAMESPACE