// 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(); if (DragOp.IsValid()) { DragOp->ResetToDefaultToolTip(); } } FReply SLayersViewRow::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) { TArray> Actors; TSharedPtr ActorDragOp = nullptr; TSharedPtr FolderDragOp = nullptr; if (const TSharedPtr CompositeDragOp = DragDropEvent.GetOperationAs()) { ActorDragOp = CompositeDragOp->GetSubOp(); FolderDragOp = CompositeDragOp->GetSubOp(); } else { ActorDragOp = DragDropEvent.GetOperationAs(); FolderDragOp = DragDropEvent.GetOperationAs(); } 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> ActorsToDrop; if (const TSharedPtr ActorDragOp = DragDropEvent.GetOperationAs()) { ActorsToDrop = ActorDragOp->Actors; bHandled = true; } else if (const TSharedPtr FolderDragOp = DragDropEvent.GetOperationAs()) { if (UWorld* World = FolderDragOp->World.Get()) { FActorFolders::GetWeakActorsFromFolders(*World, FolderDragOp->Folders, ActorsToDrop, FolderDragOp->RootObject); bHandled = true; } } else if (const TSharedPtr CompositeDragOp = DragDropEvent.GetOperationAs()) { if (const TSharedPtr ActorSubOp = CompositeDragOp->GetSubOp()) { ActorsToDrop = ActorSubOp->Actors; bHandled = true; } if (const TSharedPtr FolderSubOp = CompositeDragOp->GetSubOp()) { 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 DragDropOp = FSlateApplication::Get().GetDragDroppingContent(); if (DragDropOp.IsValid() && (DragDropOp->IsOfType() || DragDropOp->IsOfType() || DragDropOp->IsOfType())) { TArray> DraggedActors; TSharedPtr ActorDragOp; TSharedPtr FolderDragOp; if (DragDropOp->IsOfType()) { ActorDragOp = StaticCastSharedPtr(DragDropOp); } else if (DragDropOp->IsOfType()) { FolderDragOp = StaticCastSharedPtr(DragDropOp); } else if (DragDropOp->IsOfType()) { if (const TSharedPtr CompositeDrop = StaticCastSharedPtr(DragDropOp)) { ActorDragOp = CompositeDrop->GetSubOp(); FolderDragOp = CompositeDrop->GetSubOp(); } } 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