Add in support for subcomponents within subcomponents. Prioritize highest depth menu item when hovering over overlapping items.
This commit is contained in:
		
							parent
							
								
									59eb24b65b
								
							
						
					
					
						commit
						5fc5169ddd
					
				
							
								
								
									
										62
									
								
								Adventures in Lestoria/AccessoryRowItemDisplay.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								Adventures in Lestoria/AccessoryRowItemDisplay.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| #pragma region License | ||||
| /*
 | ||||
| License (OLC-3) | ||||
| ~~~~~~~~~~~~~~~ | ||||
| 
 | ||||
| Copyright 2024 Joshua Sigona <sigonasr2@gmail.com> | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without modification, | ||||
| are permitted provided that the following conditions are met: | ||||
| 
 | ||||
| 1. Redistributions or derivations of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
| 
 | ||||
| 2. Redistributions or derivative works in binary form must reproduce the above | ||||
| copyright notice. This list of conditions and the following	disclaimer must be | ||||
| reproduced in the documentation and/or other materials provided with the distribution. | ||||
| 
 | ||||
| 3. Neither the name of the copyright holder nor the names of its contributors may | ||||
| be used to endorse or promote products derived from this software without specific | ||||
| prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS	"AS IS" AND ANY | ||||
| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
| OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT | ||||
| SHALL THE COPYRIGHT	HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
| INCIDENTAL,	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||||
| TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||||
| BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
| CONTRACT, STRICT LIABILITY, OR TORT	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||||
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
| SUCH DAMAGE. | ||||
| 
 | ||||
| Portions of this software are copyright © 2024 The FreeType | ||||
| Project (www.freetype.org). Please see LICENSE_FT.txt for more information. | ||||
| All rights reserved. | ||||
| */ | ||||
| #pragma endregion | ||||
| #pragma once | ||||
| #include "RowItemDisplay.h" | ||||
| 
 | ||||
| INCLUDE_game | ||||
| INCLUDE_GFX | ||||
| 
 | ||||
| class AccessoryRowItemDisplay:public RowItemDisplay{ | ||||
|     std::weak_ptr<MenuComponent>lockButton; | ||||
| public: | ||||
|     inline AccessoryRowItemDisplay(geom2d::rect<float>rect,const std::weak_ptr<Item>itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE) | ||||
|     :RowItemDisplay(rect,itemRef,onClick,itemNameLabelName,itemDescriptionLabelName,attributes){} | ||||
|     inline ~AccessoryRowItemDisplay(){ | ||||
|         if(!lockButton.expired()){ | ||||
|             size_t subcomponentCount=parentComponent.lock()->GetSubcomponentCount(); | ||||
|             parentComponent.lock()->RemoveButton(lockButton); | ||||
|             if(parentComponent.lock()->GetSubcomponentCount()>=subcomponentCount)ERR(std::format("WARNING! The subcomponent count went from {} -> {} when trying to remove the lock button for item {}! THIS SHOULD NOT BE HAPPENING!",subcomponentCount,parentComponent.lock()->GetSubcomponentCount(),name)); | ||||
|             lockButton.reset(); | ||||
|         } | ||||
|     } | ||||
|     virtual inline void AfterCreate()override final{ | ||||
|         lockButton=parentComponent.lock()->ADDSUB(std::format("{}_lock",name),MenuComponent)(geom2d::rect<float>{rect.pos,vf2d{16.f,8.f}},"Lock",[](MenuFuncData data){ | ||||
|             return true; | ||||
|         })END; | ||||
|     } | ||||
| }; | ||||
| @ -273,6 +273,7 @@ | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="Ability.h" /> | ||||
|     <ClInclude Include="AccessoryRowItemDisplay.h" /> | ||||
|     <ClInclude Include="Animation.h" /> | ||||
|     <ClInclude Include="Attributable.h" /> | ||||
|     <ClInclude Include="AttributableStat.h"> | ||||
|  | ||||
| @ -477,6 +477,9 @@ | ||||
|     <ClInclude Include="FloatingMenuComponent.h"> | ||||
|       <Filter>Header Files\Interface</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="AccessoryRowItemDisplay.h"> | ||||
|       <Filter>Header Files\Interface</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="Player.cpp"> | ||||
|  | ||||
| @ -37,6 +37,7 @@ All rights reserved. | ||||
| #pragma endregion | ||||
| #include "InventoryCreator.h" | ||||
| #include "RowInventoryScrollableWindowComponent.h" | ||||
| #include "AccessoryRowItemDisplay.h" | ||||
| 
 | ||||
| #define DEFINE(SubName) InventoryCreator InventoryCreator::SubName##_InventoryUpdate(&InventoryCreator::SubName##_InventorySlotsUpdate,&InventoryCreator::SubName##_AddButtonOnSlotUpdate); | ||||
| 
 | ||||
| @ -76,7 +77,7 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> | ||||
| std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> InventoryCreator::RowPlayer_AddButtonOnSlotUpdate= | ||||
|     [](InventoryScrollableWindowComponent&component,ITCategory cat){ | ||||
|         RowInventoryScrollableWindowComponent*c=DYNAMIC_CAST<RowInventoryScrollableWindowComponent*>(&component); | ||||
| 	    size_t invSize=c->components.size()+1; | ||||
| 	    size_t invSize=c->GetMainComponentCount()+1; //Remove any subcomponents as they get in the way of the actual amount of items in the list.
 | ||||
|         int invWidth=int(c->rect.size.x/(float(c->options.size.x)+c->options.padding)); | ||||
|         int x=int((invSize-1)%invWidth); | ||||
|         int y=int((invSize-1)/invWidth); | ||||
| @ -84,8 +85,12 @@ std::function<void(InventoryScrollableWindowComponent&component,ITCategory cat)> | ||||
| 
 | ||||
|         vf2d buttonSize=c->options.size; | ||||
|         vf2d totalSpacing={c->options.padding+buttonSize.x,c->options.padding+buttonSize.y}; | ||||
| 
 | ||||
|         auto newItem=c->ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END; | ||||
|         std::shared_ptr<RowItemDisplay>newItem; | ||||
|         if(cat=="Accessories"){ | ||||
|             newItem=c->ADD("item_"+cat+"_"+std::to_string(itemIndex),AccessoryRowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END; | ||||
|         }else{ | ||||
|             newItem=c->ADD("item_"+cat+"_"+std::to_string(itemIndex),RowItemDisplay)(geom2d::rect<float>{totalSpacing*vf2d{float(x),float(y)},buttonSize},Inventory::GetInventorySlot(cat,itemIndex),c->inventoryButtonClickAction,c->itemNameLabelName,c->itemDescriptionLabelName,c->inventoryButtonsActive?ButtonAttr::NONE:ButtonAttr::UNSELECTABLE)END; | ||||
|         } | ||||
|         newItem->SetCompactDescriptions(c->compact); | ||||
|         newItem->SetPriceLabelType(c->priceLabel); | ||||
|         newItem->SetHoverFunc(c->inventoryButtonHoverAction); | ||||
|  | ||||
| @ -167,6 +167,7 @@ void Menu::MenuSelect(AiL*game){ | ||||
| } | ||||
| 
 | ||||
| void Menu::Update(AiL*game){ | ||||
| 
 | ||||
| 	if(!draggingComponent){ | ||||
| 		HoverMenuSelect(game); | ||||
| 	} | ||||
| @ -201,15 +202,19 @@ void Menu::Update(AiL*game){ | ||||
| 		} | ||||
| 	}else{ | ||||
| 		selection={}; | ||||
| 		for(auto&[key,component]:components){ | ||||
| 			if(component->selectable){ | ||||
| 				if(!component->disable&&!component->disableOutsideWindow&&!component->grayedOut){ | ||||
| 					if(component->GetHoverState(game)){ | ||||
| 						if(!Menu::lastHover.expired()&&&*component!=&*Menu::lastHover.lock())SoundEffect::PlaySFX("Menu Navigate",SoundEffect::CENTERED); | ||||
| 						Menu::lastHover=component; | ||||
| 						component->hovered=true; | ||||
| 		std::vector<std::weak_ptr<MenuComponent>>allComponents; | ||||
| 		std::for_each(components.begin(),components.end(),[&](auto&pair){allComponents.push_back(pair.second);}); | ||||
| 		std::sort(allComponents.begin(),allComponents.end(),[](std::weak_ptr<MenuComponent>c1,std::weak_ptr<MenuComponent>c2){return c1.lock()->depth<c2.lock()->depth;}); | ||||
| 		for(const auto&component:allComponents){ | ||||
| 			if(component.lock()->selectable){ | ||||
| 				if(!component.lock()->disable&&!component.lock()->disableOutsideWindow&&!component.lock()->grayedOut){ | ||||
| 					if(component.lock()->GetHoverState(game)){ | ||||
| 						if(!Menu::lastHover.expired()&&&*component.lock()!=&*Menu::lastHover.lock())SoundEffect::PlaySFX("Menu Navigate",SoundEffect::CENTERED); | ||||
| 						Menu::lastHover=component.lock(); | ||||
| 						component.lock()->hovered=true; | ||||
| 						itemHovered=true; | ||||
| 						SetSelection(std::weak_ptr<MenuComponent>(component)); | ||||
| 						SetSelection(std::weak_ptr<MenuComponent>(component.lock())); | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| @ -269,9 +274,6 @@ void Menu::Draw(AiL*game){ | ||||
| 		DrawTiledWindowBackground(game,pos,size,GetRenderColor()); | ||||
| 	} | ||||
| 
 | ||||
| 	std::vector<std::weak_ptr<MenuComponent>>allComponents; | ||||
| 	std::for_each(components.begin(),components.end(),[&](auto&pair){allComponents.push_back(pair.second);}); | ||||
| 	std::sort(allComponents.begin(),allComponents.end(),[](std::weak_ptr<MenuComponent>c1,std::weak_ptr<MenuComponent>c2){return c1.lock()->depth>c2.lock()->depth;}); | ||||
| 
 | ||||
| 	if(GetCurrentTheme().IsScaled()){ | ||||
| 		DrawScaledWindowBorder(game,pos,size,GetRenderColor()); | ||||
| @ -279,6 +281,9 @@ void Menu::Draw(AiL*game){ | ||||
| 		DrawTiledWindowBorder(game,pos,size,GetRenderColor()); | ||||
| 	} | ||||
| 	 | ||||
| 	std::vector<std::weak_ptr<MenuComponent>>allComponents; | ||||
| 	std::for_each(components.begin(),components.end(),[&](auto&pair){allComponents.push_back(pair.second);}); | ||||
| 	std::sort(allComponents.begin(),allComponents.end(),[](std::weak_ptr<MenuComponent>c1,std::weak_ptr<MenuComponent>c2){return c1.lock()->depth>c2.lock()->depth;}); | ||||
| 	for(const auto&component:allComponents){ | ||||
| 		if(!component.expired()&&component.lock()->renderInMain){ | ||||
| 			component.lock()->_DrawDecal(window,this==Menu::stack.back()); | ||||
| @ -688,11 +693,6 @@ void Menu::DrawThemedWindow(vf2d menuPos,vf2d size,Pixel renderColor){ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void Menu::RecalculateComponentCount(){ | ||||
| 	componentCount=components.size(); | ||||
| } | ||||
| 
 | ||||
| const MenuType Menu::GetType()const{ | ||||
| 	return type; | ||||
| } | ||||
| @ -793,3 +793,7 @@ bool Menu::IsCurrentlyActive(MenuType type){ | ||||
| void Menu::ReInitializeInputGroup(){ | ||||
| 	helpDisplay.Initialize(inputGroups); | ||||
| } | ||||
| 
 | ||||
| const bool Menu::GameInitialized()const{ | ||||
| 	return game->GameInitialized(); | ||||
| } | ||||
| @ -120,7 +120,6 @@ class Menu:public IAttributable{ | ||||
| 
 | ||||
|     float buttonHoldTime=0; | ||||
|     static vi2d lastActiveMousePos; | ||||
|     int componentCount=0; | ||||
|     float componentSelectionIndex=0.f; | ||||
|     //This variable is an override available to all menus that allows us to say we've clicked something, so do not handle any automatic clicking anymore of menus for this frame!
 | ||||
|     static bool alreadyClicked; | ||||
| @ -140,7 +139,7 @@ public: | ||||
|     std::shared_ptr<T>_AddComponent(std::string componentKey,std::shared_ptr<T>component,int depth=DEFAULT_DEPTH){ | ||||
| 	    component->parentMenu=type; | ||||
|         if(depth==DEFAULT_DEPTH){ | ||||
| 		    component->depth=STARTING_DEPTH-componentCount; | ||||
| 		    component->depth=STARTING_DEPTH-components.size(); | ||||
| 	    }else{ | ||||
| 		    component->depth=depth; | ||||
| 	    } | ||||
| @ -151,7 +150,7 @@ public: | ||||
| 	    components.SetInitialized(); | ||||
| 	    lastRegisteredComponent=componentKey; | ||||
| 
 | ||||
| 	    RecalculateComponentCount(); | ||||
|         if(GameInitialized())component->AfterCreate(); | ||||
| 
 | ||||
|         return component; | ||||
|     } | ||||
| @ -195,7 +194,6 @@ public: | ||||
| 
 | ||||
|     //X (0-2), Y (0-2) for specific 9-patch tile (tiled version).
 | ||||
|     static Renderable&GetPatchPart(int x,int y); | ||||
|     void RecalculateComponentCount(); | ||||
|     void SetSelection(std::string_view button,const bool scroll=true,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.
 | ||||
|     void SetSelection(std::weak_ptr<MenuComponent>button,const bool scroll=true,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.
 | ||||
|     void SetSelection(Data button,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.
 | ||||
| @ -224,6 +222,8 @@ private: | ||||
|     //This triggers if we use a keyboard/controller input to try and select some off-screen menu item. We should ideally follow the menu cursor.
 | ||||
|     bool HandleOutsideDisabledButtonSelection(std::weak_ptr<MenuComponent>disabledButton); | ||||
| 
 | ||||
|     const bool GameInitialized()const; | ||||
| 
 | ||||
|     Pixel GetRenderColor(); | ||||
|     MenuType type; | ||||
|     MenuInputGroups inputGroups; | ||||
|  | ||||
| @ -42,6 +42,8 @@ All rights reserved. | ||||
| 
 | ||||
| using A=Attribute; | ||||
| 
 | ||||
| #define ADDSUB(key,componentType) _AddSubcomponent<componentType>(key,std::make_shared<componentType> | ||||
| 
 | ||||
| INCLUDE_game | ||||
| 
 | ||||
| class ScrollableWindowComponent:public MenuComponent{ | ||||
| @ -52,6 +54,7 @@ protected: | ||||
|     std::weak_ptr<MenuComponent>upButton; | ||||
|     std::weak_ptr<MenuComponent>downButton; | ||||
|     geom2d::rect<float>bounds; //It's for the scrollbar.
 | ||||
|     std::vector<std::weak_ptr<MenuComponent>>subcomponents; //Subcomponents are anything that is created internally by another component.
 | ||||
|     float scrollBarHeight=0; | ||||
|     float scrollBarTop=0; | ||||
|     bool scrollBarSelected=false; | ||||
| @ -74,11 +77,26 @@ public: | ||||
|         while(components.size()>0){ | ||||
|             RemoveButton(components.back()); | ||||
|         } | ||||
|         while(subcomponents.size()>0){ | ||||
|             std::weak_ptr<MenuComponent>button=subcomponents.back(); | ||||
|             std::string componentName=button.lock()->GetName(); | ||||
|             subcomponents.erase(subcomponents.end()-1); | ||||
|             size_t removedCount=0; | ||||
| 
 | ||||
|             MenuType parentMenu=button.lock()->parentMenu; | ||||
| 
 | ||||
|             removedCount+=Menu::menus[parentMenu]->components.erase(componentName); | ||||
|             if(removedCount!=1){ | ||||
|                 std::cout<<"WARNING! Attempted to remove subbuttons from button listing, but not found!"; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     virtual inline void RemoveButton(std::weak_ptr<MenuComponent>button){ | ||||
|         auto componentSearchResults=std::find_if(components.begin(),components.end(),[&](std::weak_ptr<MenuComponent>ptr){return &*ptr.lock()==&*button.lock();}); | ||||
|         if(componentSearchResults==components.end())ERR("Could not find Component"<<std::quoted(button.lock()->GetName())<<" inside the component list!"); | ||||
|         components.erase(componentSearchResults); | ||||
|         auto subcomponentSearchResults=std::find_if(subcomponents.begin(),subcomponents.end(),[&](std::weak_ptr<MenuComponent>ptr){return &*ptr.lock()==&*button.lock();}); | ||||
|         if(componentSearchResults==components.end()&&subcomponentSearchResults==subcomponents.end())ERR("Could not find Component "<<std::quoted(button.lock()->GetName())<<" inside the component or subcomponent lists!"); | ||||
|         if(componentSearchResults!=components.end())components.erase(componentSearchResults); | ||||
|         if(subcomponentSearchResults!=subcomponents.end())subcomponents.erase(subcomponentSearchResults); | ||||
|         size_t removedCount=0; | ||||
| 
 | ||||
|         MenuType parentMenu=button.lock()->parentMenu; | ||||
| @ -87,9 +105,14 @@ public: | ||||
|         if(removedCount!=1){ | ||||
|             std::cout<<"WARNING! Attempted to remove buttons from button listing, but not found!"; | ||||
|         } | ||||
|         Menu::menus[parentMenu]->RecalculateComponentCount(); | ||||
|         CalculateBounds(); | ||||
|     } | ||||
|     virtual inline size_t GetMainComponentCount()const{ | ||||
|         return components.size(); | ||||
|     } | ||||
|     virtual inline size_t GetSubcomponentCount()const{ | ||||
|         return subcomponents.size(); | ||||
|     } | ||||
|     virtual inline void SetScrollAmount(vf2d scrollOffset){ | ||||
|         this->targetScrollOffset=scrollOffset; | ||||
|     } | ||||
| @ -148,6 +171,11 @@ protected: | ||||
|             if(componentPtr->renderInMain)ERR(std::format("WARNING! Component {} is inside a ScrollableWindowComponent but renders in main instead! Parent Component: {}",componentPtr->GetName(),GetName())); | ||||
|             componentPtr->_BeforeUpdate(game); | ||||
|         } | ||||
|         for(const auto&component:subcomponents){ | ||||
|             std::shared_ptr<MenuComponent>componentPtr=component.lock(); | ||||
|             if(componentPtr->renderInMain)ERR(std::format("WARNING! Subcomponent {} is inside a ScrollableWindowComponent but renders in main instead! Parent Component: {}",componentPtr->GetName(),GetName())); | ||||
|             componentPtr->_BeforeUpdate(game); | ||||
|         } | ||||
|     } | ||||
|     virtual inline void Update(AiL*game)override{ | ||||
| 	    MenuComponent::Update(game); | ||||
| @ -210,6 +238,15 @@ protected: | ||||
|             } | ||||
|             component.lock()->_Update(game); | ||||
|         } | ||||
|         std::sort(subcomponents.begin(),subcomponents.end(),[](std::weak_ptr<MenuComponent>c1,std::weak_ptr<MenuComponent>c2){return c1.lock()->depth>c2.lock()->depth;});         | ||||
|         for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|             if(OnScreen(component.lock())){ | ||||
|                 component.lock()->EnableOutsideWindow(); | ||||
|             }else{ | ||||
|                 component.lock()->DisableOutsideWindow(); | ||||
|             } | ||||
|             component.lock()->_Update(game); | ||||
|         } | ||||
| 
 | ||||
|         upButton.lock()->disable=false; | ||||
|         downButton.lock()->disable=false; | ||||
| @ -238,6 +275,9 @@ protected: | ||||
|                 for(std::weak_ptr<MenuComponent>component:components){ | ||||
|                     component.lock()->rect.pos=component.lock()->originalPos+scrollOffset; | ||||
|                 } | ||||
|                 for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|                     component.lock()->rect.pos=component.lock()->originalPos+scrollOffset; | ||||
|                 } | ||||
|                 lastScrollUpdate=1/60.f; | ||||
|             } | ||||
|         } | ||||
| @ -270,6 +310,9 @@ protected: | ||||
|         for(std::weak_ptr<MenuComponent>component:components){ | ||||
|             component.lock()->_DrawDecal(subWindow,focused); | ||||
|         } | ||||
|         for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|             component.lock()->_DrawDecal(subWindow,focused); | ||||
|         } | ||||
|         if(!geom2d::contains(rect,bounds)){ | ||||
|             DrawScrollbar(window,{},focused); | ||||
|         } | ||||
| @ -298,8 +341,44 @@ public: | ||||
|                 bounds.size.y+=sizeIncrease; | ||||
|             } | ||||
|         } | ||||
|         for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|             if(component.lock()->rect.pos.x<bounds.pos.x){ | ||||
|                 float sizeIncrease=bounds.pos.x-component.lock()->rect.pos.x; | ||||
|                 bounds.size.x+=sizeIncrease; | ||||
|                 bounds.pos.x=component.lock()->rect.pos.x; | ||||
|             } | ||||
|             if(component.lock()->rect.right().start.x>bounds.right().start.x){ | ||||
|                 float sizeIncrease=component.lock()->rect.right().start.x-bounds.right().start.x; | ||||
|                 bounds.size.x+=sizeIncrease; | ||||
|             } | ||||
|             if(component.lock()->rect.pos.y<bounds.pos.y){ | ||||
|                 float sizeIncrease=bounds.pos.y-component.lock()->rect.pos.y; | ||||
|                 bounds.size.y+=sizeIncrease; | ||||
|                 bounds.pos.y=component.lock()->rect.pos.y; | ||||
|             } | ||||
|             if(component.lock()->rect.bottom().start.y>bounds.bottom().start.y){ | ||||
|                 float sizeIncrease=component.lock()->rect.bottom().start.y-bounds.bottom().start.y; | ||||
|                 bounds.size.y+=sizeIncrease; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| public: | ||||
|     template<class T> | ||||
|     std::shared_ptr<T> _AddSubcomponent(std::string key,std::shared_ptr<T>button){ | ||||
|         if(Menu::menus[parentMenu]->components.count(key)){ | ||||
| 		    ERR("WARNING! Key "<<key<<" for menu"<<parentMenu<<" already exists! Key names must be unique!") | ||||
| 	    } | ||||
| 
 | ||||
|         subcomponents.push_back(button); | ||||
|         button->renderInMain=false; //Now we are in control!
 | ||||
|         button->parentComponent=DYNAMIC_POINTER_CAST<ScrollableWindowComponent>(Menu::menus[parentMenu]->components[this->GetName()]); | ||||
|         button->disable=disable; | ||||
| 
 | ||||
|         CalculateBounds(); | ||||
| 
 | ||||
|         Menu::menus[parentMenu]->_AddComponent(key,button); | ||||
|         return button; | ||||
|     } | ||||
|     template<class T> | ||||
|     std::shared_ptr<T> _AddComponent(std::string key,std::shared_ptr<T>button){ | ||||
|         if(Menu::menus[parentMenu]->components.count(key)){ | ||||
| @ -331,11 +410,17 @@ public: | ||||
|     inline std::vector<std::weak_ptr<MenuComponent>>&GetComponents(){ | ||||
|         return components; | ||||
|     } | ||||
|     inline std::vector<std::weak_ptr<MenuComponent>>&GetSubcomponents(){ | ||||
|         return subcomponents; | ||||
|     } | ||||
|     virtual inline void Enable()override final{ | ||||
|         MenuComponent::Enable(); | ||||
|         for(std::weak_ptr<MenuComponent>component:components){ | ||||
|             component.lock()->Enable(); | ||||
|         } | ||||
|         for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|             component.lock()->Enable(); | ||||
|         } | ||||
|         if(upButton.lock()){upButton.lock()->Enable();} | ||||
|         if(downButton.lock()){downButton.lock()->Enable();} | ||||
|     }; | ||||
| @ -344,6 +429,9 @@ public: | ||||
|         for(std::weak_ptr<MenuComponent>component:components){ | ||||
|             component.lock()->Disable(); | ||||
|         } | ||||
|         for(std::weak_ptr<MenuComponent>component:subcomponents){ | ||||
|             component.lock()->Disable(); | ||||
|         } | ||||
|         if(upButton.lock()){upButton.lock()->Disable();} | ||||
|         if(downButton.lock()){downButton.lock()->Disable();} | ||||
|     }; | ||||
|  | ||||
| @ -39,7 +39,7 @@ All rights reserved. | ||||
| #define VERSION_MAJOR 0 | ||||
| #define VERSION_MINOR 4 | ||||
| #define VERSION_PATCH 4 | ||||
| #define VERSION_BUILD 7910 | ||||
| #define VERSION_BUILD 7947 | ||||
| 
 | ||||
| #define stringify(a) stringify_(a) | ||||
| #define stringify_(a) #a | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user