'OHRRPGCE - Game/Custom general menu code '(C) Copyright 1997-2023 James Paige, Ralph Versteegen, and the OHRRPGCE Developers 'Dual licensed under the GNU GPL v2+ and MIT Licenses. Read LICENSE.txt for terms and disclaimer of liability. #ifndef MENUS_BI #define MENUS_BI #include "udts.bi" #include "uiconst.bi" ' Default placement (top-left) of editor menus CONST pMenuX = 4 CONST pMenuY = 4 ' Default placement of info/help line (called the "tooltip" in many menus) CONST pInfoX = pLeft + 4 CONST pInfoY = pBottom - 2 ' Something in the bottom-right or top-right corner CONST pInfoRight = pRight - 4 '' Generic MenuState Stuff DECLARE SUB init_menu_state OVERLOAD (byref state as MenuState, menu() as SimpleMenuItem, menuopts as MenuOptions = MenuOptions()) DECLARE SUB init_menu_state OVERLOAD (byref state as MenuState, byval menu as BasicMenuItem vector, menuopts as MenuOptions = MenuOptions()) DECLARE SUB init_menu_state OVERLOAD (byref state as MenuState, menu() as string, menuopts as MenuOptions = MenuOptions()) DECLARE SUB append_simplemenu_item (byref menu as SimpleMenuItem vector, caption as zstring ptr, byval unselectable as bool = NO, byval col as integer = 0, byval dat as integer = 0, byval where as integer = -1) DECLARE SUB correct_menu_state (state as MenuState) DECLARE SUB correct_menu_state_top (state as MenuState) DECLARE FUNCTION usemenu OVERLOAD (state as MenuState, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE FUNCTION usemenu OVERLOAD (byref pt as integer, byref top as integer, byval first as integer, byval last as integer, byval size as integer, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE FUNCTION usemenu OVERLOAD (state as MenuState, byval menudata as BasicMenuItem vector, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE FUNCTION usemenu OVERLOAD (state as MenuState, menu as MenuDef, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE FUNCTION usemenu OVERLOAD (state as MenuState, selectable() as bool, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE SUB usemenu_mouse_only (state as MenuState) DECLARE FUNCTION default_menu_controls(state as MenuState, escval as integer = -1) as integer DECLARE FUNCTION scrollmenu (state as MenuState, byval deckey as KBScancode = ccUp, byval inckey as KBScancode = ccDown) as bool DECLARE SUB standard_to_basic_menu (menu() as string, byref state as MenuState, byref basicmenu as BasicMenuItem vector, byval shaded as bool ptr = NULL) DECLARE SUB standardmenu OVERLOAD (menu() as string, state as MenuState, x as RelPos = pMenuX, y as RelPos = pMenuY, page as integer, menuopts as MenuOptions = MenuOptions()) DECLARE SUB standardmenu OVERLOAD (menu() as string, state as MenuState, shaded() as bool, x as RelPos = pMenuX, y as RelPos = pMenuY, page as integer, menuopts as MenuOptions = MenuOptions()) DECLARE SUB standardmenu OVERLOAD (byval menu as BasicMenuItem vector, state as MenuState, x as RelPos = pMenuX, y as RelPos = pMenuY, page as integer, menuopts as MenuOptions = MenuOptions()) DECLARE SUB calc_menustate_size OVERLOAD (byref state as MenuState) DECLARE SUB calc_menustate_size OVERLOAD (byref state as MenuState, menu as MenuDef, page as integer) DECLARE SUB calc_menu_rect OVERLOAD (state as MenuState, menuopts as MenuOptions, xy as RelPosXY, page as integer = -1, menu as BasicMenuItem vector = NULL) DECLARE SUB calc_menu_rect OVERLOAD (state as MenuState, menu as MenuDef, byval page as integer) DECLARE FUNCTION menu_item_color(state as MenuState, itemno as integer, disabled as bool = NO, unselectable as bool = NO, c_normal as integer = 0, c_disabled as integer = 0, def_normal as integer = -uiMenuItem-1, def_disabled as integer = -uiDisabledItem-1) as integer '' Mouse support DECLARE FUNCTION standardmenu_item_rect OVERLOAD (state as MenuState, menutext as string, index as integer) as RectType DECLARE FUNCTION standardmenu_item_rect OVERLOAD (menu as BasicMenuItem vector, state as MenuState) as RectType DECLARE FUNCTION find_menu_item_at_point (state as MenuState, pos as XYPair) as integer DECLARE FUNCTION mouse_update_hover (state as MenuState) as bool DECLARE SUB mouse_update_selection (state as MenuState) DECLARE SUB mouse_scroll_menu(byref state as MenuState) DECLARE SUB mouse_drag_menu(byref state as MenuState, byval button as MouseButton=mouseLeft, byval threshold as integer=10, byval magnify as double=1.0) DECLARE FUNCTION menutext_hit_tester(menutext as string, state as MenuState, index as integer, pos as XYPair) as bool DECLARE FUNCTION stringmenu_hit_tester(state as MenuState, index as integer, pos as XYPair) as bool '' Selection by typing DECLARE FUNCTION select_by_typing (selectst as SelectTypeState, byval allow_numbers as bool = YES) as bool DECLARE SUB select_clear (selectst as SelectTypeState) DECLARE SUB highlight_menu_typing_selection OVERLOAD (menu() as string, menu_display() as string, selectst as SelectTypeState, state as MenuState) DECLARE SUB highlight_menu_typing_selection OVERLOAD (byref menu as BasicMenuItem vector, byref menu_display as BasicMenuItem vector, selectst as SelectTypeState, state as MenuState) DECLARE FUNCTION highlight_menu_typing_selection_string(z as string, selectst as SelectTypeState) as string DECLARE SUB select_on_word_boundary_excluding OVERLOAD (menu() as string, selectst as SelectTypeState, state as MenuState, excludeword as string) DECLARE SUB select_on_word_boundary_excluding OVERLOAD (byval menu as BasicMenuItem vector, selectst as SelectTypeState, state as MenuState, excludeword as string) DECLARE SUB select_on_word_boundary OVERLOAD (menu() as string, selectst as SelectTypeState, state as MenuState) DECLARE SUB select_on_word_boundary OVERLOAD (byval menu as BasicMenuItem vector, selectst as SelectTypeState, state as MenuState) DECLARE SUB select_instr(menu() as string, selectst as SelectTypeState, state as MenuState) '' MenuDef DECLARE SUB ClearMenuData(dat as MenuDef) DECLARE SUB InitLikeStandardMenu(menu as MenuDef) DECLARE SUB DeleteMenuItems(menu as MenuDef) DECLARE SUB SortMenuItems(menu as MenuDef) DECLARE FUNCTION getmenuname(byval record as integer) as string DECLARE SUB init_menu_state OVERLOAD (byref state as MenuState, menu as MenuDef) DECLARE SUB sort_menu_and_select_selectable_item(menu as MenuDef, state as MenuState) DECLARE FUNCTION append_menu_item(byref menu as MenuDef, caption as zstring ptr, byval t as integer=mtypeLabel, byval sub_t as integer=0, byval dataptr as any ptr=0) as integer DECLARE SUB remove_menu_item OVERLOAD (byref menu as MenuDef, byval mi as MenuDefItem ptr) DECLARE SUB remove_menu_item OVERLOAD (byref menu as MenuDef, byval mislot as integer) DECLARE SUB swap_menu_items(byref menu1 as MenuDef, byval mislot1 as integer, byref menu2 as MenuDef, byval mislot2 as integer) '' Saving/Loading/(De)serializing MenuDefs DECLARE SUB LoadMenuData(menu_set as MenuSet, dat as MenuDef, byval record as integer, byval ignore_items as integer=NO) DECLARE SUB SaveMenuData(menu_set as MenuSet, dat as MenuDef, byval record as integer) DECLARE SUB MenuBitsToArray (menu as MenuDef, bits() as integer) DECLARE SUB MenuBitsFromArray (menu as MenuDef, bits() as integer) DECLARE SUB MenuItemBitsToArray (mi as MenuDefItem, bits() as integer) DECLARE SUB MenuItemBitsFromArray (mi as MenuDefItem, bits() as integer) DECLARE FUNCTION read_menu_int (menu as MenuDef, byval intoffset_plus1 as integer) as integer DECLARE SUB write_menu_int (menu as MenuDef, byval intoffset_plus1 as integer, byval n as integer) DECLARE FUNCTION read_menu_item_int (mi as MenuDefItem, byval intoffset as integer) as integer DECLARE SUB write_menu_item_int (mi as MenuDefItem, byval intoffset as integer, byval n as integer) '' Drawing MenuDefs DECLARE SUB draw_menu (menu as MenuDef, state as MenuState, byval page as integer) DECLARE SUB update_menu_captions (menu as MenuDef) DECLARE FUNCTION menudef_item_rect (menu as MenuDef, state as MenuState, menutext as string, index as integer) as RectType DECLARE FUNCTION anchor_point(byval anchor as AlignType, byval size as integer) as integer DECLARE FUNCTION count_visible_menu_items (menu as MenuDef) as integer DECLARE FUNCTION get_menu_item_caption (mi as MenuDefItem, menu as MenuDef) as string DECLARE FUNCTION get_special_menu_caption(byval subtype as integer) as string DECLARE FUNCTION get_menu_item_editing_annotation (mi as MenuDefItem) as string DECLARE FUNCTION menu_item_is_activatable(mi as MenuDefItem) as bool '' Scrollbars! DECLARE SUB draw_scrollbar OVERLOAD (state as MenuState, menu as MenuDef, page as integer, align as AlignType = alignRight) DECLARE SUB draw_scrollbar OVERLOAD (state as MenuState, rect as RectType, boxstyle as integer=0, page as integer, align as AlignType = alignRight) DECLARE SUB draw_fullscreen_scrollbar(state as MenuState, boxstyle as integer=0, page as integer, align as AlignType = alignRight) ' Some day this may be a universal menu class. ' In the meantime, just use a simple menu() as string, but probably ' should switch to BasicMenuItem at a minimum TYPE ModularMenu EXTENDS Object running as bool 'Whether inside run() 'These arrays contain data for each menu item menu(any) as string selectable(any) as bool 'Optional: whether selectable shaded(any) as bool 'Optional: whether a header (actually whether greyed-out, but eduiHeading by default itemtypes(any) as integer 'Optional: menu item data (meaning defined by subclass) itemids(any) as integer 'Optional: menu item data (meaning defined by subclass) tooltip as string 'Shown at the bottom of the screen title as string 'Shown at the top, like the multichoice() prompt state as MenuState selectst as SelectTypeState can_use_strgrabber as bool 'Whether you can use strgrabber (false when selecting-by-typing) using_strgrabber as bool 'Set this true in each_tick() to disable select-by-typing menuopts as MenuOptions floating as bool 'Appears in the center of the screen, like notification, instead of fullscreen use_selectable as bool 'Set to true to make use of selectable() (TODO: get rid of this horrible setting, somehow) usemenu_ret as bool 'The return value of usemenu for this tick helpkey as string holdscreen as integer '0 if none ' Add an item to the menu ' Virtual because you might want to set more per-item data DECLARE VIRTUAL SUB add_item (itemtype as integer = 0, id as integer = -1, text as string = "", canselect as bool = YES, heading as bool = NO, disabled as bool = NO) ' Wrap and split 'text' into multiple items DECLARE SUB add_wrapped_items(itemtype as integer = 0, id as integer = -1, text as string = "", canselect as bool = YES, heading as bool = NO, disabled as bool = NO) ' Add a blank line DECLARE SUB add_spacer() ' Add a header to the menu DECLARE SUB header(text as string) ' Delete all menu items DECLARE SUB clear_menu() ' Called to create/update 'menu()' and 'state' if state.need_update is true. Also called once at start. ' Should correctly set state.last DECLARE VIRTUAL SUB update() ' Called each tick. Can either call update() itself or set state.need_update=YES ' Return YES to exit the menu DECLARE VIRTUAL FUNCTION each_tick() as bool ' Called when user tries to leave the menu ' Return YES to exit the menu DECLARE VIRTUAL FUNCTION try_exit() as bool ' Called before drawing the menu to draw any extra stuff DECLARE VIRTUAL SUB draw_underlays() ' Called after drawing the menu (and tooltip) to draw any extra stuff DECLARE VIRTUAL SUB draw_overlays() ' Generally you shouldn't need to override this. DECLARE VIRTUAL SUB draw() DECLARE SUB run() PRIVATE: DECLARE SUB update_wrapper() END TYPE ' I don't think we'll use this in Game. Reduce executable size. #IFDEF IS_CUSTOM ' Displays a stack of dropdown/popup-style MenuDef menus, each one opening next to the previous menu item TYPE MenuStack menus(any) as MenuDef states(any) as MenuState helpkey as string open_at_mouse as bool DECLARE SUB open_menu() DECLARE SUB open_menu_at(itemrect as RectType) DECLARE FUNCTION add_item(text as string, t as integer = 0, sub_t as integer = 0, dataptr as any ptr = 0) byref as MenuDefItem DECLARE SUB finish_open() DECLARE SUB close_menu() DECLARE FUNCTION is_open() as bool DECLARE FUNCTION is_active() as bool DECLARE FUNCTION controls() as bool DECLARE FUNCTION activate() as bool DECLARE FUNCTION cur_menu() as MenuDef ptr DECLARE FUNCTION cur_item() as MenuDefItem ptr DECLARE SUB draw(page as integer) END TYPE #ENDIF '' Global variables EXTERN force_use_mouse as integer #endif