Files
UnrealEngine/Engine/Source/Editor/Layers/Private/SLayerStats.h
2025-05-18 13:04:45 +08:00

207 lines
5.8 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 "Layout/Margin.h"
#include "Widgets/SCompoundWidget.h"
#include "Styling/AppStyle.h"
#include "Widgets/Input/SButton.h"
#include "Layers/Layer.h"
#include "LayerViewModel.h"
#include "Widgets/SBoxPanel.h"
#include "Widgets/Images/SImage.h"
#include "Widgets/Text/STextBlock.h"
#include "Styling/SlateIconFinder.h"
#define LOCTEXT_NAMESPACE "LayerStats"
class AActor;
class SLayerStats : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS( SLayerStats ){}
SLATE_END_ARGS()
/** SLayerStats destructor */
~SLayerStats()
{
// Remove all delegates we registered
ViewModel->OnChanged().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 layer the row widget is supposed to represent
*/
void Construct( const FArguments& InArgs, const TSharedRef< FLayerViewModel >& InViewModel )
{
ViewModel = InViewModel;
ChildSlot
[
SAssignNew( StatsArea, SHorizontalBox )
];
Reconstruct();
ViewModel->OnChanged().AddSP( this, &SLayerStats::Reconstruct );
}
/**
* Rebuilds the children widgets of the StatsArea
*/
void Reconstruct()
{
StatButtonWidgets.Empty();
StatsArea->ClearChildren();
const TArray< FLayerActorStats >& ActorStats = ViewModel->GetActorStats();
for( int StatsIndex = 0; StatsIndex < ActorStats.Num(); ++StatsIndex )
{
const TWeakObjectPtr< UClass > StatsActorClass = ActorStats[ StatsIndex ].Type;
TSharedPtr< SButton > LastCreatedButton;
StatsArea->AddSlot()
.AutoWidth()
.Padding( 0.0f, 0.0f, 6.0f, 0.0f )
[
SAssignNew( LastCreatedButton, SButton )
.ButtonStyle( FAppStyle::Get(), "ToggleButton" )
.ContentPadding( FMargin( 1 ) )
.ForegroundColor( FSlateColor::UseForeground() )
.OnClicked( this, &SLayerStats::SelectLayerActorsOfSpecificType, StatsActorClass )
.ToolTipText( this, &SLayerStats::GetStatButtonToolTipText, StatsActorClass )
.Content()
[
SNew( SHorizontalBox )
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SImage)
.Image(FSlateIconFinder::FindIconBrushForClass(ActorStats[StatsIndex].Type))
.ColorAndOpacity( this, &SLayerStats::GetForegroundColorForButton, StatsIndex )
]
+SHorizontalBox::Slot()
.AutoWidth()
.Padding( 3.0f, 0.0f, 3.0f, 0.0f )
[
SNew(STextBlock)
.Text( ViewModel.Get(), &FLayerViewModel::GetActorStatTotal, StatsIndex )
.ColorAndOpacity( this, &SLayerStats::GetForegroundColorForButton, StatsIndex )
]
]
];
StatButtonWidgets.Add( LastCreatedButton );
}
}
private:
/**
* Gets the appropriate EVisibility for the specified button depending on the button's current state
*
* @param StatsIndex The index into StatButtonWidgets to find the associated button
* @return The EVisibility
*/
EVisibility GetVisibility( int StatsIndex ) const
{
if( StatsIndex >= StatButtonWidgets.Num() )
{
return EVisibility::Collapsed;
}
const auto Button = StatButtonWidgets[ StatsIndex ];
return ( Button.IsValid() && ( Button->IsHovered() || Button->IsPressed() ) ) ? EVisibility::Visible : EVisibility::Collapsed;
}
/**
* Gets the appropriate SlateColor for the specified button depending on the button's current state
*
* @param StatsIndex The index into StatButtonWidgets to find the associated button
* @return The ForegroundColor
*/
FSlateColor GetForegroundColorForButton( int StatsIndex ) const
{
if( StatsIndex >= StatButtonWidgets.Num() )
{
return FSlateColor::UseForeground();
}
const auto Button = StatButtonWidgets[ StatsIndex ];
static const FName InvertedForegroundName("InvertedForeground");
return ( Button.IsValid() && ( Button->IsHovered() || Button->IsPressed() ) ) ? FAppStyle::GetSlateColor(InvertedForegroundName): FSlateColor::UseForeground();
}
/**
* Selected the Actors assigned to the Layer of the specified type
*
* @param Class The Actor class to select by
*/
FReply SelectLayerActorsOfSpecificType( const TWeakObjectPtr< UClass > Class )
{
ViewModel->SelectActorsOfSpecificType( Class );
return FReply::Handled();
}
/**
* Remove the Actors assigned to the Layer of the specified type
*
* @param Class The Actor class to select by
*/
FReply RemoveAllLayerActorsOfSpecificType( const TWeakObjectPtr< UClass > Class )
{
TArray< TWeakObjectPtr< AActor > > Actors;
ViewModel->AppendActorsOfSpecificType( Actors, Class );
ViewModel->RemoveActors( Actors );
return FReply::Handled();
}
/**
* Retrieves the appropriate tooltip text for the stats button of the specified index
*
* @param Class The Actor class which the stats are associated with
*/
FText GetStatButtonToolTipText( const TWeakObjectPtr< UClass > Class ) const
{
return FText::Format( LOCTEXT("StatButtonToolTipFmt", "Select All {0} Actors in {1}"), FText::FromName(Class->GetFName()), FText::FromString(ViewModel->GetName()) );
}
/**
* Retrieves the appropriate tooltip text for the remove stats button of the specified index
*
* @param Class The Actor class which the stats are associated with
*/
FText GetRemoveStatButtonToolTipText( const TWeakObjectPtr< UClass > Class ) const
{
return LOCTEXT("RemoveStatButtonToolTip", "Remove All");
}
private:
/** The layer associated with this widget */
TSharedPtr< FLayerViewModel > ViewModel;
/** The Box widget holding the individual stats specific widgets */
TSharedPtr< SHorizontalBox > StatsArea;
/** The button widgets representing individual stats */
TArray< TSharedPtr< SButton> > StatButtonWidgets;
};
#undef LOCTEXT_NAMESPACE