refactor(ui/base): panel data-driven 3-brush + button via FButtonStyle
UIPanel_Base: substitui PanelType/Padding por bUseTheme + 3 chaves (Background/Outline/OutlineEffectKey) lidas de FUIStylePanel. Modo manual (bUseTheme=false) expoe 3 FSlateBrush diretos via FUIPanelBrushSet pra override por instancia. Adiciona BindWidgetOptional OutlineEffect (3o Border sobre Outline pra glow/embossing). Defaults NoDrawType (regra Hyper: brush vazio nao pinta branco). UIButton_Base: remove auto-config (Variants enum, Number/Icon/Size/ InputAction/Timer). Vira shell minimal com BindWidgetOptional + helpers GetActiveUIStyle/GetActiveButtonStyle pra leitura de DT_UI_Styles. UIStyleTokens: FUIStylePanel ganha PanelOutlineEffect map. FUIPanelBrushSet vira 3 FSlateBrush diretos. FUIStyleButton refatora pra 7 sub-maps por variante FName (ButtonStyle=FButtonStyle do Slate, ButtonStroke, ButtonFont, Text/Icon colors). Tudo com defaults NoDrawType. UIStyleTypes: adiciona enum EUIPanelTexture::Rectangle_Square_Gradient_01. Content: UI_Panel_Master e UI_Button_Master_New consomem a API nova; DT_UI_Styles atualizado com rows/keys novas. UIServerCard_Base ajustado pro consumer da API nova. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
BIN
Content/ZMMO/UI/Shared/UI_Button_Master_New.uasset
Normal file
BIN
Content/ZMMO/UI/Shared/UI_Button_Master_New.uasset
Normal file
Binary file not shown.
Binary file not shown.
@@ -3,6 +3,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Fonts/SlateFontInfo.h"
|
#include "Fonts/SlateFontInfo.h"
|
||||||
#include "Styling/SlateBrush.h"
|
#include "Styling/SlateBrush.h"
|
||||||
|
#include "Styling/SlateTypes.h"
|
||||||
#include "Layout/Margin.h"
|
#include "Layout/Margin.h"
|
||||||
#include "Templates/SubclassOf.h"
|
#include "Templates/SubclassOf.h"
|
||||||
#include "Engine/Texture2D.h"
|
#include "Engine/Texture2D.h"
|
||||||
@@ -195,117 +196,13 @@ struct ZMMO_API FUITextStyle
|
|||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
// FUIStyleButton — padrão multi-map (Hyper-style). 3 sub-mapas com a MESMA
|
// FUIStyleButton — padrão Hyper "Buttons": 7 sub-mapas independentes
|
||||||
// chave (nome da variante: "Primary", "Secondary", "Danger", "Ghost", ou
|
// indexados pela MESMA chave FName de variante (autor define livremente:
|
||||||
// customizada). UUIButton_Base.Variant é FName e busca em cada sub-mapa.
|
// "Default", "Square", "Topbar", "Home_Main_Menu", ...). UUIButton_Base.Variant
|
||||||
// O struct FUIStyleButtonVariant (composto, FLAT) permanece com a forma
|
// é FName e busca o pedaço necessário em cada sub-mapa. ButtonStyle traz
|
||||||
// antiga — assim o hook BP_ApplyUIStyle dos WBP_Master continua funcional.
|
// FButtonStyle do Slate completo (Normal/Hovered/Pressed/Disabled como
|
||||||
|
// FSlateBrush, Foregrounds, Padding, Sounds).
|
||||||
// =====================================================================
|
// =====================================================================
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct ZMMO_API FUIStyleButtonBackground
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgNormal = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgHover = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgPressed = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgDisabled = FLinearColor(0.f, 0.f, 0.f, 0.42f);
|
|
||||||
|
|
||||||
/** Textura opcional como background (Hyper-style). */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
TObjectPtr<UTexture2D> BackgroundTexture = nullptr;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FMargin BackgroundMargin = FMargin(8.f);
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct ZMMO_API FUIStyleButtonStroke
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BorderNormal = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BorderHover = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button", meta = (ClampMin = "0"))
|
|
||||||
float BorderWidth = 1.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button", meta = (ClampMin = "0"))
|
|
||||||
float CornerRadius = 8.f;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct ZMMO_API FUIStyleButtonFont
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor TextColor = FLinearColor::White;
|
|
||||||
|
|
||||||
/** CommonTextStyle define fonte/tamanho/peso; TextColor sobrescreve a cor. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
TSubclassOf<UCommonTextStyle> TextStyle;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View FLAT composta da variante de botão (Background + Stroke + Font).
|
|
||||||
* Mantida com a forma antiga (BgNormal/BgHover/.../TextStyle no topo) para
|
|
||||||
* NÃO QUEBRAR o hook BP_ApplyUIStyle nos WBP_Master existentes. É construída
|
|
||||||
* pelo UUIButton_Base::ResolveVariant a partir dos 3 sub-mapas do tema.
|
|
||||||
*/
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct ZMMO_API FUIStyleButtonVariant
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgNormal = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgHover = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgPressed = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BgDisabled = FLinearColor(0.f, 0.f, 0.f, 0.42f);
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BorderNormal = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor BorderHover = FLinearColor::Transparent;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FLinearColor TextColor = FLinearColor::White;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
TSubclassOf<UCommonTextStyle> TextStyle;
|
|
||||||
|
|
||||||
// Campos extras vindos das sub-categorias (background texture + stroke):
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
TObjectPtr<UTexture2D> BackgroundTexture = nullptr;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FMargin BackgroundMargin = FMargin(8.f);
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
float BorderWidth = 1.f;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
float CornerRadius = 8.f;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct ZMMO_API FUIStyleButton
|
struct ZMMO_API FUIStyleButton
|
||||||
{
|
{
|
||||||
@@ -313,163 +210,103 @@ struct ZMMO_API FUIStyleButton
|
|||||||
|
|
||||||
FUIStyleButton()
|
FUIStyleButton()
|
||||||
{
|
{
|
||||||
// ---- Backgrounds (Primary/Secondary/Danger/Ghost) ----
|
// Defaults "no draw" pra não pintar branco quando o brush estiver vazio
|
||||||
FUIStyleButtonBackground PriBg;
|
// (regra Hyper — ver feedback_slatebrush_empty_white). Autor preenche
|
||||||
PriBg.BgNormal = FLinearColor(FColor(201, 167, 90)); // gold
|
// no DT_UI_Styles.
|
||||||
PriBg.BgHover = FLinearColor(FColor(231, 200, 115)); // gold-hi
|
FButtonStyle DefaultStyle;
|
||||||
PriBg.BgPressed = FLinearColor(FColor(201, 167, 90));
|
DefaultStyle.Normal.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
PriBg.BgDisabled = FLinearColor(FColor(201, 167, 90, 107));
|
DefaultStyle.Hovered.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
Backgrounds.Add(TEXT("Primary"), PriBg);
|
DefaultStyle.Pressed.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
DefaultStyle.Disabled.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
ButtonStyle.Add(TEXT("Default"), DefaultStyle);
|
||||||
|
|
||||||
FUIStyleButtonBackground SecBg;
|
FSlateBrush DefaultStroke;
|
||||||
SecBg.BgNormal = FLinearColor(FColor(17, 24, 42)); // panel-2
|
DefaultStroke.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
SecBg.BgHover = FLinearColor(FColor(22, 32, 58));
|
ButtonStroke.Add(TEXT("Default"), DefaultStroke);
|
||||||
SecBg.BgPressed = FLinearColor(FColor(17, 24, 42));
|
|
||||||
Backgrounds.Add(TEXT("Secondary"), SecBg);
|
|
||||||
|
|
||||||
FUIStyleButtonBackground DngBg;
|
ButtonFont.Add(TEXT("Default"), FSlateFontInfo());
|
||||||
DngBg.BgNormal = FLinearColor(FColor(217, 92, 92, 36));
|
|
||||||
DngBg.BgHover = FLinearColor(FColor(217, 92, 92, 66));
|
|
||||||
DngBg.BgPressed = FLinearColor(FColor(217, 92, 92, 36));
|
|
||||||
Backgrounds.Add(TEXT("Danger"), DngBg);
|
|
||||||
|
|
||||||
FUIStyleButtonBackground GhoBg;
|
ButtonTextColorRegular.Add(TEXT("Default"), FLinearColor::White);
|
||||||
GhoBg.BgNormal = FLinearColor::Transparent;
|
ButtonTextColorHovered.Add(TEXT("Default"), FLinearColor::White);
|
||||||
GhoBg.BgHover = FLinearColor(FColor(22, 32, 58, 128));
|
ButtonTextColorSelected.Add(TEXT("Default"), FLinearColor::White);
|
||||||
GhoBg.BgPressed = FLinearColor::Transparent;
|
|
||||||
Backgrounds.Add(TEXT("Ghost"), GhoBg);
|
|
||||||
|
|
||||||
// ---- Strokes ----
|
ButtonIconColor.Add(TEXT("Default"), FLinearColor::White);
|
||||||
FUIStyleButtonStroke PriS;
|
|
||||||
PriS.BorderNormal = FLinearColor(FColor(201, 167, 90));
|
|
||||||
PriS.BorderHover = FLinearColor(FColor(231, 200, 115));
|
|
||||||
Strokes.Add(TEXT("Primary"), PriS);
|
|
||||||
|
|
||||||
FUIStyleButtonStroke SecS;
|
|
||||||
SecS.BorderNormal = FLinearColor(FColor(58, 75, 120));
|
|
||||||
SecS.BorderHover = FLinearColor(FColor(78, 163, 255));
|
|
||||||
Strokes.Add(TEXT("Secondary"), SecS);
|
|
||||||
|
|
||||||
FUIStyleButtonStroke DngS;
|
|
||||||
DngS.BorderNormal = FLinearColor(FColor(217, 92, 92));
|
|
||||||
DngS.BorderHover = FLinearColor(FColor(217, 92, 92));
|
|
||||||
Strokes.Add(TEXT("Danger"), DngS);
|
|
||||||
|
|
||||||
FUIStyleButtonStroke GhoS;
|
|
||||||
GhoS.BorderNormal = FLinearColor(FColor(58, 75, 120, 140));
|
|
||||||
GhoS.BorderHover = FLinearColor(FColor(78, 163, 255));
|
|
||||||
Strokes.Add(TEXT("Ghost"), GhoS);
|
|
||||||
|
|
||||||
// ---- Fonts ----
|
|
||||||
FUIStyleButtonFont PriF; PriF.TextColor = FLinearColor(FColor(10, 10, 18));
|
|
||||||
Fonts.Add(TEXT("Primary"), PriF);
|
|
||||||
FUIStyleButtonFont SecF; SecF.TextColor = FLinearColor(FColor(244, 240, 230));
|
|
||||||
Fonts.Add(TEXT("Secondary"), SecF);
|
|
||||||
FUIStyleButtonFont DngF; DngF.TextColor = FLinearColor(FColor(240, 182, 182));
|
|
||||||
Fonts.Add(TEXT("Danger"), DngF);
|
|
||||||
FUIStyleButtonFont GhoF; GhoF.TextColor = FLinearColor(FColor(174, 182, 200));
|
|
||||||
Fonts.Add(TEXT("Ghost"), GhoF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cores/textura de fundo por variante (chave FName). */
|
/** FButtonStyle do Slate por variante: Normal/Hovered/Pressed/Disabled
|
||||||
|
* como FSlateBrush completo + Foregrounds + Padding + Sounds. */
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
TMap<FName, FUIStyleButtonBackground> Backgrounds;
|
TMap<FName, FButtonStyle> ButtonStyle;
|
||||||
|
|
||||||
/** Borda (cor, espessura, raio) por variante. */
|
/** Stroke/contorno como brush independente (texturizável). Hoje o
|
||||||
|
* UUIButton_Base não consome este campo automaticamente — quem precisa
|
||||||
|
* de stroke decora o FSlateBrush dentro de ButtonStyle.Normal via
|
||||||
|
* OutlineSettings. Reservado pra evolução com 2 Borders empilhados. */
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
TMap<FName, FUIStyleButtonStroke> Strokes;
|
TMap<FName, FSlateBrush> ButtonStroke;
|
||||||
|
|
||||||
/** Tipografia (cor de texto, CommonTextStyle) por variante. */
|
/** Fonte do texto por variante. */
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
TMap<FName, FUIStyleButtonFont> Fonts;
|
TMap<FName, FSlateFontInfo> ButtonFont;
|
||||||
|
|
||||||
// Globais comuns às variantes:
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
|
||||||
FMargin Padding = FMargin(22.f, 12.f);
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
float MinHeight = 48.f;
|
TMap<FName, FLinearColor> ButtonTextColorRegular;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
float HoverScale = 1.02f;
|
TMap<FName, FLinearColor> ButtonTextColorHovered;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
float PressedScale = 0.98f;
|
TMap<FName, FLinearColor> ButtonTextColorSelected;
|
||||||
|
|
||||||
/** Tamanho por silhueta (Square/Rectangle/Topbar/Header). */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Button")
|
||||||
TMap<EUIButtonShape, FVector2D> ShapeSizes;
|
TMap<FName, FLinearColor> ButtonIconColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Espelha 1:1 o Struct_UI_Style_Panels do Hyper: só os dois mapas de brush
|
* Override manual por instância (modo bUseTheme = false). 3 brushes diretos
|
||||||
* (fundo + contorno) indexados por EUIPanelTexture. É o que o UI_Panel_Master
|
* pros 3 Borders do painel — designer edita o brush bruto no Details.
|
||||||
* do Hyper expõe editável na instância (Details). EditAnywhere/ReadWrite para
|
* Default = NoDrawType pra não pintar branco quando vazio (regra Hyper).
|
||||||
* o designer ajustar brush por widget; o tema (DT) só faz seed/fallback.
|
|
||||||
*/
|
*/
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct ZMMO_API FUIPanelBrushSet
|
struct ZMMO_API FUIPanelBrushSet
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel|Texture")
|
FUIPanelBrushSet()
|
||||||
TMap<EUIPanelTexture, FSlateBrush> PanelBackground;
|
{
|
||||||
|
PanelBackground.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
PanelOutline.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
PanelOutlineEffect.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
}
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel|Texture")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel|Brush")
|
||||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutline;
|
FSlateBrush PanelBackground;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel|Brush")
|
||||||
|
FSlateBrush PanelOutline;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel|Brush")
|
||||||
|
FSlateBrush PanelOutlineEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct ZMMO_API FUIStylePanel
|
struct ZMMO_API FUIStylePanel
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor Bg = FLinearColor(FColor(12, 18, 34, 235)); // Panel
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor BgRaised = FLinearColor(FColor(17, 24, 42)); // Panel2
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor BgSunken = FLinearColor(FColor(14, 20, 36)); // Panel3
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor BorderColor = FLinearColor(FColor(58, 75, 120));
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor BorderSoftColor = FLinearColor(FColor(58, 75, 120, 140));
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
float CornerRadius = 12.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
float CornerRadiusSmall = 10.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
float BorderWidth = 1.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FMargin Padding = FMargin(30.f);
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FMargin PaddingSmall = FMargin(20.f);
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor CardSelectedBorder = FLinearColor(FColor(201, 167, 90)); // Accent
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel")
|
|
||||||
FLinearColor CardSelectedBg = FLinearColor(FColor(24, 32, 58));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modo texturizado (espelha Struct_UI_Style_Panels do Hyper): brush por
|
|
||||||
* EUIPanelTexture. PanelBackground = fundo; PanelOutline = contorno.
|
|
||||||
* Se vazio p/ a chave, o painel usa o modo cor (RoundedBox) acima.
|
|
||||||
*/
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||||
TMap<EUIPanelTexture, FSlateBrush> PanelBackground;
|
TMap<EUIPanelTexture, FSlateBrush> PanelBackground;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||||
TMap<EUIPanelTexture, FSlateBrush> PanelOutline;
|
TMap<EUIPanelTexture, FSlateBrush> PanelOutline;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|Panel|Texture")
|
||||||
|
TMap<EUIPanelTexture, FSlateBrush> PanelOutlineEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ enum class EUIPanelTexture : uint8
|
|||||||
Rectangle_Vertical_03 UMETA(DisplayName = "Rectangle Vertical 03"),
|
Rectangle_Vertical_03 UMETA(DisplayName = "Rectangle Vertical 03"),
|
||||||
Rectangle_Vertical_04 UMETA(DisplayName = "Rectangle Vertical 04"),
|
Rectangle_Vertical_04 UMETA(DisplayName = "Rectangle Vertical 04"),
|
||||||
Rectangle_Square_01 UMETA(DisplayName = "Rectangle Square 01"),
|
Rectangle_Square_01 UMETA(DisplayName = "Rectangle Square 01"),
|
||||||
|
Rectangle_Square_Gradient_01 UMETA(DisplayName = "Rectangle Square Gradient 01"),
|
||||||
Vertical_Footer_01 UMETA(DisplayName = "Vertical Footer 01")
|
Vertical_Footer_01 UMETA(DisplayName = "Vertical Footer 01")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,11 @@
|
|||||||
void UUIServerCard_Base::NativePreConstruct()
|
void UUIServerCard_Base::NativePreConstruct()
|
||||||
{
|
{
|
||||||
Super::NativePreConstruct();
|
Super::NativePreConstruct();
|
||||||
// Reaplica tema do botao antes de qualquer SetIsEnabled — garante que o
|
// TODO(ui-system): reativar quando UUIButton_Base voltar a ter RefreshUIStyle.
|
||||||
// background da variante "Primary" pinta tanto em Normal quanto Disabled.
|
// if (Btn_Enter)
|
||||||
if (Btn_Enter)
|
// {
|
||||||
{
|
// Btn_Enter->RefreshUIStyle();
|
||||||
Btn_Enter->RefreshUIStyle();
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UUIServerCard_Base::NativeConstruct()
|
void UUIServerCard_Base::NativeConstruct()
|
||||||
@@ -25,10 +24,11 @@ void UUIServerCard_Base::NativeConstruct()
|
|||||||
Btn_Enter->OnClicked().AddUObject(this, &UUIServerCard_Base::HandleEnterClicked);
|
Btn_Enter->OnClicked().AddUObject(this, &UUIServerCard_Base::HandleEnterClicked);
|
||||||
bBound = true;
|
bBound = true;
|
||||||
}
|
}
|
||||||
if (Btn_Enter)
|
// TODO(ui-system): reativar quando UUIButton_Base voltar a ter RefreshUIStyle.
|
||||||
{
|
// if (Btn_Enter)
|
||||||
Btn_Enter->RefreshUIStyle();
|
// {
|
||||||
}
|
// Btn_Enter->RefreshUIStyle();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void UUIServerCard_Base::NativeDestruct()
|
void UUIServerCard_Base::NativeDestruct()
|
||||||
@@ -69,10 +69,11 @@ void UUIServerCard_Base::SetFromEntry(const FZMMOWorldEntry& InEntry)
|
|||||||
// o usuario pode entrar no Lobby pra ver a lista de personagens, criar/
|
// o usuario pode entrar no Lobby pra ver a lista de personagens, criar/
|
||||||
// deletar. O gate de "entrar no mundo" fica no proprio Lobby (botao
|
// deletar. O gate de "entrar no mundo" fica no proprio Lobby (botao
|
||||||
// "Entrar no Servidor"), que checa World.State antes do handoff.
|
// "Entrar no Servidor"), que checa World.State antes do handoff.
|
||||||
if (Btn_Enter)
|
// TODO(ui-system): reativar quando UUIButton_Base voltar a ter RefreshUIStyle.
|
||||||
{
|
// if (Btn_Enter)
|
||||||
Btn_Enter->RefreshUIStyle();
|
// {
|
||||||
}
|
// Btn_Enter->RefreshUIStyle();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void UUIServerCard_Base::HandleEnterClicked()
|
void UUIServerCard_Base::HandleEnterClicked()
|
||||||
|
|||||||
@@ -1,434 +1,28 @@
|
|||||||
#include "UIButton_Base.h"
|
#include "UIButton_Base.h"
|
||||||
|
|
||||||
#include "ZMMOThemeSubsystem.h"
|
#include "UI/UIStyleRow.h"
|
||||||
#include "Engine/GameInstance.h"
|
#include "UI/UIStyleTokens.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/DataTable.h"
|
||||||
#include "TimerManager.h"
|
|
||||||
#include "Components/Border.h"
|
|
||||||
#include "Styling/SlateBrush.h"
|
|
||||||
#include "Components/TextBlock.h"
|
|
||||||
#include "Components/Image.h"
|
|
||||||
#include "Components/SizeBox.h"
|
|
||||||
#include "Components/ScaleBox.h"
|
|
||||||
#include "Components/OverlaySlot.h"
|
|
||||||
#include "CommonTextBlock.h"
|
|
||||||
#include "CommonActionWidget.h"
|
|
||||||
|
|
||||||
namespace
|
const FUIStyle* UUIButton_Base::GetActiveUIStyle(FName ThemeId) const
|
||||||
{
|
{
|
||||||
/** Resolve o FUIStyle ativo; fallback p/ defaults (preview de designer). */
|
const UDataTable* DT = LoadObject<UDataTable>(nullptr,
|
||||||
const FUIStyle& ResolveActiveStyle(const UUserWidget* Widget, const FUIStyle& Fallback)
|
TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles"));
|
||||||
|
if (!DT)
|
||||||
{
|
{
|
||||||
if (Widget)
|
return nullptr;
|
||||||
{
|
|
||||||
if (const UGameInstance* GI = Widget->GetGameInstance())
|
|
||||||
{
|
|
||||||
if (const UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
|
||||||
{
|
|
||||||
return Theme->GetActiveUIStyle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Fallback; // sem GameInstance (design-time): Aurora Arcana default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const FUIStyleRow* Row = DT->FindRow<FUIStyleRow>(
|
||||||
|
ThemeId, TEXT("UUIButton_Base::GetActiveUIStyle"), false))
|
||||||
|
{
|
||||||
|
return &Row->Style;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FUIStyleButtonVariant UUIButton_Base::ResolveVariant(const FUIStyleButton& Button) const
|
const FUIStyleButton* UUIButton_Base::GetActiveButtonStyle(FName ThemeId) const
|
||||||
{
|
{
|
||||||
// Compõe FLAT a partir dos 3 sub-mapas do tema (Backgrounds/Strokes/Fonts).
|
const FUIStyle* UIStyle = GetActiveUIStyle(ThemeId);
|
||||||
// Fallback inline → Defaults (constructor de FUIStyleButton popula
|
return UIStyle ? &UIStyle->Button : nullptr;
|
||||||
// Primary/Secondary/Danger/Ghost com defaults Aurora Arcana — GC-safe).
|
|
||||||
static const FUIStyleButton Defaults;
|
|
||||||
FUIStyleButtonVariant V;
|
|
||||||
|
|
||||||
const FUIStyleButtonBackground* BG = Button.Backgrounds.Find(Variant);
|
|
||||||
if (!BG) { BG = Defaults.Backgrounds.Find(Variant); }
|
|
||||||
if (!BG) { BG = Defaults.Backgrounds.Find(TEXT("Primary")); }
|
|
||||||
if (BG)
|
|
||||||
{
|
|
||||||
V.BgNormal = BG->BgNormal;
|
|
||||||
V.BgHover = BG->BgHover;
|
|
||||||
V.BgPressed = BG->BgPressed;
|
|
||||||
V.BgDisabled = BG->BgDisabled;
|
|
||||||
V.BackgroundTexture = BG->BackgroundTexture;
|
|
||||||
V.BackgroundMargin = BG->BackgroundMargin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FUIStyleButtonStroke* ST = Button.Strokes.Find(Variant);
|
|
||||||
if (!ST) { ST = Defaults.Strokes.Find(Variant); }
|
|
||||||
if (!ST) { ST = Defaults.Strokes.Find(TEXT("Primary")); }
|
|
||||||
if (ST)
|
|
||||||
{
|
|
||||||
V.BorderNormal = ST->BorderNormal;
|
|
||||||
V.BorderHover = ST->BorderHover;
|
|
||||||
V.BorderWidth = ST->BorderWidth;
|
|
||||||
V.CornerRadius = ST->CornerRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FUIStyleButtonFont* F = Button.Fonts.Find(Variant);
|
|
||||||
if (!F) { F = Defaults.Fonts.Find(Variant); }
|
|
||||||
if (!F) { F = Defaults.Fonts.Find(TEXT("Primary")); }
|
|
||||||
if (F)
|
|
||||||
{
|
|
||||||
V.TextColor = F->TextColor;
|
|
||||||
V.TextStyle = F->TextStyle;
|
|
||||||
}
|
|
||||||
return V;
|
|
||||||
}
|
|
||||||
|
|
||||||
TArray<FString> UUIButton_Base::GetVariantOptions() const
|
|
||||||
{
|
|
||||||
TArray<FString> Options;
|
|
||||||
for (const TCHAR* N : { TEXT("Primary"), TEXT("Secondary"), TEXT("Danger"), TEXT("Ghost") })
|
|
||||||
{
|
|
||||||
Options.Add(N);
|
|
||||||
}
|
|
||||||
if (const UDataTable* DT = LoadObject<UDataTable>(nullptr,
|
|
||||||
TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles")))
|
|
||||||
{
|
|
||||||
if (const FUIStyleRow* Row = DT->FindRow<FUIStyleRow>(
|
|
||||||
FName(TEXT("Default")), TEXT("UIButtonVariantOptions"), false))
|
|
||||||
{
|
|
||||||
for (const TPair<FName, FUIStyleButtonBackground>& P : Row->Style.Button.Backgrounds) { Options.AddUnique(P.Key.ToString()); }
|
|
||||||
for (const TPair<FName, FUIStyleButtonStroke>& P : Row->Style.Button.Strokes) { Options.AddUnique(P.Key.ToString()); }
|
|
||||||
for (const TPair<FName, FUIStyleButtonFont>& P : Row->Style.Button.Fonts) { Options.AddUnique(P.Key.ToString()); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Options;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Set Button Text" ----
|
|
||||||
void UUIButton_Base::SetButtonText(FText InText)
|
|
||||||
{
|
|
||||||
if (!ButtonText)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const FText Final = bUppercaseText
|
|
||||||
? FText::FromString(InText.ToString().ToUpper())
|
|
||||||
: InText;
|
|
||||||
ButtonText->SetText(Final);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Set Number Text" ----
|
|
||||||
void UUIButton_Base::SetNumberText()
|
|
||||||
{
|
|
||||||
if (!Number_Text)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (bShowNumberText)
|
|
||||||
{
|
|
||||||
Number_Text->SetText(FText::AsNumber(NumberTextAmount));
|
|
||||||
Number_Text->SetVisibility(ESlateVisibility::Visible);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Number_Text->SetVisibility(ESlateVisibility::Hidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Set Icon" ----
|
|
||||||
void UUIButton_Base::SetIcon()
|
|
||||||
{
|
|
||||||
if (bUseIconInsteadOfText)
|
|
||||||
{
|
|
||||||
if (Image_Icon)
|
|
||||||
{
|
|
||||||
if (IconImage)
|
|
||||||
{
|
|
||||||
Image_Icon->SetBrushResourceObject(IconImage);
|
|
||||||
}
|
|
||||||
Image_Icon->SetVisibility(ESlateVisibility::Visible);
|
|
||||||
}
|
|
||||||
if (ButtonText)
|
|
||||||
{
|
|
||||||
ButtonText->SetVisibility(ESlateVisibility::Collapsed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Image_Icon)
|
|
||||||
{
|
|
||||||
Image_Icon->SetVisibility(ESlateVisibility::Collapsed);
|
|
||||||
}
|
|
||||||
if (ButtonText)
|
|
||||||
{
|
|
||||||
ButtonText->SetVisibility(ESlateVisibility::Visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Set Sizebox Master Dimmensions" ----
|
|
||||||
void UUIButton_Base::ApplySizeBox()
|
|
||||||
{
|
|
||||||
if (bDoNotOverrideWithSizebox || !SizeBox_Master)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SizeBox_Master->SetHeightOverride(InHeightOverride);
|
|
||||||
SizeBox_Master->SetWidthOverride(InWidthOverride);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Set InputAction Style" ----
|
|
||||||
void UUIButton_Base::ApplyInputActionStyle()
|
|
||||||
{
|
|
||||||
// InputActionWidget é privado em UCommonButtonBase (bind interno). Pega por
|
|
||||||
// nome — o widget do WBP chama-se "InputActionWidget" (bind do CommonUI).
|
|
||||||
UCommonActionWidget* IAW = Cast<UCommonActionWidget>(
|
|
||||||
GetWidgetFromName(TEXT("InputActionWidget")));
|
|
||||||
if (!IAW)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bShowInputActionWidget)
|
|
||||||
{
|
|
||||||
IAW->SetVisibility(ESlateVisibility::Visible);
|
|
||||||
IAW->SetIsEnabled(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IAW->SetVisibility(ESlateVisibility::Collapsed);
|
|
||||||
IAW->SetIsEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UOverlaySlot* OS = Cast<UOverlaySlot>(IAW->Slot))
|
|
||||||
{
|
|
||||||
OS->SetPadding(InputPadding);
|
|
||||||
OS->SetHorizontalAlignment(InputHorzAlignment);
|
|
||||||
OS->SetVerticalAlignment(InputVertAlignment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Initialize Button" (orquestrador) ----
|
|
||||||
void UUIButton_Base::InitializeButton()
|
|
||||||
{
|
|
||||||
SetButtonText(ButtonTextValue);
|
|
||||||
SetNumberText();
|
|
||||||
SetIcon();
|
|
||||||
ApplySizeBox();
|
|
||||||
RefreshUIStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Update Button Style" / "Set Brush" → nossa camada FUIStyle ----
|
|
||||||
void UUIButton_Base::RefreshUIStyle()
|
|
||||||
{
|
|
||||||
const FUIStyle Fallback; // defaults do struct = paleta Aurora Arcana
|
|
||||||
const FUIStyle& ActiveStyle = ResolveActiveStyle(this, Fallback);
|
|
||||||
const FUIStyleButtonVariant& VariantStyle = ResolveVariant(ActiveStyle.Button);
|
|
||||||
|
|
||||||
// Fundo + borda no estado Normal (hover/pressed/disabled via NativeOn*).
|
|
||||||
ApplyVisualState(EUIButtonVisual::Normal);
|
|
||||||
|
|
||||||
if (ButtonText)
|
|
||||||
{
|
|
||||||
// Tipografia: CommonTextStyle da variante (padrão Hyper/CommonUI).
|
|
||||||
if (VariantStyle.TextStyle)
|
|
||||||
{
|
|
||||||
ButtonText->SetStyle(VariantStyle.TextStyle);
|
|
||||||
}
|
|
||||||
// Cor: FUIStyle manda na cor por tema (sobrepõe o CommonTextStyle).
|
|
||||||
ButtonText->SetColorAndOpacity(FSlateColor(VariantStyle.TextColor));
|
|
||||||
|
|
||||||
// Alinhamento L/C/R dentro da largura do botão.
|
|
||||||
ButtonText->SetJustification(TextAlign);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Texto adapta ao tamanho do botão (ScaleToFit) ou usa tamanho fixo.
|
|
||||||
if (TextScaleBox)
|
|
||||||
{
|
|
||||||
TextScaleBox->SetStretch(bAutoSizeText ? EStretch::ScaleToFit : EStretch::None);
|
|
||||||
|
|
||||||
// Posiciona o bloco de texto L/C/R dentro do botão (slot do Overlay).
|
|
||||||
if (UOverlaySlot* OS = Cast<UOverlaySlot>(TextScaleBox->Slot))
|
|
||||||
{
|
|
||||||
EHorizontalAlignment H = HAlign_Center;
|
|
||||||
switch (TextAlign)
|
|
||||||
{
|
|
||||||
case ETextJustify::Left: H = HAlign_Left; break;
|
|
||||||
case ETextJustify::Right: H = HAlign_Right; break;
|
|
||||||
default: H = HAlign_Center; break;
|
|
||||||
}
|
|
||||||
OS->SetHorizontalAlignment(H);
|
|
||||||
OS->SetVerticalAlignment(VAlign_Center);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BP_ApplyUIStyle(ActiveStyle.Button, VariantStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::ApplyVisualState(EUIButtonVisual State)
|
|
||||||
{
|
|
||||||
if (!Background)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const FUIStyle Fallback;
|
|
||||||
const FUIStyle& AS = ResolveActiveStyle(this, Fallback);
|
|
||||||
const FUIStyleButtonVariant& V = ResolveVariant(AS.Button);
|
|
||||||
|
|
||||||
FLinearColor Fill, Outline;
|
|
||||||
switch (State)
|
|
||||||
{
|
|
||||||
case EUIButtonVisual::Hovered: Fill = V.BgHover; Outline = V.BorderHover; break;
|
|
||||||
case EUIButtonVisual::Pressed: Fill = V.BgPressed; Outline = V.BorderHover; break;
|
|
||||||
case EUIButtonVisual::Disabled: Fill = V.BgDisabled; Outline = V.BorderNormal; break;
|
|
||||||
default: Fill = V.BgNormal; Outline = V.BorderNormal; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSlateBrush Brush = Background->Background;
|
|
||||||
Brush.TintColor = FSlateColor(Fill);
|
|
||||||
if (bRoundedBackground)
|
|
||||||
{
|
|
||||||
// CornerRadius/BorderWidth agora vêm da variante composta (Stroke).
|
|
||||||
const float R = V.CornerRadius;
|
|
||||||
Brush.DrawAs = ESlateBrushDrawType::RoundedBox;
|
|
||||||
Brush.OutlineSettings = FSlateBrushOutlineSettings(
|
|
||||||
FVector4(R, R, R, R), FSlateColor(Outline), V.BorderWidth);
|
|
||||||
Brush.OutlineSettings.RoundingType = ESlateBrushRoundingType::FixedRadius;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Brush.DrawAs = ESlateBrushDrawType::Box;
|
|
||||||
Brush.OutlineSettings = FSlateBrushOutlineSettings(
|
|
||||||
FVector4(0, 0, 0, 0), FSlateColor(Outline), V.BorderWidth);
|
|
||||||
}
|
|
||||||
Background->SetBrush(Brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnHovered()
|
|
||||||
{
|
|
||||||
Super::NativeOnHovered();
|
|
||||||
ApplyVisualState(EUIButtonVisual::Hovered);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnUnhovered()
|
|
||||||
{
|
|
||||||
Super::NativeOnUnhovered();
|
|
||||||
ApplyVisualState(EUIButtonVisual::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnPressed()
|
|
||||||
{
|
|
||||||
Super::NativeOnPressed();
|
|
||||||
ApplyVisualState(EUIButtonVisual::Pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnReleased()
|
|
||||||
{
|
|
||||||
Super::NativeOnReleased();
|
|
||||||
ApplyVisualState(IsHovered() ? EUIButtonVisual::Hovered : EUIButtonVisual::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnEnabled()
|
|
||||||
{
|
|
||||||
Super::NativeOnEnabled();
|
|
||||||
ApplyVisualState(EUIButtonVisual::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeOnDisabled()
|
|
||||||
{
|
|
||||||
Super::NativeOnDisabled();
|
|
||||||
ApplyVisualState(EUIButtonVisual::Disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativePreConstruct()
|
|
||||||
{
|
|
||||||
Super::NativePreConstruct();
|
|
||||||
InitializeButton();
|
|
||||||
ApplyInputActionStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeConstruct()
|
|
||||||
{
|
|
||||||
Super::NativeConstruct();
|
|
||||||
|
|
||||||
if (!bThemeBound)
|
|
||||||
{
|
|
||||||
if (const UGameInstance* GI = GetGameInstance())
|
|
||||||
{
|
|
||||||
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
|
||||||
{
|
|
||||||
Theme->OnThemeChanged.AddDynamic(this, &UUIButton_Base::HandleThemeChanged);
|
|
||||||
bThemeBound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeButton();
|
|
||||||
ApplyInputActionStyle();
|
|
||||||
|
|
||||||
if (bDeactivatedOnConstructWithTimeout && Timeout > 0.f)
|
|
||||||
{
|
|
||||||
StartDeactivateTimeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::NativeDestruct()
|
|
||||||
{
|
|
||||||
if (UWorld* World = GetWorld())
|
|
||||||
{
|
|
||||||
World->GetTimerManager().ClearTimer(InactivityTimer);
|
|
||||||
World->GetTimerManager().ClearTimer(TimerTickHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bThemeBound)
|
|
||||||
{
|
|
||||||
if (const UGameInstance* GI = GetGameInstance())
|
|
||||||
{
|
|
||||||
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
|
||||||
{
|
|
||||||
Theme->OnThemeChanged.RemoveDynamic(this, &UUIButton_Base::HandleThemeChanged);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bThemeBound = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Super::NativeDestruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Hyper "Deactivate Button On Timeout" ----
|
|
||||||
void UUIButton_Base::StartDeactivateTimeout()
|
|
||||||
{
|
|
||||||
UWorld* World = GetWorld();
|
|
||||||
if (!World)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetIsEnabled(false);
|
|
||||||
TimeRemaining = Timeout;
|
|
||||||
|
|
||||||
World->GetTimerManager().SetTimer(
|
|
||||||
InactivityTimer, this, &UUIButton_Base::HandleTimeoutFinished, Timeout, false);
|
|
||||||
|
|
||||||
if (TimeUpdateFrequency > 0.f)
|
|
||||||
{
|
|
||||||
World->GetTimerManager().SetTimer(
|
|
||||||
TimerTickHandle, this, &UUIButton_Base::HandleTimerTick,
|
|
||||||
TimeUpdateFrequency, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::HandleTimeoutFinished()
|
|
||||||
{
|
|
||||||
if (UWorld* World = GetWorld())
|
|
||||||
{
|
|
||||||
World->GetTimerManager().ClearTimer(TimerTickHandle);
|
|
||||||
}
|
|
||||||
TimeRemaining = 0.f;
|
|
||||||
SetIsEnabled(true);
|
|
||||||
OnButtonActivatedByTimeout.Broadcast();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::HandleTimerTick()
|
|
||||||
{
|
|
||||||
TimeRemaining = FMath::Max(0.f, TimeRemaining - TimeUpdateFrequency);
|
|
||||||
OnButtonTimerUpdated.Broadcast(TimeRemaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UUIButton_Base::HandleThemeChanged(FName /*NewThemeId*/)
|
|
||||||
{
|
|
||||||
RefreshUIStyle();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,220 +2,55 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "CommonButtonBase.h"
|
#include "CommonButtonBase.h"
|
||||||
#include "Layout/Margin.h"
|
|
||||||
#include "Types/SlateEnums.h"
|
|
||||||
#include "UI/UIStyleTypes.h"
|
|
||||||
#include "UI/UIStyleTokens.h"
|
|
||||||
#include "UIButton_Base.generated.h"
|
#include "UIButton_Base.generated.h"
|
||||||
|
|
||||||
class UBorder;
|
|
||||||
class UTextBlock;
|
|
||||||
class UImage;
|
|
||||||
class USizeBox;
|
class USizeBox;
|
||||||
class UScaleBox;
|
class UImage;
|
||||||
|
class UCanvasPanel;
|
||||||
class UCommonTextBlock;
|
class UCommonTextBlock;
|
||||||
class UCommonActionWidget;
|
class UTextBlock;
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnUIButtonActivatedByTimeout);
|
struct FUIStyle;
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUIButtonTimerUpdated, float, TimeRemaining);
|
struct FUIStyleButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Botão base do ZMMO — porte 1:1 do UI_Button_Master do projeto Hyper para C++
|
* Botão base do ZMMO (CommonUI). Hoje expõe BindWidgetOptional dos widgets
|
||||||
* auto-configurável, trocando o Struct_Style_Button do Hyper pela camada de
|
* que o WBP UI_Button_Master_New consome, e helpers pra ler o estilo ativo
|
||||||
* tema C++ (FUIStyle via UZMMOThemeSubsystem::GetActiveUIStyle()).
|
* de DT_UI_Styles. A aplicação visual (pintar brushes/cores/fonte) entra
|
||||||
*
|
* depois — esta camada só prepara o acesso.
|
||||||
* Fundação: CommonUI (UCommonButtonBase) cuida de input/foco/click.
|
|
||||||
* Camada Abstract (padrão "_Abstract" do Hyper). WBP UI_Button_Base herda
|
|
||||||
* disto; UI_Button_Master herda do WBP. Os widgets visuais são opcionais
|
|
||||||
* (BindWidgetOptional) e nomeados como no Hyper.
|
|
||||||
*
|
|
||||||
* Auto-config: NativePreConstruct chama InitializeButton (text/number/icon/
|
|
||||||
* sizebox/estilo) + ApplyInputActionStyle. Reage à troca de tema.
|
|
||||||
*/
|
*/
|
||||||
UCLASS(Abstract, Blueprintable)
|
UCLASS(Abstract, Blueprintable)
|
||||||
class ZMMO_API UUIButton_Base : public UCommonButtonBase
|
class ZMMO_API UUIButton_Base : public UCommonButtonBase
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
|
||||||
// ---- Botão ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
|
|
||||||
EUIButtonShape ButtonTypeSelection = EUIButtonShape::Rectangle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variante visual do botão (dropdown vem de FUIStyle.Button.Backgrounds/
|
|
||||||
* Strokes/Fonts no DT_UI_Styles + as 4 clássicas como fallback).
|
|
||||||
* Data-driven via FName, sem enum fixo (padrão Hyper-style).
|
|
||||||
*/
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button",
|
|
||||||
meta = (GetOptions = "GetVariantOptions"))
|
|
||||||
FName Variant = TEXT("Primary");
|
|
||||||
|
|
||||||
/** Opções do dropdown de Variant (data-driven do DT_UI_Styles). */
|
|
||||||
UFUNCTION()
|
|
||||||
TArray<FString> GetVariantOptions() const;
|
|
||||||
|
|
||||||
/** Hyper "Transform Policy = To Upper": força o texto em maiúsculas. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
|
|
||||||
bool bUppercaseText = true;
|
|
||||||
|
|
||||||
// ---- Text Style ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
|
|
||||||
FText ButtonTextValue = FText::FromString(TEXT("Button Text"));
|
|
||||||
|
|
||||||
/** Alinhamento do texto dentro do botão (esquerda/centro/direita). */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
|
|
||||||
TEnumAsByte<ETextJustify::Type> TextAlign = ETextJustify::Center;
|
|
||||||
|
|
||||||
/** true = texto escala p/ caber no tamanho do botão (ScaleBox ScaleToFit);
|
|
||||||
* false = usa o tamanho fixo da fonte da variante. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
|
|
||||||
bool bAutoSizeText = true;
|
|
||||||
|
|
||||||
/** Arredonda o Background (RoundedBox) e desenha a borda na cor da
|
|
||||||
* variante. Desligado = caixa reta. Raio/largura vêm de FUIStyleButton. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
|
|
||||||
bool bRoundedBackground = true;
|
|
||||||
|
|
||||||
// ---- Number Text ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Number Text")
|
|
||||||
bool bShowNumberText = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Number Text")
|
|
||||||
int32 NumberTextAmount = 0;
|
|
||||||
|
|
||||||
// ---- Icon ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
|
|
||||||
bool bUseIconInsteadOfText = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
|
|
||||||
TObjectPtr<UObject> IconImage = nullptr;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
|
|
||||||
EUIIconType IconTypeSelection = EUIIconType::None;
|
|
||||||
|
|
||||||
// ---- Size ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
|
|
||||||
float InHeightOverride = 50.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
|
|
||||||
float InWidthOverride = 150.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
|
|
||||||
bool bDoNotOverrideWithSizebox = false;
|
|
||||||
|
|
||||||
// ---- Input Action Style ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
|
|
||||||
bool bShowInputActionWidget = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
|
|
||||||
FMargin InputPadding = FMargin(0.f, 0.f, 0.f, -22.f);
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
|
|
||||||
TEnumAsByte<EHorizontalAlignment> InputHorzAlignment = HAlign_Center;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
|
|
||||||
TEnumAsByte<EVerticalAlignment> InputVertAlignment = VAlign_Bottom;
|
|
||||||
|
|
||||||
// ---- Deactivate by Timer ----
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Deactivate By Timer")
|
|
||||||
bool bDeactivatedOnConstructWithTimeout = false;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Deactivate By Timer")
|
|
||||||
float Timeout = 0.f;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timer")
|
|
||||||
float TimeUpdateFrequency = 0.05f;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category = "Timer")
|
|
||||||
float TimeRemaining = 0.f;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintAssignable, Category = "Timer")
|
|
||||||
FOnUIButtonActivatedByTimeout OnButtonActivatedByTimeout;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintAssignable, Category = "Timer")
|
|
||||||
FOnUIButtonTimerUpdated OnButtonTimerUpdated;
|
|
||||||
|
|
||||||
// ---- API (porte 1:1 das funções do Hyper) ----
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void SetButtonText(FText InText);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void SetNumberText();
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void SetIcon();
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void ApplySizeBox();
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void ApplyInputActionStyle();
|
|
||||||
|
|
||||||
/** Orquestrador (Hyper "Initialize Button"): aplica tudo + estilo do tema. */
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
||||||
void InitializeButton();
|
|
||||||
|
|
||||||
/** Re-resolve os tokens do tema ativo e reaplica (Hyper "Update Button Style"). */
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "UI Style")
|
|
||||||
void RefreshUIStyle();
|
|
||||||
|
|
||||||
/** Estado visual do botão (mapeia nos tokens BgNormal/Hover/Pressed/Disabled). */
|
|
||||||
enum class EUIButtonVisual : uint8 { Normal, Hovered, Pressed, Disabled };
|
|
||||||
|
|
||||||
/** Pinta o Background (fill + borda) conforme o estado, re-resolvendo o tema. */
|
|
||||||
void ApplyVisualState(EUIButtonVisual State);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void NativePreConstruct() override;
|
// ---- Widgets BindWidgetOptional (espelham a árvore do UI_Button_Master_New) ----
|
||||||
virtual void NativeConstruct() override;
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
virtual void NativeDestruct() override;
|
TObjectPtr<USizeBox> SizeBox;
|
||||||
|
|
||||||
// Estados do UCommonButtonBase → repinta o Background pela variante.
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
virtual void NativeOnHovered() override;
|
TObjectPtr<UImage> ImgStoke;
|
||||||
virtual void NativeOnUnhovered() override;
|
|
||||||
virtual void NativeOnPressed() override;
|
|
||||||
virtual void NativeOnReleased() override;
|
|
||||||
virtual void NativeOnEnabled() override;
|
|
||||||
virtual void NativeOnDisabled() override;
|
|
||||||
|
|
||||||
/** Hook opcional: o WBP pode estender/sobrescrever a aplicação visual. */
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
UFUNCTION(BlueprintImplementableEvent, Category = "UI Style",
|
TObjectPtr<UCanvasPanel> CanvasPanel_Text;
|
||||||
meta = (DisplayName = "Apply UI Style"))
|
|
||||||
void BP_ApplyUIStyle(const FUIStyleButton& Button, const FUIStyleButtonVariant& VariantStyle);
|
|
||||||
|
|
||||||
FUIStyleButtonVariant ResolveVariant(const FUIStyleButton& Button) const;
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
|
|
||||||
// ---- Widgets visuais opcionais (nomes espelham o Hyper) ----
|
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
|
||||||
TObjectPtr<USizeBox> SizeBox_Master;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
|
||||||
TObjectPtr<UCommonTextBlock> ButtonText;
|
TObjectPtr<UCommonTextBlock> ButtonText;
|
||||||
|
|
||||||
/** Envolve o ButtonText: escala o texto p/ caber no botão (bAutoSizeText). */
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
|
||||||
TObjectPtr<UScaleBox> TextScaleBox;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
|
||||||
TObjectPtr<UTextBlock> Number_Text;
|
TObjectPtr<UTextBlock> Number_Text;
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
||||||
TObjectPtr<UImage> Image_Icon;
|
TObjectPtr<UImage> ImgIcon;
|
||||||
|
|
||||||
/** Fundo temável (nossa adição sobre o Hyper, p/ FUIStyle). */
|
// ---- Acesso ao estilo ativo (DT_UI_Styles) — C++ only ----
|
||||||
UPROPERTY(meta = (BindWidgetOptional))
|
|
||||||
TObjectPtr<UBorder> Background;
|
|
||||||
|
|
||||||
private:
|
/** Carrega DT_UI_Styles e devolve o FUIStyle da row pedida (default "Default").
|
||||||
void StartDeactivateTimeout();
|
* Retorna nullptr se a DT ou a row não existirem. Ponteiro válido enquanto
|
||||||
void HandleTimeoutFinished();
|
* a DT estiver carregada — uso típico é leitura imediata, sem armazenar. */
|
||||||
void HandleTimerTick();
|
const FUIStyle* GetActiveUIStyle(FName ThemeId = TEXT("Default")) const;
|
||||||
|
|
||||||
UFUNCTION()
|
/** Atalho: devolve só o bloco Button do FUIStyle ativo. */
|
||||||
void HandleThemeChanged(FName NewThemeId);
|
const FUIStyleButton* GetActiveButtonStyle(FName ThemeId = TEXT("Default")) const;
|
||||||
|
|
||||||
bool bThemeBound = false;
|
|
||||||
FTimerHandle InactivityTimer;
|
|
||||||
FTimerHandle TimerTickHandle;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,83 +52,43 @@ void UUIPanel_Base::RefreshUIStyle()
|
|||||||
const FUIStyle AS = ResolvePanelStyle(this, Fallback);
|
const FUIStyle AS = ResolvePanelStyle(this, Fallback);
|
||||||
const FUIStylePanel& P = AS.Panel;
|
const FUIStylePanel& P = AS.Panel;
|
||||||
|
|
||||||
// ---- Modo TEXTURA (padrão Hyper): brush por EUIPanelTexture ----
|
// bUseTheme = true -> brushes vêm da DT (lookup pelas 3 chaves).
|
||||||
// Fiel ao UI_Panel_Master do Hyper: só faz SetBrush nos dois Borders
|
// bUseTheme = false -> brushes vêm dos 3 FSlateBrush em Panels (direto).
|
||||||
// (Find no mapa por chave). Sem padding/visibility — a arte da textura
|
|
||||||
// já traz a moldura; o conteúdo é injetado pelo WBP filho.
|
|
||||||
// Seed dos mapas da instância a partir do tema quando vazios — assim o
|
|
||||||
// Details mostra Panel Background/Outline preenchidos e editáveis (igual
|
|
||||||
// ao Hyper, cujo `Panels` é alimentado pelo estilo). Edições do designer
|
|
||||||
// têm prioridade; o tema (P) é fallback por chave.
|
|
||||||
if (Panels.PanelBackground.Num() == 0) { Panels.PanelBackground = P.PanelBackground; }
|
|
||||||
if (Panels.PanelOutline.Num() == 0) { Panels.PanelOutline = P.PanelOutline; }
|
|
||||||
|
|
||||||
const FSlateBrush* BgTex = nullptr;
|
static const FSlateBrush NoDrawBrush = []
|
||||||
if (PanelTexture != EUIPanelTexture::None)
|
|
||||||
{
|
{
|
||||||
BgTex = Panels.PanelBackground.Find(PanelTexture);
|
FSlateBrush B;
|
||||||
if (!BgTex) { BgTex = P.PanelBackground.Find(PanelTexture); }
|
B.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
}
|
return B;
|
||||||
if (BgTex)
|
}();
|
||||||
|
|
||||||
|
auto ResolveFromTheme = [](EUIPanelTexture Key,
|
||||||
|
const TMap<EUIPanelTexture, FSlateBrush>& Map) -> const FSlateBrush*
|
||||||
{
|
{
|
||||||
Background->SetBrush(*BgTex);
|
return (Key == EUIPanelTexture::None) ? nullptr : Map.Find(Key);
|
||||||
if (Outline)
|
};
|
||||||
{
|
|
||||||
// Hyper: Find sempre seguido de SetBrush. No Hyper a entrada de
|
const FSlateBrush* BgTex = bUseTheme
|
||||||
// outline ausente é um brush TRANSPARENTE (alpha 0) — não some
|
? ResolveFromTheme(BackgroundKey, P.PanelBackground)
|
||||||
// widget, só não desenha. Um FSlateBrush default desenha um
|
: &Panels.PanelBackground;
|
||||||
// retângulo BRANCO; o equivalente correto é DrawAs=NoDrawType.
|
Background->SetBrush(BgTex ? *BgTex : NoDrawBrush);
|
||||||
const FSlateBrush* OlTex = Panels.PanelOutline.Find(PanelTexture);
|
|
||||||
if (!OlTex) { OlTex = P.PanelOutline.Find(PanelTexture); }
|
|
||||||
static const FSlateBrush NoDrawBrush = []
|
|
||||||
{
|
|
||||||
FSlateBrush B;
|
|
||||||
B.DrawAs = ESlateBrushDrawType::NoDrawType;
|
|
||||||
return B;
|
|
||||||
}();
|
|
||||||
Outline->SetBrush(OlTex ? *OlTex : NoDrawBrush);
|
|
||||||
}
|
|
||||||
BP_ApplyPanelStyle(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Modo COR (RoundedBox) ----
|
|
||||||
if (Outline)
|
if (Outline)
|
||||||
{
|
{
|
||||||
Outline->SetVisibility(ESlateVisibility::Collapsed);
|
const FSlateBrush* OlTex = bUseTheme
|
||||||
|
? ResolveFromTheme(OutlineKey, P.PanelOutline)
|
||||||
|
: &Panels.PanelOutline;
|
||||||
|
Outline->SetBrush(OlTex ? *OlTex : NoDrawBrush);
|
||||||
}
|
}
|
||||||
|
|
||||||
FLinearColor Fill;
|
if (OutlineEffect)
|
||||||
FLinearColor OutlineColor = P.BorderColor;
|
|
||||||
switch (PanelType)
|
|
||||||
{
|
{
|
||||||
case EUIPanelType::Secondary: Fill = P.BgRaised; break;
|
const FSlateBrush* OeTex = bUseTheme
|
||||||
case EUIPanelType::Tertiary: Fill = P.BgSunken; break;
|
? ResolveFromTheme(OutlineEffectKey, P.PanelOutlineEffect)
|
||||||
case EUIPanelType::Card: Fill = P.CardSelectedBg; OutlineColor = P.CardSelectedBorder; break;
|
: &Panels.PanelOutlineEffect;
|
||||||
case EUIPanelType::Primary:
|
OutlineEffect->SetBrush(OeTex ? *OeTex : NoDrawBrush);
|
||||||
case EUIPanelType::None:
|
|
||||||
default: Fill = P.Bg; break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FSlateBrush Brush = Background->Background;
|
|
||||||
Brush.TintColor = FSlateColor(Fill);
|
|
||||||
if (bRoundedBackground)
|
|
||||||
{
|
|
||||||
const float R = bUseSmallPadding ? P.CornerRadiusSmall : P.CornerRadius;
|
|
||||||
Brush.DrawAs = ESlateBrushDrawType::RoundedBox;
|
|
||||||
Brush.OutlineSettings = FSlateBrushOutlineSettings(
|
|
||||||
FVector4(R, R, R, R), FSlateColor(OutlineColor), P.BorderWidth);
|
|
||||||
Brush.OutlineSettings.RoundingType = ESlateBrushRoundingType::FixedRadius;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Brush.DrawAs = ESlateBrushDrawType::Box;
|
|
||||||
Brush.OutlineSettings = FSlateBrushOutlineSettings(
|
|
||||||
FVector4(0, 0, 0, 0), FSlateColor(OutlineColor), P.BorderWidth);
|
|
||||||
}
|
|
||||||
Background->SetBrush(Brush);
|
|
||||||
Background->SetPadding(bUseSmallPadding ? P.PaddingSmall : P.Padding);
|
|
||||||
|
|
||||||
BP_ApplyPanelStyle(P);
|
BP_ApplyPanelStyle(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,34 +23,31 @@ class ZMMO_API UUIPanel_Base : public UCommonUserWidget
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Tipo do painel — escolhe Bg/BgRaised/BgSunken/Card de FUIStylePanel. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
|
||||||
EUIPanelType PanelType = EUIPanelType::Primary;
|
|
||||||
|
|
||||||
/** Arredonda o Background (RoundedBox) com a borda do tema. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
|
||||||
bool bRoundedBackground = true;
|
|
||||||
|
|
||||||
/** Usa o padding "pequeno" do tema (PaddingSmall) em vez de Padding. */
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
|
||||||
bool bUseSmallPadding = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conjunto de textura (modo Hyper). Se != None E houver brush no mapa
|
* true = lê brushes da DT_UI_Styles (FUIStylePanel) — tema centralizado.
|
||||||
* FUIStylePanel.PanelBackground p/ esta chave, usa o painel TEXTURIZADO
|
* false = ignora a DT e usa apenas `Panels` (brushes manuais no Details).
|
||||||
* (brush bg + outline). Senão, cai no modo COR (RoundedBox acima).
|
|
||||||
*/
|
*/
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
||||||
EUIPanelTexture PanelTexture = EUIPanelTexture::None;
|
bool bUseTheme = true;
|
||||||
|
|
||||||
/**
|
// ---- Modo TEMA: escolhe a chave do mapa FUIStylePanel pra cada Border. ----
|
||||||
* Mapas de brush por instância — espelha o `Panels` do UI_Panel_Master
|
|
||||||
* do Hyper (Details mostra Panel Background / Panel Outline editáveis).
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||||
* Tem prioridade. Se não houver brush p/ a chave aqui, cai no tema
|
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||||
* (DT_UI_Styles). Em NativePreConstruct é semeado a partir do tema
|
EUIPanelTexture BackgroundKey = EUIPanelTexture::None;
|
||||||
* quando vazio, então por padrão o tema manda — como no Hyper.
|
|
||||||
*/
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel")
|
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||||
|
EUIPanelTexture OutlineKey = EUIPanelTexture::None;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||||
|
meta = (EditCondition = "bUseTheme", EditConditionHides))
|
||||||
|
EUIPanelTexture OutlineEffectKey = EUIPanelTexture::None;
|
||||||
|
|
||||||
|
// ---- Modo MANUAL: 3 brushes editáveis direto no Details. ----
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Panel",
|
||||||
|
meta = (EditCondition = "!bUseTheme", EditConditionHides))
|
||||||
FUIPanelBrushSet Panels;
|
FUIPanelBrushSet Panels;
|
||||||
|
|
||||||
/** Re-resolve os tokens do tema ativo e reaplica no Background. */
|
/** Re-resolve os tokens do tema ativo e reaplica no Background. */
|
||||||
@@ -75,6 +72,10 @@ protected:
|
|||||||
UPROPERTY(meta = (BindWidgetOptional))
|
UPROPERTY(meta = (BindWidgetOptional))
|
||||||
TObjectPtr<UBorder> Outline;
|
TObjectPtr<UBorder> Outline;
|
||||||
|
|
||||||
|
/** Efeito sobre o contorno (glow/embossing/etc.) — pintado acima do Outline. */
|
||||||
|
UPROPERTY(meta = (BindWidgetOptional))
|
||||||
|
TObjectPtr<UBorder> OutlineEffect;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UFUNCTION()
|
UFUNCTION()
|
||||||
void HandleThemeChanged(FName NewThemeId);
|
void HandleThemeChanged(FName NewThemeId);
|
||||||
|
|||||||
Reference in New Issue
Block a user