Files
UnrealEngineUWP/Engine/Source/Editor/NewLevelDialog/Private/NewLevelDialogModule.cpp
rolando caloca 2b8c415f74 UE4.22 - Remove almost all of ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER
#rb none
#jira
#rnx

#ROBOMERGE-OWNER: rolando.caloca
#ROBOMERGE-AUTHOR: rolando.caloca
#ROBOMERGE-SOURCE: CL 5054105 in //UE4/Release-4.22/...
#ROBOMERGE-BOT: RELEASE (Release-4.22 -> Main)

[CL 5054376 by rolando caloca in Main branch]
2019-02-18 18:35:01 -05:00

338 lines
9.5 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "NewLevelDialogModule.h"
#include "Layout/Margin.h"
#include "Textures/SlateShaderResource.h"
#include "Rendering/RenderingCommon.h"
#include "Rendering/DrawElements.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/SBoxPanel.h"
#include "Widgets/SOverlay.h"
#include "Widgets/SWindow.h"
#include "Widgets/SLeafWidget.h"
#include "Widgets/Text/STextBlock.h"
#include "Modules/ModuleManager.h"
#include "Misc/PackageName.h"
#include "Framework/Application/SlateApplication.h"
#include "Widgets/Layout/SBorder.h"
#include "Widgets/Layout/SWrapBox.h"
#include "Widgets/Images/SImage.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Layout/SScrollBox.h"
#include "EditorStyleSet.h"
#include "RenderingThread.h"
#include "Editor/UnrealEdEngine.h"
#include "Engine/Texture2D.h"
#include "UnrealEdGlobals.h"
#define LOCTEXT_NAMESPACE "NewLevelDialog"
/**
* Widget class for rendering a UTexture2D in Slate
* Work-in-progress idea that is defined here so that others don't use it yet
*/
class STexture2DView : public SLeafWidget, public ISlateViewport, private TSlateTexture<FTexture2DRHIRef>
{
public:
SLATE_BEGIN_ARGS(STexture2DView) {}
SLATE_END_ARGS()
void Construct( const FArguments& InArgs, UTexture2D* InTexture2D )
{
Size = FIntPoint(InTexture2D->GetSizeX(), InTexture2D->GetSizeY());
STexture2DView* TextureView = this;
ENQUEUE_RENDER_COMMAND(UpdateSTexture2DView)(
[TextureView, InTexture2D](FRHICommandListImmediate& RHICmdList)
{
TextureView->ShaderResource = ((FTexture2DResource*)(InTexture2D->Resource))->GetTexture2DRHI();
});
}
virtual int32 OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const override
{
FSlateDrawElement::MakeViewport(
OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), SharedThis( this ), ESlateDrawEffect::NoBlending, InWidgetStyle.GetColorAndOpacityTint());
return LayerId;
}
virtual FVector2D ComputeDesiredSize(float) const override
{
return FVector2D(Size.X, Size.Y);
}
virtual FIntPoint GetSize() const override { return Size; }
virtual class FSlateShaderResource* GetViewportRenderTargetTexture() const override { return ShaderResource ? (FSlateShaderResource*)this : NULL; }
virtual bool RequiresVsync() const override { return false; }
// FSlateShaderResource implementation.
virtual uint32 GetWidth() const override { return Size.X; }
virtual uint32 GetHeight() const override { return Size.Y; }
private:
FIntPoint Size;
};
/**
* Main widget class showing a table of level templates as labeled thumbnails
* for the user to select by clicking.
*/
class SNewLevelDialog : public SCompoundWidget
{
private:
struct FTemplateListItem
{
FTemplateMapInfo TemplateMapInfo;
bool bIsNewLevelItem;
};
public:
SLATE_BEGIN_ARGS(SNewLevelDialog)
{}
/** A pointer to the parent window */
SLATE_ATTRIBUTE(TSharedPtr<SWindow>, ParentWindow)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs)
{
ParentWindowPtr = InArgs._ParentWindow.Get();
OutTemplateMapPackageName = TEXT("");
bUserClickedOkay = false;
if ( GUnrealEd )
{
const TArray<FTemplateMapInfo>& TemplateInfoList = GUnrealEd->TemplateMapInfos;
// Build a list of items - one for each template
for (int32 i=0; i < TemplateInfoList.Num(); i++)
{
TSharedPtr<FTemplateListItem> Item = MakeShareable(new FTemplateListItem());
Item->TemplateMapInfo = TemplateInfoList[i];
Item->bIsNewLevelItem = false;
TemplateItemsList.Add(Item);
}
}
// Add an extra item for creating a new, blank level
TSharedPtr<FTemplateListItem> NewItem = MakeShareable(new FTemplateListItem());
NewItem->bIsNewLevelItem = true;
TemplateItemsList.Add(NewItem);
TSharedRef<SButton> CancelButton = SNew(SButton)
.ContentPadding(FMargin(10,3))
.Text(LOCTEXT("Cancel", "Cancel"))
.OnClicked(this, &SNewLevelDialog::OnCancelClicked);
this->ChildSlot
[
SNew(SBorder)
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.FillHeight(1)
[
SNew(SScrollBox)
+SScrollBox::Slot()
.Padding(15)
[
SAssignNew(TemplatesWrapBox, SWrapBox)
.PreferredWidth(DEFAULT_WINDOW_SIZE.X - 35.0) // apparently no way to auto size the width of wrap boxes
]
]
+SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Right)
.Padding(6,2)
[
CancelButton
]
]
];
// Give the cancel button initial focus so that the escape key can be checked for
ParentWindowPtr.Pin().Get()->SetWidgetToFocusOnActivate( CancelButton );
// Insert items into slots in the wrap box, TemplatesWrapBox
AddItemsToWrapBox();
}
/** A default window size for the dialog */
static const FVector2D DEFAULT_WINDOW_SIZE;
/** Level thumbnail image size in pixels */
static const float THUMBNAIL_SIZE;
FString GetChosenTemplate() const { return OutTemplateMapPackageName; }
bool IsTemplateChosen() const { return bUserClickedOkay; }
private:
void AddItemsToWrapBox()
{
for (int32 i = 0; i < TemplateItemsList.Num(); i++)
{
TSharedPtr<FTemplateListItem> Template = TemplateItemsList[i];
TemplatesWrapBox->AddSlot()
[
GetWidgetForTemplate(TemplateItemsList[i])
];
}
}
TSharedRef<SWidget> GetWidgetForTemplate(TSharedPtr<FTemplateListItem> Template)
{
TSharedPtr<SWidget> Image;
FText Text = FText::GetEmpty();
if (Template->bIsNewLevelItem)
{
// New level item
Image = SNew(SImage).Image(FEditorStyle::GetBrush(TEXT("NewLevelDialog.Blank")));
Text = LOCTEXT("NewLevelItemLabel", "Empty Level");
}
else if (Template->TemplateMapInfo.ThumbnailTexture)
{
// Level with thumbnail
Image = SNew(STexture2DView, Template->TemplateMapInfo.ThumbnailTexture);
Text = FText::FromString(Template->TemplateMapInfo.ThumbnailTexture->GetName().Replace(TEXT("_"), TEXT(" ")));
}
else
{
// Level with no thumbnail
Image = SNew(SImage).Image(FEditorStyle::GetBrush(TEXT("NewLevelDialog.Default")));
Text = FText::FromString(FPackageName::GetShortName(Template->TemplateMapInfo.Map).Replace(TEXT("_"), TEXT(" ")));
}
Image->SetCursor(EMouseCursor::Hand);
return SNew(SBox)
.HeightOverride(THUMBNAIL_SIZE)
.WidthOverride(THUMBNAIL_SIZE)
.Padding(5)
[
SNew(SButton)
.ButtonStyle( FEditorStyle::Get(), "NoBorder" )
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.OnClicked( this, &SNewLevelDialog::OnTemplateClicked, Template )
[
SNew(SBorder)
.BorderImage(FEditorStyle::GetBrush(TEXT("NewLevelDialog.BlackBorder")))
.ColorAndOpacity(this, &SNewLevelDialog::GetTemplateColor, Image )
.Padding(6)
[
SNew(SOverlay)
+SOverlay::Slot()
[
Image.ToSharedRef()
]
+SOverlay::Slot()
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Right)
.Padding(FMargin(0, 0, 5, 5))
[
SNew(STextBlock)
.Visibility(EVisibility::HitTestInvisible)
.ShadowOffset(FVector2D(1.0f, 1.0f))
.ColorAndOpacity(FLinearColor(1,1,1))
.Text(Text)
]
]
]
];
}
FReply OnTemplateClicked(TSharedPtr<FTemplateListItem> Template)
{
if (!Template->bIsNewLevelItem)
{
OutTemplateMapPackageName = Template->TemplateMapInfo.Map;
}
bUserClickedOkay = true;
ParentWindowPtr.Pin()->RequestDestroyWindow();
return FReply::Handled();
}
FReply OnCancelClicked()
{
bUserClickedOkay = false;
ParentWindowPtr.Pin()->RequestDestroyWindow();
return FReply::Handled();
}
FLinearColor GetTemplateColor(TSharedPtr<SWidget> TemplateWidget) const
{
if (TemplateWidget->IsHovered())
{
return FLinearColor(1,1,1);
}
else
{
return FLinearColor(0.75,0.75,0.75);
}
}
virtual FReply OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent ) override
{
if( InKeyEvent.GetKey() == EKeys::Escape )
{
return OnCancelClicked();
}
return SCompoundWidget::OnKeyDown( MyGeometry, InKeyEvent );
}
/** Pointer to the parent window, so we know to destroy it when done */
TWeakPtr<SWindow> ParentWindowPtr;
TArray<TSharedPtr<FTemplateListItem>> TemplateItemsList;
TSharedPtr<SWrapBox> TemplatesWrapBox;
FString OutTemplateMapPackageName;
bool bUserClickedOkay;
};
const FVector2D SNewLevelDialog::DEFAULT_WINDOW_SIZE = FVector2D(527, 418);
const float SNewLevelDialog::THUMBNAIL_SIZE = 160.0f;
IMPLEMENT_MODULE( FNewLevelDialogModule, NewLevelDialog );
const FName FNewLevelDialogModule::NewLevelDialogAppIdentifier( TEXT( "NewLevelDialogApp" ) );
void FNewLevelDialogModule::StartupModule()
{
}
void FNewLevelDialogModule::ShutdownModule()
{
}
bool FNewLevelDialogModule::CreateAndShowNewLevelDialog( const TSharedPtr<const SWidget> ParentWidget, FString& OutTemplateMapPackageName )
{
TSharedPtr<SWindow> NewLevelWindow =
SNew(SWindow)
.Title(LOCTEXT("WindowHeader", "New Level"))
.ClientSize(SNewLevelDialog::DEFAULT_WINDOW_SIZE)
.SizingRule( ESizingRule::UserSized )
.SupportsMinimize(false)
.SupportsMaximize(false);
TSharedRef<SNewLevelDialog> NewLevelDialog =
SNew(SNewLevelDialog)
.ParentWindow(NewLevelWindow);
NewLevelWindow->SetContent(NewLevelDialog);
FSlateApplication::Get().AddModalWindow(NewLevelWindow.ToSharedRef(), ParentWidget);
OutTemplateMapPackageName = NewLevelDialog->GetChosenTemplate();
return NewLevelDialog->IsTemplateChosen();
}
#undef LOCTEXT_NAMESPACE