Stabilize investor frontend entry

This commit is contained in:
2026-05-19 20:46:09 -07:00
parent d59f613e2b
commit d2b8185333
9 changed files with 169 additions and 47 deletions
@@ -17,22 +17,6 @@
#include "Styling/CoreStyle.h"
#include "TimerManager.h"
namespace
{
FButtonStyle MakeAgrarianButtonStyle(const FLinearColor& NormalColor, const FLinearColor& HoveredColor)
{
FButtonStyle ButtonStyle = FCoreStyle::Get().GetWidgetStyle<FButtonStyle>(TEXT("Button"));
ButtonStyle.Normal.TintColor = FSlateColor(NormalColor);
ButtonStyle.Hovered.TintColor = FSlateColor(HoveredColor);
ButtonStyle.Pressed.TintColor = FSlateColor(FLinearColor(
FMath::Min(HoveredColor.R + 0.12f, 1.0f),
FMath::Min(HoveredColor.G + 0.12f, 1.0f),
FMath::Min(HoveredColor.B + 0.12f, 1.0f),
HoveredColor.A));
return ButtonStyle;
}
}
void UAgrarianMvpFrontendWidget::NativeConstruct()
{
Super::NativeConstruct();
@@ -175,7 +159,7 @@ void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
{
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
{
SetActiveScreen(EAgrarianMvpFrontendScreen::JoinServer);
CompleteFrontendFlow();
return;
}
@@ -201,11 +185,6 @@ void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
CompleteFrontendFlow();
return;
}
if (ActiveScreen == EAgrarianMvpFrontendScreen::SavingAndQuit)
{
return;
}
}
void UAgrarianMvpFrontendWidget::ReturnFromActiveScreen()
@@ -226,7 +205,7 @@ void UAgrarianMvpFrontendWidget::CompleteFrontendFlow()
{
if (APlayerController* PlayerController = GetOwningPlayer())
{
if (ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection || ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
{
PlayerController->ConsoleCommand(SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale
? TEXT("AgrarianSelectCharacter female")
@@ -291,7 +270,6 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
AddText(Panel, FText::FromString(TEXT("Gameplay is paused while this menu is active.")), FMath::RoundToInt(22.0f * Scale), false, MutedTextColor, 72.0f * Scale);
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Resume")), ButtonColor, ButtonHoverColor, 16.0f * Scale);
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
PrimaryFocusButton->OnHovered.AddDynamic(this, &UAgrarianMvpFrontendWidget::FocusPrimaryButton);
UButton* QuitButton = AddButton(Panel, FText::FromString(TEXT("Save & Quit")), QuitButtonColor, FLinearColor(0.58f, 0.28f, 0.22f, 1.0f), 34.0f * Scale);
QuitButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked);
@@ -314,7 +292,7 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
const bool bMaleSelected = SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultMale;
const bool bFemaleSelected = SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale;
UButton* MaleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("MalePioneerButton"));
MaleButton->SetStyle(MakeAgrarianButtonStyle(bMaleSelected ? ButtonHoverColor : SecondaryButtonColor, ButtonHoverColor));
MaleButton->SetBackgroundColor(bMaleSelected ? ButtonHoverColor : SecondaryButtonColor);
MaleButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked);
UVerticalBox* MaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("MalePioneerStack"));
MaleButton->SetContent(MaleStack);
@@ -328,7 +306,7 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
}
UButton* FemaleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("FemalePioneerButton"));
FemaleButton->SetStyle(MakeAgrarianButtonStyle(bFemaleSelected ? ButtonHoverColor : SecondaryButtonColor, ButtonHoverColor));
FemaleButton->SetBackgroundColor(bFemaleSelected ? ButtonHoverColor : SecondaryButtonColor);
FemaleButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked);
UVerticalBox* FemaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("FemalePioneerStack"));
FemaleButton->SetContent(FemaleStack);
@@ -341,9 +319,8 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
FemaleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
}
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Continue")), ButtonColor, ButtonHoverColor, 10.0f * Scale);
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Enter Ground Zero")), ButtonColor, ButtonHoverColor, 10.0f * Scale);
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
PrimaryFocusButton->OnHovered.AddDynamic(this, &UAgrarianMvpFrontendWidget::FocusPrimaryButton);
AddText(Panel, FText::Format(FText::FromString(TEXT("Selected {0}: {1}. Click a card or use Left/Right, then continue.")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
return;
}
@@ -363,9 +340,8 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
}
PrimaryFocusButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("ContinueToLoadingButton"));
PrimaryFocusButton->SetStyle(MakeAgrarianButtonStyle(ButtonColor, ButtonHoverColor));
PrimaryFocusButton->SetBackgroundColor(ButtonColor);
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
PrimaryFocusButton->OnHovered.AddDynamic(this, &UAgrarianMvpFrontendWidget::FocusPrimaryButton);
UTextBlock* ContinueLabel = AddText(nullptr, FText::FromString(TEXT("Continue to loading")), FMath::RoundToInt(20.0f * Scale), true, TextColor, 0.0f);
PrimaryFocusButton->SetContent(ContinueLabel);
if (UButtonSlot* ContinueLabelSlot = Cast<UButtonSlot>(ContinueLabel->Slot))
@@ -380,7 +356,7 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
}
UButton* BackButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("BackButton"));
BackButton->SetStyle(MakeAgrarianButtonStyle(SecondaryButtonColor, ButtonHoverColor));
BackButton->SetBackgroundColor(SecondaryButtonColor);
BackButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleBackClicked);
UTextBlock* BackLabel = AddText(nullptr, FText::FromString(TEXT("Back")), FMath::RoundToInt(20.0f * Scale), true, TextColor, 0.0f);
BackButton->SetContent(BackLabel);
@@ -413,7 +389,6 @@ void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
AddText(Panel, FText::Format(FText::FromString(TEXT("{0}: {1} | Server: {2}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel(), JoinServerAddress), FMath::RoundToInt(18.0f * Scale), false, TextColor, 34.0f * Scale);
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Enter Ground Zero")), ButtonColor, ButtonHoverColor, 14.0f * Scale);
PrimaryFocusButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked);
PrimaryFocusButton->OnHovered.AddDynamic(this, &UAgrarianMvpFrontendWidget::FocusPrimaryButton);
AddText(Panel, FText::FromString(TEXT("Click or press Enter to close the MVP menu and begin testing.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
}
@@ -440,7 +415,7 @@ UTextBlock* UAgrarianMvpFrontendWidget::AddText(UVerticalBox* Parent, const FTex
UButton* UAgrarianMvpFrontendWidget::AddButton(UVerticalBox* Parent, const FText& Text, const FLinearColor& NormalColor, const FLinearColor& HoveredColor, float BottomPadding)
{
UButton* Button = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass());
Button->SetStyle(MakeAgrarianButtonStyle(NormalColor, HoveredColor));
Button->SetBackgroundColor(NormalColor);
Button->SetClickMethod(EButtonClickMethod::MouseDown);
Button->SetTouchMethod(EButtonTouchMethod::Down);
@@ -481,27 +456,66 @@ void UAgrarianMvpFrontendWidget::FocusPrimaryButton()
void UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked()
{
ConfirmActiveScreen();
DeferFrontendAction([this]()
{
ConfirmActiveScreen();
});
}
void UAgrarianMvpFrontendWidget::HandleBackClicked()
{
BackFromActiveScreen();
DeferFrontendAction([this]()
{
BackFromActiveScreen();
});
}
void UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked()
{
SaveAndQuit();
DeferFrontendAction([this]()
{
SaveAndQuit();
});
}
void UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked()
{
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
DeferFrontendAction([this]()
{
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
});
}
void UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked()
{
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
DeferFrontendAction([this]()
{
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
});
}
void UAgrarianMvpFrontendWidget::DeferFrontendAction(TFunction<void()> Action)
{
if (!Action)
{
return;
}
if (UWorld* World = GetWorld())
{
FTimerDelegate DeferredAction;
DeferredAction.BindLambda([WeakThis = TWeakObjectPtr<UAgrarianMvpFrontendWidget>(this), Action = MoveTemp(Action)]() mutable
{
if (WeakThis.IsValid())
{
Action();
}
});
World->GetTimerManager().SetTimerForNextTick(DeferredAction);
return;
}
Action();
}
FText UAgrarianMvpFrontendWidget::GetSelectedCharacterLabel() const
@@ -112,6 +112,8 @@ private:
UFUNCTION()
void HandleFemaleCharacterClicked();
void DeferFrontendAction(TFunction<void()> Action);
UPROPERTY()
TObjectPtr<UButton> PrimaryFocusButton;