Replace MVP frontend with UMG menu flow
This commit is contained in:
@@ -2,16 +2,42 @@
|
||||
|
||||
#include "AgrarianMvpFrontendWidget.h"
|
||||
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
#include "Components/Border.h"
|
||||
#include "Components/Button.h"
|
||||
#include "Components/ButtonSlot.h"
|
||||
#include "Components/HorizontalBox.h"
|
||||
#include "Components/HorizontalBoxSlot.h"
|
||||
#include "Components/SizeBox.h"
|
||||
#include "Components/TextBlock.h"
|
||||
#include "Components/VerticalBox.h"
|
||||
#include "Components/VerticalBoxSlot.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "Rendering/DrawElements.h"
|
||||
#include "Styling/CoreStyle.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();
|
||||
SetIsFocusable(true);
|
||||
SetKeyboardFocus();
|
||||
RebuildFrontendTree();
|
||||
FocusPrimaryButton();
|
||||
}
|
||||
|
||||
FReply UAgrarianMvpFrontendWidget::NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent)
|
||||
@@ -80,131 +106,32 @@ FReply UAgrarianMvpFrontendWidget::NativeOnKeyDown(const FGeometry& InGeometry,
|
||||
return Super::NativeOnKeyDown(InGeometry, InKeyEvent);
|
||||
}
|
||||
|
||||
FReply UAgrarianMvpFrontendWidget::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
|
||||
{
|
||||
if (InMouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
|
||||
{
|
||||
return Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
|
||||
}
|
||||
|
||||
const FVector2D LocalMousePosition = InGeometry.AbsoluteToLocal(InMouseEvent.GetScreenSpacePosition());
|
||||
float Scale = 1.0f;
|
||||
FVector2D PanelPosition = FVector2D::ZeroVector;
|
||||
FVector2D PanelSize = FVector2D::ZeroVector;
|
||||
if (!GetPanelLayout(InGeometry.GetLocalSize(), Scale, PanelPosition, PanelSize))
|
||||
{
|
||||
return Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
|
||||
}
|
||||
|
||||
const float ContentX = PanelPosition.X + (44.0f * Scale);
|
||||
const float ContentWidth = PanelSize.X - (88.0f * Scale);
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
|
||||
{
|
||||
const FVector2D CardSize((ContentWidth - (24.0f * Scale)) * 0.5f, 206.0f * Scale);
|
||||
const FVector2D MaleCardPosition(ContentX, PanelPosition.Y + (142.0f * Scale));
|
||||
const FVector2D FemaleCardPosition(ContentX + CardSize.X + (24.0f * Scale), MaleCardPosition.Y);
|
||||
const FVector2D ButtonPosition(ContentX, PanelPosition.Y + PanelSize.Y - (88.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(ContentWidth, 280.0f * Scale), 52.0f * Scale);
|
||||
|
||||
if (IsPointInside(LocalMousePosition, MaleCardPosition, CardSize))
|
||||
{
|
||||
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (IsPointInside(LocalMousePosition, FemaleCardPosition, CardSize))
|
||||
{
|
||||
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (IsPointInside(LocalMousePosition, ButtonPosition, ButtonSize))
|
||||
{
|
||||
ConfirmActiveScreen();
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
|
||||
{
|
||||
const float JoinContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float JoinContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FVector2D ButtonPosition(JoinContentX, PanelPosition.Y + (300.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(JoinContentWidth, 330.0f * Scale), 58.0f * Scale);
|
||||
const FVector2D BackButtonPosition(ButtonPosition.X + ButtonSize.X + (16.0f * Scale), ButtonPosition.Y);
|
||||
const FVector2D BackButtonSize(FMath::Min(JoinContentWidth - ButtonSize.X - (16.0f * Scale), 180.0f * Scale), ButtonSize.Y);
|
||||
|
||||
if (IsPointInside(LocalMousePosition, ButtonPosition, ButtonSize))
|
||||
{
|
||||
ConfirmActiveScreen();
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (BackButtonSize.X > 96.0f && IsPointInside(LocalMousePosition, BackButtonPosition, BackButtonSize))
|
||||
{
|
||||
BackFromActiveScreen();
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
|
||||
{
|
||||
const float LoadingContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float LoadingContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FVector2D ButtonPosition(LoadingContentX, PanelPosition.Y + (318.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(LoadingContentWidth, 310.0f * Scale), 56.0f * Scale);
|
||||
|
||||
if (IsPointInside(LocalMousePosition, ButtonPosition, ButtonSize))
|
||||
{
|
||||
ConfirmActiveScreen();
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
|
||||
{
|
||||
const float MenuContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float MenuContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FVector2D ResumeButtonPosition(MenuContentX, PanelPosition.Y + (220.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(MenuContentWidth, 310.0f * Scale), 56.0f * Scale);
|
||||
const FVector2D QuitButtonPosition(MenuContentX, ResumeButtonPosition.Y + (72.0f * Scale));
|
||||
|
||||
if (IsPointInside(LocalMousePosition, ResumeButtonPosition, ButtonSize))
|
||||
{
|
||||
ConfirmActiveScreen();
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
if (IsPointInside(LocalMousePosition, QuitButtonPosition, ButtonSize))
|
||||
{
|
||||
SaveAndQuit();
|
||||
return FReply::Handled();
|
||||
}
|
||||
}
|
||||
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::SetActiveScreen(EAgrarianMvpFrontendScreen NewScreen)
|
||||
{
|
||||
ActiveScreen = NewScreen;
|
||||
InvalidateLayoutAndVolatility();
|
||||
RebuildFrontendTree();
|
||||
FocusPrimaryButton();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype NewArchetype)
|
||||
{
|
||||
SelectedCharacterArchetype = NewArchetype;
|
||||
InvalidateLayoutAndVolatility();
|
||||
RebuildFrontendTree();
|
||||
FocusPrimaryButton();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::SetUiScale(float NewUiScale)
|
||||
{
|
||||
UiScale = FMath::Clamp(NewUiScale, 0.75f, 1.5f);
|
||||
InvalidateLayoutAndVolatility();
|
||||
RebuildFrontendTree();
|
||||
FocusPrimaryButton();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::SetHighContrastMode(bool bNewUseHighContrast)
|
||||
{
|
||||
bUseHighContrast = bNewUseHighContrast;
|
||||
InvalidateLayoutAndVolatility();
|
||||
RebuildFrontendTree();
|
||||
FocusPrimaryButton();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ConfirmActiveScreen()
|
||||
@@ -226,98 +153,6 @@ void UAgrarianMvpFrontendWidget::SaveAndQuit()
|
||||
}
|
||||
}
|
||||
|
||||
int32 UAgrarianMvpFrontendWidget::NativePaint(
|
||||
const FPaintArgs& Args,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FSlateRect& MyCullingRect,
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32 LayerId,
|
||||
const FWidgetStyle& InWidgetStyle,
|
||||
bool bParentEnabled) const
|
||||
{
|
||||
LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
|
||||
|
||||
const FVector2D Size = AllottedGeometry.GetLocalSize();
|
||||
float Scale = 1.0f;
|
||||
FVector2D PanelPosition = FVector2D::ZeroVector;
|
||||
FVector2D PanelSize = FVector2D::ZeroVector;
|
||||
GetPanelLayout(Size, Scale, PanelPosition, PanelSize);
|
||||
const FLinearColor BackdropColor = bUseHighContrast ? FLinearColor(0.0f, 0.0f, 0.0f, 1.0f) : FLinearColor(0.015f, 0.018f, 0.014f, 0.99f);
|
||||
const FLinearColor PanelColor = bUseHighContrast ? FLinearColor(0.0f, 0.0f, 0.0f, 0.98f) : FLinearColor(0.035f, 0.045f, 0.034f, 0.96f);
|
||||
const FLinearColor AccentColor = bUseHighContrast ? FLinearColor(0.95f, 0.95f, 0.30f, 1.0f) : FLinearColor(0.45f, 0.72f, 0.40f, 1.0f);
|
||||
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(Size), FSlateLayoutTransform(FVector2f::ZeroVector)),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
BackdropColor);
|
||||
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(PanelSize), FSlateLayoutTransform(FVector2f(PanelPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
PanelColor);
|
||||
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(PanelSize.X, 4.0f * Scale), FSlateLayoutTransform(FVector2f(PanelPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
AccentColor);
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
|
||||
{
|
||||
DrawMainMenu(OutDrawElements, LayerId, AllottedGeometry, PanelPosition, PanelSize, Scale);
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
|
||||
{
|
||||
DrawCharacterSelection(OutDrawElements, LayerId, AllottedGeometry, PanelPosition, PanelSize, Scale);
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
|
||||
{
|
||||
DrawJoinServer(OutDrawElements, LayerId, AllottedGeometry, PanelPosition, PanelSize, Scale);
|
||||
}
|
||||
else if (ActiveScreen == EAgrarianMvpFrontendScreen::Loading)
|
||||
{
|
||||
DrawLoading(OutDrawElements, LayerId, AllottedGeometry, PanelPosition, PanelSize, Scale);
|
||||
}
|
||||
|
||||
return LayerId;
|
||||
}
|
||||
|
||||
bool UAgrarianMvpFrontendWidget::GetPanelLayout(const FVector2D& WidgetSize, float& OutScale, FVector2D& OutPanelPosition, FVector2D& OutPanelSize) const
|
||||
{
|
||||
OutScale = FMath::Clamp(UiScale, 0.75f, 1.5f);
|
||||
constexpr float MinimumPanelMargin = 24.0f;
|
||||
constexpr float PreferredPanelWidth = 780.0f;
|
||||
constexpr float PreferredPanelHeight = 430.0f;
|
||||
const FVector2D AvailablePanelSize(
|
||||
FMath::Max(320.0f, WidgetSize.X - (MinimumPanelMargin * 2.0f)),
|
||||
FMath::Max(240.0f, WidgetSize.Y - (MinimumPanelMargin * 2.0f)));
|
||||
|
||||
OutPanelSize = FVector2D(
|
||||
FMath::Min(AvailablePanelSize.X, PreferredPanelWidth * OutScale),
|
||||
FMath::Min(AvailablePanelSize.Y, PreferredPanelHeight * OutScale));
|
||||
OutPanelPosition = FVector2D(
|
||||
(WidgetSize.X - OutPanelSize.X) * 0.5f,
|
||||
(WidgetSize.Y - OutPanelSize.Y) * 0.5f);
|
||||
|
||||
return WidgetSize.X > 0.0f && WidgetSize.Y > 0.0f;
|
||||
}
|
||||
|
||||
bool UAgrarianMvpFrontendWidget::IsPointInside(const FVector2D& Point, const FVector2D& Position, const FVector2D& Size) const
|
||||
{
|
||||
return Point.X >= Position.X
|
||||
&& Point.Y >= Position.Y
|
||||
&& Point.X <= Position.X + Size.X
|
||||
&& Point.Y <= Position.Y + Size.Y;
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::ContinueFromActiveScreen()
|
||||
{
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
|
||||
@@ -371,238 +206,253 @@ void UAgrarianMvpFrontendWidget::CompleteFrontendFlow()
|
||||
RemoveFromParent();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::DrawMainMenu(
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32& LayerId,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FVector2D& PanelPosition,
|
||||
const FVector2D& PanelSize,
|
||||
float Scale) const
|
||||
void UAgrarianMvpFrontendWidget::RebuildFrontendTree()
|
||||
{
|
||||
const float ContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float ContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(54.0f * Scale));
|
||||
const FSlateFontInfo SubtitleFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(22.0f * Scale));
|
||||
const FSlateFontInfo ButtonFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(24.0f * Scale));
|
||||
const FSlateFontInfo HintFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(16.0f * Scale));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, MainMenuTitle, FVector2D(ContentX, PanelPosition.Y + (58.0f * Scale)), ContentWidth, TitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Game menu")), FVector2D(ContentX + (4.0f * Scale), PanelPosition.Y + (128.0f * Scale)), ContentWidth, SubtitleFont, FLinearColor(0.72f, 0.80f, 0.68f, 1.0f));
|
||||
|
||||
const FVector2D ButtonPosition(ContentX, PanelPosition.Y + (220.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(ContentWidth, 310.0f * Scale), 56.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(ButtonSize), FSlateLayoutTransform(FVector2f(ButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.35f, 0.58f, 0.30f, 0.95f));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Resume")), ButtonPosition + FVector2D(22.0f * Scale, 11.0f * Scale), ButtonSize.X - (44.0f * Scale), ButtonFont, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f));
|
||||
|
||||
const FVector2D QuitButtonPosition(ContentX, ButtonPosition.Y + (72.0f * Scale));
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(ButtonSize), FSlateLayoutTransform(FVector2f(QuitButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.42f, 0.22f, 0.18f, 0.95f));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Save & Quit")), QuitButtonPosition + FVector2D(22.0f * Scale, 11.0f * Scale), ButtonSize.X - (44.0f * Scale), ButtonFont, FLinearColor(1.0f, 0.92f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Press Escape to open this menu. Save & Quit writes the current world save before closing.")), FVector2D(ContentX, PanelPosition.Y + PanelSize.Y - (66.0f * Scale)), ContentWidth, HintFont, FLinearColor(0.62f, 0.68f, 0.58f, 1.0f));
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::DrawCharacterSelection(
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32& LayerId,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FVector2D& PanelPosition,
|
||||
const FVector2D& PanelSize,
|
||||
float Scale) const
|
||||
{
|
||||
const float ContentX = PanelPosition.X + (44.0f * Scale);
|
||||
const float ContentWidth = PanelSize.X - (88.0f * Scale);
|
||||
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(34.0f * Scale));
|
||||
const FSlateFontInfo BodyFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(18.0f * Scale));
|
||||
const FSlateFontInfo CardTitleFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(22.0f * Scale));
|
||||
const FSlateFontInfo LabelFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(15.0f * Scale));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Choose your first pioneer")), FVector2D(ContentX, PanelPosition.Y + (34.0f * Scale)), ContentWidth, TitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Select the person who will step into Ground Zero.")), FVector2D(ContentX + (2.0f * Scale), PanelPosition.Y + (82.0f * Scale)), ContentWidth, BodyFont, FLinearColor(0.72f, 0.80f, 0.68f, 1.0f));
|
||||
|
||||
const FVector2D CardSize((ContentWidth - (24.0f * Scale)) * 0.5f, 206.0f * Scale);
|
||||
const FVector2D MaleCardPosition(ContentX, PanelPosition.Y + (142.0f * Scale));
|
||||
const FVector2D FemaleCardPosition(ContentX + CardSize.X + (24.0f * Scale), MaleCardPosition.Y);
|
||||
|
||||
auto DrawCharacterCard = [&](const FVector2D& CardPosition, const FText& Title, const FText& Summary, const FLinearColor& AccentColor, bool bSelected)
|
||||
if (!WidgetTree)
|
||||
{
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(CardSize), FSlateLayoutTransform(FVector2f(CardPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.055f, 0.065f, 0.05f, 0.95f));
|
||||
return;
|
||||
}
|
||||
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(CardSize.X, 3.0f * Scale), FSlateLayoutTransform(FVector2f(CardPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
AccentColor);
|
||||
PrimaryFocusButton = nullptr;
|
||||
|
||||
if (bSelected)
|
||||
const float Scale = FMath::Clamp(UiScale, 0.75f, 1.5f);
|
||||
const FLinearColor BackdropColor = bUseHighContrast ? FLinearColor::Black : FLinearColor(0.015f, 0.018f, 0.014f, 0.99f);
|
||||
const FLinearColor PanelColor = bUseHighContrast ? FLinearColor(0.0f, 0.0f, 0.0f, 0.98f) : FLinearColor(0.035f, 0.045f, 0.034f, 0.96f);
|
||||
const FLinearColor AccentColor = bUseHighContrast ? FLinearColor(0.95f, 0.95f, 0.30f, 1.0f) : FLinearColor(0.45f, 0.72f, 0.40f, 1.0f);
|
||||
const FLinearColor TextColor = bUseHighContrast ? FLinearColor::White : FLinearColor(0.92f, 0.98f, 0.84f, 1.0f);
|
||||
const FLinearColor MutedTextColor = bUseHighContrast ? FLinearColor(0.86f, 0.86f, 0.66f, 1.0f) : FLinearColor(0.72f, 0.80f, 0.68f, 1.0f);
|
||||
const FLinearColor ButtonColor = bUseHighContrast ? FLinearColor(0.30f, 0.30f, 0.02f, 1.0f) : FLinearColor(0.22f, 0.40f, 0.18f, 0.98f);
|
||||
const FLinearColor ButtonHoverColor = bUseHighContrast ? FLinearColor(0.48f, 0.48f, 0.08f, 1.0f) : FLinearColor(0.35f, 0.58f, 0.30f, 1.0f);
|
||||
const FLinearColor SecondaryButtonColor = bUseHighContrast ? FLinearColor(0.12f, 0.12f, 0.12f, 1.0f) : FLinearColor(0.10f, 0.13f, 0.09f, 0.98f);
|
||||
const FLinearColor QuitButtonColor = bUseHighContrast ? FLinearColor(0.32f, 0.10f, 0.08f, 1.0f) : FLinearColor(0.42f, 0.22f, 0.18f, 0.98f);
|
||||
|
||||
UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("MvpFrontendRoot"));
|
||||
RootBorder->SetBrushColor(BackdropColor);
|
||||
RootBorder->SetPadding(FMargin(24.0f * Scale));
|
||||
RootBorder->SetHorizontalAlignment(HAlign_Center);
|
||||
RootBorder->SetVerticalAlignment(VAlign_Center);
|
||||
WidgetTree->RootWidget = RootBorder;
|
||||
|
||||
USizeBox* PanelSizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("MvpFrontendPanelSize"));
|
||||
PanelSizeBox->SetWidthOverride(780.0f * Scale);
|
||||
PanelSizeBox->SetMinDesiredWidth(420.0f);
|
||||
PanelSizeBox->SetMinDesiredHeight(300.0f);
|
||||
RootBorder->SetContent(PanelSizeBox);
|
||||
|
||||
UBorder* PanelBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("MvpFrontendPanel"));
|
||||
PanelBorder->SetBrushColor(PanelColor);
|
||||
PanelBorder->SetPadding(FMargin(42.0f * Scale, 34.0f * Scale));
|
||||
PanelSizeBox->SetContent(PanelBorder);
|
||||
|
||||
UVerticalBox* Panel = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("MvpFrontendStack"));
|
||||
PanelBorder->SetContent(Panel);
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::MainMenu)
|
||||
{
|
||||
AddText(Panel, MainMenuTitle, FMath::RoundToInt(54.0f * Scale), true, TextColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Game menu")), 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);
|
||||
AddText(Panel, FText::FromString(TEXT("Escape opens this menu. Save & Quit writes the current world save before closing.")), FMath::RoundToInt(16.0f * Scale), false, MutedTextColor, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::CharacterSelection)
|
||||
{
|
||||
AddText(Panel, FText::FromString(TEXT("Choose your first pioneer")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 6.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Select the person who will step into Ground Zero.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 24.0f * Scale);
|
||||
|
||||
UHorizontalBox* CharacterRow = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("CharacterRow"));
|
||||
if (UVerticalBoxSlot* RowSlot = Panel->AddChildToVerticalBox(CharacterRow))
|
||||
{
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(CardSize.X, CardSize.Y), FSlateLayoutTransform(FVector2f(CardPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(AccentColor.R, AccentColor.G, AccentColor.B, 0.16f));
|
||||
RowSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 22.0f * Scale));
|
||||
}
|
||||
|
||||
const FVector2D PortraitPosition = CardPosition + FVector2D(24.0f * Scale, 42.0f * Scale);
|
||||
const FVector2D PortraitSize(72.0f * Scale, 112.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(PortraitSize), FSlateLayoutTransform(FVector2f(PortraitPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.14f, 0.16f, 0.13f, 1.0f));
|
||||
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->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked);
|
||||
UVerticalBox* MaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("MalePioneerStack"));
|
||||
MaleButton->SetContent(MaleStack);
|
||||
AddText(MaleStack, FText::FromString(TEXT("Young adult male")), FMath::RoundToInt(21.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(MaleStack, FText::FromString(TEXT("Average proportions, survival baseline, placeholder visual.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 18.0f * Scale);
|
||||
AddText(MaleStack, bMaleSelected ? FText::FromString(TEXT("Selected")) : FText::FromString(TEXT("Available")), FMath::RoundToInt(15.0f * Scale), true, bMaleSelected ? AccentColor : MutedTextColor, 0.0f);
|
||||
if (UHorizontalBoxSlot* MaleSlot = CharacterRow->AddChildToHorizontalBox(MaleButton))
|
||||
{
|
||||
MaleSlot->SetPadding(FMargin(0.0f, 0.0f, 12.0f * Scale, 0.0f));
|
||||
MaleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
|
||||
}
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, Title, CardPosition + FVector2D(116.0f * Scale, 42.0f * Scale), CardSize.X - (140.0f * Scale), CardTitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, Summary, CardPosition + FVector2D(116.0f * Scale, 82.0f * Scale), CardSize.X - (140.0f * Scale), LabelFont, FLinearColor(0.72f, 0.78f, 0.68f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, bSelected ? FText::FromString(TEXT("Selected")) : FText::FromString(TEXT("Available")), CardPosition + FVector2D(116.0f * Scale, 144.0f * Scale), CardSize.X - (140.0f * Scale), LabelFont, bSelected ? AccentColor : FLinearColor(0.58f, 0.62f, 0.54f, 1.0f));
|
||||
};
|
||||
UButton* FemaleButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("FemalePioneerButton"));
|
||||
FemaleButton->SetStyle(MakeAgrarianButtonStyle(bFemaleSelected ? ButtonHoverColor : SecondaryButtonColor, ButtonHoverColor));
|
||||
FemaleButton->OnClicked.AddDynamic(this, &UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked);
|
||||
UVerticalBox* FemaleStack = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("FemalePioneerStack"));
|
||||
FemaleButton->SetContent(FemaleStack);
|
||||
AddText(FemaleStack, FText::FromString(TEXT("Young adult female")), FMath::RoundToInt(21.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(FemaleStack, FText::FromString(TEXT("Average proportions, survival baseline, placeholder visual.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 18.0f * Scale);
|
||||
AddText(FemaleStack, bFemaleSelected ? FText::FromString(TEXT("Selected")) : FText::FromString(TEXT("Available")), FMath::RoundToInt(15.0f * Scale), true, bFemaleSelected ? AccentColor : MutedTextColor, 0.0f);
|
||||
if (UHorizontalBoxSlot* FemaleSlot = CharacterRow->AddChildToHorizontalBox(FemaleButton))
|
||||
{
|
||||
FemaleSlot->SetPadding(FMargin(12.0f * Scale, 0.0f, 0.0f, 0.0f));
|
||||
FemaleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
|
||||
}
|
||||
|
||||
DrawCharacterCard(MaleCardPosition, FText::FromString(TEXT("Young adult male")), FText::FromString(TEXT("Average proportions, survival baseline, placeholder visual.")), FLinearColor(0.36f, 0.58f, 0.78f, 1.0f), SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultMale);
|
||||
DrawCharacterCard(FemaleCardPosition, FText::FromString(TEXT("Young adult female")), FText::FromString(TEXT("Average proportions, survival baseline, placeholder visual.")), FLinearColor(0.56f, 0.68f, 0.46f, 1.0f), SelectedCharacterArchetype == EAgrarianMvpCharacterArchetype::YoungAdultFemale);
|
||||
|
||||
const FVector2D ButtonPosition(ContentX, PanelPosition.Y + PanelSize.Y - (88.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(ContentWidth, 280.0f * Scale), 52.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(ButtonSize), FSlateLayoutTransform(FVector2f(ButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.35f, 0.58f, 0.30f, 0.95f));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Continue")), ButtonPosition + FVector2D(22.0f * Scale, 10.0f * Scale), ButtonSize.X - (44.0f * Scale), CardTitleFont, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::Format(FText::FromString(TEXT("Selected {0}: {1}. Click a card or use Left/Right, then continue.")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FVector2D(ContentX, PanelPosition.Y + PanelSize.Y - (26.0f * Scale)), ContentWidth, LabelFont, FLinearColor(0.62f, 0.68f, 0.58f, 1.0f));
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::DrawJoinServer(
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32& LayerId,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FVector2D& PanelPosition,
|
||||
const FVector2D& PanelSize,
|
||||
float Scale) const
|
||||
{
|
||||
const float ContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float ContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(34.0f * Scale));
|
||||
const FSlateFontInfo BodyFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(18.0f * Scale));
|
||||
const FSlateFontInfo AddressFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(24.0f * Scale));
|
||||
const FSlateFontInfo HintFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(15.0f * Scale));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Join MVP server")), FVector2D(ContentX, PanelPosition.Y + (44.0f * Scale)), ContentWidth, TitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::Format(FText::FromString(TEXT("{0}: {1}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FVector2D(ContentX + (2.0f * Scale), PanelPosition.Y + (94.0f * Scale)), ContentWidth, BodyFont, FLinearColor(0.72f, 0.80f, 0.68f, 1.0f));
|
||||
|
||||
const FVector2D AddressPanelPosition(ContentX, PanelPosition.Y + (164.0f * Scale));
|
||||
const FVector2D AddressPanelSize(ContentWidth, 96.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(AddressPanelSize), FSlateLayoutTransform(FVector2f(AddressPanelPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.055f, 0.065f, 0.05f, 0.96f));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Server address")), AddressPanelPosition + FVector2D(24.0f * Scale, 14.0f * Scale), ContentWidth - (48.0f * Scale), HintFont, FLinearColor(0.58f, 0.64f, 0.54f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, JoinServerAddress, AddressPanelPosition + FVector2D(24.0f * Scale, 42.0f * Scale), ContentWidth - (48.0f * Scale), AddressFont, FLinearColor(0.86f, 0.94f, 0.78f, 1.0f));
|
||||
|
||||
const FVector2D ButtonPosition(ContentX, PanelPosition.Y + (300.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(ContentWidth, 330.0f * Scale), 58.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(ButtonSize), FSlateLayoutTransform(FVector2f(ButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.35f, 0.58f, 0.30f, 0.95f));
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Continue to loading")), ButtonPosition + FVector2D(22.0f * Scale, 12.0f * Scale), ButtonSize.X - (44.0f * Scale), AddressFont, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f));
|
||||
const FVector2D BackButtonPosition(ButtonPosition.X + ButtonSize.X + (16.0f * Scale), ButtonPosition.Y);
|
||||
const FVector2D BackButtonSize(FMath::Min(ContentWidth - ButtonSize.X - (16.0f * Scale), 180.0f * Scale), ButtonSize.Y);
|
||||
if (BackButtonSize.X > 96.0f)
|
||||
{
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(BackButtonSize), FSlateLayoutTransform(FVector2f(BackButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.12f, 0.15f, 0.11f, 0.95f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Back")), BackButtonPosition + FVector2D(22.0f * Scale, 12.0f * Scale), BackButtonSize.X - (44.0f * Scale), AddressFont, FLinearColor(0.82f, 0.88f, 0.76f, 1.0f));
|
||||
PrimaryFocusButton = AddButton(Panel, FText::FromString(TEXT("Continue")), 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;
|
||||
}
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Click continue, press Enter, or press Backspace/Escape to revise your pioneer.")), FVector2D(ContentX, PanelPosition.Y + PanelSize.Y - (46.0f * Scale)), ContentWidth, HintFont, FLinearColor(0.62f, 0.68f, 0.58f, 1.0f));
|
||||
|
||||
if (ActiveScreen == EAgrarianMvpFrontendScreen::JoinServer)
|
||||
{
|
||||
AddText(Panel, FText::FromString(TEXT("Join MVP server")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(Panel, FText::Format(FText::FromString(TEXT("{0}: {1}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel()), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 36.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Server address")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 4.0f * Scale);
|
||||
AddText(Panel, JoinServerAddress, FMath::RoundToInt(24.0f * Scale), true, TextColor, 42.0f * Scale);
|
||||
|
||||
UHorizontalBox* ButtonRow = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("JoinButtonRow"));
|
||||
if (UVerticalBoxSlot* RowSlot = Panel->AddChildToVerticalBox(ButtonRow))
|
||||
{
|
||||
RowSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 18.0f * Scale));
|
||||
}
|
||||
|
||||
PrimaryFocusButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("ContinueToLoadingButton"));
|
||||
PrimaryFocusButton->SetStyle(MakeAgrarianButtonStyle(ButtonColor, ButtonHoverColor));
|
||||
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))
|
||||
{
|
||||
ContinueLabelSlot->SetPadding(FMargin(22.0f, 12.0f));
|
||||
ContinueLabelSlot->SetHorizontalAlignment(HAlign_Center);
|
||||
}
|
||||
if (UHorizontalBoxSlot* ContinueSlot = ButtonRow->AddChildToHorizontalBox(PrimaryFocusButton))
|
||||
{
|
||||
ContinueSlot->SetPadding(FMargin(0.0f, 0.0f, 12.0f * Scale, 0.0f));
|
||||
ContinueSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
|
||||
}
|
||||
|
||||
UButton* BackButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("BackButton"));
|
||||
BackButton->SetStyle(MakeAgrarianButtonStyle(SecondaryButtonColor, ButtonHoverColor));
|
||||
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);
|
||||
if (UButtonSlot* BackLabelSlot = Cast<UButtonSlot>(BackLabel->Slot))
|
||||
{
|
||||
BackLabelSlot->SetPadding(FMargin(22.0f, 12.0f));
|
||||
BackLabelSlot->SetHorizontalAlignment(HAlign_Center);
|
||||
}
|
||||
if (UHorizontalBoxSlot* BackSlot = ButtonRow->AddChildToHorizontalBox(BackButton))
|
||||
{
|
||||
BackSlot->SetPadding(FMargin(12.0f * Scale, 0.0f, 0.0f, 0.0f));
|
||||
BackSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
|
||||
}
|
||||
|
||||
AddText(Panel, FText::FromString(TEXT("Click continue, press Enter, or press Backspace/Escape to revise your pioneer.")), FMath::RoundToInt(15.0f * Scale), false, MutedTextColor, 0.0f);
|
||||
return;
|
||||
}
|
||||
|
||||
AddText(Panel, FText::FromString(TEXT("Preparing Ground Zero")), FMath::RoundToInt(34.0f * Scale), true, TextColor, 8.0f * Scale);
|
||||
AddText(Panel, FText::FromString(TEXT("Loading terrain, weather, survival state, and server session data.")), FMath::RoundToInt(18.0f * Scale), false, MutedTextColor, 70.0f * Scale);
|
||||
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);
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::DrawLoading(
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32& LayerId,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FVector2D& PanelPosition,
|
||||
const FVector2D& PanelSize,
|
||||
float Scale) const
|
||||
UTextBlock* UAgrarianMvpFrontendWidget::AddText(UVerticalBox* Parent, const FText& Text, int32 FontSize, bool bBold, const FLinearColor& Color, float BottomPadding)
|
||||
{
|
||||
const float ContentX = PanelPosition.X + (48.0f * Scale);
|
||||
const float ContentWidth = PanelSize.X - (96.0f * Scale);
|
||||
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", FMath::RoundToInt(34.0f * Scale));
|
||||
const FSlateFontInfo BodyFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(18.0f * Scale));
|
||||
const FSlateFontInfo HintFont = FCoreStyle::GetDefaultFontStyle("Regular", FMath::RoundToInt(15.0f * Scale));
|
||||
UTextBlock* TextBlock = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass());
|
||||
TextBlock->SetText(Text);
|
||||
TextBlock->SetFont(FCoreStyle::GetDefaultFontStyle(bBold ? "Bold" : "Regular", FontSize));
|
||||
TextBlock->SetColorAndOpacity(FSlateColor(Color));
|
||||
TextBlock->SetAutoWrapText(true);
|
||||
TextBlock->SetJustification(ETextJustify::Left);
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Preparing Ground Zero")), FVector2D(ContentX, PanelPosition.Y + (58.0f * Scale)), ContentWidth, TitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Loading terrain, weather, survival state, and server session data.")), FVector2D(ContentX + (2.0f * Scale), PanelPosition.Y + (108.0f * Scale)), ContentWidth, BodyFont, FLinearColor(0.72f, 0.80f, 0.68f, 1.0f));
|
||||
if (Parent)
|
||||
{
|
||||
if (UVerticalBoxSlot* TextSlot = Parent->AddChildToVerticalBox(TextBlock))
|
||||
{
|
||||
TextSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, BottomPadding));
|
||||
}
|
||||
}
|
||||
|
||||
const FVector2D BarPosition(ContentX, PanelPosition.Y + (214.0f * Scale));
|
||||
const FVector2D BarSize(ContentWidth, 18.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(BarSize), FSlateLayoutTransform(FVector2f(BarPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.065f, 0.075f, 0.06f, 1.0f));
|
||||
return TextBlock;
|
||||
}
|
||||
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(BarSize.X * 0.62f, BarSize.Y), FSlateLayoutTransform(FVector2f(BarPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.45f, 0.72f, 0.40f, 1.0f));
|
||||
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->SetClickMethod(EButtonClickMethod::MouseDown);
|
||||
Button->SetTouchMethod(EButtonTouchMethod::Down);
|
||||
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::Format(FText::FromString(TEXT("{0}: {1} | Server: {2}")), GetSelectedRoleLabel(), GetSelectedCharacterLabel(), JoinServerAddress), FVector2D(ContentX, PanelPosition.Y + (270.0f * Scale)), ContentWidth, BodyFont, FLinearColor(0.78f, 0.84f, 0.72f, 1.0f));
|
||||
if (!Text.IsEmpty())
|
||||
{
|
||||
UTextBlock* Label = AddText(nullptr, Text, FMath::RoundToInt(20.0f * FMath::Clamp(UiScale, 0.75f, 1.5f)), true, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f), 0.0f);
|
||||
Button->SetContent(Label);
|
||||
if (UButtonSlot* LabelSlot = Cast<UButtonSlot>(Label->Slot))
|
||||
{
|
||||
LabelSlot->SetPadding(FMargin(22.0f, 12.0f));
|
||||
LabelSlot->SetHorizontalAlignment(HAlign_Center);
|
||||
}
|
||||
}
|
||||
|
||||
const FVector2D ButtonPosition(ContentX, PanelPosition.Y + (318.0f * Scale));
|
||||
const FVector2D ButtonSize(FMath::Min(ContentWidth, 310.0f * Scale), 56.0f * Scale);
|
||||
FSlateDrawElement::MakeBox(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(ButtonSize), FSlateLayoutTransform(FVector2f(ButtonPosition))),
|
||||
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
|
||||
ESlateDrawEffect::None,
|
||||
FLinearColor(0.35f, 0.58f, 0.30f, 0.95f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Enter Ground Zero")), ButtonPosition + FVector2D(22.0f * Scale, 11.0f * Scale), ButtonSize.X - (44.0f * Scale), BodyFont, FLinearColor(0.96f, 1.0f, 0.90f, 1.0f));
|
||||
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Click or press Enter to close the MVP menu and begin testing.")), FVector2D(ContentX, PanelPosition.Y + PanelSize.Y - (46.0f * Scale)), ContentWidth, HintFont, FLinearColor(0.62f, 0.68f, 0.58f, 1.0f));
|
||||
if (Parent)
|
||||
{
|
||||
if (UVerticalBoxSlot* ButtonSlot = Parent->AddChildToVerticalBox(Button))
|
||||
{
|
||||
ButtonSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, BottomPadding));
|
||||
ButtonSlot->SetHorizontalAlignment(HAlign_Left);
|
||||
}
|
||||
}
|
||||
|
||||
return Button;
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::FocusPrimaryButton()
|
||||
{
|
||||
if (PrimaryFocusButton)
|
||||
{
|
||||
PrimaryFocusButton->SetKeyboardFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetKeyboardFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandlePrimaryActionClicked()
|
||||
{
|
||||
ConfirmActiveScreen();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleBackClicked()
|
||||
{
|
||||
BackFromActiveScreen();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleSaveAndQuitClicked()
|
||||
{
|
||||
SaveAndQuit();
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleMaleCharacterClicked()
|
||||
{
|
||||
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultMale);
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::HandleFemaleCharacterClicked()
|
||||
{
|
||||
SetSelectedCharacterArchetype(EAgrarianMvpCharacterArchetype::YoungAdultFemale);
|
||||
}
|
||||
|
||||
FText UAgrarianMvpFrontendWidget::GetSelectedCharacterLabel() const
|
||||
@@ -616,23 +466,3 @@ FText UAgrarianMvpFrontendWidget::GetSelectedRoleLabel() const
|
||||
{
|
||||
return FText::FromString(TEXT("Pioneer"));
|
||||
}
|
||||
|
||||
void UAgrarianMvpFrontendWidget::DrawTextAt(
|
||||
FSlateWindowElementList& OutDrawElements,
|
||||
int32& LayerId,
|
||||
const FGeometry& AllottedGeometry,
|
||||
const FText& Text,
|
||||
const FVector2D& Position,
|
||||
float Width,
|
||||
const FSlateFontInfo& Font,
|
||||
const FLinearColor& Color) const
|
||||
{
|
||||
FSlateDrawElement::MakeText(
|
||||
OutDrawElements,
|
||||
++LayerId,
|
||||
AllottedGeometry.ToPaintGeometry(FVector2f(FMath::Max(96.0f, Width), Font.Size + 18.0f), FSlateLayoutTransform(FVector2f(Position))),
|
||||
Text,
|
||||
Font,
|
||||
ESlateDrawEffect::None,
|
||||
Color);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user