diff --git a/Content/ZMMO/Data/UI/DT_UI_Styles.uasset b/Content/ZMMO/Data/UI/DT_UI_Styles.uasset index 4db4ab4..edf9ca2 100644 Binary files a/Content/ZMMO/Data/UI/DT_UI_Styles.uasset and b/Content/ZMMO/Data/UI/DT_UI_Styles.uasset differ diff --git a/Content/ZMMO/UI/Shared/UI_ProgressBar_Master.uasset b/Content/ZMMO/UI/Shared/UI_ProgressBar_Master.uasset index ad5ed14..708bc69 100644 Binary files a/Content/ZMMO/UI/Shared/UI_ProgressBar_Master.uasset and b/Content/ZMMO/UI/Shared/UI_ProgressBar_Master.uasset differ diff --git a/Source/ZMMO/Data/UI/UIStyleTokens.h b/Source/ZMMO/Data/UI/UIStyleTokens.h index c048a58..65db1b2 100644 --- a/Source/ZMMO/Data/UI/UIStyleTokens.h +++ b/Source/ZMMO/Data/UI/UIStyleTokens.h @@ -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 FillMaterial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials") + TObjectPtr BackgroundMaterial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials") + TObjectPtr TrackGridMaterial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials") + TObjectPtr EdgeMaterial; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "UI Style|ProgressBar|Materials") + TObjectPtr 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 FillByType; + TMap Variants; }; USTRUCT(BlueprintType) diff --git a/Source/ZMMO/Data/UI/UIStyleTypes.h b/Source/ZMMO/Data/UI/UIStyleTypes.h index ffcef81..029850e 100644 --- a/Source/ZMMO/Data/UI/UIStyleTypes.h +++ b/Source/ZMMO/Data/UI/UIStyleTypes.h @@ -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 { diff --git a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp index 11bee67..b4e5045 100644 --- a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp +++ b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.cpp @@ -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()) + { + return Theme->GetActiveUIStyle(); + } + } + } + // Design-time fallback: lê DT_UI_Styles row "Default" direto do disk. + if (const UDataTable* DT = LoadObject(nullptr, + TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles"))) + { + if (const FUIStyleRow* Row = DT->FindRow( + FName(TEXT("Default")), TEXT("UIProgressBarDesign"), false)) + { + return Row->Style; + } + } + return FUIStyle(); + } + + TArray CollectVariantOptions() + { + TArray Options; + Options.Add(FString()); // entrada vazia = sem theme + const UDataTable* DT = LoadObject(nullptr, + TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles")); + if (!DT) return Options; + const FUIStyleRow* Row = DT->FindRow( + FName(TEXT("Default")), TEXT("UIProgressBarGetOptions"), false); + if (!Row) return Options; + for (const TPair& 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()) + { + 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()) + { + 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 UUIProgressBar_Base::GetProgressBarVariantOptions() const +{ + return CollectVariantOptions(); +} diff --git a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.h b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.h index 643dd29..e04dde7 100644 --- a/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.h +++ b/Source/ZMMO/Game/UI/Widgets/UIProgressBar_Base.h @@ -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 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;