187 lines
4.7 KiB
C++
187 lines
4.7 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Layout/Visibility.h"
|
|
#include "Styling/SlateColor.h"
|
|
#include "Input/Reply.h"
|
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
|
#include "Widgets/SCompoundWidget.h"
|
|
#include "Widgets/SBoxPanel.h"
|
|
#include "Widgets/SOverlay.h"
|
|
#include "Styling/AppStyle.h"
|
|
#include "ActorLayerCollectionViewModel.h"
|
|
#include "Widgets/Text/STextBlock.h"
|
|
#include "Widgets/Layout/SBorder.h"
|
|
#include "Widgets/Layout/SWrapBox.h"
|
|
#include "Widgets/Images/SImage.h"
|
|
#include "Widgets/Input/SButton.h"
|
|
#include "ActorLayerViewModel.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "LayerCloud"
|
|
|
|
class ULayer;
|
|
|
|
/**
|
|
* Displays a list of Layers in a "cloud" like format to the user
|
|
*/
|
|
class SActorLayerCloud : public SCompoundWidget
|
|
{
|
|
public:
|
|
|
|
SLATE_BEGIN_ARGS( SActorLayerCloud ) {}
|
|
SLATE_END_ARGS()
|
|
|
|
~SActorLayerCloud()
|
|
{
|
|
// Remove all delegates we registered
|
|
ViewModel->OnLayersChanged().RemoveAll( this );
|
|
}
|
|
|
|
/**
|
|
* Construct this widget. Called by the SNew() Slate macro.
|
|
*
|
|
* @param InArgs Declaration used by the SNew() macro to construct this widget
|
|
* @param InViewModel The UI logic not specific to slate
|
|
*/
|
|
void Construct( const FArguments& InArgs, const TSharedRef< FActorLayerCollectionViewModel >& InViewModel )
|
|
{
|
|
ViewModel = InViewModel;
|
|
|
|
ChildSlot
|
|
[
|
|
SNew( SOverlay )
|
|
+SOverlay::Slot()
|
|
[
|
|
SAssignNew( TagArea, SWrapBox )
|
|
.UseAllottedSize( true )
|
|
]
|
|
|
|
+SOverlay::Slot()
|
|
.VAlign( VAlign_Center )
|
|
.HAlign( HAlign_Center )
|
|
[
|
|
SNew( STextBlock )
|
|
.Text( LOCTEXT("NoLayersMessage", "No Layers") )
|
|
.Visibility( this, &SActorLayerCloud::GetNoLayersMessageVisibility )
|
|
]
|
|
];
|
|
|
|
Reconstruct();
|
|
|
|
ViewModel->OnLayersChanged().AddSP( this, &SActorLayerCloud::OnLayersChanged );
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/** Rebuilds the set of individual widgets representing each displayed Layer */
|
|
void Reconstruct()
|
|
{
|
|
TagArea->ClearChildren();
|
|
|
|
for( auto LayerIt = ViewModel->GetLayers().CreateConstIterator(); LayerIt; ++LayerIt )
|
|
{
|
|
const TSharedPtr< FActorLayerViewModel > Layer = *LayerIt;
|
|
|
|
TagArea->AddSlot()
|
|
.Padding( 4, 4 )
|
|
[
|
|
SNew( SBorder )
|
|
.BorderBackgroundColor( FLinearColor(.2f,.2f,.2f,.2f) )
|
|
.BorderImage( FAppStyle::GetBrush( TEXT( "LayerCloud.Item.BorderImage" ) ) )
|
|
.Content()
|
|
[
|
|
SNew( SHorizontalBox )
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.VAlign( VAlign_Center )
|
|
.Padding( 4, 0 )
|
|
[
|
|
SNew( STextBlock )
|
|
.Font( FAppStyle::GetFontStyle( FName( "LayerCloud.Item.LabelFont" ) ) )
|
|
.ColorAndOpacity( FSlateColor::UseForeground() )
|
|
.Text( Layer.Get(), &FActorLayerViewModel::GetName )
|
|
]
|
|
|
|
+ SHorizontalBox::Slot()
|
|
.AutoWidth()
|
|
.Padding( 2, 0 )
|
|
[
|
|
SNew( SButton )
|
|
.ContentPadding( 0 )
|
|
.VAlign( VAlign_Center )
|
|
.OnClicked( this, &SActorLayerCloud::OnRemoveLayerFromActorsClicked, Layer )
|
|
.ButtonStyle( FAppStyle::Get(), "NoBorder" )
|
|
.ToolTipText( LOCTEXT("RemoveLayerButton", "Remove from Layer") )
|
|
.Content()
|
|
[
|
|
SNew( SImage )
|
|
.Image( FAppStyle::GetBrush( TEXT( "LayerCloud.Item.ClearButton" ) ) )
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called whenever a change is made to Layers
|
|
*
|
|
* @param Action The action taken on one or more layers
|
|
* @param ChangedLayer The layer that changed
|
|
* @param ChangedProperty The property that changed
|
|
*/
|
|
void OnLayersChanged( const ELayersAction::Type Action, const TWeakObjectPtr< ULayer >& ChangedLayer, const FName& ChangedProperty )
|
|
{
|
|
if( Action == ELayersAction::Rename )
|
|
{
|
|
return;
|
|
}
|
|
|
|
Reconstruct();
|
|
}
|
|
|
|
/**
|
|
* Returns the current visibility for the NoLayers message
|
|
*/
|
|
EVisibility GetNoLayersMessageVisibility() const
|
|
{
|
|
return ( TagArea->GetChildren()->Num() == 0 ) ? EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
/**
|
|
* Removes all the selected actors from the currently exposed Layers
|
|
*
|
|
* @return Returns whether the event was handled, along with other possible actions
|
|
*/
|
|
FReply OnRemoveAllLayersClicked()
|
|
{
|
|
ViewModel->RemoveActorsFromAllLayers();
|
|
return FReply::Handled();
|
|
}
|
|
|
|
/**
|
|
* Removes all the selected actors from the clicked Layer
|
|
*
|
|
* @return Returns whether the event was handled, along with other possible actions
|
|
*/
|
|
FReply OnRemoveLayerFromActorsClicked( const TSharedPtr< FActorLayerViewModel > Layer )
|
|
{
|
|
ViewModel->RemoveActorsFromLayer( Layer );
|
|
return FReply::Handled();
|
|
}
|
|
|
|
|
|
private:
|
|
|
|
/** The widget box that holds the layer tags */
|
|
TSharedPtr< SWrapBox > TagArea;
|
|
|
|
/** The ViewModel for the SWidget */
|
|
TSharedPtr< FActorLayerCollectionViewModel > ViewModel;
|
|
};
|
|
|
|
#undef LOCTEXT_NAMESPACE
|