338 lines
7.9 KiB
C++
338 lines
7.9 KiB
C++
// Project Lab - NHTV Igad
|
|
|
|
#include "UnrealProject.h"
|
|
#include "MenuScreen.h"
|
|
#include "ButtonHintBar.h"
|
|
#include "SubMenu.h"
|
|
#include "MenuButton.h"
|
|
|
|
void UMenuScreen::NativeConstruct()
|
|
{
|
|
Super::NativeConstruct();
|
|
m_sideViewActive = false;
|
|
m_buttonHintBar = Cast<UButtonHintBar>(WidgetTree->FindWidget("ButtonHintBar"));
|
|
m_menuContainer = Cast<UOverlay>(WidgetTree->FindWidget("MenuContainer"));
|
|
m_sideViewContainer = Cast<UOverlay>(WidgetTree->FindWidget("SideViewContainer"));
|
|
m_menuTitle = Cast<UTextBlock>(WidgetTree->FindWidget("MenuTitle"));
|
|
m_sideViewTitle = Cast<UTextBlock>(WidgetTree->FindWidget("SideViewTitle"));
|
|
}
|
|
|
|
UMenuPanel* UMenuScreen::OpenScreenMenu(TSubclassOf<UMenuPanel> cls)
|
|
{
|
|
UMenuPanel* menu = CreateWidget<UMenuPanel>(GetWorld(), cls);
|
|
if(!menu)
|
|
{
|
|
GERROR("Failed to create menu for screen " + GetName());
|
|
return nullptr;
|
|
}
|
|
|
|
m_menuContainer->AddChildToOverlay(menu);
|
|
OpenSubMenu(menu);
|
|
|
|
menu->FadeIn();
|
|
|
|
return menu;
|
|
}
|
|
USideView* UMenuScreen::OpenSideView(TSubclassOf<class USideView> cls)
|
|
{
|
|
USideView* view = CreateWidget<USideView>(GetWorld(), cls);
|
|
if(!view)
|
|
{
|
|
GERROR("Failed to create side view for screen " + GetName());
|
|
return nullptr;
|
|
}
|
|
UPersistentSideView* pview = Cast<UPersistentSideView>(view);
|
|
|
|
UOverlaySlot* slot = m_sideViewContainer->AddChildToOverlay(view);
|
|
slot->SetHorizontalAlignment(HAlign_Fill);
|
|
slot->SetVerticalAlignment(VAlign_Fill);
|
|
|
|
if(pview)
|
|
m_OpenSubMenu(view, false);
|
|
else
|
|
OpenSubMenu(view);
|
|
|
|
view->FadeIn();
|
|
|
|
// Switch side view active event
|
|
if(!m_sideViewActive)
|
|
{
|
|
SwitchSideViewVisible(true);
|
|
m_sideViewActive = true;
|
|
}
|
|
|
|
return view;
|
|
}
|
|
|
|
void UMenuScreen::CloseAllSideViews()
|
|
{
|
|
TArray<USideView*> viewsToRemove;
|
|
for(int32 i = 0; i < m_sideViewContainer->GetChildrenCount(); i++)
|
|
{
|
|
USideView* sv = Cast<USideView>(m_sideViewContainer->GetChildAt(i));
|
|
if(sv && !sv->IsA<UPersistentSideView>())
|
|
viewsToRemove.Add(sv);
|
|
}
|
|
|
|
for(USideView* sv : viewsToRemove)
|
|
{
|
|
CloseSubMenu(sv);
|
|
}
|
|
}
|
|
|
|
void UMenuScreen::OpenPersistentSideView(UPersistentSideView* sideView)
|
|
{
|
|
UMenuScreen::OpenSubMenu(sideView);
|
|
}
|
|
void UMenuScreen::ClosePersistentSideView(UPersistentSideView* sideView)
|
|
{
|
|
m_CloseSubMenu(sideView, true);
|
|
}
|
|
|
|
void UMenuScreen::OpenSubMenu(class USubMenu* submenu)
|
|
{
|
|
m_OpenSubMenu(submenu);
|
|
}
|
|
void UMenuScreen::CloseSubMenu(class USubMenu* submenu)
|
|
{
|
|
m_CloseSubMenu(submenu);
|
|
}
|
|
|
|
void UMenuScreen::m_OpenSubMenu(class USubMenu* submenu, bool transferFocus)
|
|
{
|
|
CloseAllSideViews();
|
|
|
|
if(transferFocus)
|
|
Super::OpenSubMenu(submenu);
|
|
UMenuScreenSubMenu* mssm = Cast<UMenuScreenSubMenu>(submenu);
|
|
if(!m_menuTitle || !mssm)
|
|
return;
|
|
|
|
// Update titles and sub-titles
|
|
UMenuPanel* panel = Cast<UMenuPanel>(submenu);
|
|
if(panel)
|
|
m_menuTitle->SetText(FText::FromString(mssm->menuName));
|
|
USideView* view = Cast<USideView>(submenu);
|
|
if(view)
|
|
{
|
|
m_sideViewTitle->SetText(FText::FromString(mssm->menuName));
|
|
m_currentSideViews.Add(view);
|
|
}
|
|
}
|
|
void UMenuScreen::m_CloseSubMenu(class USubMenu* submenu, bool persist)
|
|
{
|
|
UMenuScreenSubMenu* mssm = Cast<UMenuScreenSubMenu>(submenu);
|
|
if(mssm)
|
|
mssm->m_isBeingClosed = true;
|
|
UMenuPanel* panel = Cast<UMenuPanel>(submenu);
|
|
if(panel)
|
|
{
|
|
CloseAllSideViews();
|
|
panel->onAnimationEnded.RemoveAll(this);
|
|
panel->onAnimationEnded.AddUObject(this, &UMenuScreen::m_OnFadeOutComplete);
|
|
panel->FadeOut();
|
|
}
|
|
USideView* view = Cast<USideView>(submenu);
|
|
if(view && !persist)
|
|
{
|
|
view->onAnimationEnded.RemoveAll(this);
|
|
view->onAnimationEnded.AddUObject(this, &UMenuScreen::m_OnFadeOutComplete);
|
|
view->FadeOut();
|
|
|
|
// Switch side view active event
|
|
if(m_currentSideViews.Num() > 0 && m_sideViewActive)
|
|
{
|
|
SwitchSideViewVisible(false);
|
|
m_sideViewActive = false;
|
|
}
|
|
|
|
m_currentSideViews.Remove(view);
|
|
}
|
|
|
|
Super::CloseSubMenu(submenu);
|
|
|
|
// Update titles and sub-titles
|
|
if(panel)
|
|
{
|
|
if(m_subMenus.Num() > 0)
|
|
{
|
|
UMenuPanel* newMenu = Cast<UMenuPanel>(m_subMenus.Last());
|
|
if(newMenu)
|
|
m_menuTitle->SetText(FText::FromString(newMenu->menuName));
|
|
else
|
|
goto _set_no_panel_text;
|
|
}
|
|
else
|
|
{
|
|
_set_no_panel_text:
|
|
m_menuTitle->SetText(FText());
|
|
}
|
|
}
|
|
else if(view && !persist)
|
|
{
|
|
if(m_subMenus.Num() > 0)
|
|
{
|
|
USideView* newMenu = Cast<USideView>(m_subMenus.Last());
|
|
if(newMenu)
|
|
m_sideViewTitle->SetText(FText::FromString(newMenu->menuName));
|
|
else
|
|
goto _set_no_view_text;
|
|
}
|
|
else
|
|
{
|
|
_set_no_view_text:
|
|
m_sideViewTitle->SetText(FText());
|
|
}
|
|
}
|
|
if(mssm)
|
|
mssm->m_isBeingClosed = false;
|
|
}
|
|
|
|
void UMenuScreen::m_OnFadeOutComplete(UMenuScreenSubMenu* panel, int32 type)
|
|
{
|
|
if(type == 2) // Fade Out
|
|
{
|
|
panel->RemoveFromParent();
|
|
}
|
|
}
|
|
|
|
static float animationDuration = 0.35f;
|
|
void UMenuScreenSubMenu::NativeConstruct()
|
|
{
|
|
m_animationType = 0;
|
|
m_animationTime = 0.0f;
|
|
m_isBeingClosed = false;
|
|
Super::NativeConstruct();
|
|
}
|
|
UMenuScreenSubMenu::UMenuScreenSubMenu(const FObjectInitializer& init)
|
|
: Super(init)
|
|
{
|
|
menuName = "<Unnamed Menu!>";
|
|
}
|
|
void UMenuScreenSubMenu::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
|
|
{
|
|
Super::NativeTick(MyGeometry, InDeltaTime);
|
|
|
|
float r = FMath::Clamp(m_animationTime / animationDuration, 0.0f, 1.0f);
|
|
if(m_animationType == 1) // Fade In
|
|
{
|
|
SetRenderTranslation(FVector2D(0.0f - ((1.0f - r)*(1.0f - r)) * 100.0f, 0.0f));
|
|
FLinearColor color = FLinearColor(1.0f, 1.0f, 1.0f, r);
|
|
SetColorAndOpacity(color);
|
|
}
|
|
else if(m_animationType == 2) // Fade Out
|
|
{
|
|
SetRenderTranslation(FVector2D(0.0f + (r*r) * 100.0f, 0.0f));
|
|
FLinearColor color = FLinearColor(1.0f, 1.0f, 1.0f, (1.0f-r));
|
|
SetColorAndOpacity(color);
|
|
}
|
|
|
|
if(m_animationType != 0)
|
|
{
|
|
if(r >= 1.0f)
|
|
{
|
|
onAnimationEnded.Broadcast(this, m_animationType);
|
|
m_animationType = 0;
|
|
}
|
|
m_animationTime += InDeltaTime;
|
|
}
|
|
}
|
|
|
|
void UMenuScreenSubMenu::OnSuspend(USubMenu* newSubMenu, bool loseFocus)
|
|
{
|
|
// Don't fade out / lose focus when side view is opened
|
|
USideView* sv = Cast<USideView>(newSubMenu);
|
|
|
|
if(sv)
|
|
loseFocus = false;
|
|
else
|
|
FadeOut();
|
|
Super::OnSuspend(newSubMenu, loseFocus);
|
|
}
|
|
void UMenuScreenSubMenu::OnRestore(USubMenu* removedMenu)
|
|
{
|
|
// To prevent playing the fade in animation again when we receive focus from closing side views when we are actually closing this menu
|
|
if(!m_isBeingClosed && !Cast<USideView>(removedMenu))
|
|
FadeIn();
|
|
Super::OnRestore(removedMenu);
|
|
}
|
|
|
|
void UMenuScreenSubMenu::FadeIn()
|
|
{
|
|
m_animationTime = 0.0f;
|
|
m_animationType = 1;
|
|
}
|
|
void UMenuScreenSubMenu::FadeOut()
|
|
{
|
|
m_animationTime = 0.0f;
|
|
m_animationType = 2;
|
|
}
|
|
UMenuPanel* UMenuScreenSubMenu::OpenScreenMenu(TSubclassOf<class UMenuPanel> cls)
|
|
{
|
|
UMenuScreen* screen = Cast<UMenuScreen>(GetScreen());
|
|
if(screen)
|
|
{
|
|
return screen->OpenScreenMenu(cls);
|
|
}
|
|
return nullptr;
|
|
}
|
|
USideView* UMenuScreenSubMenu::OpenSideView(TSubclassOf<class USideView> cls)
|
|
{
|
|
UMenuScreen* screen = Cast<UMenuScreen>(GetScreen());
|
|
if(screen)
|
|
{
|
|
screen->CloseAllSideViews();
|
|
return screen->OpenSideView(cls);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
class UMenuButton* UMenuScreenSubMenu::AddButton(FString label)
|
|
{
|
|
if(!container)
|
|
return nullptr;
|
|
|
|
UMenuButton* button = CreateWidget<UMenuButton>(GetWorld(), defaultButtonClass);
|
|
if(!button)
|
|
return nullptr;
|
|
|
|
container->AddChild(button);
|
|
RescanItems();
|
|
|
|
button->SetButtonText(label);
|
|
|
|
return button;
|
|
}
|
|
|
|
void UMenuScreenSubMenu::RescanItems()
|
|
{
|
|
m_backButton = nullptr;
|
|
|
|
Super::RescanItems();
|
|
|
|
for(UMenuItemBase* item : m_items)
|
|
{
|
|
UMenuButton* button = Cast<UMenuButton>(item);
|
|
if(button)
|
|
{
|
|
if(button->GetName() == "Back")
|
|
{
|
|
m_backButton = button;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void UMenuScreenSubMenu::NativeOnMenuAction(EMenuActionBinding binding)
|
|
{
|
|
Super::NativeOnMenuAction(binding);
|
|
if(binding == EMenuActionBinding::Back)
|
|
{
|
|
if(m_backButton)
|
|
{
|
|
m_backButton->SimulatePressed();
|
|
}
|
|
}
|
|
}
|
|
|