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

306 lines
8.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SLayersViewRow.h"
#include "Framework/Application/SlateApplication.h"
#include "Widgets/Images/SImage.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Views/SListView.h"
#include "Styling/AppStyle.h"
#include "DragAndDrop/ActorDragDropOp.h"
#include "DragAndDrop/FolderDragDropOp.h"
#include "DragAndDrop/CompositeDragDropOp.h"
#include "Widgets/Text/SInlineEditableTextBlock.h"
#include "EditorActorFolders.h"
#include "Engine/World.h"
#define LOCTEXT_NAMESPACE "LayersView"
void SLayersViewRow::Construct(const FArguments& InArgs, TSharedRef< FLayerViewModel > InViewModel, TSharedRef< STableViewBase > InOwnerTableView)
{
ViewModel = InViewModel;
HighlightText = InArgs._HighlightText;
SMultiColumnTableRow< TSharedPtr< FLayerViewModel > >::Construct(FSuperRowType::FArguments().OnDragDetected(InArgs._OnDragDetected), InOwnerTableView);
}
SLayersViewRow::~SLayersViewRow()
{
ViewModel->OnRenamedRequest().Remove(EnterEditingModeDelegateHandle);
}
TSharedRef< SWidget > SLayersViewRow::GenerateWidgetForColumn(const FName& ColumnID)
{
TSharedPtr< SWidget > TableRowContent;
if (ColumnID == LayersView::ColumnID_LayerLabel)
{
TableRowContent =
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.Padding(0.0f, 1.0f, 3.0f, 1.0f)
[
SNew(SImage)
.Image(FAppStyle::GetBrush(TEXT("Layer.Icon16x")))
.ColorAndOpacity(FSlateColor::UseForeground())
]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SAssignNew(InlineTextBlock, SInlineEditableTextBlock)
.Font(FAppStyle::GetFontStyle("LayersView.LayerNameFont"))
.Text(ViewModel.Get(), &FLayerViewModel::GetNameAsText)
.ColorAndOpacity(this, &SLayersViewRow::GetColorAndOpacity)
.HighlightText(HighlightText)
.ToolTipText(LOCTEXT("DoubleClickToolTip", "Double Click to Select All Actors"))
.OnVerifyTextChanged(this, &SLayersViewRow::OnRenameLayerTextChanged)
.OnTextCommitted(this, &SLayersViewRow::OnRenameLayerTextCommitted)
.IsSelected(this, &SLayersViewRow::IsSelectedExclusively)
]
;
EnterEditingModeDelegateHandle = ViewModel->OnRenamedRequest().AddSP(InlineTextBlock.Get(), &SInlineEditableTextBlock::EnterEditingMode);
}
else if (ColumnID == LayersView::ColumnID_Visibility)
{
TableRowContent =
SAssignNew(VisibilityButton, SButton)
.ContentPadding(0)
.ButtonStyle(FAppStyle::Get(), "NoBorder")
.OnClicked(this, &SLayersViewRow::OnToggleVisibility)
.ToolTipText(LOCTEXT("VisibilityButtonToolTip", "Toggle Layer Visibility"))
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
.Content()
[
SNew(SImage)
.Image(this, &SLayersViewRow::GetVisibilityBrushForLayer)
]
;
}
else
{
checkf(false, TEXT("Unknown ColumnID provided to SLayersView"));
}
return TableRowContent.ToSharedRef();
}
void SLayersViewRow::OnRenameLayerTextCommitted(const FText& InText, ETextCommit::Type eInCommitType)
{
if (!InText.IsEmpty())
{
ViewModel->RenameTo(*InText.ToString());
}
}
bool SLayersViewRow::OnRenameLayerTextChanged(const FText& NewText, FText& OutErrorMessage)
{
FString OutMessage;
if (!ViewModel->CanRenameTo(*NewText.ToString(), OutMessage))
{
OutErrorMessage = FText::FromString(OutMessage);
return false;
}
return true;
}
void SLayersViewRow::OnDragLeave(const FDragDropEvent& DragDropEvent)
{
TSharedPtr< FDecoratedDragDropOp > DragOp = DragDropEvent.GetOperationAs<FDecoratedDragDropOp>();
if (DragOp.IsValid())
{
DragOp->ResetToDefaultToolTip();
}
}
FReply SLayersViewRow::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
TArray<TWeakObjectPtr<AActor>> Actors;
TSharedPtr<FActorDragDropOp> ActorDragOp = nullptr;
TSharedPtr<FFolderDragDropOp> FolderDragOp = nullptr;
if (const TSharedPtr<FCompositeDragDropOp> CompositeDragOp = DragDropEvent.GetOperationAs<FCompositeDragDropOp>())
{
ActorDragOp = CompositeDragOp->GetSubOp<FActorDragDropOp>();
FolderDragOp = CompositeDragOp->GetSubOp<FFolderDragDropOp>();
}
else
{
ActorDragOp = DragDropEvent.GetOperationAs<FActorDragDropOp>();
FolderDragOp = DragDropEvent.GetOperationAs<FFolderDragDropOp>();
}
if (ActorDragOp.IsValid() && ActorDragOp->Actors.Num() > 0)
{
Actors = ActorDragOp->Actors;
}
if (FolderDragOp.IsValid())
{
if (UWorld* World = FolderDragOp->World.Get())
{
FActorFolders::GetWeakActorsFromFolders(*World, FolderDragOp->Folders, Actors, FolderDragOp->RootObject);
}
}
if (Actors.Num() > 0)
{
bool bCanAssign = false;
FText Message;
if (Actors.Num() > 1)
{
bCanAssign = ViewModel->CanAssignActors(Actors, OUT Message);
}
else
{
bCanAssign = ViewModel->CanAssignActor(Actors[0], OUT Message);
}
if (bCanAssign)
{
if (ActorDragOp.IsValid())
{
ActorDragOp->SetToolTip(Message, FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK")));
}
if (FolderDragOp.IsValid())
{
FolderDragOp->SetToolTip(Message, FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK")));
}
}
else
{
if (ActorDragOp.IsValid())
{
ActorDragOp->SetToolTip(Message, FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error")));
}
if (FolderDragOp.IsValid())
{
FolderDragOp->SetToolTip(Message, FAppStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error")));
}
}
return FReply::Handled();
}
return FReply::Unhandled();
}
FReply SLayersViewRow::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
bool bHandled = false;
TArray<TWeakObjectPtr<AActor>> ActorsToDrop;
if (const TSharedPtr<FActorDragDropOp> ActorDragOp = DragDropEvent.GetOperationAs<FActorDragDropOp>())
{
ActorsToDrop = ActorDragOp->Actors;
bHandled = true;
}
else if (const TSharedPtr<FFolderDragDropOp> FolderDragOp = DragDropEvent.GetOperationAs<FFolderDragDropOp>())
{
if (UWorld* World = FolderDragOp->World.Get())
{
FActorFolders::GetWeakActorsFromFolders(*World, FolderDragOp->Folders, ActorsToDrop, FolderDragOp->RootObject);
bHandled = true;
}
}
else if (const TSharedPtr<FCompositeDragDropOp> CompositeDragOp = DragDropEvent.GetOperationAs<FCompositeDragDropOp>())
{
if (const TSharedPtr<FActorDragDropOp> ActorSubOp = CompositeDragOp->GetSubOp<FActorDragDropOp>())
{
ActorsToDrop = ActorSubOp->Actors;
bHandled = true;
}
if (const TSharedPtr<FFolderDragDropOp> FolderSubOp = CompositeDragOp->GetSubOp<FFolderDragDropOp>())
{
if (UWorld* World = FolderDragOp->World.Get())
{
FActorFolders::GetWeakActorsFromFolders(*World, FolderSubOp->Folders, ActorsToDrop, FolderDragOp->RootObject);
bHandled = true;
}
}
}
if (ActorsToDrop.Num() > 0)
{
ViewModel->AddActors(ActorsToDrop);
}
return bHandled ? FReply::Handled() : FReply::Unhandled();
}
FSlateColor SLayersViewRow::GetColorAndOpacity() const
{
if (!FSlateApplication::Get().IsDragDropping())
{
return FSlateColor::UseForeground();
}
bool bCanAcceptDrop = false;
TSharedPtr<FDragDropOperation> DragDropOp = FSlateApplication::Get().GetDragDroppingContent();
if (DragDropOp.IsValid() && (DragDropOp->IsOfType<FActorDragDropOp>() || DragDropOp->IsOfType<FFolderDragDropOp>() || DragDropOp->IsOfType<FCompositeDragDropOp>()))
{
TArray<TWeakObjectPtr<AActor>> DraggedActors;
TSharedPtr<FActorDragDropOp> ActorDragOp;
TSharedPtr<FFolderDragDropOp> FolderDragOp;
if (DragDropOp->IsOfType<FActorDragDropOp>())
{
ActorDragOp = StaticCastSharedPtr<FActorDragDropOp>(DragDropOp);
}
else if (DragDropOp->IsOfType<FFolderDragDropOp>())
{
FolderDragOp = StaticCastSharedPtr<FFolderDragDropOp>(DragDropOp);
}
else if (DragDropOp->IsOfType<FCompositeDragDropOp>())
{
if (const TSharedPtr<FCompositeDragDropOp> CompositeDrop = StaticCastSharedPtr<FCompositeDragDropOp>(DragDropOp))
{
ActorDragOp = CompositeDrop->GetSubOp<FActorDragDropOp>();
FolderDragOp = CompositeDrop->GetSubOp<FFolderDragDropOp>();
}
}
if (ActorDragOp.IsValid())
{
DraggedActors = ActorDragOp->Actors;
}
if (FolderDragOp.IsValid())
{
auto World = FolderDragOp->World;
if (UWorld* WorldPtr = World.Get())
{
FActorFolders::GetWeakActorsFromFolders(*WorldPtr, FolderDragOp->Folders, DraggedActors, FolderDragOp->RootObject);
}
}
if (DraggedActors.Num() > 0)
{
FText Message;
bCanAcceptDrop = ViewModel->CanAssignActors(DraggedActors, OUT Message);
}
}
return (bCanAcceptDrop) ? FSlateColor::UseForeground() : FLinearColor(0.30f, 0.30f, 0.30f);
}
const FSlateBrush* SLayersViewRow::GetVisibilityBrushForLayer() const
{
if (ViewModel->IsVisible())
{
return IsHovered() ? FAppStyle::GetBrush("Level.VisibleHighlightIcon16x") :
FAppStyle::GetBrush("Level.VisibleIcon16x");
}
else
{
return IsHovered() ? FAppStyle::GetBrush("Level.NotVisibleHighlightIcon16x") :
FAppStyle::GetBrush("Level.NotVisibleIcon16x");
}
}
#undef LOCTEXT_NAMESPACE