Simple Text Menu

Started by kevin, June 21, 2020, 01:28:02 PM

Previous topic - Next topic

kevin

   Simple Text Menu

 While tinkering last night, I wrote a simple menu library that lets the programmer define a list of text options that can have a key and mousing bindings as well.   The library is more a starting point than a end product, but it shows a way how we can wrap a system into library that help us separate that functionality from the main program.   The user can tag a function (by name) that is called when any option is clicked or the key binding is pressed.  


Example:

 So our processing loop looks like this..

PlayBASIC Code: [Select]
   loadfont "verdana",1 , 48


cr$=chr$(10)+chr$(13)


Options$ =" L) Load File [BindKey=38][OnClick=LOAD_FUNCTION]"+cr$
Options$+=" S) Save File [BindKey=31][OnClick=SAVE_FUNCTION]"+cr$
Options$+=" D) Delete File [BindKey=32][OnClick=DELETE_FUNCTION]"+cr$


//
GUI_CREATE_SIMPLE_MENU(Options$)


Do
cls $304050

GUI_UPDATE_SIMPLE_MENU_INPUTSTATE()
GUI_DRAW_SIMPLE_MENU()


action$=GUI_Get_SIMPLE_MENU_CLICKS()

if Len(Action$)
Index=FunctionIndex(Action$)
if Index
CallFunction Action$
endif
endif

sync
loop



Function LOad_Function()
cls 255
print "LOAD FUNCTION"
EndFunction

Function SAVE_Function()
cls $00ff00
Print "SAVE FUNCTION"
EndFunction

Function DELETE_Function()
cls $ff0000
Print "DELETE FUNCTION"
EndFunction









COMPLETE EXAMPLE:

PlayBASIC Code: [Select]
   loadfont "verdana",1 , 48


cr$=chr$(10)+chr$(13)


Options$ =" L) Load File [BindKey=38][OnClick=LOAD_FUNCTION]"+cr$
Options$+=" S) Save File [BindKey=31][OnClick=SAVE_FUNCTION]"+cr$
Options$+=" D) Delete File [BindKey=32][OnClick=DELETE_FUNCTION]"+cr$


//
GUI_CREATE_SIMPLE_MENU(Options$)


Do
cls $304050

GUI_UPDATE_SIMPLE_MENU_INPUTSTATE()
GUI_DRAW_SIMPLE_MENU()


action$=GUI_Get_SIMPLE_MENU_CLICKS()

if Len(Action$)
Index=FunctionIndex(Action$)
if Index
CallFunction Action$
endif
endif

sync
loop



Function LOad_Function()
cls 255
print "LOAD FUNCTION"
EndFunction

Function SAVE_Function()
cls $00ff00
Print "SAVE FUNCTION"
EndFunction

Function DELETE_Function()
cls $ff0000
Print "DELETE FUNCTION"
EndFunction


//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------
//------------------------------------------------------------------


Type tSimpleTextMenuInputState
Status
MX
MY
MB
ScanCode
EndType



Type tSimpleTextMenu
Caption$

KeyBindingScanCode
FunctionToCall$


x1,y1,x2,y2 ; render position of this on screen
MouseOver
EndType

Dim SimpleTextMenu(256) as tSimpleTextmenu

Dim SimpleTextmenuInputState as tSimpleTextMenuInputState


function GUI_CREATE_SIMPLE_MENU(MenuOptions$)

// Redim the Global Memu
Dim SimpleTextMenu(256) as tSimpleTextmenu

//
GUI_INIT_SIMPLE_MENU_INPUTSTATE()


dim Rows$(1024)

Options$=Replace$(MenuOptions$,chr$(10),"")

LinesOfText = SplitToArray(options$,chr$(13),rows$(),0,0)


MenuIndex =1

for lp=0 to LinesOftext-1

s$=Rows$(lp)

// Check for empty line
if len(trim$(S$))>0
Param_KeyBind$ =""
Param_Onclick$ =""

Current_Pos =1
do

// Look for square brackets
Left_pos=instring(s$,"[",Current_pos)
if Left_Pos
Right_pos=instring(s$,"]",Current_pos)
If Right_Pos>Left_Pos

Opcode$=Mid$(s$,Left_pos+1,(Right_Pos-Left_Pos)-1)


Current_Pos=Left_pos
S1$= Left$(s$,Left_pos-1)
S2$= CutLeft$(s$,Right_pos)
s$=s1$+s2$

// get Opcode and Value
Value$ =""
Equals_pos = instring(opcode$,"=")
if Equals_pos
Value$ = CutLeft$(Opcode$,Equals_pos)
Opcode$ = Left$(Opcode$,Equals_pos-1)
endif

Select upper$(trim$(opcode$))

// process embedded opcodes for this menu option
case "ONCLICK"
Param_Onclick$ = value$

case "KEYBIND", "BINDKEY", "KEY"
Param_KEYBIND$ = value$

EndSelect
Login required to view complete source code

kevin

#1
   Another Simple Menu For PlayBASIC


  In this example we're creating a left to right stacking menu with Mouse hover and left clicked selection.    The menu returns the NAME of the FUNCTION for you to call.   So all you do is Name the processing function that name and dynamically call it via CallFunction.    This way you can remove the need to manually detection a click and just build your list of processing functions.

  used functions:  CallFunction, SplitToArray , Dim, MouseX, MouseY and MouseButton


PlayBASIC Code: [Select]
   loadfont "Courier new",1, 42
Dim Menu$(10)
s$="Load,Save,Delete,End"
Count=SplittoArray(s$,",",menu$())

setfps 30

// -----------------------------------------------------------------
do // MAIN LOOP
// -----------------------------------------------------------------

// Clear the screen to black
cls

// Render the menu and process what was clicked (if any)
Clicked$=Draw_Menu(0,0)

text 50,270,"Clicked:"+Clicked$
if len(Clicked$)
Clicked$=upper$(clicked$)
CallFunction Clicked$
endif

sync
loop Clicked$="MENU_END"


cls
print "Program ended"
Sync
waitkey




// -----------------------------------------------------------------
Function Menu_Load()
// -----------------------------------------------------------------
Text 0,200, "Load was selected"
EndFunction



// -----------------------------------------------------------------
Function Menu_Save()
// -----------------------------------------------------------------
Text 0,200, "Save was selected"

EndFunction

// -----------------------------------------------------------------
// -----------------------------------------------------------------
Function Menu_Delete()
// -----------------------------------------------------------------
Text 0,200, "Delete was selected"

EndFunction

// -----------------------------------------------------------------
// -----------------------------------------------------------------
Function Menu_END()
EndFunction


// -----------------------------------------------------------------
// -----------------------------------------------------------------
Function Draw_Menu(Xpos,Ypos)
// -----------------------------------------------------------------
// -----------------------------------------------------------------

Clicked_Menu$=""

mx=mousex()
my=mousey()
mb=mousebutton()

// Compute used slots and Max menu item width
MaxWidth=0
MaxCount=0
for lp=0 to getarrayelements(Menu$())
m$=Menu$(lp)
if Len(M$)>0
MaxWidth=maxval(MaxWidth,GetTextWidth(m$))
MaxCount=lp
else
exit
endif
next

Dim HoverCol(2)
Dim TextCol(2)
HoverCol(0) =$665544
HoverCol(1) =rgbfade(HoverCol(0),50)
TextCol(0) = -1
TextCol(1) = $ff00ff

MaxWidth+=GetTextWidth("__")
oldink=getink()
For lp =0 to MaxCount

// Get Menu item name
m$=Menu$(lp)

// Compute the height of this text
Ypos2=Ypos+gettextheight(m$)

// If the mouse over this rect ??
HoverStatus =pointinbox(mx,my,xpos,ypos,xpos+maxwidth,ypos2)

// check if the mouse is over this button and mouse
// button is pressed
if HoverStatus and mb & 1
Clicked_Menu$="Menu_"+M$
endif

// draw box / rectangle for this item
boxc xpos,ypos,xpos+maxwidth,ypos2,true,HoverCol(HoverStatus)

// draw our text over the top of it
ink TextCol(HoverStatus)
text Xpos,Ypos,m$

Xpos=Xpos+MaxWidth
next

ink OldInk
EndFunction Clicked_Menu$





   -- Source Code ON PasteBin


kevin

  Simple Menu V0.03

    This is updated simple menu code that's used in the BlitzBASIC 2 PlayBASIC translator

PlayBASIC Code: [Select]
; PROJECT : Convert BlitzBasic To PlayBASIC
; EDITED : 9/05/2022
; ---------------------------------------------------------------------

` *=---------------------------------------------------------------------=*
`
` >> TextMenus V0.03 <<
`
` By: Kevin Picone
`
` Started: (21st,June,2020)

` Last Updated: (28th,April,2022)
`
` (c) copyright 2020/2022 Kevin Picone, All rights reserved
`
` *=---------------------------------------------------------------------=*
`
` This library provides a set of function for rendering and navigating
` through user defined text menus.
`
` Functions:
`
`
` *=---------------------------------------------------------------------=*

constant PB_TEXTMENU_LIBRARY_ExplicitState = PBExplicitState

Explicit true



Type tSimpleTextMenuInputState
Status
MX
MY
MB
MB_CLICKED
ScanCode


// Displacement for mouse position (used for doing windows)
Offset_MX
Offset_MY
EndType



Type tSimpleTextMenu
ObjectName$
Caption$

Display
KeyBindingScanCode
FunctionToCall$


x1,y1,x2,y2 ; render position of this on surface
MouseOver
EndType



// -------------------------------------------------------------
// Declare SimpleTextMenu array as a stub, so we move the handles
// in or out of it to change menus
// -------------------------------------------------------------
MakeArray SimpleTextMenu().tSimpleTextmenu
;Dim SimpleTextMenu(256) as tSimpleTextmenu

Dim SimpleTextmenuInputState as tSimpleTextMenuInputState

//
Dim MenuStack(1024)


global SimpleTextmenu_Allow_Input



function GUI_CREATE_SIMPLE_MENU(MenuOptions$)

// Redim the Global Memu
Dim SimpleTextMenu(256) as tSimpleTextmenu

//
GUI_INIT_SIMPLE_MENU_INPUTSTATE()


dim Rows$(1024)

local Options$=Replace$(MenuOptions$,chr$(10),"")
local LinesOfText = SplitToArray(options$,chr$(13),rows$(),0,0)
local lp,MenuIndex =1

local Param_KeyBind$ ,Param_OnClick$, Param_Display,Param_ObjectName$
local Current_Pos , Left_pos,Right_Pos,Equals_pos
local Value$,Opcode$

for lp=0 to LinesOftext-1

local s$=Rows$(lp)

// Check for empty line
if len(trim$(S$))>0

Param_KeyBind$ =""
Param_Onclick$ =""
Param_Display = true
Param_ObjectName$ =""

Current_Pos =1
do

// Look for square brackets
Left_pos=instring(s$,"[",Current_pos)
if Left_Pos
Right_pos=instring(s$,"]",Current_pos)
If Right_Pos>Left_Pos

Opcode$=Mid$(s$,Left_pos+1,(Right_Pos-Left_Pos)-1)


Current_Pos=Left_pos
local S1$= Left$(s$,Left_pos-1)
local S2$= CutLeft$(s$,Right_pos)
s$=s1$+s2$

// get Opcode and Value
Value$ =""
Equals_pos = instring(opcode$,"=")
if Equals_pos
Value$ = CutLeft$(Opcode$,Equals_pos)
Opcode$ = Left$(Opcode$,Equals_pos-1)
endif

// #print opcode$
// #print Value$

Select upper$(trim$(opcode$))

// process embedded opcodes for this menu option
case "ONCLICK"
Param_Onclick$ = value$

case "KEYBIND", "BINDKEY", "KEY"
Param_KEYBIND$ = value$

Login required to view complete source code