CelticCraft/Plugins/VoxelFree/Source/VoxelEditor/Private/Details/VoxelSpawnerConfigSpawnerCustomization.cpp

170 lines
5.5 KiB
C++
Raw Normal View History

2023-07-03 16:17:13 +00:00
// Copyright 2020 Phyronnaz
#include "Details/VoxelSpawnerConfigSpawnerCustomization.h"
#include "VoxelMinimal.h"
#include "VoxelSpawners/VoxelSpawnerConfig.h"
#include "DetailWidgetRow.h"
#include "DetailLayoutBuilder.h"
#include "IDetailChildrenBuilder.h"
#include "IDetailGroup.h"
#include "IPropertyUtilities.h"
#include "PropertyCustomizationHelpers.h"
#include "Widgets/SBoxPanel.h"
#include "Widgets/Text/STextBlock.h"
#include "Widgets/Layout/SBox.h"
#define GET_CHILD_PROPERTY_IMPL(PropertyHandle, Class, Property) PropertyHandle->GetChildHandle(GET_MEMBER_NAME_STATIC(Class, Property)).ToSharedRef()
#define GET_CHILD_PROPERTY(Class, Property) GET_CHILD_PROPERTY_IMPL(PropertyHandle, Class, Property)
void FVoxelSpawnerConfigSpawnerCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> PropertyHandle, IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& CustomizationUtils)
{
const auto& SpawnerTypeEnum = *StaticEnum<EVoxelSpawnerType>();
const auto TypeHandle = GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, SpawnerType);
EVoxelSpawnerType Type;
{
FString TypeString;
if (!ensure(TypeHandle->GetValueAsFormattedString(TypeString) == FPropertyAccess::Success)) return;
const int64 TypeValue = SpawnerTypeEnum.GetValueByNameString(TypeString);
if (!ensure(TypeValue != -1)) return;
Type = EVoxelSpawnerType(TypeValue);
}
const FSimpleDelegate RefreshDelegate = FSimpleDelegate::CreateLambda([&CustomizationUtils]()
{
auto Utilities = CustomizationUtils.GetPropertyUtilities();
if (Utilities.IsValid())
{
Utilities->ForceRefresh();
}
});
TypeHandle->SetOnPropertyValueChanged(RefreshDelegate);
IDetailGroup& Group = ChildBuilder.AddGroup(TEXT("Spawner Config"), PropertyHandle->GetPropertyDisplayName());
Group.HeaderRow()
.NameContent()
[
PropertyHandle->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.MinDesiredWidth(FDetailWidgetRow::DefaultValueMinWidth)
[
TypeHandle->CreatePropertyValueWidget()
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
.Padding(2.0f, 1.0f)
[
PropertyCustomizationHelpers::MakeInsertDeleteDuplicateButton(
FExecuteAction::CreateLambda([=]() { PropertyHandle->GetParentHandle()->AsArray()->Insert(PropertyHandle->GetIndexInArray()); }),
FExecuteAction::CreateLambda([=]() { PropertyHandle->GetParentHandle()->AsArray()->DeleteItem(PropertyHandle->GetIndexInArray()); }),
FExecuteAction::CreateLambda([=]() { PropertyHandle->GetParentHandle()->AsArray()->DuplicateItem(PropertyHandle->GetIndexInArray()); }))
]
];
Group.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, Spawner));
Group.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, Density));
if (Type == EVoxelSpawnerType::Height)
{
Group.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, HeightGraphOutputName_HeightOnly));
}
Group.AddWidgetRow()
.NameContent()
[
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, ChunkSize_EditorOnly)->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.MinDesiredWidth(FDetailWidgetRow::DefaultValueMinWidth)
[
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, ChunkSize_EditorOnly)->CreatePropertyValueWidget()
]
]
+ SHorizontalBox::Slot()
.Padding(5.f, 0.f, 0.f, 0.f)
.AutoWidth()
[
SNew(STextBlock)
.Text_Lambda([=]()
{
FText Value;
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, LOD)->GetValueAsDisplayText(Value);
return FText::Format(VOXEL_LOCTEXT("LOD: {0}"), Value);
})
]
];
Group.AddWidgetRow()
.NameContent()
[
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, GenerationDistanceInVoxels_EditorOnly)->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SBox)
.MinDesiredWidth(FDetailWidgetRow::DefaultValueMinWidth)
[
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, GenerationDistanceInVoxels_EditorOnly)->CreatePropertyValueWidget()
]
]
+ SHorizontalBox::Slot()
.Padding(5.f, 0.f, 0.f, 0.f)
.AutoWidth()
[
SNew(STextBlock)
.Text_Lambda([=]()
{
FText Value;
GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, GenerationDistanceInChunks)->GetValueAsDisplayText(Value);
return FText::Format(VOXEL_LOCTEXT("{0} chunks"), Value);
})
]
];
IDetailGroup& AdvancedGroup = Group.AddGroup("Advanced", VOXEL_LOCTEXT("Advanced"));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, bSave));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, bDoNotDespawn));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, Seed));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, RandomGenerator));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, Guid));
if (Type == EVoxelSpawnerType::Ray)
{
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, DensityMultiplier_RayOnly));
}
if (Type == EVoxelSpawnerType::Height)
{
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, bComputeDensityFirst_HeightOnly));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, bCheckIfFloating_HeightOnly));
AdvancedGroup.AddPropertyRow(GET_CHILD_PROPERTY(FVoxelSpawnerConfigSpawner, bCheckIfCovered_HeightOnly));
}
}
#undef GET_CHILD_PROPERTY