Files
UnrealEngineUWP/Engine/Source/Editor/DetailCustomizations/Private/WorldSettingsDetails.cpp
Ben Marsh 20bf0eb6a1 Updating copyright notices to 2017 (copying from //Tasks/UE4/Dev-Copyright-2017).
#rb none
#lockdown Nick.Penwarden

[CL 3226823 by Ben Marsh in Main branch]
2016-12-08 08:52:44 -05:00

312 lines
9.2 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#include "WorldSettingsDetails.h"
#include "Framework/Commands/UIAction.h"
#include "Layout/WidgetPath.h"
#include "Framework/Application/MenuStack.h"
#include "Framework/Application/SlateApplication.h"
#include "Widgets/Layout/SBorder.h"
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Layout/SBox.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "GameFramework/Actor.h"
#include "Editor.h"
#include "Engine/Texture2D.h"
#include "Toolkits/AssetEditorManager.h"
#include "DetailLayoutBuilder.h"
#include "GameModeInfoCustomizer.h"
#define LOCTEXT_NAMESPACE "WorldSettingsDetails"
/* IDetailCustomization overrides
*****************************************************************************/
void FWorldSettingsDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder )
{
IDetailCategoryBuilder& Category = DetailBuilder.EditCategory("GameMode");
CustomizeGameInfoProperty("DefaultGameMode", DetailBuilder, Category);
AddLightmapCustomization(DetailBuilder);
DetailBuilder.HideProperty(GET_MEMBER_NAME_CHECKED(AActor, bHidden), AActor::StaticClass());
}
/* FWorldSettingsDetails implementation
*****************************************************************************/
void FWorldSettingsDetails::CustomizeGameInfoProperty( const FName& PropertyName, IDetailLayoutBuilder& DetailBuilder, IDetailCategoryBuilder& CategoryBuilder )
{
// Get the object that we are viewing details of. Expect to only edit one WorldSettings object at a time!
TArray< TWeakObjectPtr<UObject> > ObjectsCustomized;
DetailBuilder.GetObjectsBeingCustomized(ObjectsCustomized);
UObject* ObjectCustomized = (ObjectsCustomized.Num() > 0) ? ObjectsCustomized[0].Get() : NULL;
// Allocate customizer object
GameInfoModeCustomizer = MakeShareable(new FGameModeInfoCustomizer(ObjectCustomized, PropertyName));
// Then use it to customize
GameInfoModeCustomizer->CustomizeGameModeSetting(DetailBuilder, CategoryBuilder);
}
void FWorldSettingsDetails::AddLightmapCustomization( IDetailLayoutBuilder& DetailBuilder )
{
IDetailCategoryBuilder& Category = DetailBuilder.EditCategory("Lightmass");
TSharedRef<FLightmapCustomNodeBuilder> LightMapGroupBuilder = MakeShareable(new FLightmapCustomNodeBuilder(DetailBuilder.GetThumbnailPool()));
const bool bForAdvanced = true;
Category.AddCustomBuilder(LightMapGroupBuilder, bForAdvanced);
}
FLightmapCustomNodeBuilder::FLightmapCustomNodeBuilder(const TSharedPtr<FAssetThumbnailPool>& InThumbnailPool)
{
ThumbnailPool = InThumbnailPool;
}
FLightmapCustomNodeBuilder::~FLightmapCustomNodeBuilder()
{
FEditorDelegates::OnLightingBuildKept.RemoveAll(this);
FEditorDelegates::MapChange.RemoveAll(this);
FEditorDelegates::NewCurrentLevel.RemoveAll(this);
}
void FLightmapCustomNodeBuilder::SetOnRebuildChildren(FSimpleDelegate InOnRegenerateChildren)
{
OnRegenerateChildren = InOnRegenerateChildren;
FEditorDelegates::OnLightingBuildKept.AddSP(this, &FLightmapCustomNodeBuilder::HandleLightingBuildKept);
FEditorDelegates::MapChange.AddSP(this, &FLightmapCustomNodeBuilder::HandleMapChanged);
FEditorDelegates::NewCurrentLevel.AddSP(this, &FLightmapCustomNodeBuilder::HandleNewCurrentLevel);
}
void FLightmapCustomNodeBuilder::GenerateHeaderRowContent(FDetailWidgetRow& NodeRow)
{
NodeRow.NameContent()
[
SNew( STextBlock )
.Text( LOCTEXT("LightmapHeaderRowContent", "Lightmaps") )
.Font( IDetailLayoutBuilder::GetDetailFont() )
];
NodeRow.ValueContent()
[
SNew( STextBlock )
.Text( this, &FLightmapCustomNodeBuilder::GetLightmapCountText )
.Font( IDetailLayoutBuilder::GetDetailFont() )
];
}
void FLightmapCustomNodeBuilder::GenerateChildContent(IDetailChildrenBuilder& ChildrenBuilder)
{
RefreshLightmapItems();
for(TSharedPtr<FLightmapItem>& Item : LightmapItems)
{
ChildrenBuilder.AddChildContent(LOCTEXT("LightMapsFilter", "Lightmaps"))
.ValueContent()
.HAlign(HAlign_Fill)
[
MakeLightMapList(Item)
];
}
}
FText FLightmapCustomNodeBuilder::GetLightmapCountText() const
{
return FText::Format( LOCTEXT("LightmapHeaderRowCount", "{0} Lightmap(s)"), FText::AsNumber(LightmapItems.Num()) );
}
void FLightmapCustomNodeBuilder::HandleLightingBuildKept()
{
OnRegenerateChildren.ExecuteIfBound();
}
void FLightmapCustomNodeBuilder::HandleMapChanged(uint32 MapChangeFlags)
{
OnRegenerateChildren.ExecuteIfBound();
}
void FLightmapCustomNodeBuilder::HandleNewCurrentLevel()
{
OnRegenerateChildren.ExecuteIfBound();
}
TSharedRef<SWidget> FLightmapCustomNodeBuilder::MakeLightMapList(TSharedPtr<FLightmapItem> LightMapItem)
{
if ( !ensure(LightMapItem.IsValid()) )
{
return SNullWidget::NullWidget;
}
const uint32 ThumbnailResolution = 64;
const uint32 ThumbnailBoxPadding = 4;
UObject* LightMapObject = FindObject<UObject>(NULL, *LightMapItem->ObjectPath);
FAssetData LightMapAssetData(LightMapObject);
FAssetThumbnailConfig ThumbnailConfig;
ThumbnailConfig.bAllowFadeIn = true;
TWeakPtr<FLightmapItem> LightmapWeakPtr = LightMapItem;
return
SNew(SBorder)
.BorderImage(nullptr)
.Padding(0.0f)
.OnMouseButtonUp(this, &FLightmapCustomNodeBuilder::OnMouseButtonUp, LightmapWeakPtr)
.OnMouseDoubleClick(this, &FLightmapCustomNodeBuilder::OnLightMapListMouseButtonDoubleClick, LightmapWeakPtr)
[
SNew(SHorizontalBox)
// Viewport
+SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
[
SNew( SBox )
.WidthOverride( ThumbnailResolution + ThumbnailBoxPadding * 2 )
.HeightOverride( ThumbnailResolution + ThumbnailBoxPadding * 2 )
[
// Drop shadow border
SNew(SBorder)
.Padding(ThumbnailBoxPadding)
.BorderImage( FEditorStyle::GetBrush("ContentBrowser.ThumbnailShadow") )
[
LightMapItem->Thumbnail->MakeThumbnailWidget(ThumbnailConfig)
]
]
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding(6, 0, 0, 0)
.VAlign(VAlign_Center)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 1)
[
SNew(STextBlock)
.Font(IDetailLayoutBuilder::GetDetailFont())
.Text(FText::FromName(LightMapAssetData.AssetName) )
]
+SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 1)
[
// Class
SNew(STextBlock)
.Font(IDetailLayoutBuilder::GetDetailFont())
.Text(FText::FromName(LightMapAssetData.AssetClass))
]
]
];
}
TSharedPtr<SWidget> FLightmapCustomNodeBuilder::OnGetLightMapContextMenuContent(TSharedPtr<FLightmapItem> Lightmap)
{
if (Lightmap.IsValid() )
{
FMenuBuilder MenuBuilder(/*bInShouldCloseWindowAfterMenuSelection=*/true, NULL);
MenuBuilder.BeginSection("LightMapsContextMenuSection", LOCTEXT("LightMapsContextMenuHeading", "Options") );
{
MenuBuilder.AddMenuEntry(
LOCTEXT("ViewLightmapLabel", "View Lightmap"),
LOCTEXT("ViewLightmapTooltip", "Opens the texture editor with this lightmap."),
FSlateIcon(),
FUIAction(FExecuteAction::CreateSP(this, &FLightmapCustomNodeBuilder::ExecuteViewLightmap, Lightmap->ObjectPath))
);
}
MenuBuilder.EndSection(); //LightMapsContextMenuSection
return MenuBuilder.MakeWidget();
}
return nullptr;
}
FReply FLightmapCustomNodeBuilder::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, TWeakPtr<FLightmapItem> Lightmap)
{
if(MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
{
TSharedPtr<SWidget> MenuContent = OnGetLightMapContextMenuContent(Lightmap.Pin());
if(MenuContent.IsValid() && MouseEvent.GetEventPath() != nullptr)
{
const FVector2D& SummonLocation = MouseEvent.GetScreenSpacePosition();
FWidgetPath WidgetPath = *MouseEvent.GetEventPath();
FSlateApplication::Get().PushMenu(WidgetPath.Widgets.Last().Widget, WidgetPath, MenuContent.ToSharedRef(), SummonLocation, FPopupTransitionEffect(FPopupTransitionEffect::ContextMenu));
}
return FReply::Handled();
}
return FReply::Unhandled();
}
FReply FLightmapCustomNodeBuilder::OnLightMapListMouseButtonDoubleClick(const FGeometry& MyGeom, const FPointerEvent& PointerEvent, TWeakPtr<FLightmapItem> SelectedLightmap)
{
if ( ensure(SelectedLightmap.IsValid()) )
{
ExecuteViewLightmap(SelectedLightmap.Pin()->ObjectPath);
}
return FReply::Handled();
}
void FLightmapCustomNodeBuilder::ExecuteViewLightmap(FString SelectedLightmapPath)
{
UObject* LightMapObject = FindObject<UObject>(NULL, *SelectedLightmapPath);
if ( LightMapObject )
{
FAssetEditorManager::Get().OpenEditorForAsset(LightMapObject);
}
}
void FLightmapCustomNodeBuilder::RefreshLightmapItems()
{
LightmapItems.Empty();
FWorldContext& Context = GEditor->GetEditorWorldContext();
UWorld* World = Context.World();
if ( World )
{
TArray<UTexture2D*> LightMapsAndShadowMaps;
World->GetLightMapsAndShadowMaps(World->GetCurrentLevel(), LightMapsAndShadowMaps);
for ( auto ObjIt = LightMapsAndShadowMaps.CreateConstIterator(); ObjIt; ++ObjIt )
{
UTexture2D* CurrentObject = *ObjIt;
if (CurrentObject)
{
FAssetData AssetData = FAssetData(CurrentObject);
const uint32 ThumbnailResolution = 64;
TSharedPtr<FAssetThumbnail> LightMapThumbnail = MakeShareable( new FAssetThumbnail( AssetData, ThumbnailResolution, ThumbnailResolution, ThumbnailPool ) );
TSharedPtr<FLightmapItem> NewItem = MakeShareable( new FLightmapItem(CurrentObject->GetPathName(), LightMapThumbnail) );
LightmapItems.Add(NewItem);
}
}
}
}
#undef LOCTEXT_NAMESPACE