第一次提交
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_DetailSectionsBuilder.h"
|
||||
|
||||
TArray<TSoftClassPtr<UGUIS_ListEntryDetailSection>> UGUIS_DetailSectionsBuilder::GatherDetailSections_Implementation(const UObject* Data)
|
||||
{
|
||||
TArray<TSoftClassPtr<UGUIS_ListEntryDetailSection>> Sections;
|
||||
return Sections;
|
||||
}
|
||||
|
||||
|
||||
TArray<TSoftClassPtr<UGUIS_ListEntryDetailSection>> UGUIS_DetailSectionBuilder_Class::GatherDetailSections_Implementation(const UObject* Data)
|
||||
{
|
||||
TArray<TSoftClassPtr<UGUIS_ListEntryDetailSection>> Sections;
|
||||
|
||||
// Find extensions for it using the super chain of the setting so that we get any
|
||||
// class based extensions for this setting.
|
||||
for (UClass* Class = Data->GetClass(); Class; Class = Class->GetSuperClass())
|
||||
{
|
||||
FGUIS_EntryDetailsClassSections* ExtensionForClass = SectionsForClasses.Find(Class);
|
||||
if (ExtensionForClass)
|
||||
{
|
||||
Sections.Append(ExtensionForClass->Sections);
|
||||
}
|
||||
}
|
||||
|
||||
return Sections;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_ListEntry.h"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_ListEntryDetailSection.h"
|
||||
|
||||
|
||||
void UGUIS_ListEntryDetailSection::SetListItemObject(UObject* ListItemObject)
|
||||
{
|
||||
NativeOnListItemObjectSet(ListItemObject);
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailSection::NativeOnListItemObjectSet(UObject* ListItemObject)
|
||||
{
|
||||
OnListItemObjectSet(ListItemObject);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_ListEntryDetailView.h"
|
||||
#include "Components/VerticalBox.h"
|
||||
#include "Components/VerticalBoxSlot.h"
|
||||
#include "Engine/AssetManager.h"
|
||||
#include "Engine/StreamableManager.h"
|
||||
#include "UI/Common/GUIS_ListEntryDetailSection.h"
|
||||
#include "UI/Common/GUIS_DetailSectionsBuilder.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(GUIS_ListEntryDetailView)
|
||||
|
||||
#define LOCTEXT_NAMESPACE "EntryDetailsView"
|
||||
|
||||
UGUIS_ListEntryDetailView::UGUIS_ListEntryDetailView(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
, ExtensionWidgetPool(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::ReleaseSlateResources(bool bReleaseChildren)
|
||||
{
|
||||
Super::ReleaseSlateResources(bReleaseChildren);
|
||||
|
||||
ExtensionWidgetPool.ReleaseAllSlateResources();
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::NativeOnInitialized()
|
||||
{
|
||||
Super::NativeOnInitialized();
|
||||
|
||||
if (!IsDesignTime())
|
||||
{
|
||||
SetListItemObject(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::NativeConstruct()
|
||||
{
|
||||
Super::NativeConstruct();
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::SetListItemObject(UObject* InListItemObject)
|
||||
{
|
||||
// Ignore requests to show the same setting multiple times in a row.
|
||||
if (InListItemObject && InListItemObject == CurrentListItemObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentListItemObject = InListItemObject;
|
||||
|
||||
if (Box_DetailSections)
|
||||
{
|
||||
// First release the widgets back into the pool.
|
||||
for (UWidget* ChildExtension : Box_DetailSections->GetAllChildren())
|
||||
{
|
||||
ExtensionWidgetPool.Release(Cast<UUserWidget>(ChildExtension));
|
||||
}
|
||||
|
||||
// Remove the widgets from their container.
|
||||
Box_DetailSections->ClearChildren();
|
||||
|
||||
if (InListItemObject)
|
||||
{
|
||||
TArray<TSoftClassPtr<UGUIS_ListEntryDetailSection>> SectionClasses;
|
||||
if (SectionsBuilder)
|
||||
{
|
||||
SectionClasses = SectionsBuilder->GatherDetailSections(InListItemObject);
|
||||
}
|
||||
|
||||
if (StreamingHandle.IsValid())
|
||||
{
|
||||
StreamingHandle->CancelHandle();
|
||||
}
|
||||
|
||||
bool bEverythingAlreadyLoaded = true;
|
||||
|
||||
TArray<FSoftObjectPath> SectionPaths;
|
||||
SectionPaths.Reserve(SectionClasses.Num());
|
||||
for (TSoftClassPtr<UGUIS_ListEntryDetailSection> SoftClassPtr : SectionClasses)
|
||||
{
|
||||
bEverythingAlreadyLoaded &= SoftClassPtr.IsValid();
|
||||
SectionPaths.Add(SoftClassPtr.ToSoftObjectPath());
|
||||
}
|
||||
|
||||
if (bEverythingAlreadyLoaded)
|
||||
{
|
||||
for (TSoftClassPtr<UGUIS_ListEntryDetailSection> SoftClassPtr : SectionClasses)
|
||||
{
|
||||
CreateDetailsExtension(InListItemObject, SoftClassPtr.Get());
|
||||
}
|
||||
|
||||
ExtensionWidgetPool.ReleaseInactiveSlateResources();
|
||||
}
|
||||
else
|
||||
{
|
||||
TWeakObjectPtr<UObject> SettingPtr = InListItemObject;
|
||||
|
||||
StreamingHandle = UAssetManager::GetStreamableManager().RequestAsyncLoad(
|
||||
MoveTemp(SectionPaths),
|
||||
FStreamableDelegate::CreateWeakLambda(this, [this, SettingPtr, SectionClasses]
|
||||
{
|
||||
for (TSoftClassPtr<UGUIS_ListEntryDetailSection> SoftClassPtr : SectionClasses)
|
||||
{
|
||||
CreateDetailsExtension(SettingPtr.Get(), SoftClassPtr.Get());
|
||||
}
|
||||
|
||||
ExtensionWidgetPool.ReleaseInactiveSlateResources();
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::SetSectionsBuilder(UGUIS_DetailSectionsBuilder* NewBuilder)
|
||||
{
|
||||
SectionsBuilder = NewBuilder;
|
||||
}
|
||||
|
||||
void UGUIS_ListEntryDetailView::CreateDetailsExtension(UObject* InData, TSubclassOf<UGUIS_ListEntryDetailSection> SectionClass)
|
||||
{
|
||||
if (InData && SectionClass)
|
||||
{
|
||||
if (UGUIS_ListEntryDetailSection* Section = ExtensionWidgetPool.GetOrCreateInstance(SectionClass))
|
||||
{
|
||||
Section->SetListItemObject(InData);
|
||||
UVerticalBoxSlot* ExtensionSlot = Box_DetailSections->AddChildToVerticalBox(Section);
|
||||
ExtensionSlot->SetHorizontalAlignment(HAlign_Fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_ListView.h"
|
||||
|
||||
#include "UI/Common/GUIS_WidgetFactory.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
#include "Editor/WidgetCompilerLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
UGUIS_ListView::UGUIS_ListView(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
|
||||
{
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void UGUIS_ListView::ValidateCompiledDefaults(IWidgetCompilerLog& InCompileLog) const
|
||||
{
|
||||
Super::ValidateCompiledDefaults(InCompileLog);
|
||||
// if (EntryWidgetFactories.Num() == 0)
|
||||
// {
|
||||
// InCompileLog.Error(FText::Format(FText::FromString("{0} has no Entry widget Factories defined, can't create widgets without them."), FText::FromString(GetName())));
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
void UGUIS_ListView::SetEntryWidgetFactories(TArray<UGUIS_WidgetFactory*> NewFactories)
|
||||
{
|
||||
EntryWidgetFactories = NewFactories;
|
||||
}
|
||||
|
||||
UUserWidget& UGUIS_ListView::OnGenerateEntryWidgetInternal(UObject* Item, TSubclassOf<UUserWidget> DesiredEntryClass, const TSharedRef<STableViewBase>& OwnerTable)
|
||||
{
|
||||
TSubclassOf<UUserWidget> WidgetClass = DesiredEntryClass;
|
||||
|
||||
for (const UGUIS_WidgetFactory* Factory : EntryWidgetFactories)
|
||||
{
|
||||
if (Factory)
|
||||
{
|
||||
if (const TSubclassOf<UUserWidget> EntryClass = Factory->FindWidgetClassForData(Item))
|
||||
{
|
||||
WidgetClass = EntryClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Super::OnGenerateEntryWidgetInternal(Item, WidgetClass, OwnerTable);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_TileView.h"
|
||||
|
||||
#include "UI/Common/GUIS_WidgetFactory.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
#include "Editor/WidgetCompilerLog.h"
|
||||
#endif
|
||||
|
||||
|
||||
UGUIS_TileView::UGUIS_TileView(const FObjectInitializer& ObjectInitializer): Super(ObjectInitializer)
|
||||
{
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void UGUIS_TileView::ValidateCompiledDefaults(IWidgetCompilerLog& InCompileLog) const
|
||||
{
|
||||
Super::ValidateCompiledDefaults(InCompileLog);
|
||||
// if (EntryWidgetFactories.Num() == 0)
|
||||
// {
|
||||
// InCompileLog.Error(FText::Format(FText::FromString("{0} has no Entry widget Factories defined, can't create widgets without them."), FText::FromString(GetName())));
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
void UGUIS_TileView::SetEntryWidgetFactories(TArray<UGUIS_WidgetFactory*> NewFactories)
|
||||
{
|
||||
EntryWidgetFactories = NewFactories;
|
||||
}
|
||||
|
||||
UUserWidget& UGUIS_TileView::OnGenerateEntryWidgetInternal(UObject* Item, TSubclassOf<UUserWidget> DesiredEntryClass, const TSharedRef<STableViewBase>& OwnerTable)
|
||||
{
|
||||
TSubclassOf<UUserWidget> WidgetClass = DesiredEntryClass;
|
||||
|
||||
for (const UGUIS_WidgetFactory* Factory : EntryWidgetFactories)
|
||||
{
|
||||
if (Factory)
|
||||
{
|
||||
if (const TSubclassOf<UUserWidget> EntryClass = Factory->FindWidgetClassForData(Item))
|
||||
{
|
||||
WidgetClass = EntryClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Super::OnGenerateEntryWidgetInternal(Item, WidgetClass, OwnerTable);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_UserWidgetInterface.h"
|
||||
|
||||
|
||||
// Add default functionality here for any IGUIS_UserWidgetInterface functions that are not pure virtual.
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
||||
|
||||
|
||||
#include "UI/Common/GUIS_WidgetFactory.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Misc/DataValidation.h"
|
||||
|
||||
|
||||
TSubclassOf<UUserWidget> UGUIS_WidgetFactory::FindWidgetClassForData_Implementation(const UObject* Data) const
|
||||
{
|
||||
return TSubclassOf<UUserWidget>();
|
||||
}
|
||||
|
||||
UGUIS_WidgetFactory::UGUIS_WidgetFactory()
|
||||
{
|
||||
}
|
||||
|
||||
bool UGUIS_WidgetFactory::OnDataValidation_Implementation(FText& ValidationMessage) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
EDataValidationResult UGUIS_WidgetFactory::IsDataValid(FDataValidationContext& Context) const
|
||||
{
|
||||
FText ValidationMessage;
|
||||
if (!OnDataValidation(ValidationMessage))
|
||||
{
|
||||
Context.AddError(ValidationMessage);
|
||||
return EDataValidationResult::Invalid;
|
||||
}
|
||||
return Super::IsDataValid(Context);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user