Files
Unreal_EmberWild/Source/Survival_projet/Private/SettingRowWidget.cpp
T
2026-07-28 14:10:17 +02:00

165 lines
4.2 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "SettingRowWidget.h"
#include "Components/Button.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"
void USettingRowWidget::NativeOnInitialized()
{
Super::NativeOnInitialized();
// NativeOnInitialized et non NativeConstruct : l'onglet parent appelle
// SetupAs... depuis SON NativeConstruct, et rien ne garantit l'ordre entre
// le construct du parent et celui de ses enfants. Initialize, lui, tourne
// une seule fois a la creation de l'arbre, avant tout le monde.
if (LeftArrowButton)
{
LeftArrowButton->OnClicked.AddDynamic(this, &USettingRowWidget::HandleLeftClicked);
}
if (RightArrowButton)
{
RightArrowButton->OnClicked.AddDynamic(this, &USettingRowWidget::HandleRightClicked);
}
}
void USettingRowWidget::SetupAsChoice(const FText& Label, const TArray<FText>& Options, int32 Index)
{
bNumeric = false;
ChoiceLabels = Options;
StepCount = FMath::Max(Options.Num(), 1);
CurrentIndex = FMath::Clamp(Index, 0, StepCount - 1);
if (LabelText)
{
LabelText->SetText(Label);
}
// Une barre de remplissage sur "Maintien / Bascule" ne veut rien dire : elle
// serait vide ou pleine sans que ca informe de quoi que ce soit. On la
// masque plutot que d'imposer un second WBP juste pour les choix.
if (ValueBar)
{
ValueBar->SetVisibility(ESlateVisibility::Collapsed);
}
Refresh();
}
void USettingRowWidget::SetupAsNumber(const FText& Label, float Min, float Max, float Step, float Value, const FText& Suffix)
{
bNumeric = true;
ChoiceLabels.Reset();
NumericMin = Min;
NumericStep = FMath::Max(Step, KINDA_SMALL_NUMBER);
NumericSuffix = Suffix;
// +1 : les deux extremites comptent. 70 a 120 par 5 fait 11 paliers, pas 10.
StepCount = FMath::Max(FMath::FloorToInt((Max - Min) / NumericStep) + 1, 1);
if (LabelText)
{
LabelText->SetText(Label);
}
// HitTestInvisible et non Visible : la barre est un decor, elle ne doit pas
// intercepter les clics destines aux fleches qui l'encadrent.
if (ValueBar)
{
ValueBar->SetVisibility(ESlateVisibility::HitTestInvisible);
}
SetNumericValueSilently(Value);
}
float USettingRowWidget::GetNumericValue() const
{
return NumericMin + CurrentIndex * NumericStep;
}
void USettingRowWidget::SetIndexSilently(int32 NewIndex)
{
CurrentIndex = FMath::Clamp(NewIndex, 0, StepCount - 1);
Refresh();
}
void USettingRowWidget::SetNumericValueSilently(float Value)
{
SetIndexSilently(FMath::RoundToInt((Value - NumericMin) / NumericStep));
}
void USettingRowWidget::HandleLeftClicked()
{
StepIndex(-1);
}
void USettingRowWidget::HandleRightClicked()
{
StepIndex(1);
}
void USettingRowWidget::StepIndex(int32 Delta)
{
const int32 NewIndex = FMath::Clamp(CurrentIndex + Delta, 0, StepCount - 1);
// Pas de bouclage, volontairement : passer de 100 a 5 de sensibilite d'un
// clic de trop rendrait le jeu injouable sans qu'on comprenne pourquoi.
if (NewIndex == CurrentIndex)
{
return;
}
CurrentIndex = NewIndex;
Refresh();
OnIndexChanged.Broadcast(CurrentIndex);
}
void USettingRowWidget::Refresh()
{
if (ValueText)
{
if (bNumeric)
{
FNumberFormattingOptions Format;
Format.MaximumFractionalDigits = 0;
const FText Number = FText::AsNumber(GetNumericValue(), &Format);
// FormatOrdered plutot qu'une concatenation : selon la langue, l'unite
// ne se colle pas forcement du meme cote ni avec la meme espace.
ValueText->SetText(NumericSuffix.IsEmpty()
? Number
: FText::FormatOrdered(NSLOCTEXT("Reglages", "ValeurAvecUnite", "{0}{1}"), Number, NumericSuffix));
}
else if (ChoiceLabels.IsValidIndex(CurrentIndex))
{
ValueText->SetText(ChoiceLabels[CurrentIndex]);
}
}
if (ValueBar)
{
// Un seul palier : la barre n'a aucun sens, on la remplit entierement
// plutot que de diviser par zero.
ValueBar->SetPercent(StepCount > 1
? static_cast<float>(CurrentIndex) / static_cast<float>(StepCount - 1)
: 1.f);
}
// Les fleches se grisent aux extremites : le joueur voit qu'il est au bout
// au lieu de cliquer dans le vide.
if (LeftArrowButton)
{
LeftArrowButton->SetIsEnabled(CurrentIndex > 0);
}
if (RightArrowButton)
{
RightArrowButton->SetIsEnabled(CurrentIndex < StepCount - 1);
}
}