Snapshot do trabalho em andamento na branch feat/ui-system: refinamentos do UIButton_Base (header+impl), atualizacao de styles/themes do botao, mapa de teste L_ZeusIATest, e demais .uasset/Config tocados durante a sessao de playtest do meshing. Commit conjunto a pedido do usuario pra deixar a branch limpa antes do proximo batch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
282 lines
12 KiB
C++
282 lines
12 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "CommonButtonBase.h"
|
|
#include "UIButton_Base.generated.h"
|
|
|
|
class UImage;
|
|
class UCommonTextBlock;
|
|
class UMaterialInterface;
|
|
class UMaterialInstanceDynamic;
|
|
|
|
struct FUIStyle;
|
|
struct FUIStyleButton;
|
|
|
|
/** Tipo de borda do botão (fixo por instância; a COR acende por estado). */
|
|
UENUM(BlueprintType)
|
|
enum class EUIButtonBorderStyle : uint8
|
|
{
|
|
None UMETA(DisplayName = "Sem borda"),
|
|
Simple UMETA(DisplayName = "Linha simples (Slate)"),
|
|
Frame UMETA(DisplayName = "Frame (material)")
|
|
};
|
|
|
|
/**
|
|
* Snapshot visual de UM estado do botão (Default / Hover / Pressed / Disabled).
|
|
* As cores de gradient/glow vão pro material (UI_M_Button via MID); a borda usa
|
|
* o RoundedBox nativo do Slate (OutlineSettings) e o scale/opacity são
|
|
* RenderTransform do widget. Transições entre estados interpolam esta struct
|
|
* inteira (ver UUIButton_Base::NativeTick).
|
|
*/
|
|
USTRUCT(BlueprintType)
|
|
struct ZMMO_API FUIButtonStateVisual
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Topo do gradient vertical do fundo (param TopColour do material). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State")
|
|
FLinearColor TopColour = FLinearColor(0.910f, 0.753f, 0.376f, 0.18f);
|
|
|
|
/** Base do gradient vertical (param BottomColour). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State")
|
|
FLinearColor BottomColour = FLinearColor(0.659f, 0.471f, 0.188f, 0.10f);
|
|
|
|
/** Cor do halo externo (camada GlowFx, material UI_M_Button_Glow). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State")
|
|
FLinearColor GlowColour = FLinearColor(0.910f, 0.753f, 0.376f, 1.f);
|
|
|
|
/** Intensidade do halo externo (GlowFx). 0 = sem glow; hover acende (sai pra fora). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State",
|
|
meta = (ClampMin = "0", ClampMax = "1"))
|
|
float GlowIntensity = 0.f;
|
|
|
|
/** Cor da borda/cantos (Slate outline no modo Simple, ou material no modo Corners). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State")
|
|
FLinearColor BorderColour = FLinearColor(0.831f, 0.659f, 0.314f, 0.28f);
|
|
|
|
/** Espessura da borda em pixels (Slate OutlineSettings.Width). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State",
|
|
meta = (ClampMin = "0", ClampMax = "6"))
|
|
float BorderWidth = 1.f;
|
|
|
|
/** Cor do texto (ButtonText->SetColorAndOpacity). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State")
|
|
FLinearColor TextColour = FLinearColor(1.f, 0.847f, 0.533f, 1.f);
|
|
|
|
/** Scale do botão (CSS transform: scale). 1 = normal, 1.02 = hover, 0.98 = pressed. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State",
|
|
meta = (ClampMin = "0.5", ClampMax = "1.5"))
|
|
float Scale = 1.f;
|
|
|
|
/** Opacidade geral do botão (CSS opacity — disabled usa 0.6). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button|State",
|
|
meta = (ClampMin = "0", ClampMax = "1"))
|
|
float RenderOpacity = 1.f;
|
|
};
|
|
|
|
/**
|
|
* Botão base do ZMMO (CommonUI). Mesmo padrão do UUIProgressBar_Base: um UImage
|
|
* (`Bg`) com material custom (UI_M_Button) controlado por MID + RoundedBox nativo
|
|
* do Slate pra borda/canto. Os estados do UCommonButtonBase (Hover/Pressed/
|
|
* Disabled/Selected) trocam o FUIButtonStateVisual alvo; a transição interpola
|
|
* suave no Tick (estilo CSS `transition`).
|
|
*
|
|
* Modo atual = manual (os 4 FUIButtonStateVisual editáveis no Details, já com
|
|
* defaults do `btn-primary`). A leitura via DT_UI_Styles (bUseTheme + Variant)
|
|
* entra na fase final, reusando esta struct.
|
|
*
|
|
* WBP filho (UI_Button_Master_New): `Bg` (UImage, obrigatório, material no brush)
|
|
* + `ButtonText` (UCommonTextBlock, opcional).
|
|
*/
|
|
UCLASS(Abstract, Blueprintable)
|
|
class ZMMO_API UUIButton_Base : public UCommonButtonBase
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UUIButton_Base(const FObjectInitializer& ObjectInitializer);
|
|
|
|
/** Define o texto do botão (ButtonText). */
|
|
UFUNCTION(BlueprintCallable, Category = "UI Button")
|
|
void SetButtonText(const FText& InText);
|
|
|
|
// === Visual por estado (modo manual; defaults = btn-primary) ===
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FUIButtonStateVisual DefaultVisual;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FUIButtonStateVisual HoveredVisual;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FUIButtonStateVisual PressedVisual;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FUIButtonStateVisual DisabledVisual;
|
|
|
|
/** Estado "selecionado" (tabs/toggles). Default = igual ao Hovered. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FUIButtonStateVisual SelectedVisual;
|
|
|
|
/** Raio do canto em pixels (Slate RoundedBox). Comum a todos os estados. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "0", ClampMax = "32"))
|
|
float CornerRadius = 2.f;
|
|
|
|
/** Tipo de borda (independente dos cantos): sem borda, linha Slate ou frame material. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
EUIButtonBorderStyle BorderStyle = EUIButtonBorderStyle::Frame;
|
|
|
|
/** Liga os cantos (corner brackets) — INDEPENDENTE da borda. Pode ter os dois,
|
|
* só um, ou nenhum. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
bool bShowCorners = true;
|
|
|
|
/** Material do fundo (UI_M_Button). Fallback quando o brush do Bg não traz
|
|
* material próprio. Defaults resolvidos no construtor. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Button|Visual")
|
|
TObjectPtr<UMaterialInterface> BgMaterial;
|
|
|
|
/** Material do halo externo (UI_M_Button_Glow), aplicado no GlowFx. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Button|Visual")
|
|
TObjectPtr<UMaterialInterface> GlowMaterial;
|
|
|
|
/** Material dos cantos (UI_M_CornerBrackets), aplicado no Corners. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Button|Visual")
|
|
TObjectPtr<UMaterialInterface> CornerMaterial;
|
|
|
|
/** Material da moldura (UI_M_Button_Frame), aplicado no BorderFx. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Button|Visual")
|
|
TObjectPtr<UMaterialInterface> FrameMaterial;
|
|
|
|
/** Padding do conteúdo (texto) dentro do botão. btn-primary = 28px horiz /
|
|
* 12px vert. Aplicado no slot do ButtonText em PreConstruct (o texto fica
|
|
* centralizado). */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual")
|
|
FMargin ContentPadding = FMargin(28.f, 12.f, 28.f, 12.f);
|
|
|
|
/** Quanto o halo externo (GlowFx) vaza pra fora do botão, em pixels. Aplicado
|
|
* como padding negativo no slot do GlowFx em PreConstruct. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "0", ClampMax = "64"))
|
|
float GlowExtent = 16.f;
|
|
|
|
/** Desloca os cantos. Negativo = pra FORA (abraçando o botão, estilo CSS);
|
|
* positivo = pra dentro. Aplicado no slot do Corners em PreConstruct. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "-32", ClampMax = "32"))
|
|
float CornerInset = -5.f;
|
|
|
|
/** Comprimento de cada braço do "L" (fração da altura). Maior = L mais longo. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "0.05", ClampMax = "1.0"))
|
|
float CornerLength = 0.35f;
|
|
|
|
/** Espessura/peso do traço dos cantos (fração da altura). Menor = mais fino. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "0.005", ClampMax = "0.3"))
|
|
float CornerThickness = 0.04f;
|
|
|
|
/** Deslocamento da sombra (GlowFx) pra baixo, em px — dá o look de drop shadow. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Visual",
|
|
meta = (ClampMin = "0", ClampMax = "32"))
|
|
float GlowOffsetY = 4.f;
|
|
|
|
/** Duração da transição entre estados (s). 0 = troca instantânea. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI Button|Animation",
|
|
meta = (ClampMin = "0", ClampMax = "1"))
|
|
float TransitionSeconds = 0.12f;
|
|
|
|
protected:
|
|
virtual void NativePreConstruct() override;
|
|
virtual void NativeConstruct() override;
|
|
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
|
|
virtual int32 NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
|
|
const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements,
|
|
int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
|
|
|
|
// === Hooks de estado do UCommonButtonBase ===
|
|
virtual void NativeOnHovered() override;
|
|
virtual void NativeOnUnhovered() override;
|
|
virtual void NativeOnPressed() override;
|
|
virtual void NativeOnReleased() override;
|
|
virtual void NativeOnEnabled() override;
|
|
virtual void NativeOnDisabled() override;
|
|
virtual void NativeOnSelected(bool bBroadcast) override;
|
|
virtual void NativeOnDeselected(bool bBroadcast) override;
|
|
|
|
// === BindWidget (espelham a árvore do UI_Button_Master_New) ===
|
|
// Todos BindWidgetOptional pra não quebrar WBPs que herdam UUIButton_Base sem
|
|
// essas peças — sem elas o visual degrada (não pinta), mas não quebra.
|
|
|
|
/** Halo externo (atrás do Bg, com padding negativo pra vazar pra fora). */
|
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
|
TObjectPtr<UImage> GlowFx;
|
|
|
|
/** Fundo (gradient). */
|
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
|
TObjectPtr<UImage> Bg;
|
|
|
|
/** Moldura/frame (material), visível só no BorderStyle = Frame. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
|
TObjectPtr<UImage> BorderFx;
|
|
|
|
/** Cantos (corner brackets), visível só no BorderStyle = Corners. */
|
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
|
TObjectPtr<UImage> Corners;
|
|
|
|
UPROPERTY(BlueprintReadOnly, Category = "UI Button", meta = (BindWidgetOptional))
|
|
TObjectPtr<UCommonTextBlock> ButtonText;
|
|
|
|
// === Acesso ao estilo ativo (DT_UI_Styles) — usado na fase final ===
|
|
|
|
/** Carrega DT_UI_Styles e devolve o FUIStyle da row pedida (default "Default"). */
|
|
const FUIStyle* GetActiveUIStyle(FName ThemeId = TEXT("Default")) const;
|
|
|
|
/** Atalho: devolve só o bloco Button do FUIStyle ativo. */
|
|
const FUIStyleButton* GetActiveButtonStyle(FName ThemeId = TEXT("Default")) const;
|
|
|
|
private:
|
|
/** Cria os MIDs a partir do material no brush de cada imagem (idempotente). */
|
|
void EnsureMID();
|
|
|
|
/** Passa a proporção W/H de CADA camada (cantos/frame/glow) pro respectivo
|
|
* material que compensa aspect. Chamado no NativePaint — roda no Designer E
|
|
* em runtime (o Tick NÃO roda no Designer, por isso o traço esticava lá). */
|
|
void ApplyAspectToLayers() const;
|
|
|
|
/** Recalcula o estado-alvo (disabled>pressed>hovered>selected>default) e transiciona. */
|
|
void RefreshState();
|
|
|
|
/** Inicia transição pro visual alvo (ou aplica direto se TransitionSeconds≈0). */
|
|
void GoToState(const FUIButtonStateVisual& Target);
|
|
|
|
/** Empurra um visual pros widgets (MID + borda Slate + scale/opacity + texto). */
|
|
void ApplyVisual(const FUIButtonStateVisual& V);
|
|
|
|
static FUIButtonStateVisual LerpVisual(const FUIButtonStateVisual& A, const FUIButtonStateVisual& B, float T);
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMaterialInstanceDynamic> BgMID;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMaterialInstanceDynamic> GlowMID;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMaterialInstanceDynamic> CornerMID;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMaterialInstanceDynamic> BorderMID;
|
|
|
|
bool bHoveredState = false;
|
|
bool bPressedState = false;
|
|
bool bDisabledState = false;
|
|
bool bSelectedState = false;
|
|
|
|
FUIButtonStateVisual FromVisual;
|
|
FUIButtonStateVisual ToVisual;
|
|
FUIButtonStateVisual CurrentVisual;
|
|
float TransitionElapsed = 0.f;
|
|
bool bTransitioning = false;
|
|
};
|