// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "EditorUndoClient.h" #include "ICompElementManager.h" // for ICompElementManager::FOnElementsChanged #include "UObject/WeakObjectPtr.h" class UEditorEngine; class FCompElementViewModel; class UClass; class FUICommandList; template class IFilter; typedef IFilter&> FCompElementFilter; template class TFilterCollection; typedef TFilterCollection&> FCompElementFilterCollection; /** * The non-UI solution specific presentation logic for a comp elements' view. */ class FCompElementCollectionViewModel : public TSharedFromThis, public FEditorUndoClient { public: /** * Factory method which creates a new FCompElementCollectionViewModel object. * * @param InElementsManager The element management logic object * @param InEditor The UEditorEngine to register with (for undo/redo, etc.) */ static TSharedRef Create(const TSharedRef& InElementsManager, const TWeakObjectPtr& InEditor) { TSharedRef ElementsView(new FCompElementCollectionViewModel(InElementsManager, InEditor)); ElementsView->Initialize(); return ElementsView; } virtual ~FCompElementCollectionViewModel(); public: //~ Begin FEditorUndoClient interface virtual void PostUndo(bool bSuccess) override { Refresh(); } virtual void PostRedo(bool bSuccess) override { PostUndo(bSuccess); } //~ End FEditorUndoClient interface /** * Hook for the UI search box (and others) to filter the model's element list. */ void AddFilter(const TSharedRef& InFilter); /** * Clears an existing filter from the elements list (refreshes the lists returned by GetCompShots() and GetElementsForComp() */ void RemoveFilter(const TSharedRef& InFilter); /** * Returns the (filtered) list of top-level compositing elements (for the UI to display). */ TArray< TSharedPtr >& GetRootCompElements(); /** * Returns a (filtered) list of child elements, nested directly under the specified CompItem. */ void GetChildElements(TSharedPtr ParentPtr, TArray< TSharedPtr >& OutChildElements); /** * Some elements are not selectable (like child actors). This determines that and returns the * (parent) element that should be selected instead. * If the specified element is selectable, then this just returns that element. */ TSharedPtr GetSelectionProxy(const TSharedPtr& SelectedItem) const; /** Returns the a list of element model that are currently tracked as selected (should be reflected in the UI). */ const TArray< TSharedPtr >& GetSelectedElements() const; /** Appends the names of the currently selected elements to the provided array. */ void GetSelectedElementNames(OUT TArray& OutSelectedElementNames) const; /** Sets the specified array of element objects as the currently selected elements (provides a way to sync with the UI). */ void SetSelectedElements(const TArray< TSharedPtr >& InSelectedElements); /** Sets the current selection to the specified element. */ void SetSelectedElement(const FName& ElementName); /** Returns the bound UICommandList for the comp element view. */ const TSharedRef GetCommandList() const; /******************************************************************** * EVENTS ********************************************************************/ /** Broadcasts whenever one or more elements change. */ DECLARE_DERIVED_EVENT(FCompElementCollectionViewModel, ICompElementManager::FOnElementsChanged, FOnElementsChanged); FOnElementsChanged& OnElementsChanged() { return ElementsChanged; } /** Broadcasts whenever the currently selected elements change. */ DECLARE_EVENT(FCompElementCollectionViewModel, FOnSelectionChanged); FOnSelectionChanged& OnSelectionChanged() { return SelectionChanged; } /** Broadcasts whenever a rename is requested on the selected elements. */ DECLARE_EVENT(FCompElementCollectionViewModel, FOnRenameRequested); FOnRenameRequested& OnRenameRequested() { return RenameRequested; } private: /** * Private constructor to force users to go through Create(), which properly initializes the model. * * @param InElementsManager The element management logic object * @param InEditor The UEditorEngine to register with (for undo/redo, etc.) */ FCompElementCollectionViewModel(const TSharedRef& InElementsManager, const TWeakObjectPtr& InEditor); /** Initializes the elements view for use. */ void Initialize(); /** Binds all element browser commands to delegates. */ void BindCommands(); /** Refreshes any cached information. */ void Refresh(); /** Handles updating the view-model when one of its filters changes. */ void OnFilterChanged(); /** */ void OnElementsChanged(const ECompElementEdActions Action, const TWeakObjectPtr& ChangedComp, const FName& ChangedProperty); /** */ void OnElementAdded(const TWeakObjectPtr& AddedElement); /** Handles updating the internal view-models when elements are deleted */ void OnElementDelete(); /** */ void OnElementAttached(const TWeakObjectPtr& AttachedElement); /** Refreshes the elements list */ void OnResetElements(); /** Discards any element view-models which are invalid */ void DestructivelyPurgeInvalidViewModels(TArray< TWeakObjectPtr >& InElements); /** Creates view-models for all elements in the specified list */ void CreateViewModels(TArray< TWeakObjectPtr >& ActualElements); /** Updates the view-model hierarchy of known elements. */ void RebuildViewModelHierarchy(); /** Rebuilds the list of filtered elements. */ void RefreshFilteredElements(); /** Sorts the filtered elements list */ void SortFilteredElements(); /** Looks up the view-model associated with the specified element object. */ TSharedPtr GetViewModel(TWeakObjectPtr ElementObj); /** Looks up the view-model associated with the specified element object. Returns false if it couldn't find one. */ bool TryGetViewModel(TWeakObjectPtr CompObjPtr, TSharedPtr& OutViewModel); /** Returns a flat list of all element view-models (parents and children). */ void GetAllViewModels(TArray< TSharedPtr >& OutAllViewModels); /** Appends the selected element names to the specified array */ void AppendSelectedElementNames(TArray& OutElementNames) const; /** Updates the element selection from a selection made in the level editor. */ void OnActorSelectionChanged(const TArray& NewSelection, bool bForceRefresh); /** Updates actor selections from the internal selection state. */ void RefreshActorSelections() const; private: /** Creates a new top-level element, prompting the user to pick the class type first. */ void CreateTopLevelElement_Executed(); FName GenerateUniqueCompName() const; bool CreateTopLevelElement_CanExecute() const; /** Creates a new child element, nesting it under the currently selected element. */ void CreateChildElement_Executed(); FName GenerateUniqueElementName(TSubclassOf ElementClass) const; bool CreateChildElement_CanExecute() const; /** Cuts the currently selected element */ void CutElements_Executed(); bool CutElements_CanExecute() const; /** Copies the currently selected elements */ void CopyElements_Executed(); bool CopyElements_CanExecute() const; /** Pastes the currently selected elements */ void PasteElements_Executed(); bool PasteElements_CanExecute() const; /** Duplicates the currently selected elements */ void DuplicateElements_Executed(); bool DuplicateElements_CanExecute() const; /** Deletes the currently selected elements */ void DeleteElements_Executed(); bool DeleteElements_CanExecute() const; /** Requests renaming of the selected element */ void RequestRenameElement_Executed(); bool RequestRenameElement_CanExecute() const; /** Opens a modeless dialog window, displaying the element's render result live. */ void OpenPreview_Executed(); bool OpenPreview_CanExecute() const; /** Resets/Rebuilds the element list (useful in case the list gets stale by an unaccounted problem). */ void RefreshList_Executed(); bool RefreshList_CanExecute() const; private: /** The element management logic object. */ const TSharedRef CompElementManager; /** The UEditorEngine to use. */ const TWeakObjectPtr Editor; /** The list of commands with bound delegates for the element browser. */ const TSharedRef CommandList; /** All top-level elements managed by the view. */ TArray< TSharedPtr > RootViewModels; /** The collection of filters used to restrict the elements shown in the view. */ const TSharedRef Filters; /** All elements shown in the view. */ TArray< TSharedPtr > FilteredRootItems; typedef TMultiMap< TSharedPtr, TSharedPtr > FFilteredChildList; FFilteredChildList FilteredChildren; /** Currently selected elements. */ TArray< TSharedPtr > SelectedElements; /** Broadcasts whenever one or more elements change. */ FOnElementsChanged ElementsChanged; /** Broadcasts whenever the currently selected elements change. */ FOnSelectionChanged SelectionChanged; /** Broadcasts whenever a rename is requested on the selected elements. */ FOnRenameRequested RenameRequested; };