feat/frontend-mainmenu-skeleton #1

Merged
Mateuus merged 25 commits from feat/frontend-mainmenu-skeleton into main 2026-05-19 02:06:48 -03:00
2 changed files with 179 additions and 0 deletions
Showing only changes of commit 01c74c7683 - Show all commits

View File

@@ -0,0 +1,114 @@
#include "UIPanel_Base.h"
#include "ZMMOThemeSubsystem.h"
#include "Engine/GameInstance.h"
#include "Components/Border.h"
#include "Components/NamedSlot.h"
#include "Styling/SlateBrush.h"
namespace
{
const FUIStyle& ResolvePanelStyle(const UUserWidget* Widget, const FUIStyle& Fallback)
{
if (Widget)
{
if (const UGameInstance* GI = Widget->GetGameInstance())
{
if (const UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
{
return Theme->GetActiveUIStyle();
}
}
}
return Fallback; // design-time: defaults Aurora Arcana
}
}
void UUIPanel_Base::RefreshUIStyle()
{
if (!Background)
{
return;
}
const FUIStyle Fallback;
const FUIStyle& AS = ResolvePanelStyle(this, Fallback);
const FUIStylePanel& P = AS.Panel;
FLinearColor Fill;
FLinearColor Outline = P.BorderColor;
switch (PanelType)
{
case EUIPanelType::Secondary: Fill = P.BgRaised; break;
case EUIPanelType::Tertiary: Fill = P.BgSunken; break;
case EUIPanelType::Card: Fill = P.CardSelectedBg; Outline = P.CardSelectedBorder; break;
case EUIPanelType::Primary:
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(Outline), P.BorderWidth);
Brush.OutlineSettings.RoundingType = ESlateBrushRoundingType::FixedRadius;
}
else
{
Brush.DrawAs = ESlateBrushDrawType::Box;
Brush.OutlineSettings = FSlateBrushOutlineSettings(
FVector4(0, 0, 0, 0), FSlateColor(Outline), P.BorderWidth);
}
Background->SetBrush(Brush);
Background->SetPadding(bUseSmallPadding ? P.PaddingSmall : P.Padding);
BP_ApplyPanelStyle(P);
}
void UUIPanel_Base::NativePreConstruct()
{
Super::NativePreConstruct();
RefreshUIStyle();
}
void UUIPanel_Base::NativeConstruct()
{
Super::NativeConstruct();
if (!bThemeBound)
{
if (const UGameInstance* GI = GetGameInstance())
{
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
{
Theme->OnThemeChanged.AddDynamic(this, &UUIPanel_Base::HandleThemeChanged);
bThemeBound = true;
}
}
}
RefreshUIStyle();
}
void UUIPanel_Base::NativeDestruct()
{
if (bThemeBound)
{
if (const UGameInstance* GI = GetGameInstance())
{
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
{
Theme->OnThemeChanged.RemoveDynamic(this, &UUIPanel_Base::HandleThemeChanged);
}
}
bThemeBound = false;
}
Super::NativeDestruct();
}
void UUIPanel_Base::HandleThemeChanged(FName /*NewThemeId*/)
{
RefreshUIStyle();
}

View File

@@ -0,0 +1,65 @@
#pragma once
#include "CoreMinimal.h"
#include "CommonUserWidget.h"
#include "UI/UIStyleTypes.h"
#include "UI/UIStyleTokens.h"
#include "UIPanel_Base.generated.h"
class UBorder;
class UNamedSlot;
/**
* Painel base do ZMMO — mesmo padrão do UUIButton_Base, mas container.
* Fundação CommonUI (UCommonUserWidget). Camada Abstract; o WBP concreto
* (UI_Panel_Master) herda DIRETO desta classe C++ (UMG não encadeia árvores
* de WBP — ver ARQUITETURA.md §3.3).
*
* Visual data-driven por FUIStyle.Panel (UZMMOThemeSubsystem). Designers
* injetam o conteúdo no NamedSlot "Content".
*/
UCLASS(Abstract, Blueprintable)
class ZMMO_API UUIPanel_Base : public UCommonUserWidget
{
GENERATED_BODY()
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;
/** Re-resolve os tokens do tema ativo e reaplica no Background. */
UFUNCTION(BlueprintCallable, Category = "UI Style")
void RefreshUIStyle();
protected:
virtual void NativePreConstruct() override;
virtual void NativeConstruct() override;
virtual void NativeDestruct() override;
/** Hook opcional: o WBP pode estender/sobrescrever a aplicação visual. */
UFUNCTION(BlueprintImplementableEvent, Category = "UI Style",
meta = (DisplayName = "Apply Panel Style"))
void BP_ApplyPanelStyle(const FUIStylePanel& Panel);
/** Widgets visuais opcionais. */
UPROPERTY(meta = (BindWidgetOptional))
TObjectPtr<UBorder> Background;
UPROPERTY(meta = (BindWidgetOptional))
TObjectPtr<UNamedSlot> Content;
private:
UFUNCTION()
void HandleThemeChanged(FName NewThemeId);
bool bThemeBound = false;
};