feat(ui/progressbar): integracao com DT_UI_Styles (FUIStyleProgressBar multi-map + Variant)
FUIStyleProgressBar vira multi-map Hyper-style: TMap<FName, FUIStyleProgressBarVariant> indexado por variante (HP/MP/XP/Cast/...). Cada variante carrega materiais por layer (Fill/BG/TrackGrid/Edge/Shimmer) + style (DrawStyle/CornerRadius/Border) + toggles de efeito. UUIProgressBar_Base ganha bUseTheme + Variant (dropdown via meta=GetOptions resolvendo o DT) + RefreshUIStyle() que aplica a variante via ThemeSubsystem (runtime) ou DT direto (design-time), espelhando o padrao do UUIPanel_Base. HandleThemeChanged reaplica em troca de tema. EUIProgressBarStyle movido de UIProgressBar_Base.h para UIStyleTypes.h (usado pela struct do DT). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -374,29 +374,78 @@ struct ZMMO_API FUIStyleBorders
|
||||
float RuleSoftThickness = 1.f;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variante completa de ProgressBar: materiais por layer (Fill/BG/Track/Edge/Shimmer)
|
||||
* + parametros visuais (DrawStyle, CornerRadius, Border) + toggles de efeito.
|
||||
*
|
||||
* Material nulo = nao sobrescreve o brush do WBP (usa o que esta atribuido la).
|
||||
* Aplicada pelo UUIProgressBar_Base quando bUseTheme=true via Variant FName.
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleProgressBarVariant
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// ---- Materiais (opcionais; nullptr = mantem brush do WBP) ----
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials")
|
||||
TObjectPtr<UMaterialInterface> FillMaterial;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials")
|
||||
TObjectPtr<UMaterialInterface> BackgroundMaterial;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials")
|
||||
TObjectPtr<UMaterialInterface> TrackGridMaterial;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials")
|
||||
TObjectPtr<UMaterialInterface> EdgeMaterial;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials")
|
||||
TObjectPtr<UMaterialInterface> ShimmerMaterial;
|
||||
|
||||
// ---- Style (forma + bordas) ----
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Style")
|
||||
EUIProgressBarStyle DrawStyle = EUIProgressBarStyle::Rounded;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Style",
|
||||
meta = (ClampMin = "0", ClampMax = "100"))
|
||||
float CornerRadius = 8.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Style")
|
||||
bool bShowBorder = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Style")
|
||||
FLinearColor BorderColour = FLinearColor(0.f, 0.f, 0.f, 0.8f);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Style",
|
||||
meta = (ClampMin = "0", ClampMax = "10"))
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
// ---- Toggles de efeito ----
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Effects")
|
||||
bool bShowTrackGrid = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Effects")
|
||||
bool bShowEdge = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Effects")
|
||||
bool bShowShimmer = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* ProgressBar — padrao multi-map Hyper-style. Variantes (HP/MP/XP/Cast/...) sao
|
||||
* editadas direto no DT_UI_Styles; cada UUIProgressBar_Base referencia uma key
|
||||
* FName (dropdown via meta=GetOptions resolve esse mapa em runtime+editor).
|
||||
*/
|
||||
USTRUCT(BlueprintType)
|
||||
struct ZMMO_API FUIStyleProgressBar
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
FLinearColor TrackColor = FLinearColor(FColor(14, 20, 36)); // Panel3
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
FLinearColor BorderColor = FLinearColor(FColor(58, 75, 120, 140));
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float Height = 10.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float CornerRadius = 6.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
float BorderWidth = 1.f;
|
||||
|
||||
/** Cor de preenchimento por tipo (Health/Mana/XP...). */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar")
|
||||
TMap<EUIProgressBarType, FLinearColor> FillByType;
|
||||
TMap<FName, FUIStyleProgressBarVariant> Variants;
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
|
||||
@@ -81,6 +81,16 @@ enum class EUIProgressBarType : uint8
|
||||
Generic UMETA(DisplayName = "Generic")
|
||||
};
|
||||
|
||||
/** Preset que controla Brush.DrawAs em todos os UImages da ProgressBar. */
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIProgressBarStyle : uint8
|
||||
{
|
||||
/** DrawAs=Image. Sem mascara nos cantos. */
|
||||
Box UMETA(DisplayName = "Box"),
|
||||
/** DrawAs=RoundedBox. Cantos arredondados via Slate nativo (pixel-perfect). */
|
||||
Rounded UMETA(DisplayName = "Rounded"),
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIHeaderType : uint8
|
||||
{
|
||||
|
||||
@@ -2,10 +2,15 @@
|
||||
|
||||
#include "Components/Image.h"
|
||||
#include "Components/OverlaySlot.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "Engine/GameInstance.h"
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "Materials/MaterialInterface.h"
|
||||
#include "Styling/SlateBrush.h"
|
||||
#include "Styling/SlateTypes.h"
|
||||
#include "UI/UIStyleRow.h"
|
||||
#include "UI/UIStyleTokens.h"
|
||||
#include "ZMMOThemeSubsystem.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -46,6 +51,50 @@ namespace
|
||||
{
|
||||
return 1.f - FMath::Pow(1.f - Alpha, 3.f);
|
||||
}
|
||||
|
||||
/** Resolve a FUIStyle ativa — runtime via ThemeSubsystem, design-time via DT direto. */
|
||||
FUIStyle ResolveProgressBarStyle(const UUserWidget* Widget)
|
||||
{
|
||||
if (Widget)
|
||||
{
|
||||
if (const UGameInstance* GI = Widget->GetGameInstance())
|
||||
{
|
||||
if (const UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
||||
{
|
||||
return Theme->GetActiveUIStyle();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Design-time fallback: lê DT_UI_Styles row "Default" direto do disk.
|
||||
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("UIProgressBarDesign"), false))
|
||||
{
|
||||
return Row->Style;
|
||||
}
|
||||
}
|
||||
return FUIStyle();
|
||||
}
|
||||
|
||||
TArray<FString> CollectVariantOptions()
|
||||
{
|
||||
TArray<FString> Options;
|
||||
Options.Add(FString()); // entrada vazia = sem theme
|
||||
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("UIProgressBarGetOptions"), false);
|
||||
if (!Row) return Options;
|
||||
for (const TPair<FName, FUIStyleProgressBarVariant>& Pair : Row->Style.ProgressBar.Variants)
|
||||
{
|
||||
Options.Add(Pair.Key.ToString());
|
||||
}
|
||||
Options.Sort();
|
||||
return Options;
|
||||
}
|
||||
}
|
||||
|
||||
void UUIProgressBar_Base::NativePreConstruct()
|
||||
@@ -64,9 +113,16 @@ void UUIProgressBar_Base::NativePreConstruct()
|
||||
SecondaryElapsed = 0.f;
|
||||
bAnimatingSecondary = false;
|
||||
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
if (bUseTheme)
|
||||
{
|
||||
RefreshUIStyle();
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
}
|
||||
ApplyPrimaryToMID(CurrentPrimaryLevel);
|
||||
ApplySecondaryToMID(CurrentSecondaryLevel);
|
||||
}
|
||||
@@ -75,13 +131,56 @@ void UUIProgressBar_Base::NativeConstruct()
|
||||
{
|
||||
Super::NativeConstruct();
|
||||
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
if (!bThemeBound)
|
||||
{
|
||||
if (const UGameInstance* GI = GetGameInstance())
|
||||
{
|
||||
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
||||
{
|
||||
Theme->OnThemeChanged.AddDynamic(this, &UUIProgressBar_Base::HandleThemeChanged);
|
||||
bThemeBound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bUseTheme)
|
||||
{
|
||||
RefreshUIStyle();
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
}
|
||||
ApplyPrimaryToMID(CurrentPrimaryLevel);
|
||||
ApplySecondaryToMID(CurrentSecondaryLevel);
|
||||
}
|
||||
|
||||
void UUIProgressBar_Base::NativeDestruct()
|
||||
{
|
||||
if (bThemeBound)
|
||||
{
|
||||
if (const UGameInstance* GI = GetGameInstance())
|
||||
{
|
||||
if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
|
||||
{
|
||||
Theme->OnThemeChanged.RemoveDynamic(this, &UUIProgressBar_Base::HandleThemeChanged);
|
||||
}
|
||||
}
|
||||
bThemeBound = false;
|
||||
}
|
||||
Super::NativeDestruct();
|
||||
}
|
||||
|
||||
void UUIProgressBar_Base::HandleThemeChanged(FName /*NewThemeId*/)
|
||||
{
|
||||
if (bUseTheme)
|
||||
{
|
||||
RefreshUIStyle();
|
||||
}
|
||||
}
|
||||
|
||||
void UUIProgressBar_Base::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
|
||||
{
|
||||
Super::NativeTick(MyGeometry, InDeltaTime);
|
||||
@@ -584,3 +683,79 @@ void UUIProgressBar_Base::ApplySecondaryToMID(float Value)
|
||||
FillMID->SetScalarParameterValue(P_SecondaryLevel, Value);
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================
|
||||
// Theme integration (bUseTheme + Variant)
|
||||
// =====================================================================
|
||||
|
||||
void UUIProgressBar_Base::RefreshUIStyle()
|
||||
{
|
||||
if (!bUseTheme || Variant.IsNone())
|
||||
{
|
||||
// Fallback: comportamento manual.
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
return;
|
||||
}
|
||||
const FUIStyle ActiveStyle = ResolveProgressBarStyle(this);
|
||||
const FUIStyleProgressBarVariant* V = ActiveStyle.ProgressBar.Variants.Find(Variant);
|
||||
if (!V)
|
||||
{
|
||||
// Variante não existe no DT — fallback manual.
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
ApplyMaterialOverrides();
|
||||
return;
|
||||
}
|
||||
ApplyThemeVariant(*V);
|
||||
}
|
||||
|
||||
void UUIProgressBar_Base::ApplyThemeVariant(const FUIStyleProgressBarVariant& V)
|
||||
{
|
||||
// Style — copia pros campos do widget e re-aplica brush.
|
||||
DrawStyle = V.DrawStyle;
|
||||
CornerRadius = V.CornerRadius;
|
||||
bShowBorder = V.bShowBorder;
|
||||
BorderColour = V.BorderColour;
|
||||
BorderWidth = V.BorderWidth;
|
||||
|
||||
// Toggles de efeito
|
||||
bShowTrackGrid = V.bShowTrackGrid;
|
||||
bShowEdge = V.bShowEdge;
|
||||
bShowShimmer = V.bShowShimmer;
|
||||
|
||||
// Troca materiais nos brushes quando definidos. Reseta MIDs cacheados pra
|
||||
// que EnsureMIDs() pegue o material novo na próxima chamada.
|
||||
auto AssignMaterial = [](UImage* Img, UMaterialInterface* Mat)
|
||||
{
|
||||
if (!Img || !Mat) return;
|
||||
FSlateBrush B = Img->GetBrush();
|
||||
if (B.GetResourceObject() != Mat)
|
||||
{
|
||||
B.SetResourceObject(Mat);
|
||||
B.DrawAs = ESlateBrushDrawType::Image; // reset; ApplyBrushStyle re-aplica
|
||||
Img->SetBrush(B);
|
||||
}
|
||||
};
|
||||
if (V.FillMaterial) { AssignMaterial(FillImage, V.FillMaterial); FillMID = nullptr; }
|
||||
if (V.BackgroundMaterial) { AssignMaterial(BackgroundImage, V.BackgroundMaterial); BackgroundMID = nullptr; }
|
||||
if (V.TrackGridMaterial) { AssignMaterial(TrackGridImage, V.TrackGridMaterial); TrackGridMID = nullptr; }
|
||||
if (V.EdgeMaterial) { AssignMaterial(EdgeImage, V.EdgeMaterial); EdgeMID = nullptr; }
|
||||
if (V.ShimmerMaterial) { AssignMaterial(ShimmerImage, V.ShimmerMaterial); ShimmerMID = nullptr; }
|
||||
|
||||
ApplyBrushStyle();
|
||||
EnsureMIDs();
|
||||
// Quando vem do tema, ignora os bOverride* individuais — variante já é a
|
||||
// fonte da verdade. Cores são definidas pela MI atribuída ao brush.
|
||||
|
||||
// Aplica visibility dos toggles
|
||||
if (TrackGridImage) TrackGridImage->SetVisibility(bShowTrackGrid ? ESlateVisibility::HitTestInvisible : ESlateVisibility::Collapsed);
|
||||
if (ShimmerImage) ShimmerImage->SetVisibility(bShowShimmer ? ESlateVisibility::HitTestInvisible : ESlateVisibility::Collapsed);
|
||||
UpdateEdgeVisibility();
|
||||
}
|
||||
|
||||
TArray<FString> UUIProgressBar_Base::GetProgressBarVariantOptions() const
|
||||
{
|
||||
return CollectVariantOptions();
|
||||
}
|
||||
|
||||
@@ -2,20 +2,12 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CommonUserWidget.h"
|
||||
#include "UI/UIStyleTypes.h"
|
||||
#include "UIProgressBar_Base.generated.h"
|
||||
|
||||
class UImage;
|
||||
class UMaterialInstanceDynamic;
|
||||
|
||||
/** Preset que controla Brush.DrawAs (Image=Box, RoundedBox=Rounded) em ambos os widgets. */
|
||||
UENUM(BlueprintType)
|
||||
enum class EUIProgressBarStyle : uint8
|
||||
{
|
||||
/** DrawAs=Image. Sem mascara nos cantos. */
|
||||
Box UMETA(DisplayName = "Box"),
|
||||
/** DrawAs=RoundedBox. Cantos arredondados via Slate nativo (pixel-perfect). */
|
||||
Rounded UMETA(DisplayName = "Rounded"),
|
||||
};
|
||||
struct FUIStyleProgressBarVariant;
|
||||
|
||||
/**
|
||||
* ProgressBar do ZMMO. Wrappa um UImage (FillImage) + UImage de background
|
||||
@@ -33,6 +25,35 @@ class ZMMO_API UUIProgressBar_Base : public UCommonUserWidget
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// === Theme (DT_UI_Styles integration) ===
|
||||
|
||||
/**
|
||||
* true = le toda a config visual (materiais + style + toggles) do
|
||||
* DT_UI_Styles (FUIStyleProgressBar.Variants[Variant]). Tema
|
||||
* centralizado, ignora as UPROPERTYs override individuais abaixo.
|
||||
* false = ignora a DT, usa apenas as UPROPERTYs/toggles do widget.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Theme")
|
||||
bool bUseTheme = false;
|
||||
|
||||
/**
|
||||
* Chave da variante (HP/MP/XP/Cast/...). Dropdown popula via
|
||||
* meta=GetOptions lendo DT_UI_Styles.Default.ProgressBar.Variants. Vazio
|
||||
* = sem theme aplicado (igual bUseTheme=false).
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Theme",
|
||||
meta = (EditCondition = "bUseTheme", EditConditionHides,
|
||||
GetOptions = "GetProgressBarVariantOptions"))
|
||||
FName Variant;
|
||||
|
||||
/** Re-resolve a variante atual e reaplica nos widgets. */
|
||||
UFUNCTION(BlueprintCallable, Category = "ProgressBar|Theme")
|
||||
void RefreshUIStyle();
|
||||
|
||||
/** Populador do dropdown (meta=GetOptions) das variantes. */
|
||||
UFUNCTION()
|
||||
TArray<FString> GetProgressBarVariantOptions() const;
|
||||
|
||||
// === Levels ===
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar",
|
||||
@@ -384,6 +405,7 @@ public:
|
||||
protected:
|
||||
virtual void NativePreConstruct() override;
|
||||
virtual void NativeConstruct() override;
|
||||
virtual void NativeDestruct() override;
|
||||
virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
|
||||
|
||||
UPROPERTY(meta = (BindWidget))
|
||||
@@ -423,6 +445,12 @@ private:
|
||||
void ApplyMaterialOverrides();
|
||||
void ApplyBrushStyle();
|
||||
void UpdateEdgeVisibility();
|
||||
void ApplyThemeVariant(const FUIStyleProgressBarVariant& Variant);
|
||||
|
||||
UFUNCTION()
|
||||
void HandleThemeChanged(FName NewThemeId);
|
||||
|
||||
bool bThemeBound = false;
|
||||
|
||||
float CurrentPrimaryLevel = 1.f;
|
||||
float TargetPrimaryLevel = 1.f;
|
||||
|
||||
Reference in New Issue
Block a user