You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
1355 lines
53 KiB
C++
1355 lines
53 KiB
C++
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SLevelViewportToolBar.h"
|
|
#include "Framework/Commands/UIAction.h"
|
|
#include "Framework/MultiBox/MultiBoxDefs.h"
|
|
#include "Framework/MultiBox/MultiBoxExtender.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "Widgets/Layout/SBorder.h"
|
|
#include "Widgets/Layout/SBox.h"
|
|
#include "Widgets/Input/SSpinBox.h"
|
|
#include "EditorStyleSet.h"
|
|
#include "Camera/CameraActor.h"
|
|
#include "Misc/ConfigCacheIni.h"
|
|
#include "GameFramework/WorldSettings.h"
|
|
#include "EngineUtils.h"
|
|
#include "LevelEditor.h"
|
|
#include "STransformViewportToolbar.h"
|
|
#include "EditorShowFlags.h"
|
|
#include "LevelViewportActions.h"
|
|
#include "LevelEditorViewport.h"
|
|
#include "Layers/ILayers.h"
|
|
#include "DeviceProfiles/DeviceProfile.h"
|
|
#include "IDeviceProfileServicesModule.h"
|
|
#include "EditorViewportCommands.h"
|
|
#include "SEditorViewportToolBarMenu.h"
|
|
#include "SEditorViewportToolBarButton.h"
|
|
#include "SEditorViewportViewMenu.h"
|
|
#include "Stats/StatsData.h"
|
|
#include "BufferVisualizationData.h"
|
|
#include "FoliageType.h"
|
|
#include "ShowFlagMenuCommands.h"
|
|
#include "Bookmarks/BookmarkUI.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "LevelViewportToolBar"
|
|
|
|
/** Override the view menu, just so we can specify the level viewport as active when the button is clicked */
|
|
class SLevelEditorViewportViewMenu : public SEditorViewportViewMenu
|
|
{
|
|
public:
|
|
virtual TSharedRef<SWidget> GenerateViewMenuContent() const override
|
|
{
|
|
SLevelViewport* LevelViewport = static_cast<SLevelViewport*>(Viewport.Pin().Get());
|
|
LevelViewport->OnFloatingButtonClicked();
|
|
|
|
return SEditorViewportViewMenu::GenerateViewMenuContent();
|
|
}
|
|
};
|
|
|
|
static void FillShowMenu(class FMenuBuilder& MenuBuilder, TArray< FLevelViewportCommands::FShowMenuCommand > MenuCommands, int32 EntryOffset)
|
|
{
|
|
// Generate entries for the standard show flags
|
|
// Assumption: the first 'n' entries types like 'Show All' and 'Hide All' buttons, so insert a separator after them
|
|
for (int32 EntryIndex = 0; EntryIndex < MenuCommands.Num(); ++EntryIndex)
|
|
{
|
|
MenuBuilder.AddMenuEntry(MenuCommands[EntryIndex].ShowMenuItem, NAME_None, MenuCommands[EntryIndex].LabelOverride);
|
|
if (EntryIndex == EntryOffset - 1)
|
|
{
|
|
MenuBuilder.AddMenuSeparator();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void FillShowStatsSubMenus(class FMenuBuilder& MenuBuilder, TArray< FLevelViewportCommands::FShowMenuCommand > MenuCommands, TMap< FString, TArray< FLevelViewportCommands::FShowMenuCommand > > StatCatCommands)
|
|
{
|
|
FillShowMenu(MenuBuilder, MenuCommands, 1);
|
|
|
|
// Separate out stats into two list, those with and without submenus
|
|
TArray< FLevelViewportCommands::FShowMenuCommand > SingleStatCommands;
|
|
TMap< FString, TArray< FLevelViewportCommands::FShowMenuCommand > > SubbedStatCommands;
|
|
for (auto StatCatIt = StatCatCommands.CreateConstIterator(); StatCatIt; ++StatCatIt)
|
|
{
|
|
const TArray< FLevelViewportCommands::FShowMenuCommand >& ShowStatCommands = StatCatIt.Value();
|
|
const FString& CategoryName = StatCatIt.Key();
|
|
|
|
// If no category is specified, or there's only one category, don't use submenus
|
|
FString NoCategory = FStatConstants::NAME_NoCategory.ToString();
|
|
NoCategory.RemoveFromStart(TEXT("STATCAT_"));
|
|
if (CategoryName == NoCategory || StatCatCommands.Num() == 1)
|
|
{
|
|
for (int32 StatIndex = 0; StatIndex < ShowStatCommands.Num(); ++StatIndex)
|
|
{
|
|
const FLevelViewportCommands::FShowMenuCommand& StatCommand = ShowStatCommands[StatIndex];
|
|
SingleStatCommands.Add(StatCommand);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SubbedStatCommands.Add(CategoryName, ShowStatCommands);
|
|
}
|
|
}
|
|
|
|
// First add all the stats that don't have a sub menu
|
|
for (auto StatCatIt = SingleStatCommands.CreateConstIterator(); StatCatIt; ++StatCatIt)
|
|
{
|
|
const FLevelViewportCommands::FShowMenuCommand& StatCommand = *StatCatIt;
|
|
MenuBuilder.AddMenuEntry(StatCommand.ShowMenuItem, NAME_None, StatCommand.LabelOverride);
|
|
}
|
|
|
|
// Now add all the stats that have sub menus
|
|
for (auto StatCatIt = SubbedStatCommands.CreateConstIterator(); StatCatIt; ++StatCatIt)
|
|
{
|
|
const TArray< FLevelViewportCommands::FShowMenuCommand >& StatCommands = StatCatIt.Value();
|
|
const FText CategoryName = FText::FromString(StatCatIt.Key());
|
|
|
|
FFormatNamedArguments Args;
|
|
Args.Add(TEXT("StatCat"), CategoryName);
|
|
const FText CategoryDescription = FText::Format(NSLOCTEXT("UICommands", "StatShowCatName", "Show {StatCat} stats"), Args);
|
|
|
|
MenuBuilder.AddSubMenu(CategoryName, CategoryDescription,
|
|
FNewMenuDelegate::CreateStatic(&FillShowMenu, StatCommands, 0));
|
|
}
|
|
}
|
|
|
|
void SLevelViewportToolBar::Construct( const FArguments& InArgs )
|
|
{
|
|
Viewport = InArgs._Viewport;
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( "LevelEditor");
|
|
|
|
const FMargin ToolbarSlotPadding( 2.0f, 2.0f );
|
|
const FMargin ToolbarButtonPadding( 2.0f, 0.0f );
|
|
|
|
static const FName DefaultForegroundName("DefaultForeground");
|
|
|
|
ChildSlot
|
|
[
|
|
SNew( SBorder )
|
|
.BorderImage( FEditorStyle::GetBrush("NoBorder") )
|
|
// Color and opacity is changed based on whether or not the mouse cursor is hovering over the toolbar area
|
|
.ColorAndOpacity( this, &SViewportToolBar::OnGetColorAndOpacity )
|
|
.ForegroundColor( FEditorStyle::GetSlateColor(DefaultForegroundName) )
|
|
[
|
|
SNew( SHorizontalBox )
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
SNew( SEditorViewportToolbarMenu )
|
|
.ParentToolBar( SharedThis( this ) )
|
|
.Cursor( EMouseCursor::Default )
|
|
.Image( "EditorViewportToolBar.MenuDropdown" )
|
|
.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.MenuDropdown")))
|
|
.OnGetMenuContent( this, &SLevelViewportToolBar::GenerateOptionsMenu )
|
|
]
|
|
|
|
+ SHorizontalBox::Slot()
|
|
[
|
|
SNew( SHorizontalBox )
|
|
.Visibility(Viewport.Pin().Get(), &SLevelViewport::GetFullToolbarVisibility)
|
|
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
SNew( SEditorViewportToolbarMenu )
|
|
.ParentToolBar( SharedThis( this ) )
|
|
.Cursor( EMouseCursor::Default )
|
|
.Label( this, &SLevelViewportToolBar::GetCameraMenuLabel )
|
|
.LabelIcon( this, &SLevelViewportToolBar::GetCameraMenuLabelIcon )
|
|
.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.CameraMenu")))
|
|
.OnGetMenuContent( this, &SLevelViewportToolBar::GenerateCameraMenu )
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
SNew( SLevelEditorViewportViewMenu, ViewportRef, SharedThis(this) )
|
|
.Cursor( EMouseCursor::Default )
|
|
.MenuExtenders( GetViewMenuExtender() )
|
|
.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ViewMenuButton")))
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
SNew( SEditorViewportToolbarMenu )
|
|
.Label( LOCTEXT("ShowMenuTitle", "Show") )
|
|
.Cursor( EMouseCursor::Default )
|
|
.ParentToolBar( SharedThis( this ) )
|
|
.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.ShowMenu")))
|
|
.OnGetMenuContent( this, &SLevelViewportToolBar::GenerateShowMenu )
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
|
|
SNew( SEditorViewportToolbarMenu )
|
|
.Label( this, &SLevelViewportToolBar::GetViewModeOptionsMenuLabel )
|
|
.Cursor( EMouseCursor::Default )
|
|
.ParentToolBar( SharedThis( this ) )
|
|
.Visibility( this, &SLevelViewportToolBar::GetViewModeOptionsVisibility )
|
|
.AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.ViewModeOptions")))
|
|
.OnGetMenuContent( this, &SLevelViewportToolBar::GenerateViewModeOptionsMenu )
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( ToolbarSlotPadding )
|
|
[
|
|
SNew( SEditorViewportToolbarMenu )
|
|
.ParentToolBar( SharedThis( this ) )
|
|
.Cursor( EMouseCursor::Default )
|
|
.Label( this, &SLevelViewportToolBar::GetDevicePreviewMenuLabel )
|
|
.LabelIcon( this, &SLevelViewportToolBar::GetDevicePreviewMenuLabelIcon )
|
|
.OnGetMenuContent( this, &SLevelViewportToolBar::GenerateDevicePreviewMenu )
|
|
//@todo rendering: mobile preview in view port is not functional yet - remove this once it is.
|
|
.Visibility(EVisibility::Collapsed)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.Padding( ToolbarSlotPadding )
|
|
.HAlign( HAlign_Right )
|
|
[
|
|
SNew(STransformViewportToolBar)
|
|
.Viewport(ViewportRef)
|
|
.CommandList(LevelEditorModule.GetGlobalLevelEditorActions())
|
|
.Extenders(LevelEditorModule.GetToolBarExtensibilityManager()->GetAllExtenders())
|
|
.Visibility(ViewportRef, &SLevelViewport::GetTransformToolbarVisibility)
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.HAlign( HAlign_Right )
|
|
.AutoWidth()
|
|
.Padding( ToolbarButtonPadding )
|
|
[
|
|
//The Maximize/Minimize button is only displayed when not in Immersive mode.
|
|
SNew( SEditorViewportToolBarButton )
|
|
.Cursor( EMouseCursor::Default )
|
|
.ButtonType( EUserInterfaceActionType::ToggleButton )
|
|
.IsChecked( ViewportRef, &SLevelViewport::IsMaximized )
|
|
.OnClicked( ViewportRef, &SLevelViewport::OnToggleMaximize )
|
|
.Visibility( ViewportRef, &SLevelViewport::GetMaximizeToggleVisibility )
|
|
.Image( "LevelViewportToolBar.Maximize" )
|
|
.ToolTipText( LOCTEXT("Maximize_ToolTip", "Maximizes or restores this viewport") )
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.HAlign( HAlign_Right )
|
|
.AutoWidth()
|
|
.Padding( ToolbarButtonPadding )
|
|
[
|
|
//The Restore from Immersive' button is only displayed when the editor is in Immersive mode.
|
|
SNew( SEditorViewportToolBarButton )
|
|
.Cursor( EMouseCursor::Default )
|
|
.ButtonType( EUserInterfaceActionType::Button )
|
|
.OnClicked( ViewportRef, &SLevelViewport::OnToggleMaximize )
|
|
.Visibility( ViewportRef, &SLevelViewport::GetCloseImmersiveButtonVisibility )
|
|
.Image( "LevelViewportToolBar.RestoreFromImmersive.Normal" )
|
|
.ToolTipText( LOCTEXT("RestoreFromImmersive_ToolTip", "Restore from Immersive") )
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
SViewportToolBar::Construct(SViewportToolBar::FArguments());
|
|
}
|
|
|
|
bool SLevelViewportToolBar::IsViewModeSupported(EViewModeIndex ViewModeIndex) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
|
|
FText SLevelViewportToolBar::GetCameraMenuLabel() const
|
|
{
|
|
TSharedPtr< SLevelViewport > PinnedViewport( Viewport.Pin() );
|
|
if( PinnedViewport.IsValid() )
|
|
{
|
|
return GetCameraMenuLabelFromViewportType( PinnedViewport->GetLevelViewportClient().ViewportType );
|
|
}
|
|
|
|
return LOCTEXT("CameraMenuTitle_Default", "Camera");
|
|
}
|
|
|
|
FText SLevelViewportToolBar::GetDevicePreviewMenuLabel() const
|
|
{
|
|
FText Label = LOCTEXT("DevicePreviewMenuTitle_Default", "Preview");
|
|
|
|
TSharedPtr< SLevelViewport > PinnedViewport( Viewport.Pin() );
|
|
if( PinnedViewport.IsValid() )
|
|
{
|
|
if ( PinnedViewport->GetDeviceProfileString() != "Default" )
|
|
{
|
|
Label = FText::FromString( PinnedViewport->GetDeviceProfileString() );
|
|
}
|
|
}
|
|
|
|
return Label;
|
|
}
|
|
|
|
const FSlateBrush* SLevelViewportToolBar::GetDevicePreviewMenuLabelIcon() const
|
|
{
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
FString DeviceProfileName = ViewportRef->GetDeviceProfileString();
|
|
|
|
FName PlatformIcon = NAME_None;
|
|
if( !DeviceProfileName.IsEmpty() && DeviceProfileName != "Default" )
|
|
{
|
|
static FName DeviceProfileServices( "DeviceProfileServices" );
|
|
|
|
IDeviceProfileServicesModule& ScreenDeviceProfileUIServices = FModuleManager::LoadModuleChecked<IDeviceProfileServicesModule>(TEXT( "DeviceProfileServices"));
|
|
IDeviceProfileServicesUIManagerPtr UIManager = ScreenDeviceProfileUIServices.GetProfileServicesManager();
|
|
|
|
PlatformIcon = UIManager->GetDeviceIconName( DeviceProfileName );
|
|
|
|
return FEditorStyle::GetOptionalBrush( PlatformIcon );
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const FSlateBrush* SLevelViewportToolBar::GetCameraMenuLabelIcon() const
|
|
{
|
|
TSharedPtr< SLevelViewport > PinnedViewport( Viewport.Pin() );
|
|
if( PinnedViewport.IsValid() )
|
|
{
|
|
return GetCameraMenuLabelIconFromViewportType(PinnedViewport->GetLevelViewportClient().ViewportType);
|
|
}
|
|
|
|
return FEditorStyle::GetBrush(NAME_None);
|
|
}
|
|
|
|
bool SLevelViewportToolBar::IsCurrentLevelViewport() const
|
|
{
|
|
TSharedPtr< SLevelViewport > PinnedViewport( Viewport.Pin() );
|
|
if( PinnedViewport.IsValid() )
|
|
{
|
|
if( &( PinnedViewport->GetLevelViewportClient() ) == GCurrentLevelEditingViewportClient )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SLevelViewportToolBar::IsPerspectiveViewport() const
|
|
{
|
|
TSharedPtr< SLevelViewport > PinnedViewport( Viewport.Pin() );
|
|
if( PinnedViewport.IsValid() )
|
|
{
|
|
if( PinnedViewport->GetLevelViewportClient().IsPerspective() )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Called to generate the set bookmark submenu
|
|
*/
|
|
static void OnGenerateSetBookmarkMenu( FMenuBuilder& MenuBuilder , TWeakPtr<class SLevelViewport> Viewport )
|
|
{
|
|
// Add a menu entry for each bookmark
|
|
FEditorModeTools& Tools = GLevelEditorModeTools();
|
|
TSharedPtr<SLevelViewport> SharedViewport = Viewport.Pin();
|
|
FLevelEditorViewportClient& ViewportClient = SharedViewport->GetLevelViewportClient();
|
|
|
|
const int32 NumberOfBookmarks = static_cast<int32>(Tools.GetMaxNumberOfBookmarks(&ViewportClient));
|
|
const int32 NumberOfMappedBookmarks = FMath::Min<int32>(AWorldSettings::NumMappedBookmarks, NumberOfBookmarks);
|
|
|
|
for( int32 BookmarkIndex = 0; BookmarkIndex < NumberOfMappedBookmarks; ++BookmarkIndex )
|
|
{
|
|
MenuBuilder.AddMenuEntry( FLevelViewportCommands::Get().SetBookmarkCommands[ BookmarkIndex ], NAME_None, FBookmarkUI::GetPlainLabel(BookmarkIndex) );
|
|
}
|
|
|
|
// Only mapped bookmarks will have predefined actions.
|
|
// So, create any additional actions we need to hit the max number of bookmarks.
|
|
for (int32 BookmarkIndex = NumberOfMappedBookmarks; BookmarkIndex < NumberOfBookmarks; ++BookmarkIndex)
|
|
{
|
|
FUIAction Action;
|
|
Action.ExecuteAction.BindSP(SharedViewport.ToSharedRef(), &SLevelViewport::OnSetBookmark, BookmarkIndex);
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
FBookmarkUI::GetPlainLabel(BookmarkIndex),
|
|
FBookmarkUI::GetSetTooltip(BookmarkIndex),
|
|
FBookmarkUI::GetDefaultIcon(),
|
|
Action);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to generate the clear bookmark submenu
|
|
*/
|
|
static void OnGenerateClearBookmarkMenu( FMenuBuilder& MenuBuilder , TWeakPtr<class SLevelViewport> Viewport )
|
|
{
|
|
// Add a menu entry for each bookmark
|
|
FEditorModeTools& Tools = GLevelEditorModeTools();
|
|
TSharedPtr<SLevelViewport> SharedViewport = Viewport.Pin();
|
|
FLevelEditorViewportClient& ViewportClient = SharedViewport->GetLevelViewportClient();
|
|
|
|
const int32 NumberOfBookmarks = static_cast<int32>(Tools.GetMaxNumberOfBookmarks(&ViewportClient));
|
|
const int32 NumberOfMappedBookmarks = FMath::Min<int32>(AWorldSettings::NumMappedBookmarks, NumberOfBookmarks);
|
|
|
|
for( int32 BookmarkIndex = 0; BookmarkIndex < NumberOfMappedBookmarks; ++BookmarkIndex )
|
|
{
|
|
if ( Tools.CheckBookmark( BookmarkIndex , &ViewportClient ) )
|
|
{
|
|
MenuBuilder.AddMenuEntry( FLevelViewportCommands::Get().ClearBookmarkCommands[ BookmarkIndex ], NAME_None, FBookmarkUI::GetPlainLabel(BookmarkIndex) );
|
|
}
|
|
}
|
|
|
|
for (int32 BookmarkIndex = NumberOfMappedBookmarks; BookmarkIndex < NumberOfBookmarks; ++BookmarkIndex)
|
|
{
|
|
if ( Tools.CheckBookmark(BookmarkIndex, &ViewportClient) )
|
|
{
|
|
FUIAction Action;
|
|
Action.ExecuteAction.BindSP(SharedViewport.ToSharedRef(), &SLevelViewport::OnClearBookmark, BookmarkIndex);
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
FBookmarkUI::GetPlainLabel(BookmarkIndex),
|
|
FBookmarkUI::GetClearTooltip(BookmarkIndex),
|
|
FBookmarkUI::GetDefaultIcon(),
|
|
Action);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to generate the jump to bookmark menu.
|
|
*/
|
|
static bool GenerateJumpToBookmarkMenu( FMenuBuilder& MenuBuilder , TWeakPtr<class SLevelViewport> Viewport )
|
|
{
|
|
// Add a menu entry for each bookmark
|
|
|
|
FEditorModeTools& Tools = GLevelEditorModeTools();
|
|
TSharedPtr<SLevelViewport> SharedViewport = Viewport.Pin();
|
|
FLevelEditorViewportClient& ViewportClient = SharedViewport->GetLevelViewportClient();
|
|
|
|
const int32 NumberOfBookmarks = static_cast<int32>(Tools.GetMaxNumberOfBookmarks(&ViewportClient));
|
|
const int32 NumberOfMappedBookmarks = FMath::Min<int32>(AWorldSettings::NumMappedBookmarks, NumberOfBookmarks);
|
|
|
|
bool bFoundAnyBookmarks = false;
|
|
|
|
for( int32 BookmarkIndex = 0; BookmarkIndex < NumberOfMappedBookmarks; ++BookmarkIndex )
|
|
{
|
|
if ( Tools.CheckBookmark( BookmarkIndex , &ViewportClient ) )
|
|
{
|
|
bFoundAnyBookmarks = true;
|
|
MenuBuilder.AddMenuEntry( FLevelViewportCommands::Get().JumpToBookmarkCommands[ BookmarkIndex ] );
|
|
}
|
|
}
|
|
|
|
for (int32 BookmarkIndex = NumberOfMappedBookmarks; BookmarkIndex < NumberOfBookmarks; ++BookmarkIndex)
|
|
{
|
|
if ( Tools.CheckBookmark(BookmarkIndex, &ViewportClient) )
|
|
{
|
|
bFoundAnyBookmarks = true;
|
|
|
|
FUIAction Action;
|
|
Action.ExecuteAction.BindSP(SharedViewport.ToSharedRef(), &SLevelViewport::OnJumpToBookmark, BookmarkIndex);
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
FBookmarkUI::GetJumpToLabel(BookmarkIndex),
|
|
FBookmarkUI::GetJumpToTooltip(BookmarkIndex),
|
|
FBookmarkUI::GetDefaultIcon(),
|
|
Action);
|
|
}
|
|
}
|
|
|
|
return bFoundAnyBookmarks;
|
|
}
|
|
|
|
/**
|
|
* Called to generate the bookmark submenu
|
|
*/
|
|
static void OnGenerateBookmarkMenu( FMenuBuilder& MenuBuilder , TWeakPtr<class SLevelViewport> Viewport )
|
|
{
|
|
FEditorModeTools& Tools = GLevelEditorModeTools();
|
|
|
|
// true if a bookmark was found.
|
|
bool bFoundBookmark = false;
|
|
|
|
// Get the viewport client to pass down to the CheckBookmark function
|
|
FLevelEditorViewportClient& ViewportClient = Viewport.Pin()->GetLevelViewportClient();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportActiveBoookmarks", LOCTEXT("JumpToBookmarkHeader", "Active Bookmarks") );
|
|
|
|
const bool bFoundBookmarks = GenerateJumpToBookmarkMenu( MenuBuilder, Viewport );
|
|
|
|
MenuBuilder.EndSection();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportBookmarkSubmenus");
|
|
{
|
|
MenuBuilder.AddSubMenu(
|
|
LOCTEXT("SetBookmarkSubMenu", "Set Bookmark"),
|
|
LOCTEXT("SetBookmarkSubMenu_ToolTip", "Set viewport bookmarks"),
|
|
FNewMenuDelegate::CreateStatic( &OnGenerateSetBookmarkMenu, Viewport )
|
|
);
|
|
|
|
const FLevelViewportCommands& Actions = FLevelViewportCommands::Get();
|
|
MenuBuilder.AddMenuEntry( Actions.CompactBookmarks );
|
|
|
|
if( bFoundBookmarks )
|
|
{
|
|
MenuBuilder.AddSubMenu(
|
|
LOCTEXT("ClearBookmarkSubMenu", "Clear Bookmark"),
|
|
LOCTEXT("ClearBookmarkSubMenu_ToolTip", "Clear viewport bookmarks"),
|
|
FNewMenuDelegate::CreateStatic( &OnGenerateClearBookmarkMenu , Viewport )
|
|
);
|
|
|
|
MenuBuilder.AddMenuEntry( Actions.ClearAllBookmarks );
|
|
}
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateOptionsMenu() const
|
|
{
|
|
Viewport.Pin()->OnFloatingButtonClicked();
|
|
|
|
const FLevelViewportCommands& LevelViewportActions = FLevelViewportCommands::Get();
|
|
|
|
// Get all menu extenders for this context menu from the level editor module
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>( TEXT("LevelEditor") );
|
|
TArray<FLevelEditorModule::FLevelEditorMenuExtender> MenuExtenderDelegates = LevelEditorModule.GetAllLevelViewportOptionsMenuExtenders();
|
|
|
|
TArray<TSharedPtr<FExtender>> Extenders;
|
|
for (int32 i = 0; i < MenuExtenderDelegates.Num(); ++i)
|
|
{
|
|
if (MenuExtenderDelegates[i].IsBound())
|
|
{
|
|
Extenders.Add(MenuExtenderDelegates[i].Execute(Viewport.Pin()->GetCommandList().ToSharedRef()));
|
|
}
|
|
}
|
|
TSharedPtr<FExtender> MenuExtender = FExtender::Combine(Extenders);
|
|
|
|
const bool bIsPerspective = Viewport.Pin()->GetLevelViewportClient().IsPerspective();
|
|
const bool bInShouldCloseWindowAfterMenuSelection = true;
|
|
FMenuBuilder OptionsMenuBuilder( bInShouldCloseWindowAfterMenuSelection, Viewport.Pin()->GetCommandList(), MenuExtender );
|
|
{
|
|
OptionsMenuBuilder.BeginSection("LevelViewportViewportOptions", LOCTEXT("OptionsMenuHeader", "Viewport Options") );
|
|
{
|
|
OptionsMenuBuilder.AddMenuEntry( FEditorViewportCommands::Get().ToggleRealTime );
|
|
OptionsMenuBuilder.AddMenuEntry( FEditorViewportCommands::Get().ToggleStats );
|
|
OptionsMenuBuilder.AddMenuEntry( FEditorViewportCommands::Get().ToggleFPS );
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.ToggleViewportToolbar );
|
|
|
|
FText HideAllLabel = LOCTEXT("HideAllLabel", "Hide All");
|
|
TArray< FLevelViewportCommands::FShowMenuCommand > HideStatsMenu;
|
|
|
|
// 'Hide All' button
|
|
HideStatsMenu.Add(FLevelViewportCommands::FShowMenuCommand(LevelViewportActions.HideAllStats, HideAllLabel));
|
|
|
|
OptionsMenuBuilder.AddSubMenu(
|
|
LOCTEXT("ShowStatsMenu", "Stat"),
|
|
LOCTEXT("ShowStatsMenu_ToolTip", "Show Stat commands"),
|
|
FNewMenuDelegate::CreateStatic(&FillShowStatsSubMenus, HideStatsMenu, LevelViewportActions.ShowStatCatCommands));
|
|
|
|
if( bIsPerspective )
|
|
{
|
|
OptionsMenuBuilder.AddWidget( GenerateFOVMenu(), LOCTEXT("FOVAngle", "Field of View (H)") );
|
|
OptionsMenuBuilder.AddWidget( GenerateFarViewPlaneMenu(), LOCTEXT("FarViewPlane", "Far View Plane") );
|
|
}
|
|
|
|
OptionsMenuBuilder.AddWidget(GenerateScreenPercentageMenu(), LOCTEXT("ScreenPercentage", "Screen Percentage"));
|
|
}
|
|
OptionsMenuBuilder.EndSection();
|
|
|
|
OptionsMenuBuilder.BeginSection("LevelViewportViewportOptions2");
|
|
{
|
|
if( bIsPerspective )
|
|
{
|
|
// Cinematic preview only applies to perspective
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.ToggleCinematicPreview );
|
|
}
|
|
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.ToggleGameView );
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.ToggleImmersive );
|
|
}
|
|
OptionsMenuBuilder.EndSection();
|
|
|
|
if( bIsPerspective )
|
|
{
|
|
// Bookmarks only work in perspective viewports so only show the menu option if this toolbar is in one
|
|
|
|
OptionsMenuBuilder.BeginSection("LevelViewportBookmarks");
|
|
{
|
|
OptionsMenuBuilder.AddSubMenu(
|
|
LOCTEXT("BookmarkSubMenu", "Bookmarks"),
|
|
LOCTEXT("BookmarkSubMenu_ToolTip", "Viewport location bookmarking"),
|
|
FNewMenuDelegate::CreateStatic( &OnGenerateBookmarkMenu , Viewport )
|
|
);
|
|
}
|
|
OptionsMenuBuilder.EndSection();
|
|
|
|
OptionsMenuBuilder.AddSubMenu(
|
|
LOCTEXT("CameraSubMeun", "Create Camera Here"),
|
|
LOCTEXT("CameraSubMenu_ToolTip", "Select a camera type to create at current viewport's location"),
|
|
FNewMenuDelegate::CreateSP(this, &SLevelViewportToolBar::GenerateCameraSpawnMenu)
|
|
);
|
|
|
|
}
|
|
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.HighResScreenshot );
|
|
|
|
OptionsMenuBuilder.BeginSection("LevelViewportLayouts");
|
|
{
|
|
OptionsMenuBuilder.AddSubMenu(
|
|
LOCTEXT("ConfigsSubMenu", "Layouts"),
|
|
FText::GetEmpty(),
|
|
FNewMenuDelegate::CreateSP(this, &SLevelViewportToolBar::GenerateViewportConfigsMenu));
|
|
}
|
|
OptionsMenuBuilder.EndSection();
|
|
|
|
OptionsMenuBuilder.BeginSection("LevelViewportSettings");
|
|
{
|
|
OptionsMenuBuilder.AddMenuEntry( LevelViewportActions.AdvancedSettings );
|
|
}
|
|
OptionsMenuBuilder.EndSection();
|
|
}
|
|
|
|
return OptionsMenuBuilder.MakeWidget();
|
|
}
|
|
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateDevicePreviewMenu() const
|
|
{
|
|
IDeviceProfileServicesModule& ScreenDeviceProfileUIServices = FModuleManager::LoadModuleChecked<IDeviceProfileServicesModule>(TEXT( "DeviceProfileServices"));
|
|
IDeviceProfileServicesUIManagerPtr UIManager = ScreenDeviceProfileUIServices.GetProfileServicesManager();
|
|
|
|
// Create the menu
|
|
const bool bInShouldCloseWindowAfterMenuSelection = true;
|
|
FMenuBuilder DeviceMenuBuilder( bInShouldCloseWindowAfterMenuSelection, Viewport.Pin()->GetCommandList() );
|
|
|
|
DeviceMenuBuilder.BeginSection( "DevicePreview", LOCTEXT("DevicePreviewMenuTitle", "Device Preview") );
|
|
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
|
|
// Default menu - clear all settings
|
|
{
|
|
FUIAction Action( FExecuteAction::CreateSP( this, &SLevelViewportToolBar::SetLevelProfile, FString( "Default" ) ),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP( ViewportRef, &SLevelViewport::IsDeviceProfileStringSet, FString( "Default" ) ) );
|
|
DeviceMenuBuilder.AddMenuEntry( LOCTEXT("DevicePreviewMenuClear", "Off"), FText::GetEmpty(), FSlateIcon(), Action, NAME_None, EUserInterfaceActionType::Button );
|
|
}
|
|
|
|
DeviceMenuBuilder.EndSection();
|
|
|
|
// Recent Device Profiles
|
|
DeviceMenuBuilder.BeginSection( "Recent", LOCTEXT("RecentMenuHeading", "Recent") );
|
|
|
|
const FString INISection = "SelectedProfile";
|
|
const FString INIKeyBase = "ProfileItem";
|
|
const int32 MaxItems = 4; // Move this into a config file
|
|
FString CurItem;
|
|
for( int32 ItemIdx = 0 ; ItemIdx < MaxItems; ++ItemIdx )
|
|
{
|
|
// Build the menu from the contents of the game ini
|
|
//@todo This should probably be using GConfig->GetText [10/21/2013 justin.sargent]
|
|
if ( GConfig->GetString( *INISection, *FString::Printf( TEXT("%s%d"), *INIKeyBase, ItemIdx ), CurItem, GEditorPerProjectIni ) )
|
|
{
|
|
const FName PlatformIcon = UIManager->GetDeviceIconName( CurItem );
|
|
|
|
FUIAction Action( FExecuteAction::CreateSP( this, &SLevelViewportToolBar::SetLevelProfile, CurItem ),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP( ViewportRef, &SLevelViewport::IsDeviceProfileStringSet, CurItem ) );
|
|
DeviceMenuBuilder.AddMenuEntry( FText::FromString( CurItem ), FText(), FSlateIcon(FEditorStyle::GetStyleSetName(), PlatformIcon), Action, NAME_None, EUserInterfaceActionType::Button );
|
|
}
|
|
}
|
|
|
|
DeviceMenuBuilder.EndSection();
|
|
|
|
// Device List
|
|
DeviceMenuBuilder.BeginSection( "Devices", LOCTEXT("DevicesMenuHeading", "Devices") );
|
|
|
|
const TArray<TSharedPtr<FString> > PlatformList = UIManager->GetPlatformList();
|
|
for ( int32 Index = 0; Index < PlatformList.Num(); Index++ )
|
|
{
|
|
TArray< UDeviceProfile* > DeviceProfiles;
|
|
UIManager->GetProfilesByType( DeviceProfiles, *PlatformList[Index] );
|
|
if ( DeviceProfiles.Num() > 0 )
|
|
{
|
|
const FString PlatformNameStr = DeviceProfiles[0]->DeviceType;
|
|
const FName PlatformIcon = UIManager->GetPlatformIconName( PlatformNameStr );
|
|
DeviceMenuBuilder.AddSubMenu(
|
|
FText::FromString( PlatformNameStr ),
|
|
FText::GetEmpty(),
|
|
FNewMenuDelegate::CreateRaw( this, &SLevelViewportToolBar::MakeDevicePreviewSubMenu, DeviceProfiles ),
|
|
false,
|
|
FSlateIcon(FEditorStyle::GetStyleSetName(), PlatformIcon)
|
|
);
|
|
}
|
|
}
|
|
DeviceMenuBuilder.EndSection();
|
|
|
|
return DeviceMenuBuilder.MakeWidget();
|
|
}
|
|
|
|
void SLevelViewportToolBar::MakeDevicePreviewSubMenu(FMenuBuilder& MenuBuilder, TArray< class UDeviceProfile* > InProfiles )
|
|
{
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
|
|
for ( int32 Index = 0; Index < InProfiles.Num(); Index++ )
|
|
{
|
|
FUIAction Action( FExecuteAction::CreateSP( this, &SLevelViewportToolBar::SetLevelProfile, InProfiles[ Index ]->GetName() ),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP( ViewportRef, &SLevelViewport::IsDeviceProfileStringSet, InProfiles[ Index ]->GetName() ) );
|
|
|
|
MenuBuilder.AddMenuEntry( FText::FromString( InProfiles[ Index ]->GetName() ), FText(), FSlateIcon(), Action, NAME_None, EUserInterfaceActionType::RadioButton );
|
|
}
|
|
}
|
|
|
|
void SLevelViewportToolBar::SetLevelProfile( FString DeviceProfileName )
|
|
{
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
ViewportRef->SetDeviceProfileString( DeviceProfileName );
|
|
|
|
IDeviceProfileServicesModule& ScreenDeviceProfileUIServices = FModuleManager::LoadModuleChecked<IDeviceProfileServicesModule>(TEXT( "DeviceProfileServices"));
|
|
IDeviceProfileServicesUIManagerPtr UIManager = ScreenDeviceProfileUIServices.GetProfileServicesManager();
|
|
UIManager->SetProfile( DeviceProfileName );
|
|
}
|
|
|
|
void SLevelViewportToolBar::GeneratePlacedCameraMenuEntries( FMenuBuilder& Builder, TArray<ACameraActor*> Cameras ) const
|
|
{
|
|
FSlateIcon CameraIcon( FEditorStyle::GetStyleSetName(), "ClassIcon.CameraComponent" );
|
|
|
|
for( ACameraActor* CameraActor : Cameras )
|
|
{
|
|
// Needed for the delegate hookup to work below
|
|
AActor* GenericActor = CameraActor;
|
|
|
|
FText ActorDisplayName = FText::FromString(CameraActor->GetActorLabel());
|
|
FUIAction LookThroughCameraAction(
|
|
FExecuteAction::CreateSP(Viewport.Pin().ToSharedRef(), &SLevelViewport::OnActorLockToggleFromMenu, GenericActor),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(Viewport.Pin().ToSharedRef(), &SLevelViewport::IsActorLocked, MakeWeakObjectPtr(GenericActor))
|
|
);
|
|
|
|
Builder.AddMenuEntry( ActorDisplayName, FText::Format(LOCTEXT("LookThroughCameraActor_ToolTip", "Look through and pilot {0}"), ActorDisplayName), CameraIcon, LookThroughCameraAction, NAME_None, EUserInterfaceActionType::RadioButton );
|
|
}
|
|
}
|
|
|
|
void SLevelViewportToolBar::GenerateViewportTypeMenu( FMenuBuilder& Builder ) const
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
|
|
LevelEditorModule.IterateViewportTypes([&](FName, const FViewportTypeDefinition& InDefinition) {
|
|
if (InDefinition.ActivationCommand.IsValid())
|
|
{
|
|
Builder.AddMenuEntry(InDefinition.ActivationCommand);
|
|
}
|
|
});
|
|
}
|
|
|
|
void SLevelViewportToolBar::GenerateCameraSpawnMenu(FMenuBuilder & Builder) const
|
|
{
|
|
const FLevelViewportCommands& Actions = FLevelViewportCommands::Get();
|
|
|
|
for (TSharedPtr<FUICommandInfo> Camera : Actions.CreateCameras)
|
|
{
|
|
Builder.AddMenuEntry(Camera);
|
|
}
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateCameraMenu() const
|
|
{
|
|
Viewport.Pin()->OnFloatingButtonClicked();
|
|
|
|
const bool bInShouldCloseWindowAfterMenuSelection = true;
|
|
FMenuBuilder CameraMenuBuilder( bInShouldCloseWindowAfterMenuSelection, Viewport.Pin()->GetCommandList() );
|
|
|
|
// Camera types
|
|
CameraMenuBuilder.AddMenuEntry( FEditorViewportCommands::Get().Perspective );
|
|
|
|
CameraMenuBuilder.BeginSection("LevelViewportCameraType_Ortho", LOCTEXT("CameraTypeHeader_Ortho", "Orthographic") );
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Top);
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Bottom);
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Left);
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Right);
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Front);
|
|
CameraMenuBuilder.AddMenuEntry(FEditorViewportCommands::Get().Back);
|
|
CameraMenuBuilder.EndSection();
|
|
|
|
TArray<ACameraActor*> Cameras;
|
|
|
|
for( TActorIterator<ACameraActor> It(GetWorld().Get()); It; ++It )
|
|
{
|
|
Cameras.Add( *It );
|
|
}
|
|
|
|
FText CameraActorsHeading = LOCTEXT("CameraActorsHeading", "Placed Cameras");
|
|
|
|
// Don't add too many cameras to the top level menu or else it becomes too large
|
|
const uint32 MaxCamerasInTopLevelMenu = 10;
|
|
if( Cameras.Num() > MaxCamerasInTopLevelMenu )
|
|
{
|
|
CameraMenuBuilder.BeginSection("CameraActors");
|
|
CameraMenuBuilder.AddSubMenu( CameraActorsHeading, LOCTEXT("LookThroughPlacedCameras_ToolTip", "Look through and pilot placed cameras"), FNewMenuDelegate::CreateSP(this, &SLevelViewportToolBar::GeneratePlacedCameraMenuEntries, Cameras ) );
|
|
CameraMenuBuilder.EndSection();
|
|
}
|
|
else
|
|
{
|
|
CameraMenuBuilder.BeginSection("CameraActors", CameraActorsHeading );
|
|
GeneratePlacedCameraMenuEntries( CameraMenuBuilder, Cameras );
|
|
CameraMenuBuilder.EndSection();
|
|
}
|
|
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
|
|
|
|
int32 NumCustomViewportTypes = 0;
|
|
LevelEditorModule.IterateViewportTypes([&](FName, const FViewportTypeDefinition&){ ++NumCustomViewportTypes; });
|
|
|
|
FText ViewportTypesHeading = LOCTEXT("ViewportTypes", "Viewport Type");
|
|
const uint32 MaxViewportTypesInTopLevelMenu = 4;
|
|
if( NumCustomViewportTypes > MaxViewportTypesInTopLevelMenu )
|
|
{
|
|
CameraMenuBuilder.BeginSection("ViewportTypes");
|
|
CameraMenuBuilder.AddSubMenu( ViewportTypesHeading, FText(), FNewMenuDelegate::CreateSP(this, &SLevelViewportToolBar::GenerateViewportTypeMenu) );
|
|
CameraMenuBuilder.EndSection();
|
|
}
|
|
else
|
|
{
|
|
CameraMenuBuilder.BeginSection("ViewportTypes", ViewportTypesHeading);
|
|
GenerateViewportTypeMenu(CameraMenuBuilder);
|
|
CameraMenuBuilder.EndSection();
|
|
|
|
}
|
|
CameraMenuBuilder.EndSection();
|
|
}
|
|
|
|
return CameraMenuBuilder.MakeWidget();
|
|
}
|
|
|
|
void SLevelViewportToolBar::GenerateViewportConfigsMenu(FMenuBuilder& MenuBuilder) const
|
|
{
|
|
check (Viewport.IsValid());
|
|
TSharedPtr<FUICommandList> CommandList = Viewport.Pin()->GetCommandList();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportOnePaneConfigs", LOCTEXT("OnePaneConfigHeader", "One Pane"));
|
|
{
|
|
FToolBarBuilder OnePaneButton(CommandList, FMultiBoxCustomization::None);
|
|
OnePaneButton.SetLabelVisibility(EVisibility::Collapsed);
|
|
OnePaneButton.SetStyle(&FEditorStyle::Get(), "ViewportLayoutToolbar");
|
|
|
|
OnePaneButton.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_OnePane);
|
|
|
|
MenuBuilder.AddWidget(
|
|
SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
OnePaneButton.MakeWidget()
|
|
]
|
|
+ SHorizontalBox::Slot()
|
|
.FillWidth(1)
|
|
[
|
|
SNullWidget::NullWidget
|
|
],
|
|
FText::GetEmpty(), true
|
|
);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportTwoPaneConfigs", LOCTEXT("TwoPaneConfigHeader", "Two Panes") );
|
|
{
|
|
FToolBarBuilder TwoPaneButtons(CommandList, FMultiBoxCustomization::None);
|
|
TwoPaneButtons.SetLabelVisibility(EVisibility::Collapsed);
|
|
TwoPaneButtons.SetStyle(&FEditorStyle::Get(), "ViewportLayoutToolbar");
|
|
|
|
TwoPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_TwoPanesH, NAME_None, FText());
|
|
TwoPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_TwoPanesV, NAME_None, FText());
|
|
|
|
MenuBuilder.AddWidget(
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
TwoPaneButtons.MakeWidget()
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1)
|
|
[
|
|
SNullWidget::NullWidget
|
|
],
|
|
FText::GetEmpty(), true
|
|
);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportThreePaneConfigs", LOCTEXT("ThreePaneConfigHeader", "Three Panes") );
|
|
{
|
|
FToolBarBuilder ThreePaneButtons(CommandList, FMultiBoxCustomization::None);
|
|
ThreePaneButtons.SetLabelVisibility(EVisibility::Collapsed);
|
|
ThreePaneButtons.SetStyle(&FEditorStyle::Get(), "ViewportLayoutToolbar");
|
|
|
|
ThreePaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_ThreePanesLeft, NAME_None, FText());
|
|
ThreePaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_ThreePanesRight, NAME_None, FText());
|
|
ThreePaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_ThreePanesTop, NAME_None, FText());
|
|
ThreePaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_ThreePanesBottom, NAME_None, FText());
|
|
|
|
MenuBuilder.AddWidget(
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
ThreePaneButtons.MakeWidget()
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1)
|
|
[
|
|
SNullWidget::NullWidget
|
|
],
|
|
FText::GetEmpty(), true
|
|
);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
MenuBuilder.BeginSection("LevelViewportFourPaneConfigs", LOCTEXT("FourPaneConfigHeader", "Four Panes") );
|
|
{
|
|
FToolBarBuilder FourPaneButtons(CommandList, FMultiBoxCustomization::None);
|
|
FourPaneButtons.SetLabelVisibility(EVisibility::Collapsed);
|
|
FourPaneButtons.SetStyle(&FEditorStyle::Get(), "ViewportLayoutToolbar");
|
|
|
|
FourPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_FourPanes2x2, NAME_None, FText());
|
|
FourPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_FourPanesLeft, NAME_None, FText());
|
|
FourPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_FourPanesRight, NAME_None, FText());
|
|
FourPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_FourPanesTop, NAME_None, FText());
|
|
FourPaneButtons.AddToolBarButton(FLevelViewportCommands::Get().ViewportConfig_FourPanesBottom, NAME_None, FText());
|
|
|
|
MenuBuilder.AddWidget(
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
FourPaneButtons.MakeWidget()
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1)
|
|
[
|
|
SNullWidget::NullWidget
|
|
],
|
|
FText::GetEmpty(), true
|
|
);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateShowMenu() const
|
|
{
|
|
Viewport.Pin()->OnFloatingButtonClicked();
|
|
|
|
const FLevelViewportCommands& Actions = FLevelViewportCommands::Get();
|
|
|
|
// Get all menu extenders for this context menu from the level editor module
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
|
|
TArray<FLevelEditorModule::FLevelEditorMenuExtender> MenuExtenderDelegates = LevelEditorModule.GetAllLevelViewportShowMenuExtenders();
|
|
|
|
TArray<TSharedPtr<FExtender>> Extenders;
|
|
for (int32 i = 0; i < MenuExtenderDelegates.Num(); ++i)
|
|
{
|
|
if (MenuExtenderDelegates[i].IsBound())
|
|
{
|
|
Extenders.Add(MenuExtenderDelegates[i].Execute(Viewport.Pin()->GetCommandList().ToSharedRef()));
|
|
}
|
|
}
|
|
TSharedPtr<FExtender> MenuExtender = FExtender::Combine(Extenders);
|
|
|
|
const bool bInShouldCloseWindowAfterMenuSelection = true;
|
|
FMenuBuilder ShowMenuBuilder( bInShouldCloseWindowAfterMenuSelection, Viewport.Pin()->GetCommandList(), MenuExtender);
|
|
{
|
|
ShowMenuBuilder.AddMenuEntry(Actions.UseDefaultShowFlags);
|
|
FShowFlagMenuCommands::Get().BuildShowFlagsMenu(ShowMenuBuilder);
|
|
|
|
FText ShowAllLabel = LOCTEXT("ShowAllLabel", "Show All");
|
|
FText HideAllLabel = LOCTEXT("HideAllLabel", "Hide All");
|
|
|
|
ShowMenuBuilder.BeginSection("LevelViewportEditorShow", LOCTEXT("EditorShowHeader", "Editor"));
|
|
{
|
|
// Show Volumes sub-menu
|
|
{
|
|
TArray< FLevelViewportCommands::FShowMenuCommand > ShowVolumesMenu;
|
|
|
|
// 'Show All' and 'Hide All' buttons
|
|
ShowVolumesMenu.Add(FLevelViewportCommands::FShowMenuCommand(Actions.ShowAllVolumes, ShowAllLabel));
|
|
ShowVolumesMenu.Add(FLevelViewportCommands::FShowMenuCommand(Actions.HideAllVolumes, HideAllLabel));
|
|
|
|
// Get each show flag command and put them in their corresponding groups
|
|
ShowVolumesMenu += Actions.ShowVolumeCommands;
|
|
|
|
ShowMenuBuilder.AddSubMenu(LOCTEXT("ShowVolumesMenu", "Volumes"), LOCTEXT("ShowVolumesMenu_ToolTip", "Show volumes flags"),
|
|
FNewMenuDelegate::CreateStatic(&FillShowMenu, ShowVolumesMenu, 2));
|
|
}
|
|
|
|
// Show Layers sub-menu is dynamically generated when the user enters 'show' menu
|
|
{
|
|
ShowMenuBuilder.AddSubMenu(LOCTEXT("ShowLayersMenu", "Layers"), LOCTEXT("ShowLayersMenu_ToolTip", "Show layers flags"),
|
|
FNewMenuDelegate::CreateStatic(&SLevelViewportToolBar::FillShowLayersMenu, Viewport));
|
|
}
|
|
|
|
// Show Sprites sub-menu
|
|
{
|
|
TArray< FLevelViewportCommands::FShowMenuCommand > ShowSpritesMenu;
|
|
|
|
// 'Show All' and 'Hide All' buttons
|
|
ShowSpritesMenu.Add(FLevelViewportCommands::FShowMenuCommand(Actions.ShowAllSprites, ShowAllLabel));
|
|
ShowSpritesMenu.Add(FLevelViewportCommands::FShowMenuCommand(Actions.HideAllSprites, HideAllLabel));
|
|
|
|
// Get each show flag command and put them in their corresponding groups
|
|
ShowSpritesMenu += Actions.ShowSpriteCommands;
|
|
|
|
ShowMenuBuilder.AddSubMenu(LOCTEXT("ShowSpritesMenu", "Sprites"), LOCTEXT("ShowSpritesMenu_ToolTip", "Show sprites flags"),
|
|
FNewMenuDelegate::CreateStatic(&FillShowMenu, ShowSpritesMenu, 2));
|
|
}
|
|
|
|
// Show 'Foliage types' sub-menu is dynamically generated when the user enters 'show' menu
|
|
{
|
|
ShowMenuBuilder.AddSubMenu(LOCTEXT("ShowFoliageTypesMenu", "Foliage Types"), LOCTEXT("ShowFoliageTypesMenu_ToolTip", "Show/hide specific foliage types"),
|
|
FNewMenuDelegate::CreateStatic(&SLevelViewportToolBar::FillShowFoliageTypesMenu, Viewport));
|
|
}
|
|
|
|
}
|
|
ShowMenuBuilder.EndSection();
|
|
}
|
|
|
|
return ShowMenuBuilder.MakeWidget();
|
|
}
|
|
|
|
EVisibility SLevelViewportToolBar::GetViewModeOptionsVisibility() const
|
|
{
|
|
const FLevelEditorViewportClient& ViewClient = Viewport.Pin()->GetLevelViewportClient();
|
|
if (ViewClient.GetViewMode() == VMI_MeshUVDensityAccuracy || ViewClient.GetViewMode() == VMI_MaterialTextureScaleAccuracy || ViewClient.GetViewMode() == VMI_RequiredTextureResolution)
|
|
{
|
|
return EVisibility::SelfHitTestInvisible;
|
|
}
|
|
else
|
|
{
|
|
return EVisibility::Collapsed;
|
|
}
|
|
}
|
|
|
|
FText SLevelViewportToolBar::GetViewModeOptionsMenuLabel() const
|
|
{
|
|
Viewport.Pin()->OnFloatingButtonClicked();
|
|
const FLevelEditorViewportClient& ViewClient = Viewport.Pin()->GetLevelViewportClient();
|
|
return ::GetViewModeOptionsMenuLabel(ViewClient.GetViewMode());
|
|
}
|
|
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateViewModeOptionsMenu() const
|
|
{
|
|
Viewport.Pin()->OnFloatingButtonClicked();
|
|
FLevelEditorViewportClient& ViewClient = Viewport.Pin()->GetLevelViewportClient();
|
|
const UWorld* World = ViewClient.GetWorld();
|
|
return BuildViewModeOptionsMenu(Viewport.Pin()->GetCommandList(), ViewClient.GetViewMode(), World ? World->FeatureLevel.GetValue() : GMaxRHIFeatureLevel, ViewClient.GetViewModeParamNameMap());
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateFOVMenu() const
|
|
{
|
|
const float FOVMin = 5.f;
|
|
const float FOVMax = 170.f;
|
|
|
|
return
|
|
SNew( SBox )
|
|
.HAlign( HAlign_Right )
|
|
[
|
|
SNew( SBox )
|
|
.Padding( FMargin(4.0f, 0.0f, 0.0f, 0.0f) )
|
|
.WidthOverride( 100.0f )
|
|
[
|
|
SNew(SSpinBox<float>)
|
|
.Font( FEditorStyle::GetFontStyle( TEXT( "MenuItem.Font" ) ) )
|
|
.MinValue(FOVMin)
|
|
.MaxValue(FOVMax)
|
|
.Value( this, &SLevelViewportToolBar::OnGetFOVValue )
|
|
.OnValueChanged( this, &SLevelViewportToolBar::OnFOVValueChanged )
|
|
]
|
|
];
|
|
}
|
|
|
|
float SLevelViewportToolBar::OnGetFOVValue( ) const
|
|
{
|
|
return Viewport.Pin()->GetLevelViewportClient().ViewFOV;
|
|
}
|
|
|
|
void SLevelViewportToolBar::OnFOVValueChanged( float NewValue )
|
|
{
|
|
bool bUpdateStoredFOV = true;
|
|
FLevelEditorViewportClient& ViewportClient = Viewport.Pin()->GetLevelViewportClient();
|
|
if (ViewportClient.GetActiveActorLock().IsValid())
|
|
{
|
|
ACameraActor* CameraActor = Cast< ACameraActor >( ViewportClient.GetActiveActorLock().Get() );
|
|
if( CameraActor != NULL )
|
|
{
|
|
CameraActor->GetCameraComponent()->FieldOfView = NewValue;
|
|
bUpdateStoredFOV = false;
|
|
}
|
|
}
|
|
|
|
if ( bUpdateStoredFOV )
|
|
{
|
|
ViewportClient.FOVAngle = NewValue;
|
|
}
|
|
|
|
ViewportClient.ViewFOV = NewValue;
|
|
ViewportClient.Invalidate();
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateScreenPercentageMenu() const
|
|
{
|
|
const int32 PreviewScreenPercentageMin = FSceneViewScreenPercentageConfig::kMinTAAUpsampleResolutionFraction * 100.0f;
|
|
const int32 PreviewScreenPercentageMax = FSceneViewScreenPercentageConfig::kMaxTAAUpsampleResolutionFraction * 100.0f;
|
|
|
|
return
|
|
SNew(SBox)
|
|
.HAlign(HAlign_Right)
|
|
.IsEnabled(this, &SLevelViewportToolBar::OnScreenPercentageIsEnabled)
|
|
[
|
|
SNew(SBox)
|
|
.Padding(FMargin(4.0f, 0.0f, 0.0f, 0.0f))
|
|
.WidthOverride(100.0f)
|
|
[
|
|
SNew(SSpinBox<int32>)
|
|
.Font(FEditorStyle::GetFontStyle(TEXT("MenuItem.Font")))
|
|
.MinValue(PreviewScreenPercentageMin)
|
|
.MaxValue(PreviewScreenPercentageMax)
|
|
.Value(this, &SLevelViewportToolBar::OnGetScreenPercentageValue)
|
|
.OnValueChanged(this, &SLevelViewportToolBar::OnScreenPercentageValueChanged)
|
|
]
|
|
];
|
|
}
|
|
|
|
int32 SLevelViewportToolBar::OnGetScreenPercentageValue() const
|
|
{
|
|
return Viewport.Pin()->GetLevelViewportClient().GetPreviewScreenPercentage();
|
|
}
|
|
|
|
bool SLevelViewportToolBar::OnScreenPercentageIsEnabled() const
|
|
{
|
|
return Viewport.Pin()->GetLevelViewportClient().SupportsPreviewResolutionFraction();
|
|
}
|
|
|
|
void SLevelViewportToolBar::OnScreenPercentageValueChanged(int32 NewValue)
|
|
{
|
|
FLevelEditorViewportClient& ViewportClient = Viewport.Pin()->GetLevelViewportClient();
|
|
ViewportClient.SetPreviewScreenPercentage(NewValue);
|
|
ViewportClient.Invalidate();
|
|
}
|
|
|
|
TSharedRef<SWidget> SLevelViewportToolBar::GenerateFarViewPlaneMenu() const
|
|
{
|
|
return
|
|
SNew(SBox)
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
SNew(SBox)
|
|
.Padding(FMargin(4.0f, 0.0f, 0.0f, 0.0f))
|
|
.WidthOverride(100.0f)
|
|
[
|
|
SNew(SSpinBox<float>)
|
|
.ToolTipText(LOCTEXT("FarViewPlaneTooltip", "Distance to use as the far view plane, or zero to enable an infinite far view plane"))
|
|
.MinValue(0.0f)
|
|
.MaxValue(100000.0f)
|
|
.Font(FEditorStyle::GetFontStyle(TEXT("MenuItem.Font")))
|
|
.Value(this, &SLevelViewportToolBar::OnGetFarViewPlaneValue)
|
|
.OnValueChanged(this, &SLevelViewportToolBar::OnFarViewPlaneValueChanged)
|
|
]
|
|
];
|
|
}
|
|
|
|
float SLevelViewportToolBar::OnGetFarViewPlaneValue() const
|
|
{
|
|
return Viewport.Pin()->GetLevelViewportClient().GetFarClipPlaneOverride();
|
|
}
|
|
|
|
void SLevelViewportToolBar::OnFarViewPlaneValueChanged( float NewValue )
|
|
{
|
|
Viewport.Pin()->GetLevelViewportClient().OverrideFarClipPlane(NewValue);
|
|
}
|
|
|
|
void SLevelViewportToolBar::FillShowLayersMenu( FMenuBuilder& MenuBuilder, TWeakPtr<class SLevelViewport> Viewport )
|
|
{
|
|
MenuBuilder.BeginSection("LevelViewportLayers");
|
|
{
|
|
MenuBuilder.AddMenuEntry( FLevelViewportCommands::Get().ShowAllLayers, NAME_None, LOCTEXT("ShowAllLabel", "Show All"));
|
|
MenuBuilder.AddMenuEntry( FLevelViewportCommands::Get().HideAllLayers, NAME_None, LOCTEXT("HideAllLabel", "Hide All") );
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
if( Viewport.IsValid() )
|
|
{
|
|
TSharedRef<SLevelViewport> ViewportRef = Viewport.Pin().ToSharedRef();
|
|
MenuBuilder.BeginSection("LevelViewportLayers2");
|
|
{
|
|
// Get all the layers and create an entry for each of them
|
|
TArray<FName> AllLayerNames;
|
|
GEditor->Layers->AddAllLayerNamesTo(AllLayerNames);
|
|
|
|
for( int32 LayerIndex = 0; LayerIndex < AllLayerNames.Num(); ++LayerIndex )
|
|
{
|
|
const FName LayerName = AllLayerNames[LayerIndex];
|
|
//const FString LayerNameString = LayerName;
|
|
|
|
FUIAction Action( FExecuteAction::CreateSP( ViewportRef, &SLevelViewport::ToggleShowLayer, LayerName ),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP( ViewportRef, &SLevelViewport::IsLayerVisible, LayerName ) );
|
|
|
|
MenuBuilder.AddMenuEntry( FText::FromName( LayerName ), FText::GetEmpty(), FSlateIcon(), Action, NAME_None, EUserInterfaceActionType::ToggleButton );
|
|
}
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
}
|
|
|
|
static TMap<FName, TArray<UFoliageType*>> GroupFoliageByOuter(const TArray<UFoliageType*> FoliageList)
|
|
{
|
|
TMap<FName, TArray<UFoliageType*>> Result;
|
|
|
|
for (UFoliageType* FoliageType : FoliageList)
|
|
{
|
|
if (FoliageType->IsAsset())
|
|
{
|
|
Result.FindOrAdd(NAME_None).Add(FoliageType);
|
|
}
|
|
else
|
|
{
|
|
FName LevelName = FoliageType->GetOutermost()->GetFName();
|
|
Result.FindOrAdd(LevelName).Add(FoliageType);
|
|
}
|
|
}
|
|
|
|
Result.KeySort([](const FName& A, const FName& B) { return (A < B && B != NAME_None); });
|
|
return Result;
|
|
}
|
|
|
|
void SLevelViewportToolBar::FillShowFoliageTypesMenu(class FMenuBuilder& MenuBuilder, TWeakPtr<class SLevelViewport> Viewport)
|
|
{
|
|
auto ViewportPtr = Viewport.Pin();
|
|
if (!ViewportPtr.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
MenuBuilder.BeginSection("LevelViewportFoliageMeshes");
|
|
{
|
|
// Map 'Show All' and 'Hide All' commands
|
|
FUIAction ShowAllFoliage(FExecuteAction::CreateSP(ViewportPtr.ToSharedRef(), &SLevelViewport::ToggleAllFoliageTypes, true));
|
|
FUIAction HideAllFoliage(FExecuteAction::CreateSP(ViewportPtr.ToSharedRef(), &SLevelViewport::ToggleAllFoliageTypes, false));
|
|
|
|
MenuBuilder.AddMenuEntry(LOCTEXT("ShowAllLabel", "Show All"), FText::GetEmpty(), FSlateIcon(), ShowAllFoliage);
|
|
MenuBuilder.AddMenuEntry(LOCTEXT("HideAllLabel", "Hide All"), FText::GetEmpty(), FSlateIcon(), HideAllFoliage);
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
// Gather all foliage types used in this world and group them by sub-levels
|
|
auto AllFoliageMap = GroupFoliageByOuter(GEditor->GetFoliageTypesInWorld(ViewportPtr->GetWorld()));
|
|
|
|
for (auto& FoliagePair : AllFoliageMap)
|
|
{
|
|
// Name foliage group by an outer sub-level name, or empty if foliage type is an asset
|
|
FText EntryName = (FoliagePair.Key == NAME_None ? FText::GetEmpty() : FText::FromName(FPackageName::GetShortFName(FoliagePair.Key)));
|
|
MenuBuilder.BeginSection(NAME_None, EntryName);
|
|
|
|
TArray<UFoliageType*>& FoliageList = FoliagePair.Value;
|
|
for (UFoliageType* FoliageType : FoliageList)
|
|
{
|
|
FName MeshName = FoliageType->GetDisplayFName();
|
|
TWeakObjectPtr<UFoliageType> FoliageTypePtr = FoliageType;
|
|
|
|
FUIAction Action(
|
|
FExecuteAction::CreateSP(ViewportPtr.ToSharedRef(), &SLevelViewport::ToggleShowFoliageType, FoliageTypePtr),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(ViewportPtr.ToSharedRef(), &SLevelViewport::IsFoliageTypeVisible, FoliageTypePtr));
|
|
|
|
MenuBuilder.AddMenuEntry(FText::FromName(MeshName), FText::GetEmpty(), FSlateIcon(), Action, NAME_None, EUserInterfaceActionType::ToggleButton);
|
|
}
|
|
|
|
MenuBuilder.EndSection();
|
|
}
|
|
}
|
|
|
|
TWeakObjectPtr<UWorld> SLevelViewportToolBar::GetWorld() const
|
|
{
|
|
if (Viewport.IsValid())
|
|
{
|
|
return Viewport.Pin()->GetWorld();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
TSharedPtr<FExtender> SLevelViewportToolBar::GetViewMenuExtender()
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>(TEXT("LevelEditor"));
|
|
TSharedPtr<FExtender> LevelEditorExtenders = LevelEditorModule.GetMenuExtensibilityManager()->GetAllExtenders();
|
|
|
|
TSharedRef<FExtender> Extender(new FExtender());
|
|
Extender->AddMenuExtension(
|
|
TEXT("ViewMode"),
|
|
EExtensionHook::After,
|
|
Viewport.Pin()->GetCommandList(),
|
|
FMenuExtensionDelegate::CreateSP(this, &SLevelViewportToolBar::CreateViewMenuExtensions));
|
|
|
|
TArray<TSharedPtr<FExtender>> Extenders;
|
|
Extenders.Reserve(2);
|
|
Extenders.Add(LevelEditorExtenders);
|
|
Extenders.Add(Extender);
|
|
|
|
return FExtender::Combine(Extenders);
|
|
}
|
|
|
|
void SLevelViewportToolBar::CreateViewMenuExtensions(FMenuBuilder& MenuBuilder)
|
|
{
|
|
MenuBuilder.BeginSection("LevelViewportDeferredRendering", LOCTEXT("DeferredRenderingHeader", "Deferred Rendering") );
|
|
MenuBuilder.EndSection();
|
|
|
|
MenuBuilder.AddSubMenu(LOCTEXT("VisualizeBufferViewModeDisplayName", "Buffer Visualization"),
|
|
LOCTEXT("BufferVisualizationMenu_ToolTip", "Select a mode for buffer visualization"),
|
|
FNewMenuDelegate::CreateStatic(&FBufferVisualizationMenuCommands::BuildVisualisationSubMenu),
|
|
false,
|
|
FSlateIcon(FEditorStyle::GetStyleSetName(), "EditorViewport.VisualizeBufferMode"));
|
|
|
|
MenuBuilder.BeginSection("LevelViewportLandscape", LOCTEXT("LandscapeHeader", "Landscape") );
|
|
{
|
|
struct Local
|
|
{
|
|
static void BuildLandscapeLODMenu(FMenuBuilder& Menu, SLevelViewportToolBar* Toolbar)
|
|
{
|
|
Menu.BeginSection("LevelViewportLandScapeLOD", LOCTEXT("LandscapeLODHeader", "Landscape LOD"));
|
|
{
|
|
static const FText FormatString = LOCTEXT("LandscapeLODFixed", "Fixed at {0}");
|
|
Menu.AddMenuEntry(LOCTEXT("LandscapeLODAuto", "Auto"), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, -1), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, -1)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuSeparator();
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(0)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 0), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 0)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(1)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 1), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 1)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(2)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 2), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 2)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(3)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 3), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 3)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(4)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 4), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 4)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(5)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 5), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 5)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(6)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 6), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 6)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
Menu.AddMenuEntry(FText::Format(FormatString, FText::AsNumber(7)), FText(), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(Toolbar, &SLevelViewportToolBar::OnLandscapeLODChanged, 7), FCanExecuteAction(), FIsActionChecked::CreateSP(Toolbar, &SLevelViewportToolBar::IsLandscapeLODSettingChecked, 7)), NAME_None, EUserInterfaceActionType::RadioButton);
|
|
}
|
|
Menu.EndSection();
|
|
}
|
|
};
|
|
|
|
MenuBuilder.AddSubMenu(LOCTEXT("LandscapeLODDisplayName", "LOD"), LOCTEXT("LandscapeLODMenu_ToolTip", "Override Landscape LOD in this viewport"), FNewMenuDelegate::CreateStatic(&Local::BuildLandscapeLODMenu, this), /*Default*/false, FSlateIcon());
|
|
}
|
|
MenuBuilder.EndSection();
|
|
}
|
|
|
|
|
|
bool SLevelViewportToolBar::IsLandscapeLODSettingChecked(int32 Value) const
|
|
{
|
|
return Viewport.Pin()->GetLevelViewportClient().LandscapeLODOverride == Value;
|
|
}
|
|
|
|
void SLevelViewportToolBar::OnLandscapeLODChanged(int32 NewValue)
|
|
{
|
|
FLevelEditorViewportClient& ViewportClient = Viewport.Pin()->GetLevelViewportClient();
|
|
ViewportClient.LandscapeLODOverride = NewValue;
|
|
ViewportClient.Invalidate();
|
|
}
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|