345 lines
13 KiB
C++
345 lines
13 KiB
C++
// 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<const FTableTreeNodePtr&> FTableTreeNodeFilterCollection;
|
|
|
|
/** The text based filter - used for updating the list of tree nodes. */
|
|
typedef TTextFilter<const FTableTreeNodePtr&> 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<Insights::FTable> InTablePtr);
|
|
|
|
TSharedPtr<Insights::FTable> 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<FTable> 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<FString>& OutSearchStrings) const;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Tree View - Context Menu
|
|
|
|
TSharedPtr<SWidget> 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<SWidget> 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<FTableTreeNodePtr>& 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<ITableRow> TreeView_OnGenerateRow(FTableTreeNodePtr TreeNode, const TSharedRef<STableViewBase>& OwnerTable);
|
|
|
|
bool TableRow_ShouldBeEnabled(FTableTreeNodePtr NodePtr) const;
|
|
|
|
void TableRow_SetHoveredCell(TSharedPtr<FTable> TablePtr, TSharedPtr<FTableColumn> 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<FTableTreeNodePtr>& 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<FTreeNodeGrouping>& InEntry);
|
|
void BuildGroupingSubMenu_Change(FMenuBuilder& MenuBuilder, const TSharedPtr<FTreeNodeGrouping> CrumbGrouping);
|
|
void BuildGroupingSubMenu_Add(FMenuBuilder& MenuBuilder, const TSharedPtr<FTreeNodeGrouping> CrumbGrouping);
|
|
TSharedRef<SWidget> GetGroupingCrumbMenuContent(const TSharedPtr<FTreeNodeGrouping>& CrumbGrouping);
|
|
|
|
void PreChangeGroupings();
|
|
void PostChangeGroupings();
|
|
int32 GetGroupingDepth(const TSharedPtr<FTreeNodeGrouping>& Grouping) const;
|
|
|
|
void GroupingCrumbMenu_Reset_Execute();
|
|
void GroupingCrumbMenu_Remove_Execute(const TSharedPtr<FTreeNodeGrouping> Grouping);
|
|
void GroupingCrumbMenu_MoveLeft_Execute(const TSharedPtr<FTreeNodeGrouping> Grouping);
|
|
void GroupingCrumbMenu_MoveRight_Execute(const TSharedPtr<FTreeNodeGrouping> Grouping);
|
|
void GroupingCrumbMenu_Change_Execute(const TSharedPtr<FTreeNodeGrouping> OldGrouping, const TSharedPtr<FTreeNodeGrouping> NewGrouping);
|
|
bool GroupingCrumbMenu_Change_CanExecute(const TSharedPtr<FTreeNodeGrouping> OldGrouping, const TSharedPtr<FTreeNodeGrouping> NewGrouping) const;
|
|
void GroupingCrumbMenu_Add_Execute(const TSharedPtr<FTreeNodeGrouping> Grouping, const TSharedPtr<FTreeNodeGrouping> AfterGrouping);
|
|
bool GroupingCrumbMenu_Add_CanExecute(const TSharedPtr<FTreeNodeGrouping> Grouping, const TSharedPtr<FTreeNodeGrouping> 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<Insights::FTable> Table;
|
|
|
|
/** A weak pointer to the profiler session used to populate this widget. */
|
|
TSharedPtr<const Trace::IAnalysisSession> /*Weak*/ Session;
|
|
|
|
//////////////////////////////////////////////////
|
|
// Tree View, Columns
|
|
|
|
/** The child STreeView widget. */
|
|
TSharedPtr<STreeView<FTableTreeNodePtr>> TreeView;
|
|
|
|
/** Holds the tree view header row widget which display all columns in the tree view. */
|
|
TSharedPtr<SHeaderRow> TreeViewHeaderRow;
|
|
|
|
/** External scrollbar used to synchronize tree view position. */
|
|
TSharedPtr<SScrollBar> 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<FTableTreeNodePtr> TableTreeNodes;
|
|
|
|
/** A filtered array of group and nodes to be displayed in the tree widget. */
|
|
TArray<FTableTreeNodePtr> FilteredGroupNodes;
|
|
|
|
/** Currently expanded group nodes. */
|
|
TSet<FTableTreeNodePtr> 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<SSearchBox> SearchBox;
|
|
|
|
/** The text based filter. */
|
|
TSharedPtr<FTableTreeNodeTextFilter> TextFilter;
|
|
|
|
/** The filter collection. */
|
|
TSharedPtr<FTableTreeNodeFilterCollection> Filters;
|
|
|
|
//////////////////////////////////////////////////
|
|
// Grouping
|
|
|
|
TArray<TSharedPtr<FTreeNodeGrouping>> AvailableGroupings;
|
|
|
|
/** How we group the tree nodes? */
|
|
TArray<TSharedPtr<FTreeNodeGrouping>> CurrentGroupings;
|
|
|
|
TSharedPtr<SBreadcrumbTrail<TSharedPtr<FTreeNodeGrouping>>> GroupingBreadcrumbTrail;
|
|
|
|
//////////////////////////////////////////////////
|
|
// Sorting
|
|
|
|
/** All available sorters. */
|
|
TArray<TSharedPtr<ITableCellValueSorter>> AvailableSorters;
|
|
|
|
/** Current sorter. It is nullptr if sorting is disabled. */
|
|
TSharedPtr<ITableCellValueSorter> 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
|