You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
This was available within SDetailsViewBase, but the only publicly available function was ForceRefresh which isn't deferred Using RequestForceRefresh is preferable when the refresh can be deferred, as it can prevent performance problems from refreshing the view multiple times within a single frame #rb Rex.Hill [CL 31275746 by jamie dale in ue5-main branch]
351 lines
10 KiB
C++
351 lines
10 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SStructureDetailsView.h"
|
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
|
#include "Widgets/Images/SImage.h"
|
|
#include "Widgets/Input/SComboButton.h"
|
|
#include "AssetSelection.h"
|
|
#include "DetailCategoryBuilderImpl.h"
|
|
#include "UserInterface/PropertyDetails/PropertyDetailsUtilities.h"
|
|
#include "StructurePropertyNode.h"
|
|
#include "Widgets/Colors/SColorPicker.h"
|
|
#include "Widgets/Input/SSearchBox.h"
|
|
#include "DetailsViewPropertyGenerationUtilities.h"
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "SStructureDetailsView"
|
|
|
|
|
|
SStructureDetailsView::~SStructureDetailsView()
|
|
{
|
|
auto RootNodeLocal = GetRootNode();
|
|
|
|
if (RootNodeLocal.IsValid())
|
|
{
|
|
SaveExpandedItems(RootNodeLocal.ToSharedRef());
|
|
}
|
|
}
|
|
|
|
UStruct* SStructureDetailsView::GetBaseScriptStruct() const
|
|
{
|
|
const UStruct* Struct = StructProvider.IsValid() ? StructProvider->GetBaseStructure() : nullptr;
|
|
return const_cast<UStruct*>(Struct);
|
|
}
|
|
|
|
void SStructureDetailsView::Construct(const FArguments& InArgs)
|
|
{
|
|
DetailsViewArgs = InArgs._DetailsViewArgs;
|
|
|
|
ColumnSizeData.SetValueColumnWidth(DetailsViewArgs.ColumnWidth);
|
|
ColumnSizeData.SetRightColumnMinWidth(DetailsViewArgs.RightColumnMinWidth);
|
|
|
|
CustomName = InArgs._CustomName;
|
|
|
|
// Create the root property now
|
|
// Only one root node in a structure details view
|
|
RootNodes.Empty(1);
|
|
RootNodes.Add(MakeShareable(new FStructurePropertyNode));
|
|
|
|
PropertyUtilities = MakeShareable( new FPropertyDetailsUtilities( *this ) );
|
|
PropertyGenerationUtilities = MakeShareable(new FDetailsViewPropertyGenerationUtilities(*this));
|
|
|
|
TSharedRef<SScrollBar> ExternalScrollbar = SNew(SScrollBar);
|
|
|
|
// See note in SDetailsView for why visibility is set after construction
|
|
ExternalScrollbar->SetVisibility( TAttribute<EVisibility>(this, &SStructureDetailsView::GetScrollBarVisibility) );
|
|
|
|
FMenuBuilder DetailViewOptions( true, nullptr );
|
|
|
|
FUIAction ShowOnlyModifiedAction(
|
|
FExecuteAction::CreateSP(this, &SStructureDetailsView::OnShowOnlyModifiedClicked),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SStructureDetailsView::IsShowOnlyModifiedChecked)
|
|
);
|
|
|
|
if (DetailsViewArgs.bShowModifiedPropertiesOption)
|
|
{
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("ShowOnlyModified", "Show Only Modified Properties"),
|
|
LOCTEXT("ShowOnlyModified_ToolTip", "Displays only properties which have been changed from their default"),
|
|
FSlateIcon(),
|
|
ShowOnlyModifiedAction,
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
}
|
|
if (DetailsViewArgs.bShowKeyablePropertiesOption)
|
|
{
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("ShowOnlyKeyable", "Show Only Keyable Properties"),
|
|
LOCTEXT("ShowOnlyKeyable_ToolTip", "Displays only properties which are keyable"),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP(this, &SStructureDetailsView::OnShowKeyableClicked),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SStructureDetailsView::IsShowKeyableChecked)
|
|
),
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
}
|
|
if (DetailsViewArgs.bShowAnimatedPropertiesOption)
|
|
{
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("ShowAnimated", "Show Only Animated Properties"),
|
|
LOCTEXT("ShowAnimated_ToolTip", "Displays only properties which are animated (have tracks)"),
|
|
FSlateIcon(),
|
|
FUIAction(
|
|
FExecuteAction::CreateSP(this, &SStructureDetailsView::OnShowAnimatedClicked),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SStructureDetailsView::IsShowAnimatedChecked)
|
|
),
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
}
|
|
FUIAction ShowAllAdvancedAction(
|
|
FExecuteAction::CreateSP(this, &SStructureDetailsView::OnShowAllAdvancedClicked),
|
|
FCanExecuteAction(),
|
|
FIsActionChecked::CreateSP(this, &SStructureDetailsView::IsShowAllAdvancedChecked)
|
|
);
|
|
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("ShowAllAdvanced", "Show All Advanced Details"),
|
|
LOCTEXT("ShowAllAdvanced_ToolTip", "Shows all advanced detail sections in each category"),
|
|
FSlateIcon(),
|
|
ShowAllAdvancedAction,
|
|
NAME_None,
|
|
EUserInterfaceActionType::ToggleButton
|
|
);
|
|
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("CollapseAll", "Collapse All Categories"),
|
|
LOCTEXT("CollapseAll_ToolTip", "Collapses all root level categories"),
|
|
FSlateIcon(),
|
|
FUIAction(FExecuteAction::CreateSP(this, &SStructureDetailsView::SetRootExpansionStates, /*bExpanded=*/false, /*bRecurse=*/false)));
|
|
DetailViewOptions.AddMenuEntry(
|
|
LOCTEXT("ExpandAll", "Expand All Categories"),
|
|
LOCTEXT("ExpandAll_ToolTip", "Expands all root level categories"),
|
|
FSlateIcon(),
|
|
FUIAction(FExecuteAction::CreateSP(this, &SStructureDetailsView::SetRootExpansionStates, /*bExpanded=*/true, /*bRecurse=*/false)));
|
|
|
|
TSharedRef<SHorizontalBox> FilterBoxRow = SNew( SHorizontalBox )
|
|
.Visibility(this, &SStructureDetailsView::GetFilterBoxVisibility)
|
|
+SHorizontalBox::Slot()
|
|
.FillWidth( 1 )
|
|
.VAlign( VAlign_Center )
|
|
[
|
|
// Create the search box
|
|
SAssignNew( SearchBox, SSearchBox )
|
|
.OnTextChanged(this, &SStructureDetailsView::OnFilterTextChanged)
|
|
];
|
|
|
|
if (DetailsViewArgs.bShowOptions)
|
|
{
|
|
FilterBoxRow->AddSlot()
|
|
.HAlign(HAlign_Right)
|
|
.AutoWidth()
|
|
[
|
|
SNew( SComboButton )
|
|
.ContentPadding(0.0f)
|
|
.ForegroundColor( FSlateColor::UseForeground() )
|
|
.ButtonStyle( FAppStyle::Get(), "ToggleButton" )
|
|
.MenuContent()
|
|
[
|
|
DetailViewOptions.MakeWidget()
|
|
]
|
|
.ButtonContent()
|
|
[
|
|
SNew(SImage)
|
|
.Image( FAppStyle::GetBrush("GenericViewButton") )
|
|
]
|
|
];
|
|
}
|
|
|
|
SAssignNew(DetailTree, SDetailTree)
|
|
.Visibility(this, &SStructureDetailsView::GetTreeVisibility)
|
|
.TreeItemsSource(&RootTreeNodes)
|
|
.OnGetChildren(this, &SStructureDetailsView::OnGetChildrenForDetailTree)
|
|
.OnSetExpansionRecursive(this, &SStructureDetailsView::SetNodeExpansionStateRecursive)
|
|
.OnGenerateRow(this, &SStructureDetailsView::OnGenerateRowForDetailTree)
|
|
.OnExpansionChanged(this, &SStructureDetailsView::OnItemExpansionChanged)
|
|
.SelectionMode(ESelectionMode::None)
|
|
.ExternalScrollbar(ExternalScrollbar);
|
|
|
|
ChildSlot
|
|
[
|
|
SNew( SBox )
|
|
.Visibility(this, &SStructureDetailsView::GetPropertyEditingVisibility)
|
|
[
|
|
SNew( SVerticalBox )
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
.Padding( 0.0f, 0.0f, 0.0f, 2.0f )
|
|
[
|
|
FilterBoxRow
|
|
]
|
|
+ SVerticalBox::Slot()
|
|
.FillHeight(1.0f)
|
|
.Padding(0.0f)
|
|
[
|
|
SNew( SOverlay )
|
|
+ SOverlay::Slot()
|
|
[
|
|
DetailTree.ToSharedRef()
|
|
]
|
|
+ SOverlay::Slot()
|
|
.HAlign(HAlign_Right)
|
|
[
|
|
SNew( SBox )
|
|
.WidthOverride( 16.0f )
|
|
[
|
|
ExternalScrollbar
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
void SStructureDetailsView::SetStructureData(TSharedPtr<FStructOnScope> InStructData)
|
|
{
|
|
SetStructureProvider(InStructData ? MakeShared<FStructOnScopeStructureDataProvider>(InStructData) : TSharedPtr<IStructureDataProvider>());
|
|
}
|
|
|
|
void SStructureDetailsView::SetStructureProvider(TSharedPtr<IStructureDataProvider> InStructProvider)
|
|
{
|
|
|
|
TSharedPtr<FComplexPropertyNode> RootNode = GetRootNode();
|
|
//PRE SET
|
|
SaveExpandedItems(RootNode.ToSharedRef() );
|
|
RootNode->AsStructureNode()->RemoveStructure();
|
|
RootNodesPendingKill.Add(RootNode);
|
|
|
|
RootNodes.Empty(1);
|
|
ExpandedDetailNodes.Clear();
|
|
|
|
RootNode = MakeShareable(new FStructurePropertyNode);
|
|
RootNodes.Add(RootNode);
|
|
|
|
//SET
|
|
StructProvider = InStructProvider;
|
|
RootNode->AsStructureNode()->SetStructure(StructProvider);
|
|
if (!StructProvider.IsValid())
|
|
{
|
|
bIsLocked = false;
|
|
}
|
|
|
|
//POST SET
|
|
TSharedPtr<SColorPicker> ExistingColorPicker = GetColorPicker();
|
|
if (ExistingColorPicker.IsValid()
|
|
&& (!ExistingColorPicker->GetOptionalOwningDetailsView().IsValid()
|
|
|| ExistingColorPicker->GetOptionalOwningDetailsView().Get() == this))
|
|
{
|
|
DestroyColorPicker();
|
|
bHasOpenColorPicker = false;
|
|
}
|
|
|
|
FPropertyNodeInitParams InitParams;
|
|
InitParams.ParentNode = nullptr;
|
|
InitParams.Property = nullptr;
|
|
InitParams.ArrayOffset = 0;
|
|
InitParams.ArrayIndex = INDEX_NONE;
|
|
InitParams.bAllowChildren = true;
|
|
InitParams.bForceHiddenPropertyVisibility = FPropertySettings::Get().ShowHiddenProperties() || DetailsViewArgs.bForceHiddenPropertyVisibility;
|
|
InitParams.bCreateCategoryNodes = false;
|
|
|
|
RootNode->InitNode(InitParams);
|
|
RootNode->SetDisplayNameOverride(CustomName);
|
|
|
|
RestoreExpandedItems(RootNode.ToSharedRef());
|
|
|
|
UpdatePropertyMaps();
|
|
|
|
UpdateFilteredDetails();
|
|
}
|
|
|
|
void SStructureDetailsView::SetCustomName(const FText& Text)
|
|
{
|
|
CustomName = Text;
|
|
}
|
|
|
|
void SStructureDetailsView::ForceRefresh()
|
|
{
|
|
ClearPendingRefreshTimer();
|
|
|
|
SetStructureProvider(StructProvider);
|
|
}
|
|
|
|
void SStructureDetailsView::ClearSearch()
|
|
{
|
|
CurrentFilter.FilterStrings.Empty();
|
|
SearchBox->SetText(FText::GetEmpty());
|
|
RerunCurrentFilter();
|
|
}
|
|
|
|
|
|
const TArray< TWeakObjectPtr<UObject> >& SStructureDetailsView::GetSelectedObjects() const
|
|
{
|
|
static const TArray< TWeakObjectPtr<UObject> > DummyRef;
|
|
return DummyRef;
|
|
}
|
|
|
|
const TArray< TWeakObjectPtr<AActor> >& SStructureDetailsView::GetSelectedActors() const
|
|
{
|
|
static const TArray< TWeakObjectPtr<AActor> > DummyRef;
|
|
return DummyRef;
|
|
}
|
|
|
|
const FSelectedActorInfo& SStructureDetailsView::GetSelectedActorInfo() const
|
|
{
|
|
static const FSelectedActorInfo DummyRef;
|
|
return DummyRef;
|
|
}
|
|
|
|
bool SStructureDetailsView::IsConnected() const
|
|
{
|
|
const FStructurePropertyNode* RootNode = GetRootNode().IsValid() ? GetRootNode()->AsStructureNode() : nullptr;
|
|
return StructProvider.IsValid() && StructProvider->IsValid() && RootNode && RootNode->HasValidStructData();
|
|
}
|
|
|
|
FRootPropertyNodeList& SStructureDetailsView::GetRootNodes()
|
|
{
|
|
return RootNodes;
|
|
}
|
|
|
|
TSharedPtr<class FComplexPropertyNode> SStructureDetailsView::GetRootNode()
|
|
{
|
|
return RootNodes[0];
|
|
}
|
|
|
|
const TSharedPtr<class FComplexPropertyNode> SStructureDetailsView::GetRootNode() const
|
|
{
|
|
return RootNodes[0];
|
|
}
|
|
|
|
void SStructureDetailsView::CustomUpdatePropertyMap(TSharedPtr<FDetailLayoutBuilderImpl>& InDetailLayout)
|
|
{
|
|
FName StructCategoryName = NAME_None;
|
|
|
|
const UStruct* Struct = StructProvider.IsValid() ? StructProvider->GetBaseStructure() : nullptr;
|
|
if (Struct)
|
|
{
|
|
TArray<FName> CategoryNames;
|
|
InDetailLayout->GetCategoryNames(CategoryNames);
|
|
|
|
int32 StructCategoryNameIndex = INDEX_NONE;
|
|
CategoryNames.Find(Struct->GetFName(), StructCategoryNameIndex);
|
|
StructCategoryName = StructCategoryNameIndex != INDEX_NONE ? CategoryNames[StructCategoryNameIndex] : NAME_None;
|
|
}
|
|
|
|
InDetailLayout->DefaultCategory(StructCategoryName).SetDisplayName(NAME_None, CustomName);
|
|
}
|
|
|
|
EVisibility SStructureDetailsView::GetPropertyEditingVisibility() const
|
|
{
|
|
const FStructurePropertyNode* RootNode = GetRootNode().IsValid() ? GetRootNode()->AsStructureNode() : nullptr;
|
|
return StructProvider.IsValid() && StructProvider->IsValid() && RootNode && RootNode->HasValidStructData() ? EVisibility::Visible : EVisibility::Collapsed;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|