RealtimeStyleTransferRuntime/Plugins/UIExtension/Source/Private/Widgets/UIExtensionPointWidget.cpp

174 lines
5.1 KiB
C++
Raw Normal View History

2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Widgets/UIExtensionPointWidget.h"
#include "Editor/WidgetCompilerLog.h"
#include "Misc/UObjectToken.h"
#include "UIExtensionSystem.h"
#include "CommonLocalPlayer.h"
#include "GameFramework/PlayerState.h"
#define LOCTEXT_NAMESPACE "UIExtension"
/////////////////////////////////////////////////////
// UUIExtensionPointWidget
UUIExtensionPointWidget::UUIExtensionPointWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UUIExtensionPointWidget::ReleaseSlateResources(bool bReleaseChildren)
{
ResetExtensionPoint();
Super::ReleaseSlateResources(bReleaseChildren);
}
TSharedRef<SWidget> UUIExtensionPointWidget::RebuildWidget()
{
if (!IsDesignTime() && ExtensionPointTag.IsValid())
{
ResetExtensionPoint();
RegisterExtensionPoint();
FDelegateHandle Handle = GetOwningLocalPlayer<UCommonLocalPlayer>()->CallAndRegister_OnPlayerStateSet(
UCommonLocalPlayer::FPlayerStateSetDelegate::FDelegate::CreateUObject(this, &UUIExtensionPointWidget::RegisterExtensionPointForPlayerState)
);
}
if (IsDesignTime())
{
auto GetExtensionPointText = [this]()
{
return FText::Format(LOCTEXT("DesignTime_ExtensionPointLabel", "Extension Point\n{0}"), FText::FromName(ExtensionPointTag.GetTagName()));
};
TSharedRef<SOverlay> MessageBox = SNew(SOverlay);
MessageBox->AddSlot()
.Padding(5.0f)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Justification(ETextJustify::Center)
.Text_Lambda(GetExtensionPointText)
];
return MessageBox;
}
else
{
return Super::RebuildWidget();
}
}
void UUIExtensionPointWidget::ResetExtensionPoint()
{
ResetInternal();
ExtensionMapping.Reset();
for (FUIExtensionPointHandle& Handle : ExtensionPointHandles)
{
Handle.Unregister();
}
ExtensionPointHandles.Reset();
}
void UUIExtensionPointWidget::RegisterExtensionPoint()
{
if (UUIExtensionSubsystem* ExtensionSubsystem = GetWorld()->GetSubsystem<UUIExtensionSubsystem>())
{
TArray<UClass*> AllowedDataClasses;
AllowedDataClasses.Add(UUserWidget::StaticClass());
AllowedDataClasses.Append(DataClasses);
ExtensionPointHandles.Add(ExtensionSubsystem->RegisterExtensionPoint(
ExtensionPointTag, ExtensionPointTagMatch, AllowedDataClasses,
FExtendExtensionPointDelegate::CreateUObject(this, &ThisClass::OnAddOrRemoveExtension)
));
ExtensionPointHandles.Add(ExtensionSubsystem->RegisterExtensionPointForContext(
ExtensionPointTag, GetOwningLocalPlayer(), ExtensionPointTagMatch, AllowedDataClasses,
FExtendExtensionPointDelegate::CreateUObject(this, &ThisClass::OnAddOrRemoveExtension)
));
}
}
void UUIExtensionPointWidget::RegisterExtensionPointForPlayerState(UCommonLocalPlayer* LocalPlayer, APlayerState* PlayerState)
{
if (UUIExtensionSubsystem* ExtensionSubsystem = GetWorld()->GetSubsystem<UUIExtensionSubsystem>())
{
TArray<UClass*> AllowedDataClasses;
AllowedDataClasses.Add(UUserWidget::StaticClass());
AllowedDataClasses.Append(DataClasses);
ExtensionPointHandles.Add(ExtensionSubsystem->RegisterExtensionPointForContext(
ExtensionPointTag, PlayerState, ExtensionPointTagMatch, AllowedDataClasses,
FExtendExtensionPointDelegate::CreateUObject(this, &ThisClass::OnAddOrRemoveExtension)
));
}
}
void UUIExtensionPointWidget::OnAddOrRemoveExtension(EUIExtensionAction Action, const FUIExtensionRequest& Request)
{
if (Action == EUIExtensionAction::Added)
{
UObject* Data = Request.Data;
TSubclassOf<UUserWidget> WidgetClass(Cast<UClass>(Data));
if (WidgetClass)
{
UUserWidget* Widget = CreateEntryInternal(WidgetClass);
ExtensionMapping.Add(Request.ExtensionHandle, Widget);
}
else if (DataClasses.Num() > 0)
{
if (GetWidgetClassForData.IsBound())
{
WidgetClass = GetWidgetClassForData.Execute(Data);
// If the data is irrelevant they can just return no widget class.
if (WidgetClass)
{
if (UUserWidget* Widget = CreateEntryInternal(WidgetClass))
{
ExtensionMapping.Add(Request.ExtensionHandle, Widget);
ConfigureWidgetForData.ExecuteIfBound(Widget, Data);
}
}
}
}
}
else
{
if (UUserWidget* Extension = ExtensionMapping.FindRef(Request.ExtensionHandle))
{
RemoveEntryInternal(Extension);
ExtensionMapping.Remove(Request.ExtensionHandle);
}
}
}
#if WITH_EDITOR
void UUIExtensionPointWidget::ValidateCompiledDefaults(IWidgetCompilerLog& CompileLog) const
{
Super::ValidateCompiledDefaults(CompileLog);
// We don't care if the CDO doesn't have a specific tag.
if (!HasAnyFlags(RF_ClassDefaultObject))
{
if (!ExtensionPointTag.IsValid())
{
TSharedRef<FTokenizedMessage> Message = CompileLog.Error(FText::Format(LOCTEXT("UUIExtensionPointWidget_NoTag", "{0} has no ExtensionPointTag specified - All extension points must specify a tag so they can be located."), FText::FromString(GetName())));
Message->AddToken(FUObjectToken::Create(this));
}
}
}
#endif
/////////////////////////////////////////////////////
#undef LOCTEXT_NAMESPACE