diff --git a/Crawler/InventoryScrollableWindowComponent.h b/Crawler/InventoryScrollableWindowComponent.h index 27ce779c..181906e1 100644 --- a/Crawler/InventoryScrollableWindowComponent.h +++ b/Crawler/InventoryScrollableWindowComponent.h @@ -55,14 +55,24 @@ private: std::string itemDescriptionLabelName; bool inventoryButtonsActive=true; std::functioninventoryButtonClickAction; + std::functioninventoryButtonHoverAction; + std::functioninventoryButtonMouseOutAction; InventoryWindowOptions options; + CompactText compact=COMPACT; protected: ITCategory inventoryType; public: inline InventoryScrollableWindowComponent(geom2d::rectrect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::functioninventoryButtonClickAction,InventoryWindowOptions options={.padding=8,.size=24},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) :ScrollableWindowComponent(rect,attributes),inventoryType(invType),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName), options(options),inventoryButtonClickAction(inventoryButtonClickAction),inventoryButtonsActive(inventoryButtonsActive){ - Menu::AddInventoryListener(this,invType); + this->inventoryButtonHoverAction=DO_NOTHING; + this->inventoryButtonMouseOutAction=DO_NOTHING; + Menu::AddInventoryListener(this,invType); + } + inline InventoryScrollableWindowComponent(geom2d::rectrect,ITCategory invType,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::functioninventoryButtonClickAction,std::functioninventoryButtonHoverAction,std::functioninventoryButtonMouseOutAction,InventoryWindowOptions options={.padding=8,.size=24},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE) + :InventoryScrollableWindowComponent(rect,invType,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,options,inventoryButtonsActive,attributes){ + this->inventoryButtonHoverAction=inventoryButtonHoverAction; + this->inventoryButtonMouseOutAction=inventoryButtonMouseOutAction; } virtual inline void Update(Crawler*game)override{ ScrollableWindowComponent::Update(game); @@ -78,6 +88,16 @@ public: if(itemDescriptionLabelName.length()>0)Component(parentMenu,itemDescriptionLabelName)->SetLabel(""); } } + inline void SetCompactDescriptions(bool compact){ + if(compact)this->compact=COMPACT; + else this->compact=NON_COMPACT; + for(MenuComponent*component:components){ + MenuItemButton*itemButton=dynamic_cast(component); + if(itemButton){ + itemButton->SetCompactDescriptions(compact); + } + } + } protected: inline void 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. @@ -111,7 +131,8 @@ protected: int buttonSize=options.size; int totalSpacing=options.padding+buttonSize; - ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)({{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get(cat),itemIndex,inventoryButtonClickAction,parentMenu,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END; + ADD("item_"+cat+"_"+std::to_string(itemIndex),MenuItemButton)({{float(totalSpacing*x),float(totalSpacing*y)},{float(buttonSize),float(buttonSize)}},Inventory::get(cat),itemIndex,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,parentMenu,itemNameLabelName,itemDescriptionLabelName,inventoryButtonsActive?IconButtonAttr::SELECTABLE:IconButtonAttr::NOT_SELECTABLE)END + ->SetCompactDescriptions(compact==COMPACT); }else if(components.size()>invSize){ //There are empty spots, so let's clean up. RemoveEmptySlots(); diff --git a/Crawler/InventoryWindow.cpp b/Crawler/InventoryWindow.cpp index f32ec65b..e13dec84 100644 --- a/Crawler/InventoryWindow.cpp +++ b/Crawler/InventoryWindow.cpp @@ -40,6 +40,9 @@ All rights reserved. #include "Menu.h" #include "MenuLabel.h" #include "InventoryScrollableWindowComponent.h" +#include "MenuIconButton.h" +#include "MenuItemButton.h" +#include "MenuItemItemButton.h" INCLUDE_game INCLUDE_ITEM_CATEGORIES @@ -84,7 +87,15 @@ void Menu::InitializeInventoryWindow(){ button->SetSelectionType(HIGHLIGHT); button->S(A::CATEGORY_NAME)=category; - auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,InventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},category,"","",DO_NOTHING)END; + auto inventoryDisplay=inventoryWindow->ADD("Inventory Display - "+category,InventoryScrollableWindowComponent)({{72,28},{150,inventoryWindow->size.y-44}},category,"Item Name Label","Item Description Label",DO_NOTHING, + [](MenuFuncData data){ + Component(data.menu.GetType(),"Item Icon")->SetItem(dynamic_cast(data.component)->GetItem()); + return true; + }, + [](MenuFuncData data){ + Component(data.menu.GetType(),"Item Icon")->SetItem(Item::BLANK); + return true; + })END; if(first){ lastInventoryTypeOpened=category; @@ -92,9 +103,24 @@ void Menu::InitializeInventoryWindow(){ } inventoryDisplay->Enable(first); + inventoryDisplay->SetCompactDescriptions(false); yOffset+=20; first=false; } #pragma endregion + + #pragma region Inventory Description + float inventoryDescriptionWidth=inventoryWindow->pos.x+inventoryWindow->size.x-26-224; + inventoryWindow->ADD("Item Description Outline",MenuLabel)({{224,28},{inventoryDescriptionWidth,inventoryWindow->size.y-44}},"",1,LEFT_ALIGN|OUTLINE|BACKGROUND)END + ->decal=true; + auto itemIcon=inventoryWindow->ADD("Item Icon",MenuItemItemButton)({{226+inventoryDescriptionWidth/2-24,30},{48,48}},Item::BLANK,MenuType::ENUM_END,DO_NOTHING,"","",IconButtonAttr::NOT_SELECTABLE)END; + itemIcon->SetShowQuantity(false); + itemIcon->decal=true; + inventoryWindow->ADD("Item Name Label",MenuLabel)({{226,84},{inventoryDescriptionWidth-6,12}},"",0.75f,LEFT_ALIGN|SHADOW)END + ->decal=true; + inventoryWindow->ADD("Item Description Label",MenuLabel)({{226,94},{inventoryDescriptionWidth-6,inventoryWindow->size.y-44-66}},"",0.5f,LEFT_ALIGN|SHADOW)END + ->decal=true; + + #pragma endregion } \ No newline at end of file diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h index aa79f0c9..de209676 100644 --- a/Crawler/MenuComponent.h +++ b/Crawler/MenuComponent.h @@ -96,7 +96,6 @@ protected: bool disabled=false; //If set to true, this component will not be rendered or updated. bool renderInMain=true; //If set to false, this component is the responsibility of some other windowing system and won't be rendered or updated via the main window loop. bool valid=true; //If set to false, this would cause the component to be removed. - bool decal=false; //If set to true, will use decal rendering (For foreground shenanigans) vf2d labelScaling={1,1}; virtual void Update(Crawler*game); virtual void Draw(Crawler*game,vf2d parentPos); @@ -130,4 +129,5 @@ public: virtual void SetSelectionType(SelectionType selectionType)final; virtual void Enable(bool enabled); virtual void Cleanup(); + bool decal=false; //If set to true, will use decal rendering (For foreground shenanigans) }; \ No newline at end of file diff --git a/Crawler/MenuIconButton.h b/Crawler/MenuIconButton.h index 32955358..f4ba6d1c 100644 --- a/Crawler/MenuIconButton.h +++ b/Crawler/MenuIconButton.h @@ -60,9 +60,19 @@ protected: MenuComponent::Update(game); } virtual inline void Draw(Crawler*game,vf2d parentPos)override{ - MenuComponent::Draw(game,parentPos); - if(icon!=nullptr){ - game->DrawSprite(parentPos+rect.middle()-icon->sprite->Size()/2,icon->sprite,1,Sprite::Flip::NONE); + if(!decal){ + MenuComponent::Draw(game,parentPos); + if(icon!=nullptr){ + game->DrawSprite(parentPos+rect.middle()-icon->sprite->Size()/2,icon->sprite,1,Sprite::Flip::NONE); + } + } + } + virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{ + if(decal){ + MenuComponent::DrawDecal(game,parentPos,focused); + if(icon!=nullptr){ + game->DrawDecal(Menu::menus[parentMenu]->pos+parentPos+rect.middle()-icon->sprite->Size()/2,icon); + } } } }; diff --git a/Crawler/MenuItemButton.h b/Crawler/MenuItemButton.h index dbc631df..bfdb4ddf 100644 --- a/Crawler/MenuItemButton.h +++ b/Crawler/MenuItemButton.h @@ -56,6 +56,11 @@ private: MenuType itemDescriptionMenu; std::string itemNameLabelName; std::string itemDescriptionLabelName; + CompactText compact=COMPACT; + bool hoverState=false; + bool runHoverFunctions=false; + MenuFunc onHover; + MenuFunc onMouseOut; public: int selected=-1; //0-2 representing which loadout slot this item consumes. -1 means not selected. inline MenuItemButton(geom2d::rectrect,std::vector&invRef,int invIndex,MenuFunc onClick,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE) @@ -63,7 +68,13 @@ public: draggable=false; valid=invRef.size()>invIndex; } - inline Item GetItem(){ + inline MenuItemButton(geom2d::rectrect,std::vector&invRef,int invIndex,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE) + :MenuIconButton(rect,invRef.size()>invIndex?invRef[invIndex].Decal():nullptr,onClick,attributes),onHover(onHover),onMouseOut(onMouseOut),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){ + draggable=false; + runHoverFunctions=true; + valid=invRef.size()>invIndex; + } + inline Item&GetItem(){ return Inventory::GetItem(invRef.at(inventoryIndex).Name()); } //Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory. @@ -71,42 +82,79 @@ public: if(invRef.size()<=inventoryIndex)return false; return Inventory::UseItem(invRef.at(inventoryIndex).Name(),amt); } + inline void SetCompactDescriptions(bool compact){ + if(compact)this->compact=COMPACT; + else this->compact=NON_COMPACT; + } protected: + virtual inline void BeforeUpdate(Crawler*game)override{ + if(!hovered&&runHoverFunctions&&hoverState){ + hoverState=false; + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->Enable(false); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->Enable(false); + } + onMouseOut(MenuFuncData{*Menu::menus[parentMenu],game,this,(ScrollableWindowComponent*)(parentComponent)}); + } + } virtual inline void Update(Crawler*game)override{ MenuIconButton::Update(game); valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex].Name()); + std::string labelNameText; + std::string labelDescriptionText; if(valid){ icon=invRef[inventoryIndex].Decal(); - if(hovered){ - if(itemNameLabelName.length()>0)Component(itemDescriptionMenu,itemNameLabelName)->label=invRef[inventoryIndex].Name(); - if(itemDescriptionLabelName.length()>0)Component(itemDescriptionMenu,itemDescriptionLabelName)->label=invRef[inventoryIndex].Description(); - } + labelNameText=invRef[inventoryIndex].Name(); + labelDescriptionText=invRef[inventoryIndex].Description(compact); }else{ icon=nullptr; - if(hovered){ - if(itemNameLabelName.length()>0)Component(itemDescriptionMenu,itemNameLabelName)->label=""; - if(itemDescriptionLabelName.length()>0)Component(itemDescriptionMenu,itemDescriptionLabelName)->label=""; + labelNameText=""; + labelDescriptionText=""; + } + + if(hovered){ + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->label=labelNameText; + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText; + } + if(runHoverFunctions&&!hoverState){ + hoverState=true; + if(itemNameLabelName!=""&&labelNameText.length()>0){ + Component(parentMenu,itemNameLabelName)->Enable(true); + } + if(itemDescriptionLabelName!=""&&labelDescriptionText.length()>0){ + Component(parentMenu,itemDescriptionLabelName)->Enable(true); + } + onHover(MenuFuncData{*Menu::menus[parentMenu],game,this,(ScrollableWindowComponent*)(parentComponent)}); } } } virtual inline void Draw(Crawler*game,vf2d parentPos)override{ - MenuIconButton::Draw(game,parentPos); - if(selected!=-1){ - drawutil::DrawCrosshair(game,{parentPos+rect.pos,rect.size},0); + if(!decal){ + MenuIconButton::Draw(game,parentPos); + if(selected!=-1){ + drawutil::DrawCrosshair(game,{parentPos+rect.pos,rect.size},0); + } } } virtual inline void DrawDecal(Crawler*game,vf2d parentPos,bool focused)override{ - MenuIconButton::DrawDecal(game,parentPos,focused); - if(valid){ - int itemQuantity=Inventory::GetItemCount(invRef.at(inventoryIndex).Name()); //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts... - if(&invRef==&Inventory::get("Monster Loot")||&invRef==&Inventory::get("Stage Loot")){ - itemQuantity=invRef.at(inventoryIndex).Amt(); //So the item quantity comes from the stack itself and not our main inventory. - } - std::string quantityText="x"+std::to_string(itemQuantity); - vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*0.5; - vf2d drawPos=parentPos+rect.pos+rect.size-textSize; - if(PointWithinParent(this,drawPos)){ - game->DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,{0.5,0.5},0.5); + if(decal){ + MenuIconButton::DrawDecal(game,parentPos,focused); + if(valid){ + int itemQuantity=Inventory::GetItemCount(invRef.at(inventoryIndex).Name()); //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts... + if(&invRef==&Inventory::get("Monster Loot")||&invRef==&Inventory::get("Stage Loot")){ + itemQuantity=invRef.at(inventoryIndex).Amt(); //So the item quantity comes from the stack itself and not our main inventory. + } + std::string quantityText="x"+std::to_string(itemQuantity); + vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*0.5; + vf2d drawPos=parentPos+rect.pos+rect.size-textSize; + if(PointWithinParent(this,drawPos)){ + game->DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,{0.5,0.5},0.5); + } } } } diff --git a/Crawler/MenuItemItemButton.h b/Crawler/MenuItemItemButton.h index 8d41eb92..71187dea 100644 --- a/Crawler/MenuItemItemButton.h +++ b/Crawler/MenuItemItemButton.h @@ -60,13 +60,13 @@ private: bool hideQty=false; CompactText compact=COMPACT; public: - inline MenuItemItemButton(geom2d::rectrect,Item&itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName) - :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(DO_NOTHING){ + inline MenuItemItemButton(geom2d::rectrect,Item&itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE) + :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(DO_NOTHING){ draggable=false; valid=!itemRef.IsBlank(); } - inline MenuItemItemButton(geom2d::rectrect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,std::string itemNameLabelName="",std::string itemDescriptionLabelName="") - :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(onHover),onMouseOut(onMouseOut){ + inline MenuItemItemButton(geom2d::rectrect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,std::string itemNameLabelName="",std::string itemDescriptionLabelName="",IconButtonAttr attributes=IconButtonAttr::SELECTABLE) + :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(onHover),onMouseOut(onMouseOut){ runHoverFunctions=true; draggable=false; valid=!itemRef.IsBlank(); diff --git a/Crawler/MenuLabel.h b/Crawler/MenuLabel.h index 2b36e84c..5bfd25d4 100644 --- a/Crawler/MenuLabel.h +++ b/Crawler/MenuLabel.h @@ -45,16 +45,17 @@ INCLUDE_game class MenuLabel:public MenuComponent{ private: - int scale=1; + float scale=1; protected: bool shadow=false; bool centered=true; public: - inline MenuLabel(geom2d::rectrect,std::string label,int scale=1,ComponentAttr attributes=ComponentAttr::NONE) + inline MenuLabel(geom2d::rectrect,std::string label,float scale=1,ComponentAttr attributes=ComponentAttr::NONE) :MenuComponent(rect,label,MenuFunc{},ButtonAttr::UNSELECTABLE|ButtonAttr::UNSELECTABLE_VIA_KEYBOARD),scale(scale),centered(!(attributes&ComponentAttr::LEFT_ALIGN)),shadow(attributes&ComponentAttr::SHADOW){ border=attributes&ComponentAttr::OUTLINE; this->background=attributes&ComponentAttr::BACKGROUND; showDefaultLabel=false; + if(fmod(scale,1)>0.001)decal=true; } inline virtual void SetLabel(std::string text){ label=text; diff --git a/Crawler/Version.h b/Crawler/Version.h index 1bf2685d..beb8b5f0 100644 --- a/Crawler/Version.h +++ b/Crawler/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 0 #define VERSION_MINOR 2 #define VERSION_PATCH 1 -#define VERSION_BUILD 3761 +#define VERSION_BUILD 3803 #define stringify(a) stringify_(a) #define stringify_(a) #a