// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "Containers/UnrealString.h" #include "CoreMinimal.h" #include "DragAndDrop/CompositeDragDropOp.h" #include "HAL/Platform.h" #include "ISceneOutlinerTreeItem.h" #include "Input/DragAndDrop.h" #include "Internationalization/Text.h" #include "Layout/Visibility.h" #include "SceneOutlinerFwd.h" #include "Templates/Function.h" #include "Templates/SharedPointer.h" #include "Templates/TypeHash.h" class SWidget; struct FSlateBrush; struct ISceneOutlinerTreeItem; /** Enum to describe the compatibility of a drag drop operation */ enum class ESceneOutlinerDropCompatibility : uint8 { Compatible, Incompatible, MultipleSelection_Incompatible, CompatibleAttach, IncompatibleGeneric, CompatibleGeneric, CompatibleMultipleAttach, IncompatibleMultipleAttach, CompatibleDetach, CompatibleMultipleDetach, }; /** Consolidated drag/drop with parsing functions for the scene outliner */ struct FSceneOutlinerDragDropPayload { /** Default constructor, resulting in unset contents */ FSceneOutlinerDragDropPayload(const FDragDropOperation& InOperation = FDragDropOperation()) : SourceOperation(InOperation) { } /** Populate this payload from an array of tree items */ template FSceneOutlinerDragDropPayload(const TArray& InDraggedItems, const FDragDropOperation& InOperation = FDragDropOperation()) : SourceOperation(InOperation) { for (const auto& Item : InDraggedItems) { DraggedItems.Add(Item); } } /** Returns true if the payload has an item of a specified type */ template bool Has() const { for (const TWeakPtr& Item : DraggedItems) { if (const auto ItemPtr = Item.Pin()) { if (ItemPtr->IsA()) { return true; } } } return false; } /** Return an array of all tree items in the payload which are of a specified type */ template TArray Get() const { TArray Result; for (const TWeakPtr& Item : DraggedItems) { if (const auto ItemPtr = Item.Pin()) { if (TreeType* CastedItem = ItemPtr->CastTo()) { Result.Add(CastedItem); } } } return Result; } /** Apply a function to each item in the payload */ template void ForEachItem(TFunctionRef Func) const { for (const TWeakPtr& Item : DraggedItems) { if (const auto ItemPtr = Item.Pin()) { if (TreeType* CastedItem = ItemPtr->CastTo()) { Func(*CastedItem); } } } } /** Use a selector to retrieve an array of a specific data type from the items in the payload */ template TArray GetData(TFunctionRef, DataType&)> Selector) const { TArray Result; for (TWeakPtr& Item : DraggedItems) { DataType Data; if (Selector(Item, Data)) { Result.Add(Data); } } return Result; } /** List of all dragged items */ mutable TArray> DraggedItems; /** The source FDragDropOperation */ const FDragDropOperation& SourceOperation; }; /** Struct used for validation of a drag/drop operation in the scene outliner */ struct FSceneOutlinerDragValidationInfo { /** The tooltip type to display on the operation */ ESceneOutlinerDropCompatibility CompatibilityType; /** The tooltip text to display on the operation */ FText ValidationText; /** Construct this validation information out of a tootip type and some text */ FSceneOutlinerDragValidationInfo(const ESceneOutlinerDropCompatibility InCompatibilityType, const FText InValidationText) : CompatibilityType(InCompatibilityType) , ValidationText(InValidationText) {} /** Return a generic invalid result */ static FSceneOutlinerDragValidationInfo Invalid() { return FSceneOutlinerDragValidationInfo(ESceneOutlinerDropCompatibility::IncompatibleGeneric, FText()); } /** @return true if this operation is valid, false otheriwse */ bool IsValid() const { switch(CompatibilityType) { case ESceneOutlinerDropCompatibility::Compatible: case ESceneOutlinerDropCompatibility::CompatibleAttach: case ESceneOutlinerDropCompatibility::CompatibleGeneric: case ESceneOutlinerDropCompatibility::CompatibleMultipleAttach: case ESceneOutlinerDropCompatibility::CompatibleDetach: case ESceneOutlinerDropCompatibility::CompatibleMultipleDetach: return true; default: return false; } } }; /** A drag/drop operation that was started from the scene outliner */ struct SCENEOUTLINER_API FSceneOutlinerDragDropOp : public FCompositeDragDropOp { DRAG_DROP_OPERATOR_TYPE(FSceneOutlinerDragDropOp, FCompositeDragDropOp); FSceneOutlinerDragDropOp(); using FDragDropOperation::Construct; void ResetTooltip() { OverrideText = FText(); OverrideIcon = nullptr; } void SetTooltip(FText InOverrideText, const FSlateBrush* InOverrideIcon) { OverrideText = InOverrideText; OverrideIcon = InOverrideIcon; } virtual TSharedPtr GetDefaultDecorator() const override; private: EVisibility GetOverrideVisibility() const; EVisibility GetDefaultVisibility() const; FText OverrideText; FText GetOverrideText() const { return OverrideText; } const FSlateBrush* OverrideIcon; const FSlateBrush* GetOverrideIcon() const { return OverrideIcon; } };