// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Widgets/SCompoundWidget.h" #include "Widgets/Views/STableRow.h" #include "Widgets/Views/STreeView.h" #include "MassDebugger.h" #include "MassDebuggerModel.h" class IDetailTreeNode; class IPropertyHandle; class IPropertyRowGenerator; class FStructOnScope; class SGridPanel; class SBox; class SScrollBar; class SHorizontalBox; class SVerticalBox; class SMassEntitiesList : public SCompoundWidget { public: SLATE_BEGIN_ARGS(SMassEntitiesList){} SLATE_ARGUMENT(TArray, Entities) SLATE_END_ARGS() void Construct(const FArguments& InArgs, TSharedRef InDebuggerModel); void SetEntities(const TArray& InEntities); void RefreshEntityData(); virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; protected: struct FMassEntitiesListColumn { const UScriptStruct* StructType = nullptr; const FProperty* Property = nullptr; FString ColumnLabel; FName ColumnID; }; struct FGridRow { struct FFragmentInfo { const UScriptStruct* StructType = nullptr; TSharedPtr PropertyRowGenerator; // this is a snapshot copy of the actual mass fragment data TSharedPtr StructData; }; TArray FragmentInfo; FMassEntityHandle Entity; TWeakPtr EntitiesList; bool bDirty = true; }; public: using EntitiesTableRowPtr = TSharedPtr; class SEntitiesTableRow : public SMultiColumnTableRow { using Super = SMultiColumnTableRow; public: SLATE_BEGIN_ARGS(SEntitiesTableRow) {} SLATE_ARGUMENT(EntitiesTableRowPtr, EntitiesTableRow) SLATE_END_ARGS() void Construct(const FArguments& InArgs, const TSharedRef& InOwnerTableView); virtual TSharedRef GenerateWidgetForColumn(const FName& InColumnName) override; private: EntitiesTableRowPtr TableRowPtr; TSharedRef GenerateBreakpointWidget(FGridRow::FFragmentInfo& Info); TSharedRef GenerateDataWidget(const FProperty* Property, FGridRow::FFragmentInfo& Info); }; TSharedPtr GetFragmentSelectBox() { return FragmentSelectBox; } void AutoUpdateEntityData(bool bEnable) { bAutoUpdateEntityData = bEnable; } private: TArray GridRows; TArray Columns; TMap ColumnIndexByID; void BuildGrid(); void PopulateGridColumns(); void RefreshFragmentData(); void AddPropertyRecursive(TSharedPtr HBox, TSharedPtr VBox, TSharedPtr Prop, bool bShowName = false); TArray AvailableFragmentNames; TArray SelectedFragmentNames; TArray SelectedFragmentTypes; FReply OnClearAllSelectedFragmentsClicked(); TSharedPtr FragmentSelectBox; bool bAutoUpdateEntityData = false; void OnFragmentCheckStateChanged(ECheckBoxState NewState, FName FragmentName); ECheckBoxState GetFragmentCheckState(FName FragmentName) const; void CreateFragmentSelectDropdown(); TSharedPtr DebuggerModel; void UpdateTreeColumns(); EColumnSortMode::Type GetColumnSortMode(FName ColumnId) const; void OnColumnSortModeChanged(const EColumnSortPriority::Type SortPriority, const FName& ColumnId, const EColumnSortMode::Type InSortMode); bool bSortAscending = true; void TreeView_OnGetChildren(SMassEntitiesList::EntitiesTableRowPtr InParent, TArray& OutChildren); TSharedRef TreeView_OnGenerateRow(EntitiesTableRowPtr RowPtr, const TSharedRef& OwnerTable); TSharedPtr> TreeView; TSharedPtr TreeViewHeaderRow; TArray> NodesToSearch; };