From 13a821c0111acffa1586c4083dd47a424763685a Mon Sep 17 00:00:00 2001 From: Nic0Nic0Nii <89110903+Nic0Nic0Nii@users.noreply.github.com> Date: Thu, 8 Feb 2024 21:30:05 +0000 Subject: [PATCH] Implemented controller/keyboard controls for the inventory consumable window Co-authored-by: sigonasr2 --- .../InventoryConsumableWindow.cpp | 136 ++++++++++++++++++ Adventures in Lestoria/MenuComponent.h | 1 + Adventures in Lestoria/MenuType.h | 50 +++---- 3 files changed, 163 insertions(+), 24 deletions(-) diff --git a/Adventures in Lestoria/InventoryConsumableWindow.cpp b/Adventures in Lestoria/InventoryConsumableWindow.cpp index d46ff784..3873fb10 100644 --- a/Adventures in Lestoria/InventoryConsumableWindow.cpp +++ b/Adventures in Lestoria/InventoryConsumableWindow.cpp @@ -85,4 +85,140 @@ void Menu::InitializeConsumableInventoryWindow(){ inventoryWindow->ADD("itemDescription",MenuLabel)(geom2d::rect(vf2d{2,117.f},{windowSize.x-4,windowSize.y-108}),"",1,ComponentAttr::SHADOW)END; auto okButton=inventoryWindow->ADD("OK Button",MenuComponent)(geom2d::rect{{windowSize.x/2-24,173.f},{48,12}},"Ok",[](MenuFuncData data){Menu::CloseMenu();return true;})END; + + inventoryWindow->SetupKeyboardNavigation( + [](MenuType type,Data&returnData){ //On Open + //Get the first component in the consumables list. + std::vector>&components=Component(INVENTORY_CONSUMABLES,"inventory")->GetComponents(); + if(components.size()>0){ + returnData=components[0].lock()->GetName(); + }else{ + returnData="OK Button"; + } + }, + { //Button Key + {game->KEY_CONFIRM,{"Set Loadout Item",[](MenuType type){}}}, + {game->KEY_BACK,{"Back",[](MenuType type){ + Menu::CloseMenu(); + }}}, + } + ,{ //Button Navigation Rules + {"inventory",{ + .up="Quit Game Button", + .down="Load Game Button",}}, + {"Load Game Button",{ + .up="New Game Button", + .down="Quit Game Button",}}, + {"Quit Game Button",{ + .up=[](MenuType type,Data&returnData){ + auto&selection=Menu::menus[type]->GetSelection(); + auto&itemsList=Component(type,"inventory")->GetComponents(); + auto itemsWindow=Component(type,"inventory") + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); + if(itemsList.size()>0){ + if(component==itemsList.end()){ + //Set the selected button to the last element in the list. + returnData=itemsList.back(); + }else{ + int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); + std::weak_ptrselectedButton=DYNAMIC_POINTER_CAST(component); + int newRowIndex=selectedButton.lock()->inventoryIndex-invWidth; //Moving up moves the cursor up an entire row. + if(newRowIndex<0){ + //This means we have to wrap around. + newRowIndex+=itemsList.size(); + } + if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + //Select the component that matches this new number. + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST(comp).lock()->inventoryIndex==newRowIndex;}); + if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + returnData=component; + } + }else{ + returnData="OK Button"; + } + }, + .right=[](MenuType type,Data&returnData){ + auto&selection=Menu::menus[type]->GetSelection(); + auto&itemsList=Component(type,"inventory")->GetComponents(); + auto itemsWindow=Component(type,"inventory") + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); + if(itemsList.size()>0){ + if(component==itemsList.end()){ + //Set the selected button to the first element in the list. + returnData=itemsList.front(); + }else{ + int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); + std::weak_ptrselectedButton=DYNAMIC_POINTER_CAST(component); + int newRowIndex=std::clamp(selectedButton.lock()->inventoryIndex+1,(selectedButton.lock()->inventoryIndex/invWidth)*invWidth,std::min(itemsList.size(),(selectedButton.lock()->inventoryIndex/invWidth+1)*invWidth-1)); //Moving right, we need to wrap around if we get to the edge. + if(newRowIndex>=itemsList.size()){ + //This means we have to wrap around. + newRowIndex-=itemsList.size(); + } + if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + //Select the component that matches this new number. + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST(comp).lock()->inventoryIndex==newRowIndex;}); + if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + returnData=component; + } + }else{ + returnData="OK Button"; + } + }, + .down=[](MenuType type,Data&returnData){ + auto&selection=Menu::menus[type]->GetSelection(); + auto&itemsList=Component(type,"inventory")->GetComponents(); + auto itemsWindow=Component(type,"inventory") + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); + if(itemsList.size()>0){ + if(component==itemsList.end()){ + //Set the selected button to the first element in the list. + returnData=itemsList.front(); + }else{ + int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); + std::weak_ptrselectedButton=DYNAMIC_POINTER_CAST(component); + int newRowIndex=selectedButton.lock()->inventoryIndex+invWidth; //Moving down moves the cursor down an entire row. + if(newRowIndex>=itemsList.size()){ + //This means we have to wrap around. + newRowIndex-=itemsList.size(); + } + if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + //Select the component that matches this new number. + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST(comp).lock()->inventoryIndex==newRowIndex;}); + if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + returnData=component; + } + }else{ + returnData="OK Button"; + } + }, + .left=[](MenuType type,Data&returnData){ + auto&selection=Menu::menus[type]->GetSelection(); + auto&itemsList=Component(type,"inventory")->GetComponents(); + auto itemsWindow=Component(type,"inventory") + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return comp.lock()==selection.lock();}); + if(itemsList.size()>0){ + if(component==itemsList.end()){ + //Set the selected button to the last element in the list. + returnData=itemsList.back(); + }else{ + int invWidth=int((itemsWindow->rect.size.x-12)/(float(itemsWindow->options.size.x)+itemsWindow->options.padding)); + std::weak_ptrselectedButton=DYNAMIC_POINTER_CAST(component); + + int newRowIndex=std::clamp(selectedButton.lock()->inventoryIndex-1,(selectedButton.lock()->inventoryIndex/invWidth)*invWidth,std::min(itemsList.size(),(selectedButton.lock()->inventoryIndex/invWidth+1)*invWidth-1)); //Moving left, we need to wrap around if we get to the edge. + if(newRowIndex<0){ + //This means we have to wrap around. + newRowIndex+=itemsList.size(); + } + if(newRowIndex<0||newRowIndex>=itemsList.size())ERR(std::format("New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + //Select the component that matches this new number. + auto component=std::find_if(itemsList.begin(),itemsList.end(),[&](auto&comp){return DYNAMIC_POINTER_CAST(comp).lock()->inventoryIndex==newRowIndex;}); + if(component==itemsList.end())ERR(std::format("WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING!",newRowIndex)); + returnData=component; + } + }else{ + returnData="OK Button"; + } + }, + }}, + }); } \ No newline at end of file diff --git a/Adventures in Lestoria/MenuComponent.h b/Adventures in Lestoria/MenuComponent.h index d9aef0c5..99a3f4b1 100644 --- a/Adventures in Lestoria/MenuComponent.h +++ b/Adventures in Lestoria/MenuComponent.h @@ -77,6 +77,7 @@ class MenuComponent:public IAttributable{ friend class EncountersSpawnListScrollableWindowComponent; friend class MenuItemItemButton; friend class RowItemDisplay; + friend class InventoryConsumableWindow; MenuType menuDest; MenuFunc onHover=[](MenuFuncData dat){return true;}; MenuFunc onMouseOut=[](MenuFuncData dat){return true;}; diff --git a/Adventures in Lestoria/MenuType.h b/Adventures in Lestoria/MenuType.h index d9fa2c95..5052dff6 100644 --- a/Adventures in Lestoria/MenuType.h +++ b/Adventures in Lestoria/MenuType.h @@ -41,30 +41,32 @@ enum MenuType{ /////////////////////////////////////////////////////////// /*DO NOT REMOVE!!*/ENUM_START,/////////////////////////////// /////////////////////////////////////////////////////////// - INVENTORY_CONSUMABLES, - CLASS_INFO, - CLASS_SELECTION, - MAIN_MENU, - OVERWORLD_LEVEL_SELECT, - ITEM_LOADOUT, - LEVEL_COMPLETE, - OVERWORLD_MENU, - CHARACTER_MENU, - INVENTORY, - MERCHANT, - BUY_ITEM, - SELL_ITEM, - BLACKSMITH, - CRAFT_ITEM, - CRAFT_CONSUMABLE, - CONSUMABLE_CRAFT_ITEM, - SAVE_FILE_NAME, - LOAD_GAME, - USER_ID, - SETTINGS, - SHERMAN, - INPUT_KEY_DISPLAY, - NEW_INPUT, + // 13% Controller Compatibility. (100 total items, 4 items per menu * 25 menus) + INVENTORY_CONSUMABLES, //100% Controller Compatibility + CLASS_INFO, //0% Controller Compatibility + CLASS_SELECTION, //0% Controller Compatibility + MAIN_MENU, //100% Controller Compatibility + OVERWORLD_LEVEL_SELECT, //100% Controller Compatibility + ITEM_LOADOUT, //0% Controller Compatibility + LEVEL_COMPLETE, //0% Controller Compatibility + OVERWORLD_MENU, //0% Controller Compatibility + CHARACTER_MENU, //0% Controller Compatibility + INVENTORY, //0% Controller Compatibility + MERCHANT, //0% Controller Compatibility + BUY_ITEM, //0% Controller Compatibility + SELL_ITEM, //0% Controller Compatibility + BLACKSMITH, //0% Controller Compatibility + CRAFT_ITEM, //0% Controller Compatibility + CRAFT_CONSUMABLE, //0% Controller Compatibility + CONSUMABLE_CRAFT_ITEM, //0% Controller Compatibility + SAVE_FILE_NAME, //0% Controller Compatibility + LOAD_GAME, //0% Controller Compatibility + USER_ID, //0% Controller Compatibility + SETTINGS, //0% Controller Compatibility + SHERMAN, //0% Controller Compatibility + INPUT_KEY_DISPLAY, //25% Controller Compatibility + NEW_INPUT, //100% Controller Compatibility + PAUSE, //0% Controller Compatibility /////////////////////////////////////////////////////////// /*DO NOT REMOVE!!*/ENUM_END//////////////////////////////// ///////////////////////////////////////////////////////////