// Fill out your copyright notice in the Description page of Project Settings. #include "PauseMenuWidget.h" #include "Components/Button.h" #include "FpsPlayerController.h" UPauseMenuWidget::UPauseMenuWidget(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) { // Sans ce drapeau le widget ne peut pas prendre le focus clavier, et // NativeOnKeyDown ne serait jamais appele. Il ne se change qu'a la // construction, d'ou sa presence ici et pas dans Open(). SetIsFocusable(true); } void UPauseMenuWidget::NativeConstruct() { Super::NativeConstruct(); if (ResumeButton) { ResumeButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleResumeClicked); } if (QuitToMenuButton) { QuitToMenuButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleQuitToMenuClicked); } if (SettingsButton) { SettingsButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleSettingsClicked); } if (InviteButton) { InviteButton->OnClicked.AddDynamic(this, &UPauseMenuWidget::HandleInviteClicked); // Evalue une seule fois : le menu de pause n'est construit qu'a la // premiere ouverture, donc bien apres que la session ait reussi ou // echoue. Rien ne peut plus changer cet etat en cours de partie. const AFpsPlayerController* Controller = GetOwningPlayer(); InviteButton->SetIsEnabled(Controller && Controller->CanInviteFriends()); } } void UPauseMenuWidget::NativeDestruct() { if (ResumeButton) { ResumeButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleResumeClicked); } if (SettingsButton) { SettingsButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleSettingsClicked); } if (QuitToMenuButton) { QuitToMenuButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleQuitToMenuClicked); } if (InviteButton) { InviteButton->OnClicked.RemoveDynamic(this, &UPauseMenuWidget::HandleInviteClicked); } Super::NativeDestruct(); } void UPauseMenuWidget::Open() { SetInteractive(true); } void UPauseMenuWidget::Close() { SetVisibility(ESlateVisibility::Collapsed); } void UPauseMenuWidget::SetInteractive(bool bInteractive) { // HitTestInvisible et non Collapsed : le menu reste lisible derriere l'ecran // qui passe devant, mais on ne peut plus cliquer Reprendre a travers. SetVisibility(bInteractive ? ESlateVisibility::Visible : ESlateVisibility::HitTestInvisible); if (bInteractive) { // Le focus doit etre repris a CHAQUE fois que le menu redevient la couche // active, pas seulement a sa premiere ouverture : l'ecran de reglages et // la boite de confirmation le prennent pour eux et ne le rendent pas. SetKeyboardFocus(); } } FReply UPauseMenuWidget::NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) { const FKey Key = InKeyEvent.GetKey(); // GetVirtualKey() et non la constante, depreciee en 5.8 : la resolution se // fait a l'appel, donc selon la manette reellement branchee. if (Key == EKeys::Escape || Key == EKeys::Virtual_Gamepad_Back.GetVirtualKey()) { if (AFpsPlayerController* Controller = GetOwningPlayer()) { // HandleEscapeInput et non ResumeGame : c'est le controller qui tient // la priorite entre boite, reglages, coffre, inventaire et pause. Un // second chemin qui refermerait directement le menu laisserait // l'ecran pose par-dessus affiche dans le vide. Controller->HandleEscapeInput(); // Handled : sans ca la touche continue de remonter et serait // consommee une seconde fois par ce qui se trouve derriere. return FReply::Handled(); } } return Super::NativeOnKeyDown(InGeometry, InKeyEvent); } void UPauseMenuWidget::HandleSettingsClicked() { if (AFpsPlayerController* Controller = GetOwningPlayer()) { Controller->OpenSettings(); } } void UPauseMenuWidget::HandleResumeClicked() { if (AFpsPlayerController* Controller = GetOwningPlayer()) { Controller->ResumeGame(); } } void UPauseMenuWidget::HandleQuitToMenuClicked() { if (AFpsPlayerController* Controller = GetOwningPlayer()) { Controller->RequestQuitToMainMenu(); } } void UPauseMenuWidget::HandleInviteClicked() { if (AFpsPlayerController* Controller = GetOwningPlayer()) { Controller->ShowInviteFriends(); } }