Files
UnrealEngineUWP/Engine/Source/Editor/PropertyEditor/Private/SStructureDetailsView.cpp
sebastian nordgren 5050b88330 Details view reskin phase 1.
The details view now displays gridlines between rows, and now has 4 columns - edit condition, name, value, and reset/extensions.

Edit condition widgets are now created in SDetailSingleItemRow and are placed in their own fixed column on the left of the details view. FEditConditionParser is now in FPropertyNode rather FPropertyEditor, which allows access to it more broadly - notably in SDetailSingleItemRow.

The Reset to Default SWidget can no longer be replaced - the logic for it being visible and a handler for when it is pressed is still customizable. SPropertyEditorAsset no longer has a special slot for the reset to default widget.

All extension widgets are now placed in a resizable column on the right of the panel, including the Keyframe button.

FDetailColumnSizeData is now publicly exposed by IDetailsView, and is no longer passed around as much.

#rb matt.kuhlenschmidt

[CL 14375859 by sebastian nordgren in ue5-main branch]
2020-09-23 08:16:20 -04:00

321 lines
9.3 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 = StructData.IsValid() ? StructData->GetStruct() : NULL;
return const_cast<UStruct*>(Struct);
}
void SStructureDetailsView::Construct(const FArguments& InArgs)
{
DetailsViewArgs = InArgs._DetailsViewArgs;
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)
.ForegroundColor( FSlateColor::UseForeground() )
.ButtonStyle( FEditorStyle::Get(), "ToggleButton" )
.MenuContent()
[
DetailViewOptions.MakeWidget()
]
.ButtonContent()
[
SNew(SImage)
.Image( FEditorStyle::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)
.Padding(0)
[
SNew( SHorizontalBox )
+ SHorizontalBox::Slot()
[
DetailTree.ToSharedRef()
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew( SBox )
.WidthOverride( 16.0f )
[
ExternalScrollbar
]
]
]
]
];
}
void SStructureDetailsView::SetStructureData(TSharedPtr<FStructOnScope> InStructData)
{
TSharedPtr<FComplexPropertyNode> RootNode = GetRootNode();
//PRE SET
SaveExpandedItems(RootNode.ToSharedRef() );
RootNode->AsStructureNode()->SetStructure(nullptr);
RootNodesPendingKill.Add(RootNode);
RootNodes.Empty(1);
ExpandedDetailNodes.Empty();
RootNode = MakeShareable(new FStructurePropertyNode);
RootNodes.Add(RootNode);
//SET
StructData = InStructData;
RootNode->AsStructureNode()->SetStructure(StructData);
if (!StructData.IsValid())
{
bIsLocked = false;
}
//POST SET
DestroyColorPicker();
ColorPropertyNode = NULL;
FPropertyNodeInitParams InitParams;
InitParams.ParentNode = NULL;
InitParams.Property = NULL;
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()
{
SetStructureData(StructData);
}
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 StructData.IsValid() && StructData->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)
{
InDetailLayout->DefaultCategory(NAME_None).SetDisplayName(NAME_None, CustomName);
}
EVisibility SStructureDetailsView::GetPropertyEditingVisibility() const
{
const FStructurePropertyNode* RootNode = GetRootNode().IsValid() ? GetRootNode()->AsStructureNode() : nullptr;
return StructData.IsValid() && StructData->IsValid() && RootNode && RootNode->HasValidStructData() ? EVisibility::Visible : EVisibility::Collapsed;
}
#undef LOCTEXT_NAMESPACE