You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Splitted World Browser views into three independent windows, each window can be summoned from a hierarchy view or details view toolbar World composition can now be toggled through WorldSettings - bEnableWorldComposition. Once enabled persistent level will be treated as a world root. No more '?worldcompistion' parameter workarounds. 'Open World' command was removed, as levels saved with world composition enabled can be open through 'Open Level' command. Added bEnableWorldOriginRebasing parameter to WorldSettings, which contols whether world origin shifting should be used [CL 2072584 by Dmitriy Dyomin in Main branch]
680 lines
19 KiB
C++
680 lines
19 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
#include "WorldBrowserPrivatePCH.h"
|
|
|
|
#include "Editor/LevelEditor/Public/LevelEditor.h"
|
|
#include "TextFilter.h"
|
|
#include "SWorldHierarchy.h"
|
|
#include "SWorldHierarchyItem.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "WorldBrowser"
|
|
|
|
typedef STreeView<TSharedPtr<FLevelModel>> SLevelsTreeWidget;
|
|
typedef TTextFilter<const TSharedPtr<FLevelModel>& > LevelTextFilter;
|
|
|
|
//----------------------------------------------------------------
|
|
//
|
|
//
|
|
//----------------------------------------------------------------
|
|
class SWorldHierarchyImpl
|
|
: public SCompoundWidget
|
|
{
|
|
public:
|
|
SLATE_BEGIN_ARGS(SWorldHierarchyImpl) {}
|
|
SLATE_ARGUMENT(TSharedPtr<FLevelCollectionModel>, InWorldModel)
|
|
SLATE_END_ARGS()
|
|
|
|
SWorldHierarchyImpl()
|
|
: bUpdatingSelection(false)
|
|
{
|
|
}
|
|
|
|
~SWorldHierarchyImpl()
|
|
{
|
|
WorldModel->SelectionChanged.RemoveAll(this);
|
|
WorldModel->HierarchyChanged.RemoveAll(this);
|
|
WorldModel->CollectionChanged.RemoveAll(this);
|
|
}
|
|
|
|
void Construct(const FArguments& InArgs)
|
|
{
|
|
WorldModel = InArgs._InWorldModel;
|
|
check(WorldModel.IsValid());
|
|
|
|
WorldModel->SelectionChanged.AddSP(this, &SWorldHierarchyImpl::OnUpdateSelection);
|
|
WorldModel->HierarchyChanged.AddSP(this, &SWorldHierarchyImpl::RefreshView);
|
|
WorldModel->CollectionChanged.AddSP(this, &SWorldHierarchyImpl::RefreshView);
|
|
|
|
SearchBoxLevelFilter = MakeShareable(new LevelTextFilter(
|
|
LevelTextFilter::FItemToStringArray::CreateSP(this, &SWorldHierarchyImpl::TransformLevelToString)
|
|
));
|
|
|
|
HeaderRowWidget =
|
|
SNew( SHeaderRow )
|
|
.Visibility(EVisibility::Collapsed)
|
|
|
|
/** Level visibility column */
|
|
+ SHeaderRow::Column(HierarchyColumns::ColumnID_Visibility)
|
|
.FixedWidth(24.0f)
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(NSLOCTEXT("WorldBrowser", "Visibility", "Visibility"))
|
|
]
|
|
|
|
/** LevelName label column */
|
|
+ SHeaderRow::Column( HierarchyColumns::ColumnID_LevelLabel )
|
|
.FillWidth( 0.45f )
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(LOCTEXT("Column_LevelNameLabel", "Level"))
|
|
]
|
|
|
|
/** Level lock column */
|
|
+ SHeaderRow::Column( HierarchyColumns::ColumnID_Lock )
|
|
.FixedWidth( 24.0f )
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(NSLOCTEXT("WorldBrowser", "Lock", "Lock"))
|
|
]
|
|
|
|
/** Level kismet column */
|
|
+ SHeaderRow::Column( HierarchyColumns::ColumnID_Kismet )
|
|
.FixedWidth( 24.0f )
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(NSLOCTEXT("WorldBrowser", "Blueprint", "Open the level blueprint for this Level"))
|
|
]
|
|
|
|
/** Level SCC status column */
|
|
+ SHeaderRow::Column( HierarchyColumns::ColumnID_SCCStatus )
|
|
.FixedWidth( 24.0f )
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(NSLOCTEXT("WorldBrowser", "SCCStatus", "Status in Source Control"))
|
|
]
|
|
|
|
/** Level save column */
|
|
+ SHeaderRow::Column( HierarchyColumns::ColumnID_Save )
|
|
.FixedWidth( 24.0f )
|
|
.HeaderContent()
|
|
[
|
|
SNew(STextBlock)
|
|
.ToolTipText(NSLOCTEXT("WorldBrowser", "Save", "Save this Level"))
|
|
];
|
|
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SVerticalBox)
|
|
// Filter box
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew( SSearchBox )
|
|
.ToolTipText(LOCTEXT("FilterSearchToolTip", "Type here to search Levels").ToString())
|
|
.HintText(LOCTEXT("FilterSearchHint", "Search Levels"))
|
|
.OnTextChanged(SearchBoxLevelFilter.Get(), &LevelTextFilter::SetRawFilterText)
|
|
]
|
|
// Hierarchy
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(1.f)
|
|
[
|
|
SAssignNew(TreeWidget, SLevelsTreeWidget)
|
|
.TreeItemsSource(&WorldModel->GetRootLevelList())
|
|
.SelectionMode(ESelectionMode::Multi)
|
|
.OnGenerateRow(this, &SWorldHierarchyImpl::GenerateTreeRow)
|
|
.OnGetChildren( this, &SWorldHierarchyImpl::GetChildrenForTree)
|
|
.OnSelectionChanged(this, &SWorldHierarchyImpl::OnSelectionChanged)
|
|
.OnExpansionChanged(this, &SWorldHierarchyImpl::OnExpansionChanged)
|
|
.OnMouseButtonDoubleClick(this, &SWorldHierarchyImpl::OnTreeViewMouseButtonDoubleClick)
|
|
.OnContextMenuOpening(this, &SWorldHierarchyImpl::ConstructLevelContextMenu)
|
|
.HeaderRow(HeaderRowWidget.ToSharedRef())
|
|
]
|
|
|
|
// Separator
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding(0, 0, 0, 1)
|
|
[
|
|
SNew(SSeparator)
|
|
]
|
|
|
|
// View options
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
// Asset count
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1.f)
|
|
.VAlign(VAlign_Center)
|
|
.Padding(8, 0)
|
|
[
|
|
SNew( STextBlock )
|
|
.Text( this, &SWorldHierarchyImpl::GetFilterStatusText )
|
|
.ColorAndOpacity( this, &SWorldHierarchyImpl::GetFilterStatusTextColor )
|
|
]
|
|
|
|
// View mode combo button
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
[
|
|
SAssignNew( ViewOptionsComboButton, SComboButton )
|
|
.ContentPadding(0)
|
|
.ForegroundColor( this, &SWorldHierarchyImpl::GetViewButtonForegroundColor )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" ) // Use the tool bar item style for this button
|
|
.OnGetMenuContent( this, &SWorldHierarchyImpl::GetViewButtonContent )
|
|
.ButtonContent()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SImage).Image( FEditorStyle::GetBrush("GenericViewButton") )
|
|
]
|
|
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding(2, 0, 0, 0)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(STextBlock).Text( LOCTEXT("ViewButton", "View Options") )
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
|
|
WorldModel->AddFilter(SearchBoxLevelFilter.ToSharedRef());
|
|
RefreshView();
|
|
}
|
|
|
|
/** Regenerates current items */
|
|
void RefreshView()
|
|
{
|
|
TreeWidget->RequestTreeRefresh();
|
|
|
|
// Sync items expansion state
|
|
struct FExpander : public FLevelModelVisitor
|
|
{
|
|
TSharedPtr<SLevelsTreeWidget> TreeWidget;
|
|
virtual void Visit(FLevelModel& Item) OVERRIDE
|
|
{
|
|
TreeWidget->SetItemExpansion(Item.AsShared(), Item.GetLevelExpansionFlag());
|
|
};
|
|
} Expander;
|
|
Expander.TreeWidget = TreeWidget;
|
|
|
|
//Apply expansion
|
|
WorldModel->IterateHierarchy(Expander);
|
|
}
|
|
|
|
private:
|
|
/** Creates an item for the tree view */
|
|
TSharedRef<ITableRow> GenerateTreeRow(TSharedPtr<FLevelModel> Item, const TSharedRef<STableViewBase>& OwnerTable)
|
|
{
|
|
check(Item.IsValid());
|
|
|
|
return SNew(SWorldHierarchyItem, OwnerTable)
|
|
.InWorldModel(WorldModel)
|
|
.InItemModel(Item)
|
|
.IsItemExpanded(this, &SWorldHierarchyImpl::IsTreeItemExpanded, Item)
|
|
.HighlightText(this, &SWorldHierarchyImpl::GetSearchBoxText);
|
|
|
|
}
|
|
|
|
/** Handler for returning a list of children associated with a particular tree node */
|
|
void GetChildrenForTree(TSharedPtr<FLevelModel> Item, FLevelModelList& OutChildren)
|
|
{
|
|
OutChildren = Item->GetChildren();
|
|
}
|
|
|
|
/** @return the SWidget containing the context menu */
|
|
TSharedPtr<SWidget> ConstructLevelContextMenu() const
|
|
{
|
|
if (!WorldModel->IsReadOnly())
|
|
{
|
|
FMenuBuilder MenuBuilder(true, WorldModel->GetCommandList());
|
|
WorldModel->BuildHierarchyMenu(MenuBuilder);
|
|
return MenuBuilder.MakeWidget();
|
|
}
|
|
|
|
return SNullWidget::NullWidget;
|
|
}
|
|
|
|
/** Called by TreeView widget whenever tree item expanded or collapsed */
|
|
void OnExpansionChanged(TSharedPtr<FLevelModel> Item, bool bIsItemExpanded)
|
|
{
|
|
Item->SetLevelExpansionFlag(bIsItemExpanded);
|
|
}
|
|
|
|
/** Called by TreeView widget whenever selection is changed */
|
|
void OnSelectionChanged(const TSharedPtr<FLevelModel> Item, ESelectInfo::Type SelectInfo)
|
|
{
|
|
if (bUpdatingSelection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bUpdatingSelection = true;
|
|
WorldModel->SetSelectedLevels(TreeWidget->GetSelectedItems());
|
|
bUpdatingSelection = false;
|
|
}
|
|
|
|
/** Handles selection changes in data source */
|
|
void OnUpdateSelection()
|
|
{
|
|
if (bUpdatingSelection)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bUpdatingSelection = true;
|
|
const auto& SelectedItems = WorldModel->GetSelectedLevels();
|
|
TreeWidget->ClearSelection();
|
|
for (auto It = SelectedItems.CreateConstIterator(); It; ++It)
|
|
{
|
|
TreeWidget->SetItemSelection(*It, true);
|
|
}
|
|
|
|
if (SelectedItems.Num() == 1)
|
|
{
|
|
TreeWidget->RequestScrollIntoView(SelectedItems[0]);
|
|
}
|
|
|
|
RefreshView();
|
|
|
|
bUpdatingSelection = false;
|
|
}
|
|
|
|
/**
|
|
* Called by STreeView when the user double-clicks on an item
|
|
*
|
|
* @param Item The item that was double clicked
|
|
*/
|
|
void OnTreeViewMouseButtonDoubleClick(TSharedPtr<FLevelModel> Item)
|
|
{
|
|
Item->MakeLevelCurrent();
|
|
}
|
|
|
|
/**
|
|
* Checks to see if this widget supports keyboard focus. Override this in derived classes.
|
|
*
|
|
* @return True if this widget can take keyboard focus
|
|
*/
|
|
virtual bool SupportsKeyboardFocus() const OVERRIDE
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Called after a key is pressed when this widget has keyboard focus
|
|
*
|
|
* @param MyGeometry The Geometry of the widget receiving the event
|
|
* @param InKeyboardEvent Keyboard event
|
|
*
|
|
* @return Returns whether the event was handled, along with other possible actions
|
|
*/
|
|
virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyboardEvent& InKeyboardEvent) OVERRIDE
|
|
{
|
|
if (WorldModel->GetCommandList()->ProcessCommandBindings(InKeyboardEvent))
|
|
{
|
|
return FReply::Handled();
|
|
}
|
|
|
|
return SCompoundWidget::OnKeyDown(MyGeometry, InKeyboardEvent);
|
|
}
|
|
|
|
private:
|
|
/** @returns Whether specified item should be expanded */
|
|
bool IsTreeItemExpanded(TSharedPtr<FLevelModel> Item) const
|
|
{
|
|
return Item->GetLevelExpansionFlag();
|
|
}
|
|
|
|
/** Appends the Level's name to the OutSearchStrings array if the Level is valid */
|
|
void TransformLevelToString(const TSharedPtr<FLevelModel>& Level, TArray<FString>& OutSearchStrings) const
|
|
{
|
|
if (Level.IsValid() && Level->HasValidPackage())
|
|
{
|
|
OutSearchStrings.Add(FPackageName::GetShortName(Level->GetLongPackageName()));
|
|
}
|
|
}
|
|
|
|
/** @return Text entered in search box */
|
|
FText GetSearchBoxText() const
|
|
{
|
|
return SearchBoxLevelFilter->GetRawFilterText();
|
|
}
|
|
|
|
/** @return Returns the filter status text */
|
|
FString GetFilterStatusText() const
|
|
{
|
|
const int32 SelectedLevelsCount = WorldModel->GetSelectedLevels().Num();
|
|
const int32 TotalLevelsCount = WorldModel->GetAllLevels().Num();
|
|
const int32 FilteredLevelsCount = WorldModel->GetFilteredLevels().Num();
|
|
|
|
if (!WorldModel->IsFilterActive())
|
|
{
|
|
if (SelectedLevelsCount == 0)
|
|
{
|
|
return FString::Printf( *LOCTEXT("ShowingAllLevels", "%d levels").ToString(), TotalLevelsCount );
|
|
}
|
|
else
|
|
{
|
|
return FString::Printf( *LOCTEXT("ShowingAllLevelsSelected", "%d levels (%d selected)").ToString(), TotalLevelsCount, SelectedLevelsCount );
|
|
}
|
|
}
|
|
else if(WorldModel->IsFilterActive() && FilteredLevelsCount == 0)
|
|
{
|
|
return FString::Printf( *LOCTEXT("ShowingNoLevels", "No matching levels (%d total)").ToString(), TotalLevelsCount );
|
|
}
|
|
else if (SelectedLevelsCount != 0)
|
|
{
|
|
return FString::Printf( *LOCTEXT("ShowingOnlySomeLevelsSelected", "Showing %d of %d levels (%d selected)").ToString(), FilteredLevelsCount, TotalLevelsCount, SelectedLevelsCount );
|
|
}
|
|
else
|
|
{
|
|
return FString::Printf( *LOCTEXT("ShowingOnlySomeLevels", "Showing %d of %d levels").ToString(), FilteredLevelsCount, TotalLevelsCount );
|
|
}
|
|
}
|
|
|
|
|
|
/** @return Returns color for the filter status text message, based on success of search filter */
|
|
FSlateColor GetFilterStatusTextColor() const
|
|
{
|
|
if (!WorldModel->IsFilterActive() )
|
|
{
|
|
// White = no text filter
|
|
return FLinearColor( 1.0f, 1.0f, 1.0f );
|
|
}
|
|
else if(WorldModel->GetFilteredLevels().Num() == 0)
|
|
{
|
|
// Red = no matching actors
|
|
return FLinearColor( 1.0f, 0.4f, 0.4f );
|
|
}
|
|
else
|
|
{
|
|
// Green = found at least one match!
|
|
return FLinearColor( 0.4f, 1.0f, 0.4f );
|
|
}
|
|
}
|
|
|
|
/** @return the content for the view button */
|
|
TSharedRef<SWidget> GetViewButtonContent()
|
|
{
|
|
FMenuBuilder MenuBuilder(true, NULL);
|
|
|
|
MenuBuilder.BeginSection("SubLevelsViewMenu", LOCTEXT("ShowHeading", "Show"));
|
|
{
|
|
MenuBuilder.AddMenuEntry(LOCTEXT("ToggleDisplayPaths", "Display Paths"),
|
|
LOCTEXT("ToggleDisplayPaths_Tooltip", "If enabled, displays the path for each level"),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP(this, &SWorldHierarchyImpl::ToggleDisplayPaths_Executed),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SWorldHierarchyImpl::GetDisplayPathsState)),
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
|
|
MenuBuilder.AddMenuEntry(LOCTEXT("ToggleDisplayActorsCount", "Display Actors Count"),
|
|
LOCTEXT("ToggleDisplayActorsCount_Tooltip", "If enabled, displays actors count for each level"),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP(this, &SWorldHierarchyImpl::ToggleDisplayActorsCount_Executed),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SWorldHierarchyImpl::GetDisplayActorsCountState)),
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
|
|
}
|
|
MenuBuilder.EndSection();
|
|
|
|
return MenuBuilder.MakeWidget();
|
|
}
|
|
|
|
/** @return the foreground color for the view button */
|
|
FSlateColor GetViewButtonForegroundColor() const
|
|
{
|
|
return ViewOptionsComboButton->IsHovered() ? FEditorStyle::GetSlateColor("InvertedForeground") : FEditorStyle::GetSlateColor("DefaultForeground");
|
|
}
|
|
|
|
/** Toggles state of 'display path' */
|
|
void ToggleDisplayPaths_Executed()
|
|
{
|
|
WorldModel->SetDisplayPathsState(!WorldModel->GetDisplayPathsState());
|
|
}
|
|
|
|
/** Gets the state of the 'display paths' enabled/disabled */
|
|
bool GetDisplayPathsState() const
|
|
{
|
|
return WorldModel->GetDisplayPathsState();
|
|
}
|
|
|
|
/** Toggles state of 'display actors count' */
|
|
void ToggleDisplayActorsCount_Executed()
|
|
{
|
|
WorldModel->SetDisplayActorsCountState(!WorldModel->GetDisplayActorsCountState());
|
|
}
|
|
|
|
/** Gets the state of the 'display actors count' enabled/disabled */
|
|
bool GetDisplayActorsCountState() const
|
|
{
|
|
return WorldModel->GetDisplayActorsCountState();
|
|
}
|
|
|
|
private:
|
|
/** Whether the view is currently updating the viewmodel selection */
|
|
bool bUpdatingSelection;
|
|
/** Our list view widget */
|
|
TSharedPtr<SLevelsTreeWidget> TreeWidget;
|
|
|
|
/** Items collection to display */
|
|
TSharedPtr<FLevelCollectionModel> WorldModel;
|
|
|
|
/** The Header Row for the hierarchy */
|
|
TSharedPtr<SHeaderRow> HeaderRowWidget;
|
|
|
|
/** The LevelTextFilter that constrains which Levels appear in the hierarchy */
|
|
TSharedPtr<LevelTextFilter> SearchBoxLevelFilter;
|
|
|
|
/** Button representing view options on bottom */
|
|
TSharedPtr<SComboButton> ViewOptionsComboButton;
|
|
};
|
|
|
|
//----------------------------------------------------------------
|
|
//
|
|
//
|
|
//----------------------------------------------------------------
|
|
SWorldHierarchy::SWorldHierarchy()
|
|
{
|
|
}
|
|
|
|
SWorldHierarchy::~SWorldHierarchy()
|
|
{
|
|
FWorldBrowserModule& WorldBrowserModule = FModuleManager::GetModuleChecked<FWorldBrowserModule>("WorldBrowser");
|
|
WorldBrowserModule.OnBrowseWorld.RemoveAll(this);
|
|
}
|
|
|
|
void SWorldHierarchy::Construct(const FArguments& InArgs)
|
|
{
|
|
FWorldBrowserModule& WorldBrowserModule = FModuleManager::GetModuleChecked<FWorldBrowserModule>("WorldBrowser");
|
|
WorldBrowserModule.OnBrowseWorld.AddSP(this, &SWorldHierarchy::OnBrowseWorld);
|
|
|
|
OnBrowseWorld(InArgs._InWorld);
|
|
}
|
|
|
|
void SWorldHierarchy::OnBrowseWorld(UWorld* InWorld)
|
|
{
|
|
// Remove all binding to an old world
|
|
ChildSlot
|
|
[
|
|
SNullWidget::NullWidget
|
|
];
|
|
|
|
WorldModel = nullptr;
|
|
|
|
// Bind to a new world
|
|
if (InWorld)
|
|
{
|
|
FWorldBrowserModule& WorldBrowserModule = FModuleManager::GetModuleChecked<FWorldBrowserModule>("WorldBrowser");
|
|
WorldModel = WorldBrowserModule.SharedWorldModel(InWorld);
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SVerticalBox)
|
|
|
|
// Toolbar
|
|
+SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FEditorStyle::GetBrush(TEXT("ToolPanel.GroupBorder")))
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
// Toolbar
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1.f)
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Left)
|
|
[
|
|
// Levels menu
|
|
SNew( SComboButton )
|
|
.ComboButtonStyle(FEditorStyle::Get(), "ToolbarComboButton")
|
|
.ForegroundColor(FLinearColor::White)
|
|
.ContentPadding(0)
|
|
.OnGetMenuContent(this, &SWorldHierarchy::GetFileButtonContent)
|
|
//.ToolTipText(this, &SWorldHierarchy::GetNewAssetToolTipText)
|
|
//.IsEnabled(this, &SWorldHierarchy::IsAssetPathSelected )
|
|
.ButtonContent()
|
|
[
|
|
SNew(SHorizontalBox)
|
|
|
|
// Icon
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FEditorStyle::GetBrush("ContentBrowser.NewAsset"))
|
|
]
|
|
|
|
// Text
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
.Padding(0,0,2,0)
|
|
[
|
|
SNew(STextBlock)
|
|
.TextStyle(FEditorStyle::Get(), "ContentBrowser.TopBar.Font")
|
|
.Text(LOCTEXT("LevelsButton", "Levels"))
|
|
]
|
|
]
|
|
]
|
|
|
|
// Button to summon levels details tab
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FEditorStyle::Get(), "ToggleButton")
|
|
.OnClicked(this, &SWorldHierarchy::OnSummonDetails)
|
|
.ToolTipText(LOCTEXT("SummonDetailsToolTipText", "Summons sublevels details"))
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
.Content()
|
|
[
|
|
SNew(SImage)
|
|
.Image(this, &SWorldHierarchy::GetSummonDetailsBrush)
|
|
]
|
|
]
|
|
|
|
// Button to summon world composition tab
|
|
+SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign(VAlign_Center)
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
SNew(SButton)
|
|
.Visibility(this, &SWorldHierarchy::GetCompositionButtonVisibility)
|
|
.ButtonStyle(FEditorStyle::Get(), "ToggleButton")
|
|
.OnClicked(this, &SWorldHierarchy::OnSummonComposition)
|
|
.ToolTipText(LOCTEXT("SummonHierarchyToolTipText", "Summons world composition"))
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
.Content()
|
|
[
|
|
SNew(SImage)
|
|
.Image(this, &SWorldHierarchy::GetSummonCompositionBrush)
|
|
]
|
|
]
|
|
]
|
|
]
|
|
|
|
// Hierarchy
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(1.f)
|
|
.Padding(0,4,0,0)
|
|
[
|
|
SNew(SBorder)
|
|
.BorderImage(FEditorStyle::GetBrush(TEXT("ToolPanel.GroupBorder")))
|
|
[
|
|
SNew(SWorldHierarchyImpl).InWorldModel(WorldModel)
|
|
]
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
FReply SWorldHierarchy::OnSummonDetails()
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>( "LevelEditor" );
|
|
LevelEditorModule.SummonWorldBrowserDetails();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
const FSlateBrush* SWorldHierarchy::GetSummonDetailsBrush() const
|
|
{
|
|
return FEditorStyle::GetBrush("WorldBrowser.DetailsButtonBrush");
|
|
}
|
|
|
|
EVisibility SWorldHierarchy::GetCompositionButtonVisibility() const
|
|
{
|
|
return WorldModel->IsTileWorld() ? EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
FReply SWorldHierarchy::OnSummonComposition()
|
|
{
|
|
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>( "LevelEditor" );
|
|
LevelEditorModule.SummonWorldBrowserComposition();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
const FSlateBrush* SWorldHierarchy::GetSummonCompositionBrush() const
|
|
{
|
|
return FEditorStyle::GetBrush("WorldBrowser.CompositionButtonBrush");
|
|
}
|
|
|
|
TSharedRef<SWidget> SWorldHierarchy::GetFileButtonContent()
|
|
{
|
|
FMenuBuilder MenuBuilder(true, WorldModel->GetCommandList());
|
|
|
|
// let current level collection model fill additional 'File' commands
|
|
WorldModel->CustomizeFileMainMenu(MenuBuilder);
|
|
|
|
return MenuBuilder.MakeWidget();
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE |