// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "SettingRowWidget.generated.h" class UButton; class UProgressBar; class UTextBlock; DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSettingRowIndexChanged, int32, NewIndex); /** * Une ligne de reglage : un libelle, une fleche gauche, une valeur, une fleche * droite, et une barre de remplissage optionnelle derriere la valeur. * * TOUT reglage est ramene a un index dans une liste de paliers, y compris les * nombres : "Champ de vision, 70 a 120 par pas de 5" devient un index de 0 a 10. * La ligne ne connait donc jamais que CurrentIndex et StepCount, et c'est ce qui * permet de n'avoir qu'UN SEUL WBP a dessiner pour tout le menu, qu'il s'agisse * d'un choix (Maintien / Bascule) ou d'une valeur continue. * * Elle ne sait pas ce qu'elle regle : elle previent via OnIndexChanged, et c'est * l'onglet qui traduit l'index en appel sur USurvivalUserSettings. Meme principe * que UConfirmDialogWidget, qui ignore ce qu'il confirme. * * Classe Abstract : on cree un WBP_SettingRow qui en herite. */ UCLASS(Abstract) class SURVIVAL_PROJET_API USettingRowWidget : public UUserWidget { GENERATED_BODY() public: virtual void NativeOnInitialized() override; /** Previent d'un changement venant du joueur, jamais d'un rafraichissement. */ UPROPERTY(BlueprintAssignable, Category = "Reglages") FOnSettingRowIndexChanged OnIndexChanged; /** * Mode choix : la valeur affichee est prise telle quelle dans Options. * Sert aussi bien a un oui/non qu'a une liste de qualites. */ UFUNCTION(BlueprintCallable, Category = "Reglages") void SetupAsChoice(const FText& Label, const TArray& Options, int32 Index); /** * Mode nombre : la valeur affichee est calculee a partir de l'index. * Suffix sert aux unites ("%", "°") et peut rester vide. */ UFUNCTION(BlueprintCallable, Category = "Reglages") void SetupAsNumber(const FText& Label, float Min, float Max, float Step, float Value, const FText& Suffix); UFUNCTION(BlueprintPure, Category = "Reglages") int32 GetIndex() const { return CurrentIndex; } /** Reconvertit l'index en valeur reelle. Sans objet en mode choix. */ UFUNCTION(BlueprintPure, Category = "Reglages") float GetNumericValue() const; /** * Repositionne la ligne sans rien diffuser. * * A utiliser pour tout rafraichissement venant des reglages : diffuser ici * ferait boucler l'onglet sur lui-meme (il reecrit le reglage, qui rafraichit * la ligne, qui rediffuse...). */ UFUNCTION(BlueprintCallable, Category = "Reglages") void SetIndexSilently(int32 NewIndex); /** Repositionne la ligne sur une valeur reelle, sans rien diffuser. */ UFUNCTION(BlueprintCallable, Category = "Reglages") void SetNumericValueSilently(float Value); protected: UPROPERTY(meta = (BindWidget)) TObjectPtr LabelText; UPROPERTY(meta = (BindWidget)) TObjectPtr ValueText; UPROPERTY(meta = (BindWidget)) TObjectPtr LeftArrowButton; UPROPERTY(meta = (BindWidget)) TObjectPtr RightArrowButton; /** * Facultative : une ligne de choix (Maintien / Bascule) n'a rien a remplir. * Volontairement une ProgressBar et non un Slider : la barre montre ou l'on * en est, ce sont les fleches qui reglent. Un slider glissable produirait des * valeurs entre deux paliers que le setter refuserait ensuite. */ UPROPERTY(meta = (BindWidgetOptional)) TObjectPtr ValueBar; private: UFUNCTION() void HandleLeftClicked(); UFUNCTION() void HandleRightClicked(); /** Deplace l'index de Delta paliers et diffuse, si le mouvement est possible. */ void StepIndex(int32 Delta); /** Reecrit le texte, la barre et l'etat des deux fleches. */ void Refresh(); /** Vide en mode nombre. */ TArray ChoiceLabels; FText NumericSuffix; float NumericMin = 0.f; float NumericStep = 1.f; int32 CurrentIndex = 0; /** Nombre de paliers, donc d'index valides. Toujours au moins 1. */ int32 StepCount = 1; bool bNumeric = false; };