mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 09:35:25 +00:00
Added SteveFixedDataTableRowHandle
This commit is contained in:
parent
91e428a7d6
commit
19363c00f7
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Engine/DataTable.h"
|
||||||
|
|
||||||
|
#include "StevesFixedDataTableRowHandle.generated.h"
|
||||||
|
|
||||||
|
/// Just a type to denote that this table row handle should be edited differently
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct STEVESUEHELPERS_API FStevesFixedDataTableRowHandle : public FDataTableRowHandle
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,194 @@
|
|||||||
|
#include "StevesFixedDataTableCustomisationLayout.h"
|
||||||
|
|
||||||
|
#include "AssetRegistry/AssetData.h"
|
||||||
|
#include "Containers/Map.h"
|
||||||
|
#include "DataTableEditorUtils.h"
|
||||||
|
#include "Delegates/Delegate.h"
|
||||||
|
#include "DetailWidgetRow.h"
|
||||||
|
#include "Editor.h"
|
||||||
|
#include "Engine/DataTable.h"
|
||||||
|
#include "Fonts/SlateFontInfo.h"
|
||||||
|
#include "Framework/Commands/UIAction.h"
|
||||||
|
#include "HAL/Platform.h"
|
||||||
|
#include "HAL/PlatformCrt.h"
|
||||||
|
#include "Internationalization/Internationalization.h"
|
||||||
|
#include "Internationalization/Text.h"
|
||||||
|
#include "Misc/Attribute.h"
|
||||||
|
#include "PropertyCustomizationHelpers.h"
|
||||||
|
#include "PropertyEditorModule.h"
|
||||||
|
#include "PropertyHandle.h"
|
||||||
|
#include "Templates/Casts.h"
|
||||||
|
#include "UObject/Class.h"
|
||||||
|
#include "UObject/Object.h"
|
||||||
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
||||||
|
#include "Widgets/Text/STextBlock.h"
|
||||||
|
|
||||||
|
class SToolTip;
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FSsFixedDataTableCustomisationLayout"
|
||||||
|
|
||||||
|
void FStevesFixedDataTableCustomisationLayout::CustomizeHeader(TSharedRef<class IPropertyHandle> InStructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
|
||||||
|
{
|
||||||
|
DataTablePropertyHandle = InStructPropertyHandle->GetChildHandle("DataTable");
|
||||||
|
RowNamePropertyHandle = InStructPropertyHandle->GetChildHandle("RowName");
|
||||||
|
|
||||||
|
if (InStructPropertyHandle->HasMetaData(TEXT("DataTable")))
|
||||||
|
{
|
||||||
|
// Find data table from asset ref
|
||||||
|
const FString& DataTablePath = InStructPropertyHandle->GetMetaData(TEXT("DataTable"));
|
||||||
|
if (UDataTable* DataTable = LoadObject<UDataTable>(nullptr, *DataTablePath, nullptr))
|
||||||
|
{
|
||||||
|
DataTablePropertyHandle->SetValue(DataTable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDataTable, Warning, TEXT("No Datatable found at %s"), *DataTablePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogDataTable, Warning, TEXT("No Datatable meta tag present on property %s"), *InStructPropertyHandle->GetPropertyDisplayName().ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FPropertyComboBoxArgs ComboArgs(RowNamePropertyHandle,
|
||||||
|
FOnGetPropertyComboBoxStrings::CreateSP(this, &FStevesFixedDataTableCustomisationLayout::OnGetRowStrings),
|
||||||
|
FOnGetPropertyComboBoxValue::CreateSP(this, &FStevesFixedDataTableCustomisationLayout::OnGetRowValueString));
|
||||||
|
ComboArgs.ShowSearchForItemCount = 1;
|
||||||
|
|
||||||
|
|
||||||
|
TSharedRef<SWidget> BrowseTableButton = PropertyCustomizationHelpers::MakeBrowseButton(
|
||||||
|
FSimpleDelegate::CreateSP(this, &FStevesFixedDataTableCustomisationLayout::BrowseTableButtonClicked),
|
||||||
|
LOCTEXT("SsBrowseToDatatable", "Browse to DataTable in Content Browser"));
|
||||||
|
HeaderRow
|
||||||
|
.NameContent()
|
||||||
|
[
|
||||||
|
InStructPropertyHandle->CreatePropertyNameWidget()
|
||||||
|
]
|
||||||
|
.ValueContent()
|
||||||
|
.MaxDesiredWidth(0.0f) // don't constrain the combo button width
|
||||||
|
[
|
||||||
|
SNew(SHorizontalBox)
|
||||||
|
+SHorizontalBox::Slot()
|
||||||
|
.FillWidth(1.0f)
|
||||||
|
[
|
||||||
|
PropertyCustomizationHelpers::MakePropertyComboBox(ComboArgs)
|
||||||
|
]
|
||||||
|
+SHorizontalBox::Slot()
|
||||||
|
.Padding(2.0f)
|
||||||
|
.HAlign(HAlign_Center)
|
||||||
|
.VAlign(VAlign_Center)
|
||||||
|
.AutoWidth()
|
||||||
|
[
|
||||||
|
BrowseTableButton
|
||||||
|
]
|
||||||
|
]; ;
|
||||||
|
|
||||||
|
FDataTableEditorUtils::AddSearchForReferencesContextMenu(HeaderRow, FExecuteAction::CreateSP(this, &FStevesFixedDataTableCustomisationLayout::OnSearchForReferences));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FStevesFixedDataTableCustomisationLayout::BrowseTableButtonClicked()
|
||||||
|
{
|
||||||
|
if (DataTablePropertyHandle.IsValid())
|
||||||
|
{
|
||||||
|
UObject* SourceDataTable = nullptr;
|
||||||
|
if (DataTablePropertyHandle->GetValue(SourceDataTable) == FPropertyAccess::Success)
|
||||||
|
{
|
||||||
|
TArray<FAssetData> Assets;
|
||||||
|
Assets.Add(SourceDataTable);
|
||||||
|
GEditor->SyncBrowserToObjects(Assets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FStevesFixedDataTableCustomisationLayout::GetCurrentValue(UDataTable*& OutDataTable, FName& OutName) const
|
||||||
|
{
|
||||||
|
if (RowNamePropertyHandle.IsValid() && RowNamePropertyHandle->IsValidHandle() && DataTablePropertyHandle.IsValid() && DataTablePropertyHandle->IsValidHandle())
|
||||||
|
{
|
||||||
|
// If either handle is multiple value or failure, fail
|
||||||
|
UObject* SourceDataTable = nullptr;
|
||||||
|
if (DataTablePropertyHandle->GetValue(SourceDataTable) == FPropertyAccess::Success)
|
||||||
|
{
|
||||||
|
OutDataTable = Cast<UDataTable>(SourceDataTable);
|
||||||
|
|
||||||
|
if (RowNamePropertyHandle->GetValue(OutName) == FPropertyAccess::Success)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FStevesFixedDataTableCustomisationLayout::OnSearchForReferences()
|
||||||
|
{
|
||||||
|
UDataTable* DataTable;
|
||||||
|
FName RowName;
|
||||||
|
|
||||||
|
if (GetCurrentValue(DataTable, RowName) && DataTable)
|
||||||
|
{
|
||||||
|
TArray<FAssetIdentifier> AssetIdentifiers;
|
||||||
|
AssetIdentifiers.Add(FAssetIdentifier(DataTable, RowName));
|
||||||
|
|
||||||
|
FEditorDelegates::OnOpenReferenceViewer.Broadcast(AssetIdentifiers, FReferenceViewerParams());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FString FStevesFixedDataTableCustomisationLayout::OnGetRowValueString() const
|
||||||
|
{
|
||||||
|
if (!RowNamePropertyHandle.IsValid() || !RowNamePropertyHandle->IsValidHandle())
|
||||||
|
{
|
||||||
|
return FString();
|
||||||
|
}
|
||||||
|
|
||||||
|
FName RowNameValue;
|
||||||
|
const FPropertyAccess::Result RowResult = RowNamePropertyHandle->GetValue(RowNameValue);
|
||||||
|
if (RowResult == FPropertyAccess::Success)
|
||||||
|
{
|
||||||
|
if (RowNameValue.IsNone())
|
||||||
|
{
|
||||||
|
return LOCTEXT("DataTable_None", "None").ToString();
|
||||||
|
}
|
||||||
|
return RowNameValue.ToString();
|
||||||
|
}
|
||||||
|
else if (RowResult == FPropertyAccess::Fail)
|
||||||
|
{
|
||||||
|
return LOCTEXT("DataTable_None", "None").ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return LOCTEXT("MultipleValues", "Multiple Values").ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FStevesFixedDataTableCustomisationLayout::OnGetRowStrings(TArray< TSharedPtr<FString> >& OutStrings, TArray<TSharedPtr<SToolTip>>& OutToolTips, TArray<bool>& OutRestrictedItems) const
|
||||||
|
{
|
||||||
|
UDataTable* DataTable = nullptr;
|
||||||
|
FName IgnoredRowName;
|
||||||
|
|
||||||
|
// Ignore return value as we will show rows if table is the same but row names are multiple values
|
||||||
|
GetCurrentValue(DataTable, IgnoredRowName);
|
||||||
|
|
||||||
|
TArray<FName> AllRowNames;
|
||||||
|
if (DataTable != nullptr)
|
||||||
|
{
|
||||||
|
for (TMap<FName, uint8*>::TConstIterator Iterator(DataTable->GetRowMap()); Iterator; ++Iterator)
|
||||||
|
{
|
||||||
|
AllRowNames.Add(Iterator.Key());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the names alphabetically.
|
||||||
|
AllRowNames.Sort(FNameLexicalLess());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const FName& RowName : AllRowNames)
|
||||||
|
{
|
||||||
|
OutStrings.Add(MakeShared<FString>(RowName.ToString()));
|
||||||
|
OutRestrictedItems.Add(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Containers/Array.h"
|
||||||
|
#include "Containers/UnrealString.h"
|
||||||
|
#include "IPropertyTypeCustomization.h"
|
||||||
|
#include "Templates/SharedPointer.h"
|
||||||
|
#include "UObject/NameTypes.h"
|
||||||
|
|
||||||
|
class IPropertyHandle;
|
||||||
|
class SToolTip;
|
||||||
|
class UDataTable;
|
||||||
|
class UScriptStruct;
|
||||||
|
struct FAssetData;
|
||||||
|
|
||||||
|
/// Drop-down for data table row name when the table itself is fixed in meta tags
|
||||||
|
class FStevesFixedDataTableCustomisationLayout : public IPropertyTypeCustomization
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static TSharedRef<IPropertyTypeCustomization> MakeInstance()
|
||||||
|
{
|
||||||
|
return MakeShareable( new FStevesFixedDataTableCustomisationLayout );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void CustomizeHeader(TSharedRef<class IPropertyHandle> InStructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
|
||||||
|
// Not needed, but must be implemented
|
||||||
|
virtual void CustomizeChildren(TSharedRef<class IPropertyHandle> InStructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool GetCurrentValue(UDataTable*& OutDataTable, FName& OutName) const;
|
||||||
|
void OnSearchForReferences();
|
||||||
|
void OnGetRowStrings(TArray< TSharedPtr<FString> >& OutStrings, TArray<TSharedPtr<SToolTip>>& OutToolTips, TArray<bool>& OutRestrictedItems) const;
|
||||||
|
FString OnGetRowValueString() const;
|
||||||
|
void BrowseTableButtonClicked();
|
||||||
|
|
||||||
|
TSharedPtr<IPropertyHandle> DataTablePropertyHandle;
|
||||||
|
TSharedPtr<IPropertyHandle> RowNamePropertyHandle;
|
||||||
|
|
||||||
|
};
|
20
Source/StevesUEHelpersEd/Private/StevesUEHelpersEd.cpp
Normal file
20
Source/StevesUEHelpersEd/Private/StevesUEHelpersEd.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "StevesUEHelpersEd.h"
|
||||||
|
#include "StevesFixedDataTableCustomisationLayout.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FStevesUEHelpersEdModule"
|
||||||
|
|
||||||
|
void FStevesUEHelpersEdModule::StartupModule()
|
||||||
|
{
|
||||||
|
FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||||
|
PropertyModule.RegisterCustomPropertyTypeLayout("StevesFixedDataTableRowHandle", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FStevesFixedDataTableCustomisationLayout::MakeInstance));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FStevesUEHelpersEdModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
|
||||||
|
PropertyModule.UnregisterCustomPropertyTypeLayout("StevesFixedDataTableRowHandle");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FStevesUEHelpersEdModule, StevesUEHelpersEd)
|
11
Source/StevesUEHelpersEd/Public/StevesUEHelpersEd.h
Normal file
11
Source/StevesUEHelpersEd/Public/StevesUEHelpersEd.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FStevesUEHelpersEdModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
};
|
30
Source/StevesUEHelpersEd/StevesUEHelpersEd.Build.cs
Normal file
30
Source/StevesUEHelpersEd/StevesUEHelpersEd.Build.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class StevesUEHelpersEd : ModuleRules
|
||||||
|
{
|
||||||
|
public StevesUEHelpersEd(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore",
|
||||||
|
|
||||||
|
"UnrealEd",
|
||||||
|
"PropertyEditor",
|
||||||
|
"DataTableEditor"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,35 +1,39 @@
|
|||||||
{
|
{
|
||||||
"FileVersion" : 3,
|
"FileVersion": 3,
|
||||||
"Version" : 1,
|
"Version": 1,
|
||||||
"VersionName" : "1.0",
|
"VersionName": "1.0",
|
||||||
"FriendlyName" : "Steve's UE4 Helpers",
|
"FriendlyName": "Steve's UE4 Helpers",
|
||||||
"Description" : "A set of common helper classes for UE4 projects by Steve Streeing",
|
"Description": "A set of common helper classes for UE4 projects by Steve Streeing",
|
||||||
"Category" : "Code Utilities",
|
"Category": "Code Utilities",
|
||||||
"CreatedBy" : "Steve Streeting",
|
"CreatedBy": "Steve Streeting",
|
||||||
"CreatedByURL" : "https://www.stevestreeting.com",
|
"CreatedByURL": "https://www.stevestreeting.com",
|
||||||
"DocsURL" : "",
|
"DocsURL": "",
|
||||||
"MarketplaceURL" : "",
|
"MarketplaceURL": "",
|
||||||
"SupportURL" : "https://github.com/sinbad/StevesUEHelpers",
|
"SupportURL": "https://github.com/sinbad/StevesUEHelpers",
|
||||||
"EnabledByDefault" : true,
|
"EnabledByDefault": true,
|
||||||
"CanContainContent" : false,
|
"CanContainContent": false,
|
||||||
"IsBetaVersion" : true,
|
"IsBetaVersion": true,
|
||||||
"Installed" : false,
|
"Installed": false,
|
||||||
"Modules" :
|
"Modules": [
|
||||||
[
|
|
||||||
{
|
{
|
||||||
"Name" : "StevesUEHelpers",
|
"Name": "StevesUEHelpers",
|
||||||
"Type" : "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase" : "PreDefault"
|
"LoadingPhase": "PreDefault"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "StevesUEHelpersEd",
|
||||||
|
"Type": "Editor",
|
||||||
|
"LoadingPhase": "PostDefault"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Plugins": [
|
"Plugins": [
|
||||||
{
|
{
|
||||||
"Name": "Paper2D",
|
"Name": "Paper2D",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Name": "EnhancedInput",
|
"Name": "EnhancedInput",
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user