diff --git a/Crawler/CharacterMenuWindow.cpp b/Crawler/CharacterMenuWindow.cpp index 74cc75b0..361770c2 100644 --- a/Crawler/CharacterMenuWindow.cpp +++ b/Crawler/CharacterMenuWindow.cpp @@ -57,7 +57,7 @@ void Menu::InitializeCharacterMenuWindow(){ Menu*characterMenuWindow=CreateMenu(CHARACTER_MENU,CENTERED,windowSize); characterMenuWindow->ADD("Character Label",MenuLabel)({{0,-4},{float(windowSize.x)-1,24}},"Character",2,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END; - characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)({{0,28},{120,windowSize.y-48}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; + characterMenuWindow->ADD("Equip Slot Outline",MenuComponent)({{0,28},{120,windowSize.y-37}},"",DO_NOTHING,ButtonAttr::UNSELECTABLE)END; characterMenuWindow->ADD("Character Rotating Display",CharacterRotatingDisplay)({{135,28},{90,windowSize.y-48}},GFX[classutils::GetClassInfo(game->GetPlayer()->GetClassName()).classFullImgName].Decal())END; const static std::arraydisplayAttrs{ @@ -90,7 +90,7 @@ void Menu::InitializeCharacterMenuWindow(){ } equipmentWindowOpened=false; return true; - })END; + })DEPTH 0 END; equipSelectionSelectButton->Enable(false); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 47101f4e..035d51fc 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -366,6 +366,10 @@ + + + + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index 8005006a..f19e4c0d 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -300,6 +300,9 @@ Header Files + + Header Files\Interface + diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index c20e9418..fb44a312 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -255,13 +255,13 @@ void Menu::Update(Crawler*game){ for(auto&[key,value]:buttons){ for(auto&button:value){ if(button->renderInMain){ - button->BeforeUpdate(game); + button->_BeforeUpdate(game); } } } for(auto&component:displayComponents){ if(component->renderInMain){ - component->BeforeUpdate(game); + component->_BeforeUpdate(game); } } for(auto&[key,value]:buttons){ diff --git a/Crawler/MenuComponent.cpp b/Crawler/MenuComponent.cpp index 6f3fbd32..2aec8a2c 100644 --- a/Crawler/MenuComponent.cpp +++ b/Crawler/MenuComponent.cpp @@ -77,6 +77,10 @@ MenuComponent::~MenuComponent(){ void MenuComponent::AfterCreate(){} +void MenuComponent::_BeforeUpdate(Crawler*game){ + _OnMouseOut(); + BeforeUpdate(game); +} void MenuComponent::BeforeUpdate(Crawler*game){} void MenuComponent::Update(Crawler*game){ @@ -89,6 +93,7 @@ void MenuComponent::Update(Crawler*game){ void MenuComponent::_Update(Crawler*game){ if(!disabled){ + _OnHover(); Update(game); } } @@ -194,4 +199,38 @@ void MenuComponent::SetSelected(bool selected){ void MenuComponent::SetSelectionType(SelectionType selectionType){ this->selectionType=selectionType; -} \ No newline at end of file +} + +void MenuComponent::OnMouseOut(){}; +void MenuComponent::OnHover(){}; + +void MenuComponent::_OnMouseOut(){ + if(name=="Equip Item 2"){std::cout<func){ + runHoverFunctions=true; + onHover=func; +}; +void MenuComponent::SetMouseOutFunc(std::functionfunc){ + runHoverFunctions=true; + onMouseOut=func; +}; \ No newline at end of file diff --git a/Crawler/MenuComponent.h b/Crawler/MenuComponent.h index bfabc845..171f8067 100644 --- a/Crawler/MenuComponent.h +++ b/Crawler/MenuComponent.h @@ -67,13 +67,21 @@ class MenuComponent:public IAttributable{ friend class ScrollableWindowComponent; friend class InventoryScrollableWindowComponent; friend class MenuItemItemButton; + friend class RowItemDisplay; MenuType menuDest; + MenuFunc onHover=[](MenuFuncData dat){return true;}; + MenuFunc onMouseOut=[](MenuFuncData dat){return true;}; + bool hoverState=false; + bool runHoverFunctions=false; private: virtual bool GetHoverState(Crawler*game); std::pairmemoryLeakInfo; //Used to identify memory leak hints for this component. + void _BeforeUpdate(Crawler*game); virtual void BeforeUpdate(Crawler*game); void _Update(Crawler*game); void _DrawDecal(ViewPort&window,bool focused); + void _OnMouseOut(); + void _OnHover(); bool selected=false; SelectionType selectionType=CROSSHAIR; protected: @@ -103,6 +111,8 @@ protected: virtual bool PointWithinParent(MenuComponent*child,vi2d drawPos); //CALL THIS FOR A PARENT to check a child's DrawDecal validity! virtual bool PointWithinParent(MenuComponent*child,geom2d::rect drawRect); + virtual void OnMouseOut(); + virtual void OnHover(); public: MenuType parentMenu=MenuType::ENUM_END; MenuComponent*parentComponent=nullptr; @@ -128,4 +138,6 @@ public: virtual void SetSelectionType(SelectionType selectionType)final; virtual void Enable(bool enabled); virtual void Cleanup(); + virtual void SetHoverFunc(std::functionfunc); + virtual void SetMouseOutFunc(std::functionfunc); }; \ No newline at end of file diff --git a/Crawler/MenuItemButton.h b/Crawler/MenuItemButton.h index 1e7f1e96..9d17717b 100644 --- a/Crawler/MenuItemButton.h +++ b/Crawler/MenuItemButton.h @@ -57,10 +57,6 @@ private: 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) @@ -69,10 +65,12 @@ public: valid=invRef.size()>invIndex; } 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){ + :MenuIconButton(rect,invRef.size()>invIndex?invRef[invIndex].Decal():nullptr,onClick,attributes),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){ draggable=false; runHoverFunctions=true; valid=invRef.size()>invIndex; + SetHoverFunc(onHover); + SetMouseOutFunc(onMouseOut); } inline Item&GetItem(){ return Inventory::GetItem(invRef.at(inventoryIndex).Name()); @@ -87,21 +85,16 @@ public: 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 OnMouseOut()override{ + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->Enable(false); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->Enable(false); } } - virtual inline void Update(Crawler*game)override{ - MenuIconButton::Update(game); - valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex].Name()); + void UpdateLabel(){ + if(invRef[inventoryIndex].IsBlank())return; std::string labelNameText; std::string labelDescriptionText; if(valid){ @@ -113,24 +106,24 @@ protected: labelNameText=""; labelDescriptionText=""; } - + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->label=labelNameText; + Component(parentMenu,itemNameLabelName)->Enable(true); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText; + Component(parentMenu,itemDescriptionLabelName)->Enable(true); + } + } + virtual inline void OnHover()override{ + UpdateLabel(); + } + virtual inline void Update(Crawler*game)override{ + MenuIconButton::Update(game); + valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex].Name()); + 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)}); - } + UpdateLabel(); } } virtual inline void DrawDecal(ViewPort&window,bool focused)override{ diff --git a/Crawler/MenuItemItemButton.h b/Crawler/MenuItemItemButton.h index 16186189..1d0f860e 100644 --- a/Crawler/MenuItemItemButton.h +++ b/Crawler/MenuItemItemButton.h @@ -53,23 +53,21 @@ private: std::reference_wrapperitemRef; std::string itemNameLabelName; std::string itemDescriptionLabelName; - bool runHoverFunctions=false; - MenuFunc onHover; - MenuFunc onMouseOut; - bool hoverState=false; bool hideQty=false; CompactText compact=COMPACT; public: 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){ + :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){ 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="",IconButtonAttr attributes=IconButtonAttr::SELECTABLE) - :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),onHover(onHover),onMouseOut(onMouseOut){ + :MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){ runHoverFunctions=true; draggable=false; valid=!itemRef.IsBlank(); + SetHoverFunc(onHover); + SetMouseOutFunc(onMouseOut); } inline Item&GetItem(){ return itemRef.get(); @@ -85,21 +83,19 @@ public: 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 OnMouseOut()override{ + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->Enable(false); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->Enable(false); } } - virtual inline void Update(Crawler*game)override{ - MenuIconButton::Update(game); - valid=!itemRef.get().IsBlank(); + virtual inline void OnHover()override{ + UpdateLabel(); + } + void UpdateLabel(){ + if(itemRef.get().IsBlank())return; std::string labelNameText; std::string labelDescriptionText; if(valid){ @@ -111,24 +107,21 @@ protected: labelNameText=""; labelDescriptionText=""; } - + if(itemNameLabelName!=""&&labelNameText.length()>0){ + Component(parentMenu,itemNameLabelName)->label=labelNameText; + Component(parentMenu,itemNameLabelName)->Enable(true); + } + if(itemDescriptionLabelName!=""&&labelDescriptionText.length()>0){ + Component(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText; + Component(parentMenu,itemDescriptionLabelName)->Enable(true); + } + } + virtual inline void Update(Crawler*game)override{ + MenuIconButton::Update(game); + valid=!itemRef.get().IsBlank(); + 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)}); - } + UpdateLabel(); } } virtual inline void DrawDecal(ViewPort&window,bool focused)override{ diff --git a/Crawler/RowItemDisplay.h b/Crawler/RowItemDisplay.h new file mode 100644 index 00000000..a22c3b97 --- /dev/null +++ b/Crawler/RowItemDisplay.h @@ -0,0 +1,98 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2018 - 2022 OneLoneCoder.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 © 2023 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion + +#include "Item.h" +#include "Crawler.h" +#include "MenuLabel.h" + +INCLUDE_game + +class RowItemDisplay:public MenuComponent{ + Item&itemRef; + std::string itemNameLabelName; + std::string itemDescriptionLabelName; + CompactText compact=NON_COMPACT; +public: + inline RowItemDisplay(geom2d::rectrect,Item&itemRef,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,ButtonAttr attributes=ButtonAttr::NONE) + :MenuComponent(rect,"",onClick,attributes),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName),itemRef(itemRef){ + + } + virtual inline void DrawDecal(ViewPort&window,bool focused)final{ + float scaleFactor=rect.size.y/24; + vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f; + window.DrawDecal(rect.pos+vf2d{2,2},itemRef.Decal(),{scaleFactor,scaleFactor}); + window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize); + + window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+iconSize,itemRef.Name()); + + std::string quantityText=std::format("x{}",itemRef.Amt()); + vf2d qtyTextSize=game->GetTextSizeProp(quantityText); + window.DrawShadowStringPropDecal(rect.pos+rect.size-vf2d{2,2}+vf2d{-qtyTextSize.x,qtyTextSize.y},quantityText); + } + inline void SetCompactDescriptions(bool compact){ + if(compact)this->compact=COMPACT; + else this->compact=NON_COMPACT; + } + virtual inline void OnMouseOut()override{ + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->Enable(false); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->Enable(false); + } + } + virtual inline void OnHover()override{ + std::string labelNameText; + std::string labelDescriptionText; + if(valid){ + labelNameText=itemRef.Name(); + labelDescriptionText=itemRef.Description(compact); + }else{ + labelNameText=""; + labelDescriptionText=""; + } + if(itemNameLabelName!=""){ + Component(parentMenu,itemNameLabelName)->label=labelNameText; + Component(parentMenu,itemNameLabelName)->Enable(true); + } + if(itemDescriptionLabelName!=""){ + Component(parentMenu,itemDescriptionLabelName)->label=labelDescriptionText; + Component(parentMenu,itemDescriptionLabelName)->Enable(true); + } + } +}; \ No newline at end of file diff --git a/Crawler/ScrollableWindowComponent.h b/Crawler/ScrollableWindowComponent.h index 6d9fd1f0..5b9d53bc 100644 --- a/Crawler/ScrollableWindowComponent.h +++ b/Crawler/ScrollableWindowComponent.h @@ -113,8 +113,9 @@ protected: if(downButton){downButton->Enable(!disabled);} } virtual inline void BeforeUpdate(Crawler*game)override{ + MenuComponent::BeforeUpdate(game); for(MenuComponent*component:components){ - component->BeforeUpdate(game); + component->_BeforeUpdate(game); } } virtual inline void Update(Crawler*game)override{ @@ -162,7 +163,7 @@ protected: SetScrollAmount({GetScrollAmount().x,0}); } - std::sort(components.begin(),components.end(),[](MenuComponent*c1,MenuComponent*c2){return c1->depth>c2->depth;}); + std::sort(components.begin(),components.end(),[](MenuComponent*c1,MenuComponent*c2){return c1->depth>c2->depth;}); for(MenuComponent*component:components){ component->disabled=!OnScreen(component); component->_Update(game); diff --git a/Crawler/Version.h b/Crawler/Version.h index 16191e27..72c4470a 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 3969 +#define VERSION_BUILD 3990 #define stringify(a) stringify_(a) #define stringify_(a) #a