diff --git a/Source/ZMMO/Game/UI/Widgets/UIButton_Base.cpp b/Source/ZMMO/Game/UI/Widgets/UIButton_Base.cpp index d126c4f..862852f 100644 --- a/Source/ZMMO/Game/UI/Widgets/UIButton_Base.cpp +++ b/Source/ZMMO/Game/UI/Widgets/UIButton_Base.cpp @@ -166,32 +166,9 @@ void UUIButton_Base::RefreshUIStyle() const FUIStyle& ActiveStyle = ResolveActiveStyle(this, Fallback); const FUIStyleButtonVariant& VariantStyle = ResolveVariant(ActiveStyle.Button); - if (Background) - { - // Fundo + borda na cor da variante. RoundedBox dá cantos arredondados - // e a borda colorida (BorderNormal) — "só borda" = BgNormal transparente. - FSlateBrush Brush = Background->Background; - Brush.TintColor = FSlateColor(VariantStyle.BgNormal); - if (bRoundedBackground) - { - const float R = ActiveStyle.Button.CornerRadius; - Brush.DrawAs = ESlateBrushDrawType::RoundedBox; - Brush.OutlineSettings = FSlateBrushOutlineSettings( - FVector4(R, R, R, R), - FSlateColor(VariantStyle.BorderNormal), - ActiveStyle.Button.BorderWidth); - Brush.OutlineSettings.RoundingType = ESlateBrushRoundingType::FixedRadius; - } - else - { - Brush.DrawAs = ESlateBrushDrawType::Box; - Brush.OutlineSettings = FSlateBrushOutlineSettings( - FVector4(0, 0, 0, 0), - FSlateColor(VariantStyle.BorderNormal), - ActiveStyle.Button.BorderWidth); - } - Background->SetBrush(Brush); - } + // Fundo + borda no estado Normal (hover/pressed/disabled via NativeOn*). + ApplyVisualState(EUIButtonVisual::Normal); + if (ButtonText) { // Tipografia: CommonTextStyle da variante (padrão Hyper/CommonUI). @@ -229,6 +206,80 @@ void UUIButton_Base::RefreshUIStyle() 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) + { + const float R = AS.Button.CornerRadius; + Brush.DrawAs = ESlateBrushDrawType::RoundedBox; + Brush.OutlineSettings = FSlateBrushOutlineSettings( + FVector4(R, R, R, R), FSlateColor(Outline), AS.Button.BorderWidth); + Brush.OutlineSettings.RoundingType = ESlateBrushRoundingType::FixedRadius; + } + else + { + Brush.DrawAs = ESlateBrushDrawType::Box; + Brush.OutlineSettings = FSlateBrushOutlineSettings( + FVector4(0, 0, 0, 0), FSlateColor(Outline), AS.Button.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(); diff --git a/Source/ZMMO/Game/UI/Widgets/UIButton_Base.h b/Source/ZMMO/Game/UI/Widgets/UIButton_Base.h index 75caf99..e7367d7 100644 --- a/Source/ZMMO/Game/UI/Widgets/UIButton_Base.h +++ b/Source/ZMMO/Game/UI/Widgets/UIButton_Base.h @@ -150,11 +150,25 @@ public: 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: virtual void NativePreConstruct() override; virtual void NativeConstruct() override; virtual void NativeDestruct() override; + // Estados do UCommonButtonBase → repinta o Background pela variante. + virtual void NativeOnHovered() override; + 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. */ UFUNCTION(BlueprintImplementableEvent, Category = "UI Style", meta = (DisplayName = "Apply UI Style"))