// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Misc/FilterCollection.h" #include "Misc/TextFilter.h" #include "SlateFwd.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Widgets/Navigation/SBreadcrumbTrail.h" #include "Widgets/SCompoundWidget.h" #include "Widgets/SWidget.h" #include "Widgets/Views/SHeaderRow.h" #include "Widgets/Views/STableRow.h" #include "Widgets/Views/STableViewBase.h" #include "Widgets/Views/STreeView.h" // Insights #include "Insights/Table/ViewModels/TableTreeNode.h" class FMenuBuilder; namespace Trace { class IAnalysisSession; } namespace Insights { class FTable; class FTableColumn; class FTreeNodeGrouping; class ITableCellValueSorter; //////////////////////////////////////////////////////////////////////////////////////////////////// /** The filter collection - used for updating the list of tree nodes. */ typedef TFilterCollection FTableTreeNodeFilterCollection; /** The text based filter - used for updating the list of tree nodes. */ typedef TTextFilter FTableTreeNodeTextFilter; //////////////////////////////////////////////////////////////////////////////////////////////////// /** * A custom widget used to display the list of tree nodes. */ class STableTreeView: public SCompoundWidget { public: /** Default constructor. */ STableTreeView(); /** Virtual destructor. */ virtual ~STableTreeView(); SLATE_BEGIN_ARGS(STableTreeView) {} SLATE_END_ARGS() /** * Construct this widget * @param InArgs - The declaration data for this widget */ void Construct(const FArguments& InArgs, TSharedPtr InTablePtr); TSharedPtr GetTable() const { return Table; } virtual void Reset(); void RebuildColumns(); /** * Rebuilds the tree (if necessary). * @param bResync - If true, it forces a resync even if the list did not changed since last sync. */ virtual void RebuildTree(bool bResync); FTableTreeNodePtr GetNodeByTableRowIndex(int32 RowIndex) const; void SelectNodeByTableRowIndex(int32 RowIndex); protected: void ConstructWidget(TSharedPtr InTablePtr); void UpdateTree(); /** Called when the analysis session has changed. */ void InsightsManager_OnSessionChanged(); /** * Populates OutSearchStrings with the strings that should be used in searching. * * @param GroupOrStatNodePtr - the group and stat node to get a text description from. * @param OutSearchStrings - an array of strings to use in searching. * */ void HandleItemToStringArray(const FTableTreeNodePtr& GroupOrStatNodePtr, TArray& OutSearchStrings) const; //////////////////////////////////////////////////////////////////////////////////////////////////// // Tree View - Context Menu TSharedPtr TreeView_GetMenuContent(); void TreeView_BuildSortByMenu(FMenuBuilder& MenuBuilder); void TreeView_BuildViewColumnMenu(FMenuBuilder& MenuBuilder); //////////////////////////////////////////////////////////////////////////////////////////////////// // Tree View - Columns' Header void InitializeAndShowHeaderColumns(); FText GetColumnHeaderText(const FName ColumnId) const; TSharedRef TreeViewHeaderRow_GenerateColumnMenu(const FTableColumn& Column); //////////////////////////////////////////////////////////////////////////////////////////////////// // Tree View - Misc void TreeView_Refresh(); /** * Called by STreeView to retrieves the children for the specified parent item. * @param InParent - The parent node to retrieve the children from. * @param OutChildren - List of children for the parent node. */ void TreeView_OnGetChildren(FTableTreeNodePtr InParent, TArray& OutChildren); /** Called by STreeView when selection has changed. */ void TreeView_OnSelectionChanged(FTableTreeNodePtr SelectedItem, ESelectInfo::Type SelectInfo); /** Called by STreeView when a tree item is double clicked. */ void TreeView_OnMouseButtonDoubleClick(FTableTreeNodePtr TreeNode); //////////////////////////////////////////////////////////////////////////////////////////////////// // Tree View - Table Row /** Called by STreeView to generate a table row for the specified item. */ TSharedRef TreeView_OnGenerateRow(FTableTreeNodePtr TreeNode, const TSharedRef& OwnerTable); bool TableRow_ShouldBeEnabled(FTableTreeNodePtr NodePtr) const; void TableRow_SetHoveredCell(TSharedPtr TablePtr, TSharedPtr ColumnPtr, FTableTreeNodePtr NodePtr); EHorizontalAlignment TableRow_GetColumnOutlineHAlignment(const FName ColumnId) const; FText TableRow_GetHighlightText() const; FName TableRow_GetHighlightedNodeName() const; //////////////////////////////////////////////////////////////////////////////////////////////////// // Filtering /** Populates the group and stat tree with items based on the current data. */ void ApplyFiltering(); bool ApplyFilteringForNode(FTableTreeNodePtr NodePtr); bool SearchBox_IsEnabled() const; void SearchBox_OnTextChanged(const FText& InFilterText); //////////////////////////////////////////////////////////////////////////////////////////////////// // Grouping void CreateGroupings(); void CreateGroups(); void GroupNodesRec(const TArray& Nodes, FTableTreeNode& ParentGroup, int32 GroupingDepth); void ResetAggregatedValuesRec(FTableTreeNode& GroupNode); void UpdateInt64SumAggregationRec(FTableColumn& Column, FTableTreeNode& GroupNode); void UpdateFloatSumAggregationRec(FTableColumn& Column, FTableTreeNode& GroupNode); void UpdateDoubleSumAggregationRec(FTableColumn& Column, FTableTreeNode& GroupNode); void RebuildGroupingCrumbs(); void OnGroupingCrumbClicked(const TSharedPtr& InEntry); void BuildGroupingSubMenu_Change(FMenuBuilder& MenuBuilder, const TSharedPtr CrumbGrouping); void BuildGroupingSubMenu_Add(FMenuBuilder& MenuBuilder, const TSharedPtr CrumbGrouping); TSharedRef GetGroupingCrumbMenuContent(const TSharedPtr& CrumbGrouping); void PreChangeGroupings(); void PostChangeGroupings(); int32 GetGroupingDepth(const TSharedPtr& Grouping) const; void GroupingCrumbMenu_Reset_Execute(); void GroupingCrumbMenu_Remove_Execute(const TSharedPtr Grouping); void GroupingCrumbMenu_MoveLeft_Execute(const TSharedPtr Grouping); void GroupingCrumbMenu_MoveRight_Execute(const TSharedPtr Grouping); void GroupingCrumbMenu_Change_Execute(const TSharedPtr OldGrouping, const TSharedPtr NewGrouping); bool GroupingCrumbMenu_Change_CanExecute(const TSharedPtr OldGrouping, const TSharedPtr NewGrouping) const; void GroupingCrumbMenu_Add_Execute(const TSharedPtr Grouping, const TSharedPtr AfterGrouping); bool GroupingCrumbMenu_Add_CanExecute(const TSharedPtr Grouping, const TSharedPtr AfterGrouping) const; //////////////////////////////////////////////////////////////////////////////////////////////////// // Sorting static const EColumnSortMode::Type GetDefaultColumnSortMode(); static const FName GetDefaultColumnBeingSorted(); void CreateSortings(); void UpdateCurrentSortingByColumn(); void SortTreeNodes(); void SortTreeNodesRec(FTableTreeNode& GroupNode, const ITableCellValueSorter& Sorter); EColumnSortMode::Type GetSortModeForColumn(const FName ColumnId) const; void SetSortModeForColumn(const FName& ColumnId, EColumnSortMode::Type SortMode); void OnSortModeChanged(const EColumnSortPriority::Type SortPriority, const FName& ColumnId, const EColumnSortMode::Type SortMode); //////////////////////////////////////////////////////////////////////////////////////////////////// // Sorting actions // SortMode (HeaderMenu) bool HeaderMenu_SortMode_IsChecked(const FName ColumnId, const EColumnSortMode::Type InSortMode); bool HeaderMenu_SortMode_CanExecute(const FName ColumnId, const EColumnSortMode::Type InSortMode) const; void HeaderMenu_SortMode_Execute(const FName ColumnId, const EColumnSortMode::Type InSortMode); // SortMode (ContextMenu) bool ContextMenu_SortMode_IsChecked(const EColumnSortMode::Type InSortMode); bool ContextMenu_SortMode_CanExecute(const EColumnSortMode::Type InSortMode) const; void ContextMenu_SortMode_Execute(const EColumnSortMode::Type InSortMode); // SortByColumn (ContextMenu) bool ContextMenu_SortByColumn_IsChecked(const FName ColumnId); bool ContextMenu_SortByColumn_CanExecute(const FName ColumnId) const; void ContextMenu_SortByColumn_Execute(const FName ColumnId); //////////////////////////////////////////////////////////////////////////////////////////////////// // Column visibility actions // ShowColumn bool CanShowColumn(const FName ColumnId) const; void ShowColumn(const FName ColumnId); // HideColumn bool CanHideColumn(const FName ColumnId) const; void HideColumn(const FName ColumnId); // ToggleColumnVisibility bool IsColumnVisible(const FName ColumnId); bool CanToggleColumnVisibility(const FName ColumnId) const; void ToggleColumnVisibility(const FName ColumnId); // ShowAllColumns (ContextMenu) bool ContextMenu_ShowAllColumns_CanExecute() const; void ContextMenu_ShowAllColumns_Execute(); // ResetColumns (ContextMenu) bool ContextMenu_ResetColumns_CanExecute() const; void ContextMenu_ResetColumns_Execute(); //////////////////////////////////////////////////////////////////////////////////////////////////// protected: /** Table view model. */ TSharedPtr Table; /** A weak pointer to the profiler session used to populate this widget. */ TSharedPtr /*Weak*/ Session; ////////////////////////////////////////////////// // Tree View, Columns /** The child STreeView widget. */ TSharedPtr> TreeView; /** Holds the tree view header row widget which display all columns in the tree view. */ TSharedPtr TreeViewHeaderRow; /** External scrollbar used to synchronize tree view position. */ TSharedPtr ExternalScrollbar; ////////////////////////////////////////////////// // Hovered Column, Hovered Tree Node /** Name of the column currently being hovered by the mouse. */ FName HoveredColumnId; /** A shared pointer to the tree node currently being hovered by the mouse. */ FTableTreeNodePtr HoveredNodePtr; /** Name of the tree node that should be drawn as highlighted. */ FName HighlightedNodeName; ////////////////////////////////////////////////// // Tree Nodes static const FName RootNodeName; /** The root node of the tree. */ FTableTreeNodePtr Root; /** Table (row) nodes. Each node corresponds to a table row. Index in this array corresponds to RowIndex in source table. */ TArray TableTreeNodes; /** A filtered array of group and nodes to be displayed in the tree widget. */ TArray FilteredGroupNodes; /** Currently expanded group nodes. */ TSet ExpandedNodes; /** If true, the expanded nodes have been saved before applying a text filter. */ bool bExpansionSaved; ////////////////////////////////////////////////// // Search box and filters /** The search box widget used to filter items displayed in the stats and groups tree. */ TSharedPtr SearchBox; /** The text based filter. */ TSharedPtr TextFilter; /** The filter collection. */ TSharedPtr Filters; ////////////////////////////////////////////////// // Grouping TArray> AvailableGroupings; /** How we group the tree nodes? */ TArray> CurrentGroupings; TSharedPtr>> GroupingBreadcrumbTrail; ////////////////////////////////////////////////// // Sorting /** All available sorters. */ TArray> AvailableSorters; /** Current sorter. It is nullptr if sorting is disabled. */ TSharedPtr CurrentSorter; /** Name of the column currently being sorted. Can be NAME_None if sorting is disabled (CurrentSorting == nullptr) or if a complex sorting is used (CurrentSorting != nullptr). */ FName ColumnBeingSorted; /** How we sort the nodes? Ascending or Descending. */ EColumnSortMode::Type ColumnSortMode; ////////////////////////////////////////////////// double StatsStartTime; double StatsEndTime; }; //////////////////////////////////////////////////////////////////////////////////////////////////// } // namespace Insights