#pragma once #include "Menu.h" enum class ButtonAttr{ NONE=0b00, UNSELECTABLE=0b01, //Makes the component unselectable. UNSELECTABLE_VIA_KEYBOARD=0b10, //Makes the component unselectable via keyboard. }; enum class ComponentAttr{ NONE=0b0000, LEFT_ALIGN=0b0001, //Labels are centered by default. SHADOW=0b0010, //Adds shadows to the label text. OUTLINE=0b0100, //Adds an outline around the component. BACKGROUND=0b1000, //Renders the background of the menu theme for this component. }; class MenuComponent:IAttributable{ friend class Menu; friend class MenuItemButton; friend class ScrollableWindowComponent; friend class InventoryScrollableWindowComponent; MenuType menuDest; private: virtual bool GetHoverState(Crawler*game); //CALL THIS FOR A PARENT to check a child's DrawDecal validity! virtual bool PointWithinParent(MenuComponent*child,vi2d drawPos); std::pairmemoryLeakInfo; //Used to identify memory leak hints for this component. protected: float hoverEffect=0; std::string name=""; geom2d::rectrect; std::string label; bool border=true; bool draggable=false; bool background=true; bool showDefaultLabel=true; MenuFunc onClick; MenuType parentMenu=MenuType::ENUM_END; MenuComponent*parentComponent=nullptr; bool hovered=false; bool selectable=true; bool selectableViaKeyboard=true; 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. virtual void Update(Crawler*game); virtual void Draw(Crawler*game,vf2d parentPos); virtual void DrawDecal(Crawler*game,vf2d parentPos,bool focused); virtual bool GetHoverState(Crawler*game,MenuComponent*child); virtual void AfterCreate(); //Called after the creation of all menus finish. public: MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE); MenuComponent(MenuType parent,geom2d::rectrect,std::string label,MenuType menuDest,MenuFunc onClick,ButtonAttr attributes=ButtonAttr::NONE); virtual ~MenuComponent(); void _Update(Crawler*game); void _Draw(Crawler*game); void _Draw(Crawler*game,vf2d parentPos); void _DrawDecal(Crawler*game,bool focused); void _DrawDecal(Crawler*game,vf2d parentPos,bool focused); vf2d GetPos(); //We picked up a draggable component, we should make a copy and return it here. If a nullptr is returned here, the pickup is not allowed. //WARNING!!! This allocates a brand new component when successful!!! Be prepared to clear it! virtual MenuComponent*PickUpDraggableItem(); //We are attempting to drop draggable onto this item. If it's not allowed, return false. 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); std::string GetLabel(); std::string GetName(); void Enable(bool enabled); virtual void Cleanup(); }; constexpr auto operator|(ButtonAttr attribute,ButtonAttr attribute2) noexcept { return ButtonAttr(static_cast>(attribute)|static_cast>(attribute2)); } constexpr auto operator&(ButtonAttr attribute,ButtonAttr attribute2) noexcept { return static_cast>(attribute)&static_cast>(attribute2); } constexpr auto operator|(ComponentAttr attribute,ComponentAttr attribute2) noexcept { return ComponentAttr(static_cast>(attribute)|static_cast>(attribute2)); } constexpr auto operator&(ComponentAttr attribute,ComponentAttr attribute2) noexcept { return static_cast>(attribute)&static_cast>(attribute2); }