Make lastActiveMousePos static for menus so the mouse cursor doesn't get detected as "moved" everytime we open a new menu. Fixed compile issues for various aspects of gamepad menu opening. Finished interpreting all combinations of setting up buttons and navigation.

pull/35/head
sigonasr2 11 months ago
parent 210a46a5f9
commit c972b33c56
  1. 12
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 22
      Adventures in Lestoria/LoadGameWindow.cpp
  3. 6
      Adventures in Lestoria/MainMenuWindow.cpp
  4. 103
      Adventures in Lestoria/Menu.cpp
  5. 21
      Adventures in Lestoria/Menu.h
  6. 4
      Adventures in Lestoria/SaveFileWindow.cpp
  7. 4
      Adventures in Lestoria/SoundEffect.cpp
  8. 2
      Adventures in Lestoria/TODO.txt
  9. 2
      Adventures in Lestoria/Version.h

@ -101,6 +101,7 @@ InputGroup AiL::KEY_SCROLLUP;
InputGroup AiL::KEY_SCROLLDOWN;
InputGroup AiL::KEY_BACK;
InputGroup AiL::KEY_START;
InputGroup AiL::KEY_SELECT;
#ifndef __EMSCRIPTEN__
::discord::Core*Discord{};
@ -284,6 +285,17 @@ bool AiL::OnUserUpdate(float fElapsedTime){
RenderWorld(GetElapsedTime());
GameState::STATE->Draw(this);
RenderMenu();
if(Menu::stack.size()>0){
std::weak_ptr<MenuComponent>component=Menu::stack.back()->GetSelection();
if(!component.expired()){
DrawShadowStringDecal({2,2},"Selection: "+component.lock()->GetName());
}
std::weak_ptr<MenuComponent>keyComponent=Menu::stack.back()->GetKeySelection();
if(!keyComponent.expired()){
DrawShadowStringDecal({2,14},"Key Selection: "+keyComponent.lock()->GetName());
}
}
DrawShadowStringDecal({2,26},"MOUSE NAVIGATION: "+std::to_string(Menu::MOUSE_NAVIGATION));
RenderFadeout();
RenderVersionInfo();
#ifndef __EMSCRIPTEN__

@ -38,6 +38,7 @@ All rights reserved.
#include "Menu.h"
#include "ScrollableWindowComponent.h"
#include "SaveFile.h"
void Menu::InitializeLoadGameWindow(){
Menu*loadGameWindow=CreateMenu(LOAD_GAME,CENTERED,vi2d{96,120});
@ -47,11 +48,11 @@ void Menu::InitializeLoadGameWindow(){
loadGameWindow->ADD("Go Back Button",MenuComponent)(geom2d::rect<float>{{24,124},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END;
loadGameWindow->SetupKeyboardNavigation(
[](MenuType type){ //On Open
[](MenuType type,Data&returnData){ //On Open
if(SaveFile::GetSaveFileCount()>0){
Menu::menus[type]->SetSelection(Component<ScrollableWindowComponent>(type,"Game Files List")->GetComponents()[0]);
returnData=Component<ScrollableWindowComponent>(type,"Game Files List")->GetComponents()[0];
}else{
Menu::menus[type]->SetSelection("Go Back Button");
returnData="Go Back Button";
}
},
{ //Button Key
@ -64,16 +65,17 @@ void Menu::InitializeLoadGameWindow(){
}
,{ //Button Navigation Rules
{"Game Files List",{
.up=[](MenuType type){
.up=[](MenuType type,Data&returnData){
auto&selection=Menu::menus[type]->GetSelection();
auto&gameFilesList=Component<ScrollableWindowComponent>(type,"Game Files List")->GetComponents();
if(std::find_if(gameFilesList.begin(),gameFilesList.end(),[&](auto&comp){return comp.lock()==selection.lock();})==gameFilesList.begin()){
auto component=std::find_if(gameFilesList.begin(),gameFilesList.end(),[&](auto&comp){return comp.lock()==selection.lock();});
if(component==gameFilesList.begin()){
returnData="Go Back Button";
}else{
returnData=*(--component);
}
},
.down="Back Button",}},
{"Go Back Button",{
.left="Continue Button",
.right="Continue Button",}},
.down="Go Back Button",}},
{"Go Back Button",{}},
});
}

@ -83,11 +83,11 @@ void Menu::InitializeMainMenuWindow(){
})END;
mainMenuWindow->SetupKeyboardNavigation(
[](MenuType type){ //On Open
[](MenuType type,Data&returnData){ //On Open
if(SaveFile::GetSaveFileCount()>0){
Menu::menus[type]->SetSelection("Load Game Button");
returnData="Load Game Button";
}else{
Menu::menus[type]->SetSelection("New Game Button");
returnData="New Game Button";
}
},
{ //Button Key

@ -49,6 +49,7 @@ INCLUDE_ITEM_CATEGORIES
INCLUDE_DATA
bool Menu::MOUSE_NAVIGATION=true;
vi2d Menu::lastActiveMousePos{};
std::vector<Menu*>Menu::stack;
std::map<MenuType,Menu*>Menu::menus;
std::string Menu::themeSelection="BlueDefault";
@ -112,23 +113,6 @@ void Menu::InitializeMenus(){
if(menus.count(type)==0){
ERR("WARNING! Menu Type "<<type<<" does not exist!")
}
if(menus[type]->defaultButton.expired()){
bool foundComponent=false;
if(menus[type]->componentCount>0){
for(auto&[key,component]:menus[type]->components){
if(component->selectable){
menus[type]->defaultButton=component;
std::cout<<std::format("WARNING! Menu {} does not have a default button! Automatically choosing {}",int(type),component->GetName())<<std::endl;
foundComponent=true;
break;
}
}
}
if(!foundComponent){
std::cout<<std::format("WARNING! Menu {} does not have a default button and has no default components to set it automatically!",int(type))<<std::endl;
}
}
for(auto&[key,value]:menus[type]->components){
value->AfterCreate();
}
@ -210,7 +194,7 @@ void Menu::Update(AiL*game){
if(component->GetHoverState(game)){
component->hovered=true;
itemHovered=true;
selection=component;
SetSelection(std::weak_ptr<MenuComponent>(component));
}
}
}
@ -311,14 +295,12 @@ void Menu::Draw(AiL*game){
void Menu::OpenMenu(MenuType menu,bool cover){
menus[menu]->cover=cover;
menus[menu]->onOpenFunc(menu);
Data returnData;
menus[menu]->onOpenFunc(menu,returnData);
menus[menu]->SetSelection(returnData);
stack.push_back(menus[menu]);
}
void Menu::SetDefaultButton(std::weak_ptr<MenuComponent>button){
defaultButton=button;
}
void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
std::weak_ptr<MenuComponent>prevSelection=selection;
@ -333,33 +315,51 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
if(game->KEY_UP.Pressed()){
SetMouseNavigation(false);
if(std::holds_alternative<std::string>(nav.up)&&std::get<std::string>(nav.up).length()>0)selection=components[std::get<std::string>(nav.up)];
if(std::holds_alternative<std::string>(nav.up)&&std::get<std::string>(nav.up).length()>0)SetSelection(std::string_view(std::get<std::string>(nav.up)));
else
if(std::holds_alternative<MenuDataFunc>(nav.up))std::get<MenuDataFunc>(nav.up)(type);
if(std::holds_alternative<MenuDataFunc>(nav.up)){
Data returnData;
std::get<MenuDataFunc>(nav.up)(type,returnData);
SetSelection(returnData);
}
}
if(game->KEY_DOWN.Pressed()){
SetMouseNavigation(false);
if(std::holds_alternative<std::string>(nav.down)&&std::get<std::string>(nav.down).length()>0)selection=components[std::get<std::string>(nav.down)];
if(std::holds_alternative<std::string>(nav.down)&&std::get<std::string>(nav.down).length()>0)SetSelection(std::string_view(std::get<std::string>(nav.down)));
else
if(std::holds_alternative<MenuDataFunc>(nav.down))std::get<MenuDataFunc>(nav.down)(type);
if(std::holds_alternative<MenuDataFunc>(nav.down)){
Data returnData;
std::get<MenuDataFunc>(nav.down)(type,returnData);
SetSelection(returnData);
}
}
if(game->KEY_LEFT.Pressed()){
SetMouseNavigation(false);
if(std::holds_alternative<std::string>(nav.left)&&std::get<std::string>(nav.left).length()>0)selection=components[std::get<std::string>(nav.left)];
if(std::holds_alternative<std::string>(nav.left)&&std::get<std::string>(nav.left).length()>0)SetSelection(std::string_view(std::get<std::string>(nav.left)));
else
if(std::holds_alternative<MenuDataFunc>(nav.left))std::get<MenuDataFunc>(nav.left)(type);
if(std::holds_alternative<MenuDataFunc>(nav.left)){
Data returnData;
std::get<MenuDataFunc>(nav.left)(type,returnData);
SetSelection(returnData);
}
}
if(game->KEY_RIGHT.Pressed()){
SetMouseNavigation(false);
if(std::holds_alternative<std::string>(nav.right)&&std::get<std::string>(nav.right).length()>0)selection=components[std::get<std::string>(nav.right)];
if(std::holds_alternative<std::string>(nav.right)&&std::get<std::string>(nav.right).length()>0)SetSelection(std::string_view(std::get<std::string>(nav.right)));
else
if(std::holds_alternative<MenuDataFunc>(nav.right))std::get<MenuDataFunc>(nav.right)(type);
if(std::holds_alternative<MenuDataFunc>(nav.right)){
Data returnData;
std::get<MenuDataFunc>(nav.right)(type,returnData);
SetSelection(returnData);
}
}
}
}
if(game->KEY_CONFIRM.Pressed()){
SetMouseNavigation(game->GetMouse(0).bPressed); //If a click occurs we use mouse controls.
if(game->KEY_UP.Pressed()||game->KEY_RIGHT.Pressed()||game->KEY_LEFT.Pressed()||game->KEY_DOWN.Pressed()||
game->KEY_BACK.Pressed()||game->KEY_CONFIRM.Pressed()||game->KEY_START.Pressed()||game->KEY_SELECT.Pressed()||
game->KEY_SCROLLDOWN.Pressed()||game->KEY_SCROLLUP.Pressed()){
SetMouseNavigation(game->GetMouse(Mouse::LEFT).bPressed||game->GetMouse(Mouse::RIGHT).bPressed||game->GetMouse(Mouse::MIDDLE).bPressed); //If a click occurs we use mouse controls.
buttonHoldTime=0;
}
if(&*prevSelection.lock()!=&*selection.lock()){
@ -374,7 +374,7 @@ void Menu::KeyboardButtonNavigation(AiL*game,vf2d menuPos){
}
if(!handled){
// If the new selection of a button on this frame is disabled for some reason and we didn't handle it, we need to go back to what we had selected before.
selection=prevSelection;
SetSelection(prevSelection);
}
}
}
@ -479,6 +479,9 @@ void Menu::SetMouseNavigation(bool mouseNavigation){
if(MOUSE_NAVIGATION&&!mouseNavigation){
//When mouse navigation was enabled and now needs to be disabled, we store the mouse position.
lastActiveMousePos=game->GetMousePos();
if(!keyboardSelection.expired()){
SetSelection(keyboardSelection);
}
}
MOUSE_NAVIGATION=mouseNavigation;
};
@ -613,10 +616,6 @@ void Menu::AddChapterListener(std::weak_ptr<MenuComponent>component){
MenuFuncData::MenuFuncData(Menu&menu,AiL*const game,std::weak_ptr<MenuComponent>component,std::weak_ptr<ScrollableWindowComponent>parentComponent)
:menu(menu),game(game),component(component),parentComponent(parentComponent){}
void Menu::SetSelection(std::weak_ptr<MenuComponent>button){
selection=button;
}
void Menu::SetupKeyboardNavigation(MenuDataFunc onOpen,MenuInputGroups inputGroups,ButtonNavigationGroups navigationGroups){
this->onOpenFunc=onOpen;
this->inputGroups=inputGroups;
@ -627,7 +626,33 @@ const std::weak_ptr<MenuComponent>Menu::GetSelection()const{
return selection;
}
const std::weak_ptr<MenuComponent>Menu::GetKeySelection()const{
return keyboardSelection;
}
void Menu::SetSelection(std::weak_ptr<MenuComponent>button){
selection=button;
if(navigationGroups.count(button.lock()->GetName())||
!button.lock()->parentComponent.expired()&&navigationGroups.count(button.lock()->parentComponent.lock()->GetName())){
keyboardSelection=button;
}
}
void Menu::SetSelection(std::string_view button){
selection=Component<MenuComponent>(type,button);
selection=Component<MenuComponent>(type,std::string(button));
if(navigationGroups.count(std::string(button))||
!selection.lock()->parentComponent.expired()&&navigationGroups.count(selection.lock()->parentComponent.lock()->GetName())){
keyboardSelection=selection;
}
}
void Menu::SetSelection(std::variant<std::string,std::weak_ptr<MenuComponent>>button){
if(std::holds_alternative<std::string>(button)){
SetSelection(std::string_view(std::get<std::string>(button)));
}else
if(std::holds_alternative<std::weak_ptr<MenuComponent>>(button)){
SetSelection(std::get<std::weak_ptr<MenuComponent>>(button));
}else{
ERR("WARNING! Specified menu opening function does not hold neither a string nor a pointer to a component to use!");
}
}

@ -99,19 +99,20 @@ enum MenuType{
///////////////////////////////////////////////////////////
};
using MenuDataFunc=std::function<void(MenuType)>;
using InputGroupActionDisplayName=std::string;
using ButtonName=std::string;
using MenuInputGroups=std::map<InputGroup,std::pair<InputGroupActionDisplayName,std::variant<ButtonName,MenuDataFunc>>>;
using Data=std::variant<ButtonName,std::weak_ptr<MenuComponent>>;
using MenuDataFunc=std::function<void(MenuType,Data&)>;
using MenuInputGroups=std::map<InputGroup,std::pair<InputGroupActionDisplayName,std::variant<ButtonName,std::function<void(MenuType)>>>>;
using ButtonNavigationGroups=std::map<ButtonName,Navigation>;
struct Navigation{
std::variant<std::string,MenuDataFunc>up;
std::variant<std::string,MenuDataFunc>down;
std::variant<std::string,MenuDataFunc>left;
std::variant<std::string,MenuDataFunc>right;
std::variant<ButtonName,MenuDataFunc>up;
std::variant<ButtonName,MenuDataFunc>down;
std::variant<ButtonName,MenuDataFunc>left;
std::variant<ButtonName,MenuDataFunc>right;
};
class Menu:public IAttributable{
@ -141,7 +142,7 @@ class Menu:public IAttributable{
friend class EntityStats;
float buttonHoldTime=0;
vi2d lastActiveMousePos={};
static vi2d lastActiveMousePos;
int componentCount=0;
std::unique_ptr<MenuComponent>draggingComponent;
@ -218,7 +219,9 @@ public:
void SetSelection(std::string_view button);
void SetSelection(std::weak_ptr<MenuComponent>button);
void SetSelection(std::variant<std::string,std::weak_ptr<MenuComponent>>button);
const std::weak_ptr<MenuComponent>GetSelection()const;
const std::weak_ptr<MenuComponent>GetKeySelection()const;
private:
Menu(vf2d pos,vf2d size);
static MenuType lastMenuTypeCreated;
@ -243,7 +246,9 @@ private:
MenuType type;
MenuInputGroups inputGroups;
ButtonNavigationGroups navigationGroups;
MenuOpenFunc onOpenFunc;
MenuDataFunc onOpenFunc;
std::weak_ptr<MenuComponent>selection;
std::weak_ptr<MenuComponent>keyboardSelection;
static bool MOUSE_NAVIGATION;
bool cover; //A black cover for when a menu pops up to fade out the stuff behind it.

@ -55,8 +55,8 @@ void Menu::InitializeSaveFileWindow(){
saveFileWindow->SetupKeyboardNavigation(
[](MenuType type){ //On Open
Menu::menus[type]->SetSelection("Continue Button");
[](MenuType type,Data&returnData){ //On Open
returnData="Continue Button";
},
{ //Button Key
{game->KEY_START,{"Confirm Filename",[](MenuType type){

@ -61,8 +61,8 @@ void SoundEffect::Initialize(){
utils::datafile&data=DATA["Events"]["SFX"][key][std::format("File[{}]",counter)];
float minPitch=0.9f;
float maxPitch=1.1f;
if(data.GetValueCount()>=3){minPitch=data.GetInt(2)/100.f};
if(data.GetValueCount()>=4){maxPitch=data.GetInt(3)/100.f};
if(data.GetValueCount()>=3){minPitch=data.GetInt(2)/100.f;}
if(data.GetValueCount()>=4){maxPitch=data.GetInt(3)/100.f;}
SOUND_EFFECTS.insert({key,SoundEffect{data.GetString(0),data.GetInt(1)/100.f,minPitch,maxPitch}});
counter++;
}

@ -12,6 +12,8 @@ Settings Menu
-We have to save keybinds to the save file.
- Fix Stage Completed screen, item displays can hit the scrollbar.
- Monster spawn list is not populated in Emscripten?
- Random pitch up down +/-10%.
January 31st
============

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 5974
#define VERSION_BUILD 5997
#define stringify(a) stringify_(a)
#define stringify_(a) #a

Loading…
Cancel
Save