# pragma once
# include "Item.h"
# include <stack>
# include "safemap.h"
# include "Theme.h"
# include "Attributable.h"
# include "olcUTIL_Geometry2D.h"
class Crawler ;
class MenuComponent ;
enum MenuType {
TEST ,
TEST_2 ,
INVENTORY ,
///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ ENUM_END ////////////////////////////////
///////////////////////////////////////////////////////////
} ;
class Menu : IAttributable {
friend class Crawler ;
friend class Player ;
friend class ItemInfo ;
float buttonHoldTime = 0 ;
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 ;
virtual ~ Menu ( ) = default ;
void AddComponent ( std : : string key , MenuComponent * button ) ;
void Update ( Crawler * game ) ;
void Draw ( Crawler * game ) ;
static void InitializeMenus ( ) ;
static void OpenMenu ( MenuType menu ) ;
static std : : vector < Menu * > stack ;
static std : : string themeSelection ;
static safeunorderedmap < std : : string , Theme > themes ;
static const vf2d CENTERED ;
safemap < std : : string , MenuComponent * > components ; //A friendly way to interrogate any component we are interested in.
static std : : map < MenuType , Menu * > menus ;
vf2d pos ; //Specify the upper-left corner of the window. Using CENTERED will always put this where the upper-left corner would center the window.
vf2d size ; //Size in tiles (24x24), every menu will be tile-based
safemap < int /*Y*/ , std : : vector < MenuComponent * > > buttons ; //Buttons are stored in rows followed by their column order.
safemap < int /*Y*/ , std : : vector < MenuComponent * > > keyboardButtons ; //Button ordered storage for keyboard/menu
static Theme & GetCurrentTheme ( ) ;
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 ) ;
void MenuSelect ( Crawler * game ) ;
void CheckClickAndPerformMenuSelect ( Crawler * game ) ;
//Mandatory before any menu operations! This creates and sets up the menu in memory.
static Menu * CreateMenu ( MenuType type , vf2d pos , vf2d size ) ;
static void InitializeTestMenu ( ) ;
static void InitializeTestSubMenu ( ) ;
static void InitializeInventoryWindow ( ) ;
static void InitializeCharacterInfoWindow ( ) ;
//X (0-3), Y (0-2) for specific 9-patch tile (tiled version).
static Renderable & GetPatchPart ( int x , int y ) ;
void KeyboardButtonNavigation ( Crawler * game , vf2d menuPos ) ;
void DrawScaledWindowBackground ( Crawler * game , vf2d menuPos ) ;
void DrawTiledWindowBackground ( Crawler * game , vf2d menuPos ) ;
void DrawScaledWindowBorder ( Crawler * game , vf2d menuPos ) ;
void DrawTiledWindowBorder ( Crawler * game , vf2d menuPos ) ;
//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 ( MenuComponent * disabledButton ) ;
Pixel GetRenderColor ( ) ;
static bool MOUSE_NAVIGATION ;
} ;
struct MenuFuncData {
Menu & menu ;
Crawler * game ;
MenuComponent * component ;
} ;
typedef std : : function < void ( MenuFuncData ) > MenuFunc ;