refactor(ui/panel): TMap<EUIPanelTexture> -> TMap<FName> com PostSerialize migration
FUIStylePanel migra de TMap<EUIPanelTexture, FSlateBrush> (enum legacy) para TMap<FName, FSlateBrush>. Permite adicionar/remover categorias diretamente no DT_UI_Styles via dropdown (meta=GetOptions) sem mexer no enum em C++. PanelBackground, PanelOutline e PanelOutlineEffect viraram *_DEPRECATED. Versoes novas: PanelBackgroundByName, PanelOutlineByName, PanelOutlineEffectByName. PostSerialize migra os legacy -> ByName no PostLoad de cada FUIStyleRow. Apos o primeiro re-save no editor os deprecated ficam vazios e o codigo vira no-op. PropertyRedirects em DefaultEngine.ini preservam a leitura do asset antigo (3 entries: PanelBackground, PanelOutline, PanelOutlineEffect). Atualiza UIPanel_Base pra ler ByName + DT_UI_Styles, UI_Panel_Master e UI_PlayerStatus_Window resalvos. Inclui nova textura T_Panel_Outline_Effect_Square_02. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,15 @@ GameViewportClientClassName=/Script/CommonUI.CommonGameViewportClient
|
||||
+ActiveClassRedirects=(OldClassName="TP_ThirdPersonCharacter",NewClassName="ZMMOPlayerCharacter")
|
||||
+ActiveClassRedirects=(OldClassName="ZMMOCharacter",NewClassName="ZMMOPlayerCharacter")
|
||||
|
||||
[CoreRedirects]
|
||||
; Migração v1→v2 do FUIStylePanel: TMap<EUIPanelTexture,...> (Enum) → TMap<FName,...>.
|
||||
; Os campos *_DEPRECATED preservam a leitura do asset antigo; PostSerialize copia
|
||||
; pros novos ByName e após re-save os legacy ficam vazios. Os redirects podem
|
||||
; ser removidos quando todos os DTs do projeto tiverem sido re-salvos.
|
||||
+PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelBackground",NewName="/Script/ZMMO.UIStylePanel.PanelBackground_DEPRECATED")
|
||||
+PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutline",NewName="/Script/ZMMO.UIStylePanel.PanelOutline_DEPRECATED")
|
||||
+PropertyRedirects=(OldName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect",NewName="/Script/ZMMO.UIStylePanel.PanelOutlineEffect_DEPRECATED")
|
||||
|
||||
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
|
||||
bEnablePlugin=True
|
||||
bAllowNetworkConnection=True
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
48
Source/ZMMO/Data/UI/UIStyleTokens.cpp
Normal file
48
Source/ZMMO/Data/UI/UIStyleTokens.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "UIStyleTokens.h"
|
||||
|
||||
#include "UObject/Class.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
|
||||
void FUIStylePanel::PostSerialize(const FArchive& Ar)
|
||||
{
|
||||
// Migração v1→v2: TMap<EUIPanelTexture, ...> (legacy) → TMap<FName, ...> (atual).
|
||||
// Roda no PostLoad de cada FUIStyleRow; depois do primeiro re-save no editor
|
||||
// os campos *_DEPRECATED ficam vazios e este código vira no-op.
|
||||
if (!Ar.IsLoading())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UEnum* EnumPtr = StaticEnum<EUIPanelTexture>();
|
||||
if (EnumPtr == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto MigrateOne = [EnumPtr](
|
||||
TMap<EUIPanelTexture, FSlateBrush>& Legacy,
|
||||
TMap<FName, FSlateBrush>& ByName)
|
||||
{
|
||||
if (Legacy.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (const TPair<EUIPanelTexture, FSlateBrush>& Pair : Legacy)
|
||||
{
|
||||
if (Pair.Key == EUIPanelTexture::None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const FName KeyName(*EnumPtr->GetAuthoredNameStringByValue(static_cast<int64>(Pair.Key)));
|
||||
if (!ByName.Contains(KeyName))
|
||||
{
|
||||
ByName.Add(KeyName, Pair.Value);
|
||||
}
|
||||
}
|
||||
Legacy.Reset();
|
||||
};
|
||||
|
||||
MigrateOne(PanelBackground_DEPRECATED, PanelBackgroundByName);
|
||||
MigrateOne(PanelOutline_DEPRECATED, PanelOutlineByName);
|
||||
MigrateOne(PanelOutlineEffect_DEPRECATED, PanelOutlineEffectByName);
|
||||
}
|
||||
@@ -290,23 +290,58 @@ struct ZMMO_API FUIPanelBrushSet
|
||||
};
|
||||
|
||||
/**
|
||||
* Espelha 1:1 o Struct_UI_Style_Panels do Hyper, agora com 3 brushes por
|
||||
* EUIPanelTexture: fundo, contorno e efeito sobre o contorno. Tudo
|
||||
* data-driven via brush no DT_UI_Styles.
|
||||
* Espelha 1:1 o Struct_UI_Style_Panels do Hyper. 3 brushes por categoria
|
||||
* (FName livre): fundo, contorno e efeito sobre o contorno. Categorias são
|
||||
* editadas direto no DT_UI_Styles — UUIPanel_Base resolve via dropdown
|
||||
* dinâmico (meta=GetOptions).
|
||||
*
|
||||
* Migração: assets v1 tinham TMap<EUIPanelTexture, ...>; os campos
|
||||
* *_DEPRECATED preservam essas keys via PropertyRedirect no DefaultEngine.ini.
|
||||
* PostSerialize copia legacy→ByName no PostLoad — após re-save no editor,
|
||||
* o legacy fica vazio e o asset só carrega o ByName.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStylePanel
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelBackground;
|
||||
// ---- Novo (FName livre) -------------------------------------------
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutline;
|
||||
TMap<FName, FSlateBrush> PanelBackgroundByName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutlineEffect;
|
||||
TMap<FName, FSlateBrush> PanelOutlineByName;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||
TMap<FName, FSlateBrush> PanelOutlineEffectByName;
|
||||
|
||||
// ---- Legacy (carrega assets antigos via CoreRedirect) -------------
|
||||
//
|
||||
// Não aparecem no Details (DeprecatedProperty); persistem só pra leitura
|
||||
// do asset pré-migração. PostSerialize copia o conteúdo pros campos
|
||||
// ByName e zera os legacy.
|
||||
|
||||
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use PanelBackgroundByName (FName)."))
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelBackground_DEPRECATED;
|
||||
|
||||
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use PanelOutlineByName (FName)."))
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutline_DEPRECATED;
|
||||
|
||||
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use PanelOutlineEffectByName (FName)."))
|
||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutlineEffect_DEPRECATED;
|
||||
|
||||
/** Chamado automaticamente após Serialize. Migra dados legacy→ByName. */
|
||||
void PostSerialize(const FArchive& Ar);
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TStructOpsTypeTraits<FUIStylePanel> : public TStructOpsTypeTraitsBase2<FUIStylePanel>
|
||||
{
|
||||
enum
|
||||
{
|
||||
WithPostSerialize = true,
|
||||
};
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
|
||||
@@ -62,21 +62,21 @@ void UUIPanel_Base::RefreshUIStyle()
|
||||
return B;
|
||||
}();
|
||||
|
||||
auto ResolveFromTheme = [](EUIPanelTexture Key,
|
||||
const TMap<EUIPanelTexture, FSlateBrush>& Map) -> const FSlateBrush*
|
||||
auto ResolveFromTheme = [](FName Key,
|
||||
const TMap<FName, FSlateBrush>& Map) -> const FSlateBrush*
|
||||
{
|
||||
return (Key == EUIPanelTexture::None) ? nullptr : Map.Find(Key);
|
||||
return Key.IsNone() ? nullptr : Map.Find(Key);
|
||||
};
|
||||
|
||||
const FSlateBrush* BgTex = bUseTheme
|
||||
? ResolveFromTheme(BackgroundKey, P.PanelBackground)
|
||||
? ResolveFromTheme(BackgroundKey, P.PanelBackgroundByName)
|
||||
: &Panels.PanelBackground;
|
||||
Background->SetBrush(BgTex ? *BgTex : NoDrawBrush);
|
||||
|
||||
if (Outline)
|
||||
{
|
||||
const FSlateBrush* OlTex = bUseTheme
|
||||
? ResolveFromTheme(OutlineKey, P.PanelOutline)
|
||||
? ResolveFromTheme(OutlineKey, P.PanelOutlineByName)
|
||||
: &Panels.PanelOutline;
|
||||
Outline->SetBrush(OlTex ? *OlTex : NoDrawBrush);
|
||||
}
|
||||
@@ -84,7 +84,7 @@ void UUIPanel_Base::RefreshUIStyle()
|
||||
if (OutlineEffect)
|
||||
{
|
||||
const FSlateBrush* OeTex = bUseTheme
|
||||
? ResolveFromTheme(OutlineEffectKey, P.PanelOutlineEffect)
|
||||
? ResolveFromTheme(OutlineEffectKey, P.PanelOutlineEffectByName)
|
||||
: &Panels.PanelOutlineEffect;
|
||||
OutlineEffect->SetBrush(OeTex ? *OeTex : NoDrawBrush);
|
||||
}
|
||||
@@ -136,3 +136,59 @@ void UUIPanel_Base::HandleThemeChanged(FName /*NewThemeId*/)
|
||||
{
|
||||
RefreshUIStyle();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
enum class EPanelBrushSlot : uint8 { Background, Outline, OutlineEffect };
|
||||
|
||||
TArray<FString> CollectPanelOptions(EPanelBrushSlot Slot)
|
||||
{
|
||||
TArray<FString> Options;
|
||||
Options.Add(FString()); // entry vazia = "sem brush" (NoDrawType)
|
||||
|
||||
const UDataTable* DT = LoadObject<UDataTable>(nullptr,
|
||||
TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles"));
|
||||
if (!DT)
|
||||
{
|
||||
return Options;
|
||||
}
|
||||
const FUIStyleRow* Row = DT->FindRow<FUIStyleRow>(
|
||||
FName(TEXT("Default")), TEXT("UIPanelGetOptions"), false);
|
||||
if (!Row)
|
||||
{
|
||||
return Options;
|
||||
}
|
||||
|
||||
const TMap<FName, FSlateBrush>* Map = nullptr;
|
||||
switch (Slot)
|
||||
{
|
||||
case EPanelBrushSlot::Background: Map = &Row->Style.Panel.PanelBackgroundByName; break;
|
||||
case EPanelBrushSlot::Outline: Map = &Row->Style.Panel.PanelOutlineByName; break;
|
||||
case EPanelBrushSlot::OutlineEffect: Map = &Row->Style.Panel.PanelOutlineEffectByName; break;
|
||||
}
|
||||
if (Map)
|
||||
{
|
||||
for (const TPair<FName, FSlateBrush>& Pair : *Map)
|
||||
{
|
||||
Options.Add(Pair.Key.ToString());
|
||||
}
|
||||
Options.Sort();
|
||||
}
|
||||
return Options;
|
||||
}
|
||||
}
|
||||
|
||||
TArray<FString> UUIPanel_Base::GetPanelBackgroundOptions() const
|
||||
{
|
||||
return CollectPanelOptions(EPanelBrushSlot::Background);
|
||||
}
|
||||
|
||||
TArray<FString> UUIPanel_Base::GetPanelOutlineOptions() const
|
||||
{
|
||||
return CollectPanelOptions(EPanelBrushSlot::Outline);
|
||||
}
|
||||
|
||||
TArray<FString> UUIPanel_Base::GetPanelOutlineEffectOptions() const
|
||||
{
|
||||
return CollectPanelOptions(EPanelBrushSlot::OutlineEffect);
|
||||
}
|
||||
|
||||
@@ -30,19 +30,26 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
||||
bool bUseTheme = true;
|
||||
|
||||
// ---- Modo TEMA: escolhe a chave do mapa FUIStylePanel pra cada Border. ----
|
||||
// ---- Modo TEMA: chave FName do TMap FUIStylePanel pra cada Border. ----
|
||||
//
|
||||
// GetOptions popula dropdown lendo DT_UI_Styles row "Default" — adicione
|
||||
// uma entry em FUIStylePanel.PanelBackgroundByName no DT e a categoria
|
||||
// aparece aqui sem recompilar C++. Vazio = sem brush (NoDrawType).
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||
EUIPanelTexture BackgroundKey = EUIPanelTexture::None;
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides,
|
||||
GetOptions = "GetPanelBackgroundOptions"))
|
||||
FName BackgroundKey;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||
EUIPanelTexture OutlineKey = EUIPanelTexture::None;
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides,
|
||||
GetOptions = "GetPanelOutlineOptions"))
|
||||
FName OutlineKey;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||
EUIPanelTexture OutlineEffectKey = EUIPanelTexture::None;
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides,
|
||||
GetOptions = "GetPanelOutlineEffectOptions"))
|
||||
FName OutlineEffectKey;
|
||||
|
||||
// ---- Modo MANUAL: 3 brushes editáveis direto no Details. ----
|
||||
|
||||
@@ -54,6 +61,22 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "UI Style")
|
||||
void RefreshUIStyle();
|
||||
|
||||
/**
|
||||
* Populadores do dropdown (meta=GetOptions) das chaves de textura.
|
||||
* Lêem DT_UI_Styles row "Default" e retornam as FName de cada sub-mapa
|
||||
* do FUIStylePanel. Editar o DT no editor reflete aqui sem recompilar.
|
||||
* São métodos de instância porque o UE precisa de UFUNCTION reflexável;
|
||||
* o conteúdo não usa estado da instância (poderia ser estático).
|
||||
*/
|
||||
UFUNCTION()
|
||||
TArray<FString> GetPanelBackgroundOptions() const;
|
||||
|
||||
UFUNCTION()
|
||||
TArray<FString> GetPanelOutlineOptions() const;
|
||||
|
||||
UFUNCTION()
|
||||
TArray<FString> GetPanelOutlineEffectOptions() const;
|
||||
|
||||
protected:
|
||||
virtual void NativePreConstruct() override;
|
||||
virtual void NativeConstruct() override;
|
||||
|
||||
Reference in New Issue
Block a user