You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
1031 lines
30 KiB
C++
1031 lines
30 KiB
C++
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include "Editor/UnrealEd/Public/DragAndDrop/ActorDragDropGraphEdOp.h"
|
|
#include "AssetToolsModule.h"
|
|
#include "ISourceControlModule.h"
|
|
#include "SVectorInputBox.h"
|
|
#include "LevelUtils.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "LevelsView"
|
|
|
|
namespace LevelsView
|
|
{
|
|
/** IDs for list columns */
|
|
static const FName ColumnID_LevelLabel( "Level" );
|
|
static const FName ColumnID_Visibility( "Visibility" );
|
|
static const FName ColumnID_Lock( "Lock" );
|
|
static const FName ColumnID_SCCStatus( "SCC_Status" );
|
|
static const FName ColumnID_Save( "Save" );
|
|
static const FName ColumnID_Kismet( "Kismet" );
|
|
static const FName ColumnID_Color( "Color" );
|
|
static const FName ColumnID_ActorCount( "ActorCount" );
|
|
static const FName ColumnID_LightmassSize( "LightmassSize" );
|
|
static const FName ColumnID_FileSize( "FileSize" );
|
|
static const FName ColumnID_EditorOffset( "EditorOffset" );
|
|
}
|
|
|
|
/**
|
|
* The widget that represents a row in the LevelsView's list view control. Generates widgets for each column on demand.
|
|
*/
|
|
class SLevelsViewRow : public SMultiColumnTableRow< TSharedPtr< FLevelViewModel > >
|
|
{
|
|
|
|
public:
|
|
|
|
SLATE_BEGIN_ARGS( SLevelsViewRow ){}
|
|
SLATE_ATTRIBUTE( FText, HighlightText )
|
|
SLATE_END_ARGS()
|
|
|
|
/**
|
|
* Construct this widget. Called by the SNew() Slate macro.
|
|
*
|
|
* @param InArgs Declaration used by the SNew() macro to construct this widget
|
|
* @param InViewModel The Level the row widget is supposed to represent
|
|
* @param InOwnerTableView The owner of the row widget
|
|
*/
|
|
void Construct( const FArguments& InArgs, TSharedRef< FLevelViewModel > InViewModel, TSharedRef< STableViewBase > InOwnerTableView )
|
|
{
|
|
ViewModel = InViewModel;
|
|
|
|
// Check we have the streaming level
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(LevelStreaming)
|
|
{
|
|
// Cache Transform, so we can update spin box without rotating level till commit
|
|
LevelTransform = LevelStreaming->LevelTransform;
|
|
}
|
|
bSliderMovement = false;
|
|
|
|
HighlightText = InArgs._HighlightText;
|
|
|
|
SMultiColumnTableRow< TSharedPtr< FLevelViewModel > >::Construct( FSuperRowType::FArguments(), InOwnerTableView );
|
|
|
|
ForegroundColor = TAttribute<FSlateColor>( this, &SLevelsViewRow::GetForegroundBasedOnSelection );
|
|
}
|
|
|
|
FSlateColor GetForegroundBasedOnSelection() const
|
|
{
|
|
return FEditorStyle::GetSlateColor("DefaultForeground");
|
|
}
|
|
|
|
protected:
|
|
|
|
/** @return the visibility for the Actor Count column */
|
|
EVisibility IsActorColumnVisible() const
|
|
{
|
|
return (GetDefault<ULevelBrowserSettings>()->bDisplayActorCount)?
|
|
EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
/** @return the visibility for the Lightmass Size column */
|
|
EVisibility IsLightmassSizeColumnVisible() const
|
|
{
|
|
return (GetDefault<ULevelBrowserSettings>()->bDisplayLightmassSize)?
|
|
EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
/** @return the visibility for the File Size column */
|
|
EVisibility IsFileSizeColumnVisible() const
|
|
{
|
|
return (GetDefault<ULevelBrowserSettings>()->bDisplayFileSize)?
|
|
EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
/** @return the visibility for the Editor Offset column */
|
|
EVisibility IsEditorOffsetColumnVisible() const
|
|
{
|
|
return (ViewModel->IsPersistent() || !ViewModel->IsLevel()) ? EVisibility::Hidden : EVisibility::Visible;
|
|
}
|
|
|
|
/**
|
|
* Constructs the widget that represents the specified ColumnID for this Row
|
|
*
|
|
* @param ColumnName A unique ID for a column in this TableView; see SHeaderRow::FColumn for more info.
|
|
*
|
|
* @return a widget to represent the contents of a cell in this row of a TableView.
|
|
*/
|
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
virtual TSharedRef< SWidget > GenerateWidgetForColumn( const FName & ColumnID ) OVERRIDE
|
|
{
|
|
TSharedPtr< SWidget > TableRowContent;
|
|
|
|
if( ColumnID == LevelsView::ColumnID_LevelLabel )
|
|
{
|
|
TableRowContent =
|
|
SNew( SHorizontalBox )
|
|
+SHorizontalBox::Slot()
|
|
.VAlign(VAlign_Center)
|
|
.AutoWidth()
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( this, &SLevelsViewRow::GetFont )
|
|
.Text( ViewModel.Get(), &FLevelViewModel::GetDisplayName )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetColorAndOpacity )
|
|
.HighlightText( HighlightText )
|
|
.ToolTipText( LOCTEXT("DoubleClickToolTip", "Double-Click to make this the current Level") )
|
|
.ShadowOffset( FVector2D(1.0f, 1.0f) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_ActorCount )
|
|
{
|
|
TableRowContent =
|
|
SNew( SHorizontalBox )
|
|
.Visibility(this, &SLevelsViewRow::IsActorColumnVisible )
|
|
+SHorizontalBox::Slot()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( this, &SLevelsViewRow::GetFont )
|
|
.Text( ViewModel.Get(), &FLevelViewModel::GetActorCountString )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetColorAndOpacity )
|
|
.HighlightText( HighlightText )
|
|
.ToolTipText( LOCTEXT("ActorCountToolTip", "The number of Actors in this level") )
|
|
.ShadowOffset( FVector2D(1.0f, 1.0f) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_LightmassSize )
|
|
{
|
|
TableRowContent =
|
|
SNew( SHorizontalBox )
|
|
.Visibility(this, &SLevelsViewRow::IsLightmassSizeColumnVisible )
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1.0f)
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( this, &SLevelsViewRow::GetFont )
|
|
.Text( ViewModel.Get(), &FLevelViewModel::GetLightmassSizeString )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetColorAndOpacity )
|
|
.HighlightText( HighlightText )
|
|
.ToolTipText( LOCTEXT("LightmassSizeToolTip", "The size of the lightmap data for this level") )
|
|
.ShadowOffset( FVector2D(1.0f, 1.0f) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_FileSize )
|
|
{
|
|
TableRowContent =
|
|
SNew( SHorizontalBox )
|
|
.Visibility(this, &SLevelsViewRow::IsFileSizeColumnVisible )
|
|
+SHorizontalBox::Slot()
|
|
.HAlign(HAlign_Right)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( this, &SLevelsViewRow::GetFont )
|
|
.Text( ViewModel.Get(), &FLevelViewModel::GetFileSizeString )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetColorAndOpacity )
|
|
.HighlightText( HighlightText )
|
|
.ToolTipText( LOCTEXT("FileSizeToolTip", "The size of the file for this level") )
|
|
.ShadowOffset( FVector2D(1.0f, 1.0f) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_Visibility )
|
|
{
|
|
TableRowContent =
|
|
SAssignNew( VisibilityButton, SButton )
|
|
.ContentPadding( 0 )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
|
|
.OnClicked( this, &SLevelsViewRow::OnToggleVisibility )
|
|
.ToolTipText( LOCTEXT("VisibilityButtonToolTip", "Toggle Level Visibility") )
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.HAlign( HAlign_Center )
|
|
.VAlign( VAlign_Center )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetVisibilityBrushForLevel )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetForegroundColorForVisibilityButton )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_Lock )
|
|
{
|
|
TableRowContent =
|
|
SAssignNew( LockButton, SButton )
|
|
.ContentPadding( 0 )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
|
|
.OnClicked( this, &SLevelsViewRow::OnToggleLock )
|
|
.ToolTipText( this, &SLevelsViewRow::GetLockToolTipForLevel )
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.HAlign( HAlign_Center )
|
|
.VAlign( VAlign_Center )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetLockBrushForLevel )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetForegroundColorForLockButton )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_Color)
|
|
{
|
|
TableRowContent =
|
|
SAssignNew( ColorButton, SButton )
|
|
.ContentPadding( 0 )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
|
|
.OnClicked( this, &SLevelsViewRow::OnChangeColor )
|
|
.ToolTipText( LOCTEXT("ColorButtonToolTip", "Change Level Color") )
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.HAlign( HAlign_Center )
|
|
.VAlign( VAlign_Center )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetColorBrushForLevel )
|
|
.ColorAndOpacity( TAttribute< FSlateColor >::Create( TAttribute< FSlateColor >::FGetter::CreateSP( this, &SLevelsViewRow::GetLevelColorAndOpacity ) ) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_SCCStatus )
|
|
{
|
|
TableRowContent =
|
|
SNew(SVerticalBox)
|
|
+SVerticalBox::Slot()
|
|
.FillHeight(1.0f)
|
|
.HAlign(HAlign_Center)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew(SHorizontalBox)
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth(1.0f)
|
|
.VAlign(VAlign_Center)
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetSCCStateImage )
|
|
.ToolTipText(this, &SLevelsViewRow::GetSCCStateTooltip)
|
|
]
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_Save )
|
|
{
|
|
TableRowContent =
|
|
SAssignNew( SaveButton, SButton )
|
|
.ContentPadding( 0 )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
|
|
.OnClicked( this, &SLevelsViewRow::OnSave )
|
|
.ToolTipText( LOCTEXT("SaveButtonToolTip", "Save Level") )
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.HAlign( HAlign_Center )
|
|
.VAlign( VAlign_Center )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetSaveBrushForLevel )
|
|
.ColorAndOpacity( TAttribute< FSlateColor >::Create( TAttribute< FSlateColor >::FGetter::CreateSP( this, &SLevelsViewRow::GetSaveButtonColorAndOpacity ) ) )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_Kismet )
|
|
{
|
|
TableRowContent =
|
|
SAssignNew( KismetButton, SButton )
|
|
.ContentPadding( 0 )
|
|
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
|
|
.OnClicked( this, &SLevelsViewRow::OnOpenKismet )
|
|
.ToolTipText( LOCTEXT("KismetButtonToolTip", "Open Level Blueprint") )
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.HAlign( HAlign_Center )
|
|
.VAlign( VAlign_Center )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( this, &SLevelsViewRow::GetKismetBrushForLevel )
|
|
.ColorAndOpacity( this, &SLevelsViewRow::GetForegroundColorForKismetButton )
|
|
]
|
|
;
|
|
}
|
|
else if( ColumnID == LevelsView::ColumnID_EditorOffset )
|
|
{
|
|
TableRowContent =
|
|
SNew( SHorizontalBox )
|
|
.Visibility(this, &SLevelsViewRow::IsEditorOffsetColumnVisible )
|
|
+SHorizontalBox::Slot()
|
|
.Padding(FMargin(10,0,0,0))
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Center)
|
|
.FillWidth(0.25f)
|
|
[
|
|
SNew( SButton )
|
|
.Text( LOCTEXT("EditLevelTransform", "Viewport Edit") )
|
|
.ToolTipText( LOCTEXT("EditLevelToolTip", "Edit level transform in viewport.") )
|
|
.OnClicked( FOnClicked::CreateSP( this, &SLevelsViewRow::OnEditLevelClicked ) )
|
|
.IsEnabled( this, &SLevelsViewRow::LevelTransformAllowed )
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.Padding(FMargin(10,0,0,0))
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Center)
|
|
.FillWidth(0.55f)
|
|
[
|
|
SNew( SVectorInputBox )
|
|
.X( this, &SLevelsViewRow::GetLevelOffset, 0 )
|
|
.Y( this, &SLevelsViewRow::GetLevelOffset, 1 )
|
|
.Z( this, &SLevelsViewRow::GetLevelOffset, 2 )
|
|
.bColorAxisLabels( true )
|
|
.OnXCommitted( this, &SLevelsViewRow::OnSetLevelOffset, 0 )
|
|
.OnYCommitted( this, &SLevelsViewRow::OnSetLevelOffset, 1 )
|
|
.OnZCommitted( this, &SLevelsViewRow::OnSetLevelOffset, 2 )
|
|
.Font( FEditorStyle::GetFontStyle( TEXT("PropertyWindow.NormalFont") ) ) // Look the same as transform editing in the details panel
|
|
.IsEnabled( this, &SLevelsViewRow::LevelEditTextTransformAllowed )
|
|
]
|
|
+SHorizontalBox::Slot()
|
|
.Padding(FMargin(10,0,0,0))
|
|
.HAlign(HAlign_Fill)
|
|
.VAlign(VAlign_Center)
|
|
.FillWidth(0.2f)
|
|
[
|
|
SNew( SNumericEntryBox<float> )
|
|
.IsEnabled( this, &SLevelsViewRow::LevelEditTextTransformAllowed )
|
|
.Font( FEditorStyle::GetFontStyle( TEXT("PropertyWindow.NormalFont") ) )
|
|
.Delta(90.0f)
|
|
.AllowSpin( true )
|
|
.MinValue(0.0f)
|
|
.MaxValue(270.0f)
|
|
.MinSliderValue(0.0f)
|
|
.MaxSliderValue(270.0f)
|
|
.Value( this, &SLevelsViewRow::GetLevelRotation )
|
|
.OnValueChanged( this, &SLevelsViewRow::OnSetLevelRotation )
|
|
.OnValueCommitted( this, &SLevelsViewRow::OnCommitLevelRotation )
|
|
.OnBeginSliderMovement( this, &SLevelsViewRow::OnBeginLevelRotatonSlider )
|
|
.OnEndSliderMovement( this, &SLevelsViewRow::OnEndLevelRotatonSlider )
|
|
.LabelPadding(0)
|
|
.Label()
|
|
[
|
|
SNumericEntryBox<float>::BuildLabel( LOCTEXT("LevelRotation_Label", "Yaw"), FLinearColor::White, SNumericEntryBox<float>::BlueLabelBackgroundColor )
|
|
]
|
|
]
|
|
;
|
|
}
|
|
else
|
|
{
|
|
checkf(false, TEXT("Unknown ColumnID provided to SLevelsView") );
|
|
}
|
|
|
|
return TableRowContent.ToSharedRef();
|
|
}
|
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
|
|
|
/**
|
|
* Called during drag and drop when the drag leaves a widget.
|
|
*
|
|
* @param DragDropEvent The drag and drop event.
|
|
*/
|
|
virtual void OnDragLeave( const FDragDropEvent& DragDropEvent ) OVERRIDE
|
|
{
|
|
TSharedPtr< FActorDragDropGraphEdOp > DragActorOp = DragDropEvent.GetOperationAs< FActorDragDropGraphEdOp >();
|
|
if (DragActorOp.IsValid())
|
|
{
|
|
DragActorOp->ResetToDefaultToolTip();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called during drag and drop when the the mouse is being dragged over a widget.
|
|
*
|
|
* @param MyGeometry The geometry of the widget receiving the event.
|
|
* @param DragDropEvent The drag and drop event.
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
virtual FReply OnDragOver( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent ) OVERRIDE
|
|
{
|
|
TSharedPtr< FActorDragDropGraphEdOp > DragActorOp = DragDropEvent.GetOperationAs< FActorDragDropGraphEdOp >();
|
|
if (!DragActorOp.IsValid())
|
|
{
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
bool bCanAssign = false;
|
|
FText Message;
|
|
if( DragActorOp->Actors.Num() > 1 )
|
|
{
|
|
bCanAssign = ViewModel->CanAssignActors( DragActorOp->Actors, OUT Message );
|
|
}
|
|
else
|
|
{
|
|
bCanAssign = ViewModel->CanAssignActor( DragActorOp->Actors[ 0 ], OUT Message );
|
|
}
|
|
|
|
if ( bCanAssign )
|
|
{
|
|
DragActorOp->SetToolTip( FActorDragDropGraphEdOp::ToolTip_CompatibleGeneric, Message );
|
|
}
|
|
else
|
|
{
|
|
DragActorOp->SetToolTip( FActorDragDropGraphEdOp::ToolTip_IncompatibleGeneric, Message );
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called when the user is dropping something onto a widget; terminates drag and drop.
|
|
*
|
|
* @param MyGeometry The geometry of the widget receiving the event.
|
|
* @param DragDropEvent The drag and drop event.
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
virtual FReply OnDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent ) OVERRIDE
|
|
{
|
|
TSharedPtr< FActorDragDropGraphEdOp > DragActorOp = DragDropEvent.GetOperationAs< FActorDragDropGraphEdOp >();
|
|
if (!DragActorOp.IsValid())
|
|
{
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
ViewModel->AddActors( DragActorOp->Actors );
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/** @return the FSlateFontInfo for the Level label; bold if current or level invalid */
|
|
FSlateFontInfo GetFont() const
|
|
{
|
|
if ( ViewModel->IsCurrent() ||
|
|
(!ViewModel->IsLevel() && ViewModel->IsLevelStreaming()) )
|
|
{
|
|
return FEditorStyle::GetFontStyle("LevelBrowser.LabelFontBold");
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetFontStyle("LevelBrowser.LabelFont");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the appropriate SlateColor for each button depending on the button's current state
|
|
*
|
|
* @return The ForegroundColor
|
|
*/
|
|
FSlateColor GetForegroundColorForVisibilityButton() const
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
FSlateColor GetForegroundColorForLockButton() const
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
FSlateColor GetForegroundColorForKismetButton() const
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
|
|
/**
|
|
* Returns the Color and Opacity for displaying the bound Level's Name.
|
|
* The Color and Opacity changes depending on whether a drag/drop operation is occurring
|
|
*
|
|
* @return The SlateColor to render the Level's name in
|
|
*/
|
|
FSlateColor GetColorAndOpacity() const
|
|
{
|
|
if ( ViewModel->IsCurrent() )
|
|
{
|
|
return FLinearColor( 0.12f, 0.56f, 1.0f );
|
|
}
|
|
|
|
// Force the text to display red if level is missing
|
|
if (!ViewModel->IsLevel() && ViewModel->IsLevelStreaming())
|
|
{
|
|
return FLinearColor( 1.0f, 0.0f, 0.0f);
|
|
}
|
|
|
|
if ( !FSlateApplication::Get().IsDragDropping() )
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
|
|
bool bCanAcceptDrop = false;
|
|
TSharedPtr<FDragDropOperation> DragDropOp = FSlateApplication::Get().GetDragDroppingContent();
|
|
|
|
if (DragDropOp.IsValid() && DragDropOp->IsOfType<FActorDragDropGraphEdOp>())
|
|
{
|
|
TSharedPtr<FActorDragDropGraphEdOp> DragDropActorOp = StaticCastSharedPtr<FActorDragDropGraphEdOp>(DragDropOp);
|
|
|
|
FText Message;
|
|
bCanAcceptDrop = ViewModel->CanAssignActors( DragDropActorOp->Actors, OUT Message );
|
|
}
|
|
|
|
return ( bCanAcceptDrop ) ? FSlateColor::UseForeground() : FLinearColor( 0.30f, 0.30f, 0.30f );
|
|
}
|
|
|
|
/**
|
|
* Returns the Color and Opacity for displaying the bound Level's Name.
|
|
* The Color and Opacity changes depending on whether a drag/drop operation is occurring
|
|
*
|
|
* @return The SlateColor to render the Level's name in
|
|
*/
|
|
FSlateColor GetLockButtonColorAndOpacity() const
|
|
{
|
|
if ( !ViewModel->GetLevel().IsValid() )
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
|
|
return ( ViewModel->IsPersistent() ) ? FSlateColor::UseForeground() : FLinearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
|
}
|
|
|
|
/**
|
|
* Returns the Color and Opacity for displaying the Level's Save Button.
|
|
*
|
|
* @return The SlateColor to render the Level's Saves icon
|
|
*/
|
|
FSlateColor GetSaveButtonColorAndOpacity() const
|
|
{
|
|
if ( ViewModel->IsDirty() )
|
|
{
|
|
return FLinearColor::White;
|
|
}
|
|
else
|
|
{
|
|
return FSlateColor::UseForeground();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the Color and Opacity for displaying the Level's color.
|
|
*
|
|
* @return The SlateColor to render the Level's color icon
|
|
*/
|
|
FSlateColor GetLevelColorAndOpacity() const
|
|
{
|
|
return ViewModel->GetColor();
|
|
}
|
|
|
|
/**
|
|
* Called when the user clicks on the visibility icon for a Level's row widget
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
FReply OnToggleVisibility()
|
|
{
|
|
ViewModel->ToggleVisibility();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called when the user clicks on the lock icon for a Level's row widget
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
FReply OnToggleLock()
|
|
{
|
|
// If were locking a level, lets make sure to close the level transform mode if its the same level currently selected for edit
|
|
FEdModeLevel* LevelMode = static_cast<FEdModeLevel*>(GEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_Level ));
|
|
if( LevelMode )
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if( LevelMode->IsEditing( LevelStreaming ) )
|
|
{
|
|
GEditorModeTools().DeactivateMode( FBuiltinEditorModes::EM_Level );
|
|
}
|
|
}
|
|
|
|
const FScopedTransaction Transaction( LOCTEXT("ToggleLevelLock", "Toggle Level Lock") );
|
|
|
|
ViewModel->ToggleLock();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called when the user clicks on the save icon for a Level's row widget
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
FReply OnSave()
|
|
{
|
|
ViewModel->Save();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called when the user clicks on the kismet icon for a Level's row widget
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
FReply OnOpenKismet()
|
|
{
|
|
ViewModel->OpenKismet();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called when the user clicks on the color icon for a Level's row widget
|
|
*
|
|
* @return A reply that indicated whether this event was handled.
|
|
*/
|
|
FReply OnChangeColor()
|
|
{
|
|
ViewModel->ChangeColor(AsShared());
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Called to get the Slate Image Brush representing the visibility state of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The SlateBrush representing the Level's visibility state
|
|
*/
|
|
const FSlateBrush* GetVisibilityBrushForLevel() const
|
|
{
|
|
if ( ViewModel->IsLevel() )
|
|
{
|
|
if ( ViewModel->IsVisible() )
|
|
{
|
|
return VisibilityButton->IsHovered() ? FEditorStyle::GetBrush( "Level.VisibleHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.VisibleIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
return VisibilityButton->IsHovered() ? FEditorStyle::GetBrush( "Level.NotVisibleHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.NotVisibleIcon16x" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to get the Slate Image Brush representing the lock state of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The SlateBrush representing the Level's lock state
|
|
*/
|
|
const FSlateBrush* GetLockBrushForLevel() const
|
|
{
|
|
if ( !ViewModel->IsLevel() || ViewModel->IsPersistent() )
|
|
{
|
|
//Locking the persistent level is not allowed; stub in a different brush
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
//Non-Persistent
|
|
if ( GEngine && GEngine->bLockReadOnlyLevels )
|
|
{
|
|
if(ViewModel->IsReadOnly())
|
|
{
|
|
return LockButton->IsHovered() ? FEditorStyle::GetBrush( "Level.ReadOnlyLockedHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.ReadOnlyLockedIcon16x" );
|
|
}
|
|
}
|
|
|
|
if ( ViewModel->IsLocked() )
|
|
{
|
|
return LockButton->IsHovered() ? FEditorStyle::GetBrush( "Level.LockedHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.LockedIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
return LockButton->IsHovered() ? FEditorStyle::GetBrush( "Level.UnlockedHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.UnlockedIcon16x" );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to get the tooltip string representing the lock state of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The tooltip representing the Level's lock state
|
|
*/
|
|
FString GetLockToolTipForLevel() const
|
|
{
|
|
//Non-Persistent
|
|
|
|
if ( GEngine && GEngine->bLockReadOnlyLevels )
|
|
{
|
|
if(ViewModel->IsReadOnly())
|
|
{
|
|
return LOCTEXT("ReadOnly_LockButtonToolTip", "Read-Only levels are locked!").ToString();
|
|
}
|
|
}
|
|
|
|
return LOCTEXT("LockButtonToolTip", "Toggle Level Lock").ToString();
|
|
}
|
|
|
|
FString GetSCCStateTooltip() const
|
|
{
|
|
ULevel* Level = ViewModel->GetLevel().Get();
|
|
if (Level != NULL)
|
|
{
|
|
FSourceControlStatePtr SourceControlState = ISourceControlModule::Get().GetProvider().GetState(Level->GetOutermost(), EStateCacheUsage::Use);
|
|
if(SourceControlState.IsValid())
|
|
{
|
|
return SourceControlState->GetDisplayTooltip().ToString();
|
|
}
|
|
}
|
|
|
|
return FString();
|
|
}
|
|
|
|
const FSlateBrush* GetSCCStateImage() const
|
|
{
|
|
ULevel* Level = ViewModel->GetLevel().Get();
|
|
if (Level != NULL)
|
|
{
|
|
FSourceControlStatePtr SourceControlState = ISourceControlModule::Get().GetProvider().GetState(Level->GetOutermost(), EStateCacheUsage::Use);
|
|
if(SourceControlState.IsValid())
|
|
{
|
|
return FEditorStyle::GetBrush(SourceControlState->GetSmallIconName());
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Called to get the Slate Image Brush representing the save state of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The SlateBrush representing the Level's save state
|
|
*/
|
|
const FSlateBrush* GetSaveBrushForLevel() const
|
|
{
|
|
if ( ViewModel->IsLevel() )
|
|
{
|
|
if ( ViewModel->IsLocked() )
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.SaveDisabledIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
if ( ViewModel->IsDirty() )
|
|
{
|
|
return SaveButton->IsHovered() ? FEditorStyle::GetBrush( "Level.SaveModifiedHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.SaveModifiedIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
return SaveButton->IsHovered() ? FEditorStyle::GetBrush( "Level.SaveHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.SaveIcon16x" );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to get the Slate Image Brush representing the kismet state of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The SlateBrush representing the Level's kismet state
|
|
*/
|
|
const FSlateBrush* GetKismetBrushForLevel() const
|
|
{
|
|
if ( ViewModel->IsLevel() )
|
|
{
|
|
if ( ViewModel->HasKismet() )
|
|
{
|
|
return KismetButton->IsHovered() ? FEditorStyle::GetBrush( "Level.ScriptHighlightIcon16x" ) :
|
|
FEditorStyle::GetBrush( "Level.ScriptIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called to get the Slate Image Brush representing the color of
|
|
* the Level this row widget represents
|
|
*
|
|
* @return The SlateBrush representing the Level's color
|
|
*/
|
|
const FSlateBrush* GetColorBrushForLevel() const
|
|
{
|
|
if ( !ViewModel->IsLevel() || ViewModel->IsPersistent() )
|
|
{
|
|
//stub in a different brush for the persistent level, since the color cannot be changed
|
|
return FEditorStyle::GetBrush( "Level.EmptyIcon16x" );
|
|
}
|
|
else
|
|
{
|
|
return FEditorStyle::GetBrush( "Level.ColorIcon40x" );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Transform column, to set the new values.
|
|
*
|
|
* @param NewValue The new value entered.
|
|
* @param CommitInfo The way in which the value was committed, currently ignored, we always use the new value.
|
|
* @param Axis The axis being edited.
|
|
*/
|
|
void OnSetLevelOffset( float NewValue, ETextCommit::Type CommitInfo, int32 Axis )
|
|
{
|
|
// Check we have the streaming level
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(!LevelStreaming)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Setup a new transform
|
|
FVector Translation = LevelTransform.GetTranslation();
|
|
Translation[Axis] = NewValue;
|
|
LevelTransform.SetTranslation(Translation);
|
|
FLevelUtils::SetEditorTransform(LevelStreaming, LevelTransform);
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Transform column, to get the current values.
|
|
*
|
|
* @param Axis The axis to return the value for.
|
|
*
|
|
* @return The current value of the translation for given axis.
|
|
*/
|
|
TOptional<float> GetLevelOffset( int32 Axis ) const
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(!LevelStreaming)
|
|
{
|
|
FVector Translation = LevelTransform.GetTranslation();
|
|
return Translation[Axis];
|
|
}
|
|
FVector Translation = LevelStreaming->LevelTransform.GetTranslation();
|
|
return Translation[Axis];
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Rotation column, to commit the new values.
|
|
*
|
|
* @param NewValue The new value entered.
|
|
* @param CommitInfo The way in which the value was committed, currently ignored, we always use the new value.
|
|
*/
|
|
void OnCommitLevelRotation( float NewValue, ETextCommit::Type CommitInfo )
|
|
{
|
|
// Check we have the streaming level
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(!LevelStreaming)
|
|
{
|
|
return;
|
|
}
|
|
// Use LevelTransform set by OnSetLeveRotation as OnCommitLevelRotation NewValue seems to ignore min delta of a spin box
|
|
FLevelUtils::SetEditorTransform(LevelStreaming, LevelTransform);
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Rotation column, to set the new values.
|
|
*
|
|
* @param NewValue The new value entered.
|
|
*/
|
|
void OnSetLevelRotation( float NewValue )
|
|
{
|
|
FRotator Rotation = LevelTransform.GetRotation().Rotator();
|
|
Rotation.Yaw = NewValue;
|
|
LevelTransform.SetRotation(Rotation.Quaternion());
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Rotation column, to set weve started spinning the value.
|
|
*/
|
|
void OnBeginLevelRotatonSlider()
|
|
{
|
|
bSliderMovement = true;
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Rotation column, to set weve stopped spinning the value.
|
|
*
|
|
* @param NewValue The new value entered.
|
|
*/
|
|
void OnEndLevelRotatonSlider( float NewValue )
|
|
{
|
|
bSliderMovement = false;
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Transform column, to get the current values.
|
|
*
|
|
* @return The current value of the Level Yaw.
|
|
*/
|
|
TOptional<float> GetLevelRotation() const
|
|
{
|
|
// If were not using the spin box use the actual transform instead of cached as it may have changed with the view port widget
|
|
if( !bSliderMovement )
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(LevelStreaming)
|
|
{
|
|
return LevelStreaming->LevelTransform.GetRotation().Rotator().Yaw;
|
|
}
|
|
}
|
|
return LevelTransform.GetRotation().Rotator().Yaw;
|
|
}
|
|
|
|
/**
|
|
* Called by the Editor Level Edit Viewport button.
|
|
*/
|
|
FReply OnEditLevelClicked()
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(!LevelStreaming)
|
|
{
|
|
return FReply::Handled();
|
|
}
|
|
|
|
if( !GEditorModeTools().IsModeActive(FBuiltinEditorModes::EM_Level))
|
|
{
|
|
// Activate Level Mode if it was not active
|
|
GEditorModeTools().ActivateMode( FBuiltinEditorModes::EM_Level );
|
|
}
|
|
|
|
FEdModeLevel* ActiveMode = static_cast<FEdModeLevel*>(GEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_Level ));
|
|
check(ActiveMode != NULL);
|
|
|
|
if( ActiveMode->IsEditing(LevelStreaming) == true )
|
|
{
|
|
// Toggle this mode off if already editing this level
|
|
GEditorModeTools().DeactivateMode(FBuiltinEditorModes::EM_Level);
|
|
|
|
// Cache Transform, as it might of changed by doing a view port edit
|
|
LevelTransform = LevelStreaming->LevelTransform;
|
|
}
|
|
else
|
|
{
|
|
// Set the level we now want to edit
|
|
ActiveMode->SetLevel(LevelStreaming);
|
|
}
|
|
|
|
return FReply::Handled();
|
|
}
|
|
|
|
bool LevelTransformAllowed() const
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
if(LevelStreaming)
|
|
{
|
|
if( LevelStreaming->GetLoadedLevel()->bIsVisible && !LevelStreaming->bLocked )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool LevelEditTextTransformAllowed() const
|
|
{
|
|
ULevelStreaming* LevelStreaming = ViewModel->GetLevelStreaming().Get();
|
|
FEdModeLevel* ActiveMode = static_cast<FEdModeLevel*>(GEditorModeTools().GetActiveMode( FBuiltinEditorModes::EM_Level ));
|
|
if( ActiveMode && ActiveMode->IsEditing(LevelStreaming) == true )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return LevelTransformAllowed();
|
|
}
|
|
|
|
private:
|
|
|
|
/** The Level associated with this row of data */
|
|
TSharedPtr< FLevelViewModel > ViewModel;
|
|
|
|
/** The visibility button for the Level */
|
|
TSharedPtr< SButton > VisibilityButton;
|
|
|
|
/** The lock button for the Level */
|
|
TSharedPtr< SButton > LockButton;
|
|
|
|
/** The save button for the Level */
|
|
TSharedPtr< SButton > SaveButton;
|
|
|
|
/** The kismet button for the Level */
|
|
TSharedPtr< SButton > KismetButton;
|
|
|
|
/** The color button for the Level */
|
|
TSharedPtr< SButton > ColorButton;
|
|
|
|
/** The string to highlight on any text contained in the row widget */
|
|
TAttribute< FText > HighlightText;
|
|
|
|
/** Cached Level Transform, so we don't have to edit the original before we commit change*/
|
|
FTransform LevelTransform;
|
|
|
|
/** Set When the user is using the rotation spin box so we can update the value with the cached Transform */
|
|
bool bSliderMovement;
|
|
};
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|