// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "UMGEditorModule.h" #include "Modules/ModuleManager.h" #include "UObject/UObjectHash.h" #include "Editor.h" #include "Blueprint/UserWidget.h" #include "Blueprint/WidgetBlueprintGeneratedClass.h" #include "Settings/WidgetDesignerSettings.h" #include "WidgetBlueprint.h" #include "Animation/WidgetAnimation.h" #include "AssetToolsModule.h" #include "IAssetTypeActions.h" #include "AssetTypeActions_WidgetBlueprint.h" #include "KismetCompilerModule.h" #include "WidgetBlueprintCompiler.h" #include "ISequencerModule.h" #include "Animation/MarginTrackEditor.h" #include "Animation/Sequencer2DTransformTrackEditor.h" #include "Animation/WidgetMaterialTrackEditor.h" #include "Animation/MovieSceneSequenceEditor_WidgetAnimation.h" #include "IUMGModule.h" #include "Designer/DesignerCommands.h" #include "ClassIconFinder.h" #include "UMGEditorProjectSettings.h" #include "ISettingsModule.h" #include "SequencerSettings.h" #include "BlueprintEditorModule.h" #include "PropertyEditorModule.h" #include "DynamicEntryBoxDetails.h" #include "ListViewBaseDetails.h" #define LOCTEXT_NAMESPACE "UMG" const FName UMGEditorAppIdentifier = FName(TEXT("UMGEditorApp")); class FUMGEditorModule : public IUMGEditorModule, public FGCObject { public: /** Constructor, set up console commands and variables **/ FUMGEditorModule() : Settings(nullptr) { } /** Called right after the module DLL has been loaded and the module object has been created */ virtual void StartupModule() override { FModuleManager::LoadModuleChecked("UMG"); if (GIsEditor) { FDesignerCommands::Register(); } MenuExtensibilityManager = MakeShareable(new FExtensibilityManager()); ToolBarExtensibilityManager = MakeShareable(new FExtensibilityManager()); DesignerExtensibilityManager = MakeShareable(new FDesignerExtensibilityManager()); // Register widget blueprint compiler we do this no matter what. IKismetCompilerInterface& KismetCompilerModule = FModuleManager::LoadModuleChecked("KismetCompiler"); KismetCompilerModule.GetCompilers().Add(&WidgetBlueprintCompiler); // Register asset types IAssetTools& AssetTools = FModuleManager::LoadModuleChecked("AssetTools").Get(); RegisterAssetTypeAction(AssetTools, MakeShareable(new FAssetTypeActions_WidgetBlueprint())); FKismetCompilerContext::RegisterCompilerForBP(UWidgetBlueprint::StaticClass(), &UWidgetBlueprint::GetCompilerForWidgetBP ); // Register with the sequencer module that we provide auto-key handlers. ISequencerModule& SequencerModule = FModuleManager::Get().LoadModuleChecked("Sequencer"); SequenceEditorHandle = SequencerModule.RegisterSequenceEditor(UWidgetAnimation::StaticClass(), MakeUnique()); MarginTrackEditorCreateTrackEditorHandle = SequencerModule.RegisterPropertyTrackEditor(); TransformTrackEditorCreateTrackEditorHandle = SequencerModule.RegisterPropertyTrackEditor(); WidgetMaterialTrackEditorCreateTrackEditorHandle = SequencerModule.RegisterTrackEditor(FOnCreateTrackEditor::CreateStatic(&FWidgetMaterialTrackEditor::CreateTrackEditor)); RegisterSettings(); // Class detail customizations FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked(TEXT("PropertyEditor")); PropertyModule.RegisterCustomClassLayout(TEXT("DynamicEntryBoxBase"), FOnGetDetailCustomizationInstance::CreateStatic(&FDynamicEntryBoxBaseDetails::MakeInstance)); PropertyModule.RegisterCustomClassLayout(TEXT("DynamicEntryBox"), FOnGetDetailCustomizationInstance::CreateStatic(&FDynamicEntryBoxDetails::MakeInstance)); PropertyModule.RegisterCustomClassLayout(TEXT("ListViewBase"), FOnGetDetailCustomizationInstance::CreateStatic(&FListViewBaseDetails::MakeInstance)); } /** Called before the module is unloaded, right before the module object is destroyed. */ virtual void ShutdownModule() override { MenuExtensibilityManager.Reset(); ToolBarExtensibilityManager.Reset(); IKismetCompilerInterface& KismetCompilerModule = FModuleManager::LoadModuleChecked("KismetCompiler"); KismetCompilerModule.GetCompilers().Remove(&WidgetBlueprintCompiler); // Unregister all the asset types that we registered if ( FModuleManager::Get().IsModuleLoaded("AssetTools") ) { IAssetTools& AssetTools = FModuleManager::GetModuleChecked("AssetTools").Get(); for ( int32 Index = 0; Index < CreatedAssetTypeActions.Num(); ++Index ) { AssetTools.UnregisterAssetTypeActions(CreatedAssetTypeActions[Index].ToSharedRef()); } } CreatedAssetTypeActions.Empty(); // Unregister sequencer track creation delegates ISequencerModule* SequencerModule = FModuleManager::GetModulePtr( "Sequencer" ); if ( SequencerModule != nullptr ) { SequencerModule->UnregisterSequenceEditor(SequenceEditorHandle); SequencerModule->UnRegisterTrackEditor( MarginTrackEditorCreateTrackEditorHandle ); SequencerModule->UnRegisterTrackEditor( TransformTrackEditorCreateTrackEditorHandle ); SequencerModule->UnRegisterTrackEditor( WidgetMaterialTrackEditorCreateTrackEditorHandle ); } UnregisterSettings(); //// Unregister the setting //ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); //if ( SettingsModule != nullptr ) //{ // SettingsModule->UnregisterSettings("Editor", "ContentEditors", "WidgetDesigner"); // SettingsModule->UnregisterSettings("Project", "Editor", "UMGEditor"); //} } /** Gets the extensibility managers for outside entities to extend gui page editor's menus and toolbars */ virtual TSharedPtr GetMenuExtensibilityManager() override { return MenuExtensibilityManager; } virtual TSharedPtr GetToolBarExtensibilityManager() override { return ToolBarExtensibilityManager; } virtual TSharedPtr GetDesignerExtensibilityManager() override { return DesignerExtensibilityManager; } /** Register settings objects. */ void RegisterSettings() { ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); if (SettingsModule != nullptr) { Settings = USequencerSettingsContainer::GetOrCreate(TEXT("UMGSequencerSettings")); SettingsModule->RegisterSettings("Editor", "ContentEditors", "UMGSequencerSettings", LOCTEXT("UMGSequencerSettingsSettingsName", "UMG Sequence Editor"), LOCTEXT("UMGSequencerSettingsSettingsDescription", "Configure the look and feel of the UMG Sequence Editor."), Settings); } } /** Unregister settings objects. */ void UnregisterSettings() { ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); if (SettingsModule != nullptr) { SettingsModule->UnregisterSettings("Editor", "ContentEditors", "UMGSequencerSettings"); } } /** FGCObject interface */ virtual void AddReferencedObjects( FReferenceCollector& Collector ) override { if (Settings) { Collector.AddReferencedObject(Settings); } } virtual FWidgetBlueprintCompiler* GetRegisteredCompiler() override { return &WidgetBlueprintCompiler; } private: void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef Action) { AssetTools.RegisterAssetTypeActions(Action); CreatedAssetTypeActions.Add(Action); } private: TSharedPtr MenuExtensibilityManager; TSharedPtr ToolBarExtensibilityManager; TSharedPtr DesignerExtensibilityManager; FDelegateHandle SequenceEditorHandle; FDelegateHandle MarginTrackEditorCreateTrackEditorHandle; FDelegateHandle TransformTrackEditorCreateTrackEditorHandle; FDelegateHandle WidgetMaterialTrackEditorCreateTrackEditorHandle; /** All created asset type actions. Cached here so that we can unregister it during shutdown. */ TArray< TSharedPtr > CreatedAssetTypeActions; USequencerSettings* Settings; /** Compiler customization for Widgets */ FWidgetBlueprintCompiler WidgetBlueprintCompiler; }; IMPLEMENT_MODULE(FUMGEditorModule, UMGEditor); #undef LOCTEXT_NAMESPACE