Refactor inventory window so the scrollable consumable window now subscribes to a listener.
Listener list system removes the arbitrary requirement of components needing to be called "inventory" (very error-prone)
This commit is contained in:
parent
04d6f42526
commit
46462a24e7
64
Crawler/.vscode/settings.json
vendored
Normal file
64
Crawler/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
@ -23,6 +23,10 @@ void Menu::InitializeInventoryWindow(){
|
||||
|
||||
ScrollableWindowComponent*inventory=new ScrollableWindowComponent(INVENTORY,{{1,0},{windowSize.x,float(totalSpacing*3-itemSpacing)}},nullptr,[](MenuFuncData data){});
|
||||
inventoryWindow->AddComponent("inventory",inventory);
|
||||
Menu::AddInventoryListener(inventory,"Consumables");
|
||||
Menu::AddInventoryListener(inventory,"Equipment");
|
||||
Menu::AddInventoryListener(inventory,"Accessories");
|
||||
Menu::AddInventoryListener(inventory,"Materials");
|
||||
|
||||
//We don't have to actually populate the inventory list because now when an item gets added, it will automatically add the correct component in for us.
|
||||
|
||||
|
@ -564,49 +564,21 @@ void Menu::SetMouseNavigation(bool mouseNavigation){
|
||||
void Menu::InventorySlotsUpdated(ITCategory cat){
|
||||
//Update the inventory with a new inventory slot, since there's one additional item to interact with now.
|
||||
std::vector<std::string>&inv=Inventory::get(cat);
|
||||
MenuType inventoryWindow;
|
||||
if(cat=="Consumables"){
|
||||
inventoryWindow=INVENTORY;
|
||||
}else
|
||||
if(cat=="Equipment"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
||||
return; //Currenly a no-op
|
||||
}else
|
||||
if(cat=="Accesories"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
||||
return; //Currenly a no-op
|
||||
}else
|
||||
if(cat=="Materials"){
|
||||
//TODO: Update different inventories depending on what the item's category is.
|
||||
std::cout<<"WARNING! Unimplemented inventory slot addition for category "<<cat<<"!"<<std::endl;
|
||||
return; //Currenly a no-op
|
||||
}else{
|
||||
throw;
|
||||
std::cout<<"WARNING! Attempting to add an inventory to a category that does not exist. THIS SHOULD NOT BE HAPPENING!"<<std::endl;
|
||||
}
|
||||
//HACK ALERT!! We make a very bold assumption here that every inventory window will contain a ScrollableWindowComponent called "inventory"! Because it's a safemap, if it doesn't exist it will let us know as such, we won't include any extra checks here.
|
||||
ScrollableWindowComponent*inventory=((ScrollableWindowComponent*)menus[inventoryWindow]->components["inventory"]);
|
||||
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
||||
if(inventory->ComponentCount()<inv.size()){//We need more space to display our items.
|
||||
int invWidth="ThemeGlobal.InventoryWidth"_I;
|
||||
int x=(inv.size()-1)%invWidth;
|
||||
int y=(inv.size()-1)/invWidth;
|
||||
int itemIndex=y*invWidth+x;
|
||||
|
||||
int buttonSize="ThemeGlobal.InventoryButtonSize"_I;
|
||||
int totalSpacing="ThemeGlobal.InventoryItemSpacing"_I+buttonSize;
|
||||
|
||||
MenuFunc useItemFunc=[](MenuFuncData data){
|
||||
MenuItemButton*button=(MenuItemButton*)data.component;
|
||||
button->UseItem();
|
||||
};
|
||||
|
||||
MenuItemButton*button=new MenuItemButton{inventoryWindow,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
|
||||
inventory->AddComponent(menus[inventoryWindow],"item"+std::to_string(itemIndex),button);
|
||||
}else
|
||||
if(inventory->ComponentCount()>inv.size()){ //There are empty spots, so let's clean up.
|
||||
inventory->RemoveEmptySlots();
|
||||
for(MenuComponent*component:inventoryListeners.at(cat)){
|
||||
component->OnInventorySlotsUpdate(cat);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::AddInventoryListener(MenuComponent*component,ITCategory category){
|
||||
if(inventoryListeners.count(category)){
|
||||
std::vector<MenuComponent*>&listenerList=inventoryListeners.at(category);
|
||||
if(std::find(listenerList.begin(),listenerList.end(),component)!=listenerList.end()){
|
||||
std::cout<<"WARNING! Component "<<component->name<<" has already been added to the "<<category<<" listener list! There should not be any duplicates!!"<<std::endl;
|
||||
throw;
|
||||
}
|
||||
listenerList.push_back(component);
|
||||
}else{
|
||||
std::cout<<"WARNING! Inventory category "<<category<<" does not exist!"<<std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
@ -24,12 +24,13 @@ class Menu:IAttributable{
|
||||
friend class Player;
|
||||
|
||||
float buttonHoldTime=0;
|
||||
std::vector<MenuComponent*>displayComponents; //Components that are only for displaying purposes.
|
||||
std::vector<MenuComponent*>displayComponents; //Comp.onents that are only for displaying purposes.
|
||||
vi2d selection={-1,-1};
|
||||
vi2d lastActiveMousePos={};
|
||||
|
||||
MenuComponent*draggingComponent=nullptr;
|
||||
Renderable r,overlay;
|
||||
static safemap<ITCategory,std::vector<MenuComponent*>>inventoryListeners; //All menu components that care about inventory updates subscribe to this list indirectly (See Menu::AddInventoryListener()).
|
||||
public:
|
||||
//The constructor is private. Use CreateMenu() instead!
|
||||
Menu()=default;
|
||||
@ -54,6 +55,7 @@ public:
|
||||
bool UsingMouseNavigation();
|
||||
void SetMouseNavigation(bool mouseNavigation);
|
||||
static void InventorySlotsUpdated(ITCategory cat); //Called whenever an inventory item gets added to the player's inventory, thus increasing the total number of slots in our bag.
|
||||
static void AddInventoryListener(MenuComponent*component,ITCategory category); //Adds a component to be in a given listener category.
|
||||
private:
|
||||
Menu(vf2d pos,vf2d size);
|
||||
void HoverMenuSelect(Crawler*game);
|
||||
|
@ -85,3 +85,5 @@ bool MenuComponent::HandleOutsideDisabledButtonSelection(MenuComponent*disabledB
|
||||
vf2d MenuComponent::GetPos(){
|
||||
return rect.pos;
|
||||
}
|
||||
|
||||
void MenuComponent::OnInventorySlotsUpdate(ITCategory cat){}
|
@ -45,4 +45,6 @@ public:
|
||||
virtual bool DropDraggableItem(MenuComponent*draggable);
|
||||
//A notification that a button outside the region has been selected. Return false if it's not allowed.
|
||||
virtual bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton);
|
||||
//Called whenever an inventory slot gets updated, whether it's adding or removing an item.
|
||||
virtual void OnInventorySlotsUpdate(ITCategory cat);
|
||||
};
|
@ -191,7 +191,7 @@ public:
|
||||
virtual inline size_t ComponentCount(){
|
||||
return components.size();
|
||||
}
|
||||
virtual void RemoveButton(MenuComponent*button){
|
||||
virtual inline void RemoveButton(MenuComponent*button){
|
||||
std::vector<MenuComponent*>&buttonList=Menu::menus[button->parentMenu]->buttons.at(button->GetPos().y);
|
||||
std::vector<MenuComponent*>&keyboardButtonList=Menu::menus[button->parentMenu]->keyboardButtons.at(button->GetPos().y);
|
||||
size_t removedCount=0;
|
||||
@ -214,7 +214,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void RemoveEmptySlots(){
|
||||
void inline RemoveEmptySlots(){
|
||||
//Algorithm will iterate through all slots, finding blank slots. Each time a blank slot is found, all items will shift over by one, and then the last item will be removed. Repeat until all slots iterated through.
|
||||
for(int i=0;i<components.size();i++){
|
||||
MenuComponent*button=components[i];
|
||||
@ -237,4 +237,28 @@ public:
|
||||
}
|
||||
bounds=CalculateBounds(); //Recalculate the bounds as it's possible the width/height of the component has changed.
|
||||
}
|
||||
virtual void OnInventorySlotsUpdate(ITCategory cat)override{
|
||||
std::vector<std::string>&inv=Inventory::get(cat);
|
||||
//We only want to refresh the inventory slots if the component count no longer matches what's actually in our inventory.
|
||||
if(ComponentCount()<inv.size()){//We need more space to display our items.
|
||||
int invWidth="ThemeGlobal.InventoryWidth"_I;
|
||||
int x=(inv.size()-1)%invWidth;
|
||||
int y=(inv.size()-1)/invWidth;
|
||||
int itemIndex=y*invWidth+x;
|
||||
|
||||
int buttonSize="ThemeGlobal.InventoryButtonSize"_I;
|
||||
int totalSpacing="ThemeGlobal.InventoryItemSpacing"_I+buttonSize;
|
||||
|
||||
MenuFunc useItemFunc=[](MenuFuncData data){
|
||||
MenuItemButton*button=(MenuItemButton*)data.component;
|
||||
button->UseItem();
|
||||
};
|
||||
|
||||
MenuItemButton*button=new MenuItemButton{parentMenu,{{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get("Consumables"),itemIndex,useItemFunc};
|
||||
AddComponent(Menu::menus[parentMenu],"item"+std::to_string(itemIndex),button);
|
||||
}else
|
||||
if(ComponentCount()>inv.size()){ //There are empty spots, so let's clean up.
|
||||
RemoveEmptySlots();
|
||||
}
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user