// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Delegates/Delegate.h" #include "Delegates/DelegateCombinations.h" #include "Input/Events.h" #include "Layout/Geometry.h" #include "LiveLinkRole.h" #include "LiveLinkSourceSettings.h" #include "Misc/Guid.h" #include "Templates/SharedPointer.h" #include "Widgets/Views/SListView.h" #include "Widgets/Views/STreeView.h" class FLiveLinkClient; struct FLiveLinkSourceUIEntry; class FLiveLinkSourcesView; struct FLiveLinkSubjectUIEntry; class FLiveLinkSubjectsView; class FUICommandList; class IDetailsView; class ITableRow; struct FPropertyChangedEvent; class SLiveLinkSourceListView; class SLiveLinkDataView; class STableViewBase; class SWidget; typedef TSharedPtr FLiveLinkSourceUIEntryPtr; typedef TSharedPtr FLiveLinkSubjectUIEntryPtr; namespace UE::LiveLink { TSharedPtr LIVELINKEDITOR_API CreateSourcesDetailsView(const TSharedPtr& InSourcesView, const TAttribute& bInReadOnly); TSharedPtr LIVELINKEDITOR_API CreateSubjectsDetailsView(FLiveLinkClient* InLiveLinkClient, const TAttribute& bInReadOnly); } // Structure that defines a single entry in the subject UI struct FLiveLinkSubjectUIEntry { FLiveLinkSubjectUIEntry(const FLiveLinkSubjectKey& InSubjectKey, FLiveLinkClient* InClient, bool bIsSource = false); // Subject key FLiveLinkSubjectKey SubjectKey; // LiveLink Client FLiveLinkClient* Client; // Children (if this entry represents a source instead of a specific subject TArray> Children; // Whether the subject entry is a subject bool IsSubject() const; // Whether the subject entry is a source bool IsSource() const; // Whether the subject is virtual bool IsVirtualSubject() const; // Get the subject or source settings UObject* GetSettings() const; // Whether the subject is enabled bool IsSubjectEnabled() const; // Whether the subject is valid bool IsSubjectValid() const; // Enable or disable a subject void SetSubjectEnabled(bool bIsEnabled); // Get a textual representation of the ui entry FText GetItemText() const; // Get the livelink role of this entry TSubclassOf GetItemRole() const; // Remove the subject or source from the livelink client void RemoveFromClient() const; // Pause or unpause a subject if it's already paused void PauseSubject(); // Returns whether a subject is currently paused. bool IsPaused() const; private: // Whether the subject is virtual bool bIsVirtualSubject = false; // Whether this represents a source. bool bIsSource = false; }; // Structure that defines a single entry in the source UI struct FLiveLinkSourceUIEntry { public: FLiveLinkSourceUIEntry(FGuid InEntryGuid, FLiveLinkClient* InClient) : EntryGuid(InEntryGuid) , Client(InClient) {} // Get the guid of the source FGuid GetGuid() const; // Get the type of the source FText GetSourceType() const; // Get the machine name of the source FText GetMachineName() const; // Get the source's status FText GetStatus() const; // Get the source's settings ULiveLinkSourceSettings* GetSourceSettings() const; // Remove the source from the client void RemoveFromClient() const; // Get the display name of the source FText GetDisplayName() const; // Get the tooltip of the source FText GetToolTip() const; private: // GUID of the source FGuid EntryGuid; // Pointer to the livelink client FLiveLinkClient* Client = nullptr; }; namespace UE::LiveLink { /** Base class for live link list/tree views, handles removing list element by pressing delete. */ template class SLiveLinkListView : public ListType { public: virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override { if (InKeyEvent.GetKey() == EKeys::Delete || InKeyEvent.GetKey() == EKeys::BackSpace) { if (!bReadOnly.Get()) { TArray SelectedItem = ListType::GetSelectedItems(); for (ListElementType Item : SelectedItem) { Item->RemoveFromClient(); } } return FReply::Handled(); } return FReply::Unhandled(); } // Whether the panel is in read-only mode or not. TAttribute bReadOnly; }; } class SLiveLinkSourceListView : public UE::LiveLink::SLiveLinkListView, FLiveLinkSourceUIEntryPtr> { public: void Construct(const FArguments& InArgs, TAttribute bInReadOnly) { bReadOnly = bInReadOnly; UE::LiveLink::SLiveLinkListView, FLiveLinkSourceUIEntryPtr>::Construct(InArgs); } }; class SLiveLinkSubjectsTreeView : public UE::LiveLink::SLiveLinkListView, FLiveLinkSubjectUIEntryPtr> { public: void Construct(const FArguments& InArgs, TAttribute bInReadOnly) { bReadOnly = bInReadOnly; UE::LiveLink::SLiveLinkListView, FLiveLinkSubjectUIEntryPtr>::Construct(InArgs); } }; class LIVELINKEDITOR_API FLiveLinkSubjectsView : public TSharedFromThis { public: DECLARE_DELEGATE_TwoParams(FOnSubjectSelectionChanged, FLiveLinkSubjectUIEntryPtr, ESelectInfo::Type); FLiveLinkSubjectsView(FOnSubjectSelectionChanged InOnSubjectSelectionChanged, const TSharedPtr& InCommandList, TAttribute bInReadOnly); // Helper functions for building the subject tree UI TSharedRef MakeTreeRowWidget(FLiveLinkSubjectUIEntryPtr InInfo, const TSharedRef& OwnerTable); // Get a subjectsview's children void GetChildrenForInfo(FLiveLinkSubjectUIEntryPtr InInfo, TArray< FLiveLinkSubjectUIEntryPtr >& OutChildren); // Handle subject selection changed void OnSubjectSelectionChanged(FLiveLinkSubjectUIEntryPtr SubjectEntry, ESelectInfo::Type SelectInfo); // Handler for the subject tree context menu opening TSharedPtr OnOpenVirtualSubjectContextMenu(TSharedPtr InCommandList); // Return whether a subject can be removed bool CanRemoveSubject() const; // Refresh the list of subjects using the livelink client. void RefreshSubjects(); // Return whether a subject can be paused bool CanPauseSubject() const; // Pauses/Unpauses a subject void HandlePauseSubject(); private: // Create the subjects tree view void CreateSubjectsTreeView(const TSharedPtr& InCommandList); /** Get the label for the pause subject context menu entry. */ FText GetPauseSubjectLabel() const; /** Get the tooltip for the pause subject context menu entry. */ FText GetPauseSubjectToolTip() const; /** Returns whether the selected subject is paused. */ bool IsSelectedSubjectPaused() const; public: // Subject tree widget TSharedPtr SubjectsTreeView; // Subject tree items TArray SubjectData; // Subject Selection Changed delegate FOnSubjectSelectionChanged SubjectSelectionChangedDelegate; // Returns whether the panel is in read-only mode. TAttribute bReadOnly; }; class FLiveLinkSourcesView : public TSharedFromThis { public: DECLARE_DELEGATE_TwoParams(FOnSourceSelectionChanged, FLiveLinkSourceUIEntryPtr, ESelectInfo::Type); FLiveLinkSourcesView(FLiveLinkClient* InLiveLinkClient, TSharedPtr InCommandList, TAttribute bInReadOnly, FOnSourceSelectionChanged InOnSourceSelectionChanged); // Gather information about all sources and update the list view void RefreshSourceData(bool bRefreshUI); // Handler that creates a widget row for a given ui entry TSharedRef MakeSourceListViewWidget(FLiveLinkSourceUIEntryPtr Entry, const TSharedRef& OwnerTable) const; // Handles constructing a context menu for the sources TSharedPtr OnSourceConstructContextMenu(TSharedPtr InCommandList); // Return whether a source can be removed bool CanRemoveSource(); // Removes a livelink source from the livelink client void HandleRemoveSource(); // Callback when property changes on source settings void OnPropertyChanged(const FPropertyChangedEvent& InEvent); // Handle selection change, triggering the OnSourceSelectionChangedDelegate delegate. void OnSourceListSelectionChanged(FLiveLinkSourceUIEntryPtr Entry, ESelectInfo::Type SelectionType) const; private: // Create the sources list view void CreateSourcesListView(const TSharedPtr& InCommandList); public: // Holds the data that will be displayed in the list view TArray SourceData; // Holds the sources list view widget TSharedPtr SourcesListView; // LiveLink Client FLiveLinkClient* Client; // Source selection changed delegate FOnSourceSelectionChanged OnSourceSelectionChangedDelegate; // Returns whether the panel is in read-only mode. TAttribute bReadOnly; };