// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #include "SLevelEditorToolBox.h" #include "Framework/MultiBox/MultiBoxDefs.h" #include "Widgets/Text/STextBlock.h" #include "Framework/MultiBox/MultiBoxBuilder.h" #include "Framework/Commands/InputBindingManager.h" #include "EditorModeRegistry.h" #include "Modules/ModuleManager.h" #include "Widgets/Layout/SBorder.h" #include "EditorStyleSet.h" #include "Editor/EditorPerProjectUserSettings.h" #include "LevelEditor.h" #include "LevelEditorActions.h" #include "LevelEditorModesActions.h" #define LOCTEXT_NAMESPACE "SLevelEditorToolBox" SLevelEditorToolBox::~SLevelEditorToolBox() { if (UObjectInitialized()) { GetMutableDefault()->OnUserSettingChanged().RemoveAll(this); } } void SLevelEditorToolBox::Construct( const FArguments& InArgs, const TSharedRef< class ILevelEditor >& OwningLevelEditor ) { LevelEditor = OwningLevelEditor; // Important: We use a raw binding here because we are releasing our binding in our destructor (where a weak pointer would be invalid) // It's imperative that our delegate is removed in the destructor for the level editor module to play nicely with reloading. GetMutableDefault()->OnUserSettingChanged().AddRaw( this, &SLevelEditorToolBox::HandleUserSettingsChange ); ChildSlot [ SNew( SVerticalBox ) + SVerticalBox::Slot() .AutoHeight() .HAlign( HAlign_Left ) .Padding(0, 0, 0, 0) [ SAssignNew( ModeToolBarContainer, SBorder ) .BorderImage( FEditorStyle::GetBrush( "NoBorder" ) ) .Padding( FMargin(4, 0, 0, 0) ) ] + SVerticalBox::Slot() .FillHeight( 1.0f ) .Padding( 2, 0, 0, 0 ) [ SNew( SVerticalBox ) + SVerticalBox::Slot() [ SAssignNew(InlineContentHolder, SBorder) .BorderImage( FEditorStyle::GetBrush( "ToolPanel.GroupBorder" ) ) .Padding(0.f) .Visibility( this, &SLevelEditorToolBox::GetInlineContentHolderVisibility ) ] + SVerticalBox::Slot() .AutoHeight() .HAlign( HAlign_Center ) .Padding( 2.0f, 14.0f, 2.0f, 2.0f ) [ SNew( STextBlock ) .Text( LOCTEXT("NoToolSelected", "Select a tool to display its options.") ) .Visibility( this, &SLevelEditorToolBox::GetNoToolSelectedTextVisibility ) ] ] ]; UpdateModeToolBar(); } void SLevelEditorToolBox::HandleUserSettingsChange( FName PropertyName ) { UpdateModeToolBar(); } void SLevelEditorToolBox::OnEditorModeCommandsChanged() { UpdateModeToolBar(); } void SLevelEditorToolBox::UpdateModeToolBar() { FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked( "LevelEditor"); const TSharedPtr< const FUICommandList > CommandList = LevelEditorModule.GetGlobalLevelEditorActions(); const TSharedPtr ModeBarExtenders = LevelEditorModule.GetModeBarExtensibilityManager()->GetAllExtenders(); FToolBarBuilder EditorModeTools( CommandList, FMultiBoxCustomization::None, ModeBarExtenders ); { EditorModeTools.SetStyle(&FEditorStyle::Get(), "EditorModesToolbar"); EditorModeTools.SetLabelVisibility( EVisibility::Collapsed ); const FLevelEditorModesCommands& Commands = LevelEditorModule.GetLevelEditorModesCommands(); for ( const FEditorModeInfo& Mode : FEditorModeRegistry::Get().GetSortedModeInfo() ) { // If the mode isn't visible don't create a menu option for it. if ( !Mode.bVisible ) { continue; } FName EditorModeCommandName = FName( *( FString( "EditorMode." ) + Mode.ID.ToString() ) ); TSharedPtr EditorModeCommand = FInputBindingManager::Get().FindCommandInContext( Commands.GetContextName(), EditorModeCommandName ); // If a command isn't yet registered for this mode, we need to register one. if ( !EditorModeCommand.IsValid() ) { continue; } const FUIAction* UIAction = EditorModeTools.GetTopCommandList()->GetActionForCommand( EditorModeCommand ); if ( ensure( UIAction ) ) { EditorModeTools.AddToolBarButton( EditorModeCommand, Mode.ID, Mode.Name, Mode.Name, Mode.IconBrush, Mode.ID );// , EUserInterfaceActionType::ToggleButton ); } } } ModeToolBarContainer->SetContent( EditorModeTools.MakeWidget() ); const TArray< TSharedPtr< IToolkit > >& HostedToolkits = LevelEditor.Pin()->GetHostedToolkits(); for( auto HostedToolkitIt = HostedToolkits.CreateConstIterator(); HostedToolkitIt; ++HostedToolkitIt ) { UpdateInlineContent( ( *HostedToolkitIt )->GetInlineContent() ); break; } } EVisibility SLevelEditorToolBox::GetInlineContentHolderVisibility() const { return InlineContentHolder->GetContent() == SNullWidget::NullWidget ? EVisibility::Collapsed : EVisibility::Visible; } EVisibility SLevelEditorToolBox::GetNoToolSelectedTextVisibility() const { return InlineContentHolder->GetContent() == SNullWidget::NullWidget ? EVisibility::Visible : EVisibility::Collapsed; } void SLevelEditorToolBox::UpdateInlineContent(TSharedPtr InlineContent) const { if (InlineContent.IsValid() && InlineContentHolder.IsValid()) { InlineContentHolder->SetContent(InlineContent.ToSharedRef()); } } void SLevelEditorToolBox::OnToolkitHostingStarted( const TSharedRef< class IToolkit >& Toolkit ) { UpdateInlineContent( Toolkit->GetInlineContent() ); } void SLevelEditorToolBox::OnToolkitHostingFinished( const TSharedRef< class IToolkit >& Toolkit ) { bool FoundAnotherToolkit = false; const TArray< TSharedPtr< IToolkit > >& HostedToolkits = LevelEditor.Pin()->GetHostedToolkits(); for( auto HostedToolkitIt = HostedToolkits.CreateConstIterator(); HostedToolkitIt; ++HostedToolkitIt ) { if ( ( *HostedToolkitIt ) != Toolkit ) { UpdateInlineContent( ( *HostedToolkitIt )->GetInlineContent() ); FoundAnotherToolkit = true; break; } } if ( !FoundAnotherToolkit ) { UpdateInlineContent( SNullWidget::NullWidget ); } } FSlateIcon SLevelEditorToolBox::GetEditorModeIcon(TSharedPtr< FUICommandInfo > EditorModeUICommand, FEditorModeID EditorMode ) { const FSlateIcon& Icon = EditorModeUICommand->GetIcon(); FName IconName = Icon.GetStyleName(); if( FLevelEditorActionCallbacks::IsEditorModeActive(EditorMode) ) { IconName = FEditorStyle::Join(IconName, ".Selected"); } return FSlateIcon(Icon.GetStyleSetName(), IconName); } #undef LOCTEXT_NAMESPACE