@ -38,11 +38,11 @@ All rights reserved.
# include "Menu.h"
# include "AdventuresInLestoria.h"
# include "MenuLabel.h"
# include "MenuComponent.h"
# include "InventoryScrollableWindowComponent.h"
# include "PopupMenuLabel.h"
# include "Unlock.h"
# include "State_OverworldMap.h"
# include "ProgressBar.h"
INCLUDE_game
@ -51,7 +51,10 @@ void Menu::InitializeLevelCompleteWindow(){
Menu * levelCompleteWindow = Menu : : CreateMenu ( LEVEL_COMPLETE , windowSize . pos , windowSize . size ) ;
levelCompleteWindow - > ADD ( " Stage Complete Label " , MenuLabel ) ( geom2d : : rect < float > { { 0 , 4 } , { windowSize . size . x - 1.f , 20 } } , " Stage Completed " , 2 , ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND | ComponentAttr : : SHADOW ) END ;
levelCompleteWindow - > ADD ( " Stage Complete Label " , MenuLabel ) ( geom2d : : rect < float > { { 0 , - 8 } , { windowSize . size . x - 1.f , 20 } } , " Stage Completed " , 2 , ComponentAttr : : OUTLINE | ComponentAttr : : BACKGROUND | ComponentAttr : : SHADOW ) END ;
levelCompleteWindow - > ADD ( " XP Bar " , ProgressBar ) ( geom2d : : rect < float > { vf2d { windowSize . size . x / 2.f - 96.f , 18.f } , { 192.f , 8.f } } , Pixel { 247 , 183 , 82 } , BLACK , game - > GetPlayer ( ) - > CurrentXP ( ) , game - > GetPlayer ( ) - > NextLevelXPRequired ( ) , " xp " ) END ;
levelCompleteWindow - > ADD ( " Level Display " , MenuLabel ) ( geom2d : : rect < float > { vf2d { windowSize . size . x / 2.f - 96.f - 42.f , 18.f } , { 42.f , 8.f } } , std : : format ( " Lv{} " , game - > GetPlayer ( ) - > Level ( ) ) , 1.f , ComponentAttr : : SHADOW | ComponentAttr : : RIGHT_ALIGN ) END ;
levelCompleteWindow - > ADD ( " Monster Loot Outline " , MenuComponent ) ( geom2d : : rect < float > { { 0 , 32 } , { windowSize . size . x - 80.f , 72 } } , " " , DO_NOTHING , ButtonAttr : : UNSELECTABLE ) END ;
levelCompleteWindow - > ADD ( " Monster Loot Label " , MenuLabel ) ( geom2d : : rect < float > { { 0 , 32 } , { windowSize . size . x - 80.f , 12 } } , " Monster Loot " , 1 , ComponentAttr : : LEFT_ALIGN | ComponentAttr : : SHADOW | ComponentAttr : : OUTLINE ) END ;
@ -117,39 +120,412 @@ void Menu::InitializeLevelCompleteWindow(){
, { //Button Navigation Rules
{ " Monster Loot Window " , {
. up = [ ] ( MenuType type , Data & returnData ) {
auto & selection = Menu : : menus [ type ] - > GetSelection ( ) ;
auto & itemsList = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) - > GetComponents ( ) ;
auto itemsWindow = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ;
if ( itemsList . size ( ) > 0 ) {
if ( component = = itemsList . end ( ) ) {
//Set the selected button to the last element in the list.
returnData = itemsList . back ( ) ;
# pragma region Inventory Wrapping Handling Up Macros
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . back ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex - invWidth ; /*Moving up moves the cursor up an entire row.*/ \
if ( newRowIndex < 0 ) {
# define DefaultBehavior \
} \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} \
else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=itemsList.size()-1;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Monster Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
int colIndex = ( newRowIndex + invWidth ) % invWidth ; //Negative index, so we have to loop around.
//Get the base row index of the new inventory.
auto stageLootWindow = Component < InventoryScrollableWindowComponent > ( type , " Stage Loot Window " ) ;
if ( stageLootWindow - > GetComponents ( ) . size ( ) > 0 ) {
int rowBaseIndex = ( stageLootWindow - > GetComponents ( ) . back ( ) . lock ( ) - > inventoryIndex / invWidth ) * invWidth ;
returnData = stageLootWindow - > GetComponents ( ) [ std : : clamp ( rowBaseIndex + colIndex , 0 , int ( stageLootWindow - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
return ;
} else {
returnData = selectedButton ;
}
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. down = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Down Macros
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . front ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex + invWidth ; /*Moving down moves the cursor down an entire row.*/ \
if ( newRowIndex > = itemsList . size ( ) ) { \
int currentRow = newRowIndex / invWidth ; \
/*The logic here is, if we clamp this row index to the last possible index and we're still on the same row, it means there is at least an item on this row. So we go to that instead.*/ \
newRowIndex = std : : clamp ( newRowIndex , 0 , int ( itemsList . size ( ) - 1 ) ) ; \
int newRow = newRowIndex / invWidth ; \
if ( currentRow ! = newRow ) //This means we are on a different row, so the row we went down on didn't have any items. Simply drop down to the OK Button.
# define DefaultBehavior \
} \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} \
else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=0;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Monster Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
int colIndex = newRowIndex % invWidth ;
//Get the base row index of the new inventory.
auto stageLootWindow = Component < InventoryScrollableWindowComponent > ( type , " Stage Loot Window " ) ;
if ( stageLootWindow - > GetComponents ( ) . size ( ) > 0 ) {
returnData = stageLootWindow - > GetComponents ( ) [ std : : clamp ( colIndex , 0 , int ( stageLootWindow - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
return ;
} else {
returnData = selectedButton ;
}
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. left = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Left Macros
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . back ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex - 1 ; \
if ( newRowIndex < rowBaseIndex )
# define DefaultBehavior \
newRowIndex = std : : min ( int ( itemsList . size ( ) ) - 1 , newRowIndex ) ; \
if ( newRowIndex < 0 ) newRowIndex + = itemsList . size ( ) ; \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex+=invWidth;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Monster Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
returnData = " Next Button " ;
return ;
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. right = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Right Macros
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . front ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex + 1 ; \
int newRowBaseIndex = ( newRowIndex / invWidth ) * invWidth ; \
if ( rowBaseIndex ! = newRowBaseIndex )
# define DefaultBehavior \
newRowIndex = std : : clamp ( newRowIndex , 0 , int ( itemsList . size ( ) - 1 ) ) ; \
newRowIndex = std : : min ( int ( itemsList . size ( ) ) - 1 , newRowIndex ) ; \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} else
# define DEFAULT_WRAPPING_BEHAVIOR \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
newRowIndex = rowBaseIndex ;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Monster Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
returnData = " Next Button " ;
return ;
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} , } } ,
{ " Stage Loot Window " , {
. up = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Up Macros
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . back ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex - invWidth ; /*Moving up moves the cursor up an entire row.*/ \
if ( newRowIndex < 0 ) {
# define DefaultBehavior \
} \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} \
else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=itemsList.size()-1;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Stage Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
int colIndex = ( newRowIndex + invWidth ) % invWidth ;
//Get the base row index of the new inventory.
auto stageLootWindow = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
if ( stageLootWindow - > GetComponents ( ) . size ( ) > 0 ) {
int rowBaseIndex = ( stageLootWindow - > GetComponents ( ) . back ( ) . lock ( ) - > inventoryIndex / invWidth ) * invWidth ;
returnData = stageLootWindow - > GetComponents ( ) [ std : : clamp ( rowBaseIndex + colIndex , 0 , int ( stageLootWindow - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
return ;
} else {
returnData = selectedButton ;
}
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. down = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Down Macros
//Make sure before using this you have #define SUBCLASS with the children class for this inventory scrollable window component!
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . front ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex + invWidth ; /*Moving down moves the cursor down an entire row.*/ \
if ( newRowIndex > = itemsList . size ( ) ) { \
int currentRow = newRowIndex / invWidth ; \
/*The logic here is, if we clamp this row index to the last possible index and we're still on the same row, it means there is at least an item on this row. So we go to that instead.*/ \
newRowIndex = std : : clamp ( newRowIndex , 0 , int ( itemsList . size ( ) - 1 ) ) ; \
int newRow = newRowIndex / invWidth ; \
if ( currentRow ! = newRow ) //This means we are on a different row, so the row we went down on didn't have any items. Simply drop down to the OK Button.
# define DefaultBehavior \
} \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} \
else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex=0;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Stage Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
int colIndex = newRowIndex % invWidth ;
//Get the base row index of the new inventory.
auto stageLootWindow = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
if ( stageLootWindow - > GetComponents ( ) . size ( ) > 0 ) {
returnData = stageLootWindow - > GetComponents ( ) [ std : : clamp ( colIndex , 0 , int ( stageLootWindow - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
return ;
} else {
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ;
std : : weak_ptr < MenuItemButton > selectedButton = DYNAMIC_POINTER_CAST < MenuItemButton > ( * component ) ;
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex - invWidth ; //Moving up moves the cursor up an entire row.
if ( newRowIndex < 0 ) {
//This means we have to wrap around.
returnData = " OK Button " ;
return ;
}
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ;
//Select the component that matches this new number.
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < MenuItemButton > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ;
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ;
returnData = * component ;
returnData = selectedButton ;
}
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. left = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Left Macros
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . back ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex - 1 ; \
if ( newRowIndex < rowBaseIndex )
# define DefaultBehavior \
newRowIndex = std : : min ( int ( itemsList . size ( ) ) - 1 , newRowIndex ) ; \
if ( newRowIndex < 0 ) newRowIndex + = itemsList . size ( ) ; \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} else
# define DEFAULT_WRAPPING_BEHAVIOR newRowIndex+=invWidth;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Stage Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
returnData = " Next Button " ;
return ;
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} ,
. right = [ ] ( MenuType type , Data & returnData ) {
# pragma region Inventory Wrapping Handling Right Macros
# define DetectInventory(menuClass,menuType,inventoryComponentName) \
auto & selection = Menu : : menus [ menuType ] - > GetSelection ( ) ; \
auto & itemsList = Component < menuClass > ( menuType , inventoryComponentName ) - > GetComponents ( ) ; \
auto itemsWindow = Component < menuClass > ( menuType , inventoryComponentName ) ; \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return comp . lock ( ) = = selection . lock ( ) ; } ) ; \
if ( itemsList . size ( ) > 0 ) { \
if ( component = = itemsList . end ( ) ) { \
/*Set the selected button to the last element in the list.*/ \
returnData = itemsList . front ( ) ; \
} else { \
int invWidth = int ( ( itemsWindow - > rect . size . x - 12 ) / ( float ( itemsWindow - > options . size . x ) + itemsWindow - > options . padding ) ) ; \
std : : weak_ptr < SUBCLASS > selectedButton = DYNAMIC_POINTER_CAST < SUBCLASS > ( * component ) ; \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
int newRowIndex = selectedButton . lock ( ) - > inventoryIndex + 1 ; \
int newRowBaseIndex = ( newRowIndex / invWidth ) * invWidth ; \
if ( rowBaseIndex ! = newRowBaseIndex | | newRowIndex > = itemsList . size ( ) )
# define DefaultBehavior \
newRowIndex = std : : clamp ( newRowIndex , 0 , int ( itemsList . size ( ) - 1 ) ) ; \
newRowIndex = std : : min ( int ( itemsList . size ( ) ) - 1 , newRowIndex ) ; \
if ( newRowIndex < 0 | | newRowIndex > = itemsList . size ( ) ) ERR ( std : : format ( " New Row Index ended up out-of-bounds! newRowIndex={}. THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
/*Select the component that matches this new number.*/ \
auto component = std : : find_if ( itemsList . begin ( ) , itemsList . end ( ) , [ & ] ( auto & comp ) { return DYNAMIC_POINTER_CAST < SUBCLASS > ( comp ) - > inventoryIndex = = newRowIndex ; } ) ; \
if ( component = = itemsList . end ( ) ) ERR ( std : : format ( " WARNING! Could not find row index {} in items list while navigating! THIS SHOULD NOT BE HAPPENING! " , newRowIndex ) ) ; \
returnData = * component ; \
} \
} else
# define DEFAULT_WRAPPING_BEHAVIOR \
int rowBaseIndex = ( selectedButton . lock ( ) - > inventoryIndex / invWidth ) * invWidth ; \
newRowIndex = rowBaseIndex ;
# pragma endregion
# define SUBCLASS MenuItemButton
DetectInventory ( InventoryScrollableWindowComponent , type , " Stage Loot Window " )
{ //This means we have to wrap around. We have access to itemsList if we needed to point to a specific item in the inventory.
//By returning here, you are processing returnData yourself. Otherwise manipulate newRowIndex to point to an item in the itemsList when wrapping.
returnData = " Next Button " ;
return ;
}
DefaultBehavior { //When nothing is found...
returnData = " Next Button " ;
}
} , } } ,
{ " Next Button " , {
. up = [ ] ( MenuType type , Data & returnData ) {
auto monsterLoot = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
auto stageLoot = Component < InventoryScrollableWindowComponent > ( type , " Stage Loot Window " ) ;
if ( monsterLoot - > GetComponents ( ) . size ( ) > 0 ) {
int invWidth = monsterLoot - > GetInventoryWidth ( ) ;
returnData = monsterLoot - > GetComponents ( ) [ 0 ] ;
} else
if ( stageLoot - > GetComponents ( ) . size ( ) > 0 ) {
int invWidth = stageLoot - > GetInventoryWidth ( ) ;
returnData = stageLoot - > GetComponents ( ) [ 0 ] ;
} else {
returnData = " OK Button " ;
returnData = " Next Button" ;
}
} ,
. down = " Load Game Button " , } } ,
{ " Load Game Button " , {
. up = " New Game Button " ,
. down = " Quit Game Button " , } } ,
{ " Quit Game Button " , {
. up = " Load Game Button " ,
. down = " New Game Button " , } } ,
. left = [ ] ( MenuType type , Data & returnData ) {
auto monsterLoot = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
auto stageLoot = Component < InventoryScrollableWindowComponent > ( type , " Stage Loot Window " ) ;
if ( monsterLoot - > GetComponents ( ) . size ( ) > 0 ) {
int invWidth = monsterLoot - > GetInventoryWidth ( ) ;
returnData = monsterLoot - > GetComponents ( ) [ std : : clamp ( invWidth - 1 , 0 , int ( monsterLoot - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
} else
if ( stageLoot - > GetComponents ( ) . size ( ) > 0 ) {
int invWidth = stageLoot - > GetInventoryWidth ( ) ;
returnData = stageLoot - > GetComponents ( ) [ std : : clamp ( invWidth - 1 , 0 , int ( stageLoot - > GetComponents ( ) . size ( ) - 1 ) ) ] ;
} else {
returnData = " Next Button " ;
}
} ,
. right = [ ] ( MenuType type , Data & returnData ) {
auto monsterLoot = Component < InventoryScrollableWindowComponent > ( type , " Monster Loot Window " ) ;
auto stageLoot = Component < InventoryScrollableWindowComponent > ( type , " Stage Loot Window " ) ;
if ( monsterLoot - > GetComponents ( ) . size ( ) > 0 ) {
returnData = monsterLoot - > GetComponents ( ) [ 0 ] ;
} else
if ( stageLoot - > GetComponents ( ) . size ( ) > 0 ) {
returnData = stageLoot - > GetComponents ( ) [ 0 ] ;
} else {
returnData = " Next Button " ;
}
} , } } ,
} ) ;
}