247 lines
8.0 KiB
C++
247 lines
8.0 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Blueprint/UserWidget.h"
|
|
#include "SettingsMenuWidget.generated.h"
|
|
|
|
class UButton;
|
|
class UConfirmDialogWidget;
|
|
class UKeyCaptureWidget;
|
|
class USettingsTabWidget;
|
|
class UWidgetSwitcher;
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnSettingsCloseRequested);
|
|
|
|
/** Reponse a une demande de confirmation. bConfirmed est faux sur un refus ou une expiration. */
|
|
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnSettingsConfirmationResult, bool, bConfirmed);
|
|
|
|
/** Touche capturee. Invalide si le joueur a annule avec Echap. */
|
|
DECLARE_DYNAMIC_DELEGATE_OneParam(FOnSettingsKeyCaptureResult, FKey, CapturedKey);
|
|
|
|
/**
|
|
* L'ecran de reglages : une barre d'onglets, un WidgetSwitcher, Retour et
|
|
* Reinitialiser.
|
|
*
|
|
* Il ne sait PAS qui l'a ouvert. Il demande a se fermer via OnCloseRequested et
|
|
* c'est l'appelant -- menu principal ou menu de pause -- qui decide de ce que
|
|
* "Retour" veut dire. Sans ca il faudrait un ecran par contexte.
|
|
*
|
|
* Il ne connait pas davantage le contenu de ses onglets : il appelle
|
|
* RefreshFromSettings et ResetToDefaults sur USettingsTabWidget. Ajouter
|
|
* l'onglet Graphismes ne demandera aucune ligne ici.
|
|
*
|
|
* Classe Abstract : on cree un WBP_Settings qui en herite.
|
|
*/
|
|
UCLASS(Abstract)
|
|
class SURVIVAL_PROJET_API USettingsMenuWidget : public UUserWidget
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
USettingsMenuWidget(const FObjectInitializer& ObjectInitializer);
|
|
|
|
virtual void NativeConstruct() override;
|
|
virtual void NativeDestruct() override;
|
|
virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
|
|
|
|
UPROPERTY(BlueprintAssignable, Category = "Reglages")
|
|
FOnSettingsCloseRequested OnCloseRequested;
|
|
|
|
/**
|
|
* Affiche l'ecran, rafraichit l'onglet visible et prend le focus clavier.
|
|
*
|
|
* Passe par ici et jamais par SetVisibility : sans le focus, Echap ne
|
|
* refermerait pas l'ecran.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Reglages")
|
|
void Open();
|
|
|
|
/** Masque l'ecran et ecrit le fichier de reglages. */
|
|
UFUNCTION(BlueprintCallable, Category = "Reglages")
|
|
void Close();
|
|
|
|
/**
|
|
* ZOrder de la boite de confirmation, impose par celui qui ouvre l'ecran.
|
|
*
|
|
* L'ecran ne le choisit PAS lui-meme : il est ouvert depuis deux contextes
|
|
* dont les empilements n'ont rien a voir (50 au menu principal, 150 en jeu).
|
|
* Un numero code en dur ici obligerait le widget a savoir qui l'affiche,
|
|
* exactement ce qu'on evite avec OnCloseRequested. A appeler AVANT Open().
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Reglages")
|
|
void SetDialogZOrder(int32 InZOrder) { DialogZOrder = InZOrder; }
|
|
|
|
/**
|
|
* Pose une question au joueur pour le compte d'un onglet.
|
|
*
|
|
* L'ecran est le seul a posseder une boite : un onglet qui creerait la
|
|
* sienne devrait a son tour se demander a quel ZOrder la poser, et on
|
|
* repartirait pour un tour.
|
|
*
|
|
* @param MessageOrFormat texte simple, ou format contenant {0} si
|
|
* CountdownSeconds est superieur a zero.
|
|
* @param CountdownSeconds 0 pour une question sans limite de temps.
|
|
* @return false si aucune boite n'est configuree -- l'appelant doit alors
|
|
* decider seul, sa reponse n'arrivera jamais.
|
|
*/
|
|
bool RequestConfirmation(const FText& MessageOrFormat, float CountdownSeconds, const FOnSettingsConfirmationResult& OnResult);
|
|
|
|
/**
|
|
* Ouvre le voile de capture de touche pour le compte d'un onglet.
|
|
*
|
|
* Meme raison que la boite : un voile pose DANS l'onglet serait clippe a la
|
|
* zone du WidgetSwitcher au lieu de couvrir l'ecran, et devrait a son tour
|
|
* se trouver un ZOrder.
|
|
*
|
|
* @return false si aucun voile n'est configure -- la reponse n'arrivera
|
|
* jamais, l'appelant doit renoncer.
|
|
*/
|
|
bool RequestKeyCapture(const FText& ActionLabel, const FOnSettingsKeyCaptureResult& OnResult);
|
|
|
|
/**
|
|
* Bascule le voile deja ouvert sur la question de conflit.
|
|
*
|
|
* Le voile RESTE ouvert entre la capture et la reponse : c'est le meme geste
|
|
* pour le joueur, il n'a pas a le voir disparaitre puis revenir.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Reglages")
|
|
void ShowKeyCaptureConflict(const FText& Message, const FOnSettingsConfirmationResult& OnAnswer);
|
|
|
|
/** Referme le voile. A appeler quand le remappage est termine ou abandonne. */
|
|
UFUNCTION(BlueprintCallable, Category = "Reglages")
|
|
void CloseKeyCapture();
|
|
|
|
protected:
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UWidgetSwitcher> TabSwitcher;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> BackButton;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> ResetButton;
|
|
|
|
/**
|
|
* Les trois onglets qui existent sont OBLIGATOIRES : un WBP_Settings sans eux
|
|
* ne compile pas.
|
|
*
|
|
* BindWidgetOptional echoue en silence -- un nom mal orthographie donnait un
|
|
* bouton parfaitement inerte, sans le moindre message. Pour un element dont
|
|
* l'absence n'a aucun sens, on veut l'erreur a la compilation du Blueprint.
|
|
*/
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> GameplayTabButton;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> DisplayTabButton;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> GraphicsTabButton;
|
|
|
|
UPROPERTY(meta = (BindWidget))
|
|
TObjectPtr<UButton> ControlsTabButton;
|
|
|
|
/**
|
|
* Celui-la reste optionnel : sa page n'existe pas encore. Il passera en
|
|
* BindWidget le jour ou l'onglet Audio sera ecrit -- en attendant, il se
|
|
* grise tout seul si tu le poses.
|
|
*/
|
|
UPROPERTY(meta = (BindWidgetOptional))
|
|
TObjectPtr<UButton> AudioTabButton;
|
|
|
|
/**
|
|
* Ton WBP_ConfirmDialog, a renseigner dans les Class Defaults de
|
|
* WBP_Settings. Laisse-le vide et "Reinitialiser" agit sans rien demander.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Reglages")
|
|
TSubclassOf<UConfirmDialogWidget> ResetDialogClass;
|
|
|
|
/** La question posee avant de reinitialiser l'onglet visible. */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Reglages")
|
|
FText ResetDialogMessage;
|
|
|
|
/** Ton WBP_KeyCapture. Sans lui, l'onglet Touches ne peut rien remapper. */
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Reglages")
|
|
TSubclassOf<UKeyCaptureWidget> KeyCaptureClass;
|
|
|
|
UPROPERTY(Transient, BlueprintReadOnly, Category = "Reglages")
|
|
TObjectPtr<UConfirmDialogWidget> ResetDialog;
|
|
|
|
UPROPERTY(Transient, BlueprintReadOnly, Category = "Reglages")
|
|
TObjectPtr<UKeyCaptureWidget> KeyCapture;
|
|
|
|
private:
|
|
UFUNCTION()
|
|
void HandleBackClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleResetClicked();
|
|
|
|
/** Reponse a la question du bouton Reinitialiser. */
|
|
UFUNCTION()
|
|
void HandleResetAnswered(bool bConfirmed);
|
|
|
|
UFUNCTION()
|
|
void HandleDialogConfirmed();
|
|
|
|
UFUNCTION()
|
|
void HandleDialogCancelled();
|
|
|
|
/** Referme la boite et rend la reponse a qui a pose la question. */
|
|
void FinishConfirmation(bool bConfirmed);
|
|
|
|
/** Cree la boite au premier besoin. Renvoie nullptr si aucune classe n'est assignee. */
|
|
UConfirmDialogWidget* EnsureDialog();
|
|
|
|
UFUNCTION()
|
|
void HandleGameplayTabClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleDisplayTabClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleGraphicsTabClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleControlsTabClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleAudioTabClicked();
|
|
|
|
UFUNCTION()
|
|
void HandleKeyCaptured(FKey CapturedKey);
|
|
|
|
UFUNCTION()
|
|
void HandleKeyCaptureCancelled();
|
|
|
|
UFUNCTION()
|
|
void HandleKeyConflictAnswered(bool bConfirmed);
|
|
|
|
/** A qui rendre la reponse du conflit affiche dans le voile. */
|
|
FOnSettingsConfirmationResult PendingConflictAnswer;
|
|
|
|
/** Change de page et rafraichit la nouvelle. Ignore un index inexistant. */
|
|
void ShowTab(int32 Index);
|
|
|
|
/** La page actuellement affichee, ou nullptr si le switcher est vide. */
|
|
USettingsTabWidget* GetActiveTab() const;
|
|
|
|
/** Grise les boutons dont la page n'existe pas encore. */
|
|
void UpdateTabButtonStates();
|
|
|
|
/** A qui rendre la reponse de la boite ouverte. Vide quand rien n'est pose. */
|
|
FOnSettingsConfirmationResult PendingConfirmation;
|
|
|
|
/** A qui rendre la touche capturee. Vide quand le voile est ferme. */
|
|
FOnSettingsKeyCaptureResult PendingKeyCapture;
|
|
|
|
bool bResetDialogOpen = false;
|
|
|
|
bool bKeyCaptureOpen = false;
|
|
|
|
/** Valeur de repli si l'appelant oublie SetDialogZOrder : devant le fondu exclu. */
|
|
int32 DialogZOrder = 500;
|
|
};
|