# pragma region License
/*
License ( OLC - 3 )
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Copyright 2024 Joshua Sigona < sigonasr2 @ gmail . 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
# pragma once
# include "Menu.h"
# include "BitwiseEnum.h"
enum class ButtonAttr {
NONE = 0 b000 ,
UNSELECTABLE = 0 b001 , //Makes the component unselectable.
UNSELECTABLE_VIA_KEYBOARD = 0 b010 , //Makes the component unselectable via keyboard.
FIT_TO_LABEL = 0 b100 , //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
} ;
enum class ComponentAttr {
NONE = 0 b0 ' 0000 ' 0000 ,
LEFT_ALIGN = 0 b0 ' 0000 ' 0001 , //Labels are centered by default.
SHADOW = 0 b0 ' 0000 ' 0010 , //Adds shadows to the label text.
OUTLINE = 0 b0 ' 0000 ' 0100 , //Adds an outline around the component.
BACKGROUND = 0 b0 ' 0000 ' 1000 , //Renders the background of the menu theme for this component.
FIT_TO_LABEL = 0 b0 ' 0001 ' 0000 , //Scales the text horizontally to fit the label if the text takes up more space rather than wrapping.
FIXED_WIDTH_FONT = 0 b0 ' 0010 ' 0000 , //Uses a fixed-width font (instead of a proportional one) for text rendering.
} ;
enum class SelectionType {
CROSSHAIR ,
HIGHLIGHT ,
INNER_BOX ,
NONE ,
} ;
using SelectionType : : CROSSHAIR ;
using SelectionType : : HIGHLIGHT ;
using SelectionType : : INNER_BOX ;
class InventoryScrollableWindowComponent ;
class MenuComponent : public IAttributable {
friend class Menu ;
friend class MenuItemButton ;
friend class ScrollableWindowComponent ;
friend class InventoryScrollableWindowComponent ;
friend class EncountersSpawnListScrollableWindowComponent ;
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 ( AiL * game ) ;
std : : pair < MenuType , std : : string > memoryLeakInfo ; //Used to identify memory leak hints for this component.
void _BeforeUpdate ( AiL * game ) ;
virtual void BeforeUpdate ( AiL * game ) ;
void _Update ( AiL * game ) ;
void _DrawDecal ( ViewPort & window , bool focused ) ;
void _OnMouseOut ( ) ;
void _OnHover ( ) ;
SelectionType selectionType = CROSSHAIR ;
protected :
int depth = 0 ;
float hoverEffect = 0 ;
std : : string name = " " ;
geom2d : : rect < float > rect ;
vf2d originalPos ;
std : : string label ;
bool border = true ;
bool draggable = false ;
bool background = true ;
bool showDefaultLabel = true ;
MenuFunc onClick ;
bool hovered = false ;
bool selectable = true ;
bool selectableViaKeyboard = true ;
bool selected = false ;
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 fitToLabel = false ; //Will shrink text horizontally to fit the size of the label if the display text is too large.
bool grayedOut = false ; //If turned on, a button will appear grayed out and unresponsive.
int inventoryIndex = 0 ;
vf2d labelScaling = { 1 , 1 } ;
virtual void Update ( AiL * game ) ;
virtual void DrawDecal ( ViewPort & window , bool focused ) ;
virtual bool GetHoverState ( AiL * game , MenuComponent * child ) ;
virtual void AfterCreate ( ) ; //Called after the creation of all menus finish.
//CALL THIS FOR A PARENT to check a child's DrawDecal validity!
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 < float > drawRect ) ;
virtual void OnMouseOut ( ) ;
virtual void OnHover ( ) ;
public :
MenuType parentMenu = MenuType : : ENUM_END ;
std : : weak_ptr < ScrollableWindowComponent > parentComponent { } ;
MenuComponent ( geom2d : : rect < float > rect , std : : string label , MenuFunc onClick , ButtonAttr attributes = ButtonAttr : : NONE ) ;
MenuComponent ( geom2d : : rect < float > rect , std : : string label , MenuType menuDest , MenuFunc onClick , ButtonAttr attributes = ButtonAttr : : NONE ) ;
MenuComponent ( geom2d : : rect < float > rect , std : : string label , MenuType menuDest , MenuFunc onClick , vf2d labelScaling , ButtonAttr attributes = ButtonAttr : : NONE ) ;
virtual ~ MenuComponent ( ) ;
vf2d GetPos ( ) ;
const vf2d & GetSize ( ) const ;
//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 std : : unique_ptr < MenuComponent > PickUpDraggableItem ( ) ;
//We are attempting to drop draggable onto this item. If it's not allowed, return false.
virtual bool DropDraggableItem ( std : : unique_ptr < MenuComponent > draggable ) ;
//A notification that a button outside the region has been selected. Return false if it's not allowed.
virtual bool HandleOutsideDisabledButtonSelection ( std : : weak_ptr < MenuComponent > disabledButton ) ;
//Called whenever equipment and base stats are updated, notifying a component that numbers that may be displayed have changed.
virtual void OnEquipStatsUpdate ( ) ;
virtual const std : : string & GetLabel ( ) const ;
std : : string GetName ( ) ;
virtual void SetSelected ( bool selected ) final ;
virtual void SetSelectionType ( SelectionType selectionType ) final ;
virtual void Enable ( bool enabled ) ;
virtual void Cleanup ( ) ;
virtual void SetHoverFunc ( std : : function < bool ( MenuFuncData ) > func ) ;
virtual void SetMouseOutFunc ( std : : function < bool ( MenuFuncData ) > func ) ;
void SetGrayedOut ( bool grayedOut ) ;
virtual void OnPlayerMoneyUpdate ( uint32_t newMoney ) ;
virtual void OnChapterUpdate ( uint8_t newChapter ) ;
virtual void Click ( ) ;
} ;