Microsoft Small Basic

Program Listing: BGF911-1
'http://smallbasic.com/program/?VST735-1
'Drop Down Menu System - (under construction) by Jibba Jabba, January 2014
'For my native SB code library

Initialise()

While "True"
UpdateProgram()
UpdateFrame()
FrameRate()
EndWhile

'=======================================================
'FIRST ORDER SUBROUTINES
'=======================================================

Sub UpdateProgram
start = Clock.ElapsedMilliseconds

If mouseMove Then
GetMousePosition()
UpdateMenuOnMouseMove()

mouseMove = "False"
EndIf

If mouseDown Then
UpdateMenuOnMouseDown() 'creates a non async OnMenuClicked Event
'GetMousePosition() 'not used here for menu

mouseDown = "False"
EndIf

If menuClicked Then 'OnMenuClicked
TextWindow.WriteLine("menu = " + menu[menuSelection])
TextWindow.WriteLine(" submenu = " + subMenu[menuSelection][subMenuSelection])

menuSelection = 0
subMenuSelection = 0
menuClicked = "False"
EndIf
EndSub

Sub UpdateFrame
UpdateMenuFrame()
EndSub

Sub FrameRate
delay = 1000 / fps - (Clock.ElapsedMilliseconds - start)
If delay > 0 Then
'TextWindow.WriteLine("ms = " + (Clock.ElapsedMilliseconds - start)) 'speed
Program.Delay(delay)
Else
'TextWindow.WriteLine("delay = " + delay) 'lag
EndIf
EndSub

'============================================================
'SECOND ORDER SUBROUTINES - except for Menu Module
'============================================================
Sub GetMousePosition
mseX = GraphicsWindow.MouseX
mseY = GraphicsWindow.MouseY
EndSub

'===========================================================
'INITIALISE
'===========================================================
Sub Initialise
'DEBUG
TextWindow.Top = 20
TextWindow.Left = GraphicsWindow.Width + 50
GraphicsWindow.Left = 10

'Main Loop
fps = 50 '*6 drags > 300fps

'Get &/Or Set Stuff
gw = GraphicsWindow.Width
gh = GraphicsWindow.Height
GetMousePosition()

InitialiseMenu()

'Register Events
GraphicsWindow.MouseMove = OnMouseMove
GraphicsWindow.MouseDown = OnMouseDown
EndSub

'=========================================================
'Event Handlers
'=========================================================
Sub OnMouseMove
mouseMove = "True"
EndSub

Sub OnMouseDown
mouseDown = "True"
EndSub

'************************************************************************************************************
'============================================================
'DROP DOWN MENU SUBROUTINES
'============================================================
'Customise & Dynamic Subs - Second Order
'-----------------------------------------------------------------------------------------------------
Sub MenuDataTable 'USE THIS SUB TO CUSTOMISE MENU
'MENU
'Data Table
menu = "1=View Screen;2=Program;3=Help;4=Test This" 'ADD DATA
menuWidth = "1=105;2=85;3=55;4=85" 'MATCH WIDTH WITH DATA
subMenu[1] = "1=Home;2=Small;3=Leaders Board;4=Extra for one;5=Another Extra for testing submenu one"
subMenu[2] = "1=Debug;2=Close;3=test submenu two;4=more again"
subMenu[3] = "1=How;2=About Match Picture;3=Again test me"
subMenu[4] = "1=Test One;2=Test Sub Menu two"
subMenuWidth = "1=285;2=145;3=165;4=155" 'MATCH WIDTH WITH DATA
EndSub

Sub DrawMenuBar 'USE THIS SUB TO REDRAW MENU BAR on Resize 'UNTESTED
'Add Menu Bar - Sub {redraw for new window size}
If weHaveSprites Then
GraphicsWindow.DrawResizedImage(menuBarTexture, 0, 0, gw, menuHeight)
Else
GraphicsWindow.BrushColor = "Peru"
GraphicsWindow.FillRectangle(0, 0, gw, menuHeight)
EndIf
EndSub

'-----------------------------------------------------------------------------------------------------------
'Initialise Menu - First Order
'-----------------------------------------------------------------------------------------------------------
Sub InitialiseMenu
MenuDataTable() 'USED TO CUSTOMISE THE MENU

'Load Menu Sprites
menuFileName[1] = "\Focus Texture.png"
menuFocusSprite = ImageList.LoadImage(Program.Directory + menuFileName[1])
menuFileName[2] = "\subMenu Focus Sprite.png"
subMenuFocusSprite = ImageList.LoadImage(Program.Directory + menuFileName[2])
menuFileName[3] = "\Sub Menu Background Sprite 2.png"
subMenuBackgroundSprite = ImageList.LoadImage(Program.Directory + menuFileName[3])
menuFileName[4] = "\Menu Bar Texture.png"
menuBarTexture = ImageList.LoadImage(Program.Directory + menuFileName[4])

' The following line could be harmful and has been automatically commented.
' The following line could be harmful and has been automatically commented.
' ' getMenuFiles = File.GetFiles(Program.Directory)
getMenuFiles = ""

weHaveSprites = "True"
For i = Array.GetItemCount(menuFileName) To 1 Step -1
If Text.IsSubText(getMenuFiles, menuFileName[i]) <> "True" Then
weHaveSprites = "False"
EndIf
EndFor

menuFocusOpacityIndex = 0

'Get posX for menuFocus
For i = 1 To Array.GetItemCount(menuWidth) 'to be reversed
totalMenuWidth = totalMenuWidth + menuWidth[i]
menuFocusX[i] = totalMenuWidth - menuWidth[i]
EndFor

If totalMenuWidth > gw Then
TextWindow.WriteLine("ERROR: total menu widths exceeds GW")
TextWindow.Pause()
EndIf

'Set Parameters
menuHeight = 25
menuFocusWidth = 50 'original width before Zoom scale X
menuTextOffset = 8
isMenuSelected = -1 'toggle init OFF
menuFocusOpacity = "1=100;-1=30;0=0"
subMenuTextOffset = 16

DrawMenuBar() 'USED TO REDRAW MENU AFTER WINDOW RESIZE

'Add Menu Focus
If weHaveSprites Then
menuFocus = Shapes.AddImage(menuFocusSprite)
Else
GraphicsWindow.BrushColor = "DeepPink"
GraphicsWindow.PenWidth = 0
menuFocus = Shapes.AddRectangle(menuFocusWidth, menuHeight) 'WIP ************
EndIf
Shapes.SetOpacity(menuFocus, 0)

'Add Menu
GraphicsWindow.FontName = "Segoe Print"
GraphicsWindow.FontSize = 13
GraphicsWindow.BrushColor = "PaleGreen"

For i = Array.GetItemCount(menu) To 1 Step -1
menuText[i] = Shapes.AddText(menu[i])
Shapes.Move(menuText[i], menuFocusX[i] + menuTextOffset, 0)
EndFor

'Error Check subMenu Width. NEEDS MORE TESTING
If menuFocusX[Array.GetItemCount(menu)] + subMenuWidth[Array.GetItemCount(menu)] > gw Then
TextWindow.WriteLine("ERROR: sum of all subMenu widths exceeds GW")
TextWindow.Pause()
EndIf

'Add Sub Menus - FIXING B/GROUND SPRITE *******************************
If weHaveSprites Then
subMenuBackground = Shapes.AddImage(subMenuBackgroundSprite)
Else
GraphicsWindow.BrushColor = "SandyBrown"
subMenuBackground = Shapes.AddRectangle(menuFocusWidth, menuHeight)
EndIf
Shapes.SetOpacity(subMenuBackground, 0)

'Add SubMenus
If weHaveSprites Then
subMenuFocus = Shapes.AddImage(subMenuFocusSprite) 'wip sprite ***********
Else
GraphicsWindow.BrushColor = "Grey"
GraphicsWindow.PenWidth = 0
subMenuFocus = Shapes.AddRectangle(menuFocusWidth, menuHeight)
EndIf
Shapes.SetOpacity(subMenuFocus, 0)

For j = Array.GetItemCount(subMenu) To 1 Step -1
left = menuFocusX[j] + subMenuTextOffset
For i = Array.GetItemCount(subMenu[j]) To 1 Step -1
GraphicsWindow.BrushColor = "PaleGreen"
subMenuText[j][i] = Shapes.AddText(subMenu[j][i])
Shapes.Move(subMenuText[j][i], left, menuHeight * i)
Shapes.SetOpacity(subMenuText[j][i], 0)
EndFor
EndFor
EndSub

'------------------------------------------------------------------------------------------------------------
'Menu Updates - Second Order
'------------------------------------------------------------------------------------------------------------
Sub UpdateMenuOnMouseMove
'Update Menu Focus onMouseMove
menuFocusedOn = 0
menuFocusOpacityIndex = 0
If mseY <= menuHeight And mseX <= totalMenuWidth Then
For i = Array.GetItemCount(menu) To 1 Step -1
If mseX >= menuFocusX[i] And mseX <= menuFocusX[i] + menuWidth[i] Then
menuFocusOpacityIndex = isMenuSelected 'isMenuSelected toggles onMouseDown 1/-1
menuFocusZoomX = menuWidth[i] / menuFocusWidth
menuFocusedOn = i 'determines which SubMenu[i] to open If isMenuSelected = 1
nextMenuFocus = menuFocusedOn
EndIf
EndFor

If isMenuSelected = 1 And nextMenuFocus <> currentMenuFocus Then 'change selected Menu focus
priorMenuFocus = currentMenuFocus
currentMenuFocus = nextMenuFocus
EndIf

ElseIf isMenuSelected = 1 Then 'lock the selected Menu and its opacity to show related SubMenu
menuFocusedOn = currentMenuFocus '...so that SubMenu stays open when mouse is off location
menuFocusOpacityIndex = 1
EndIf

'Update SubMenu Focus onMouseMove
subMenuFocusedOn = 0 'WIP
If isMenuSelected = 1 Then
subMenuFocusOpacity = 0

'Loop thru sub menu, as required. Sets subMenuFocus Top, Opacity & ZoomX. And sets subMenuBackgroundZoomY
If mseX >= menuFocusX[menuFocusedOn] And mseX <= menuFocusX[menuFocusedOn] + subMenuWidth[menuFocusedOn] Then
If mseY > menuHeight And mseY <= menuHeight * (Array.GetItemCount(subMenu[menuFocusedOn]) + 1) Then
For i = Array.GetItemCount(subMenu[menuFocusedOn]) To 1 Step -1
If mseY >= menuHeight * i And mseY <= menuHeight * (i+1) Then
subMenuFocusTop = menuHeight * i
subMenuFocusedOn = i
EndIf
EndFor
subMenuFocusOpacity = 100
EndIf
subMenuFocusZoomX = subMenuWidth[menuFocusedOn] / menuFocusWidth
subMenuBackgroundZoomY = (Array.GetItemCount(subMenu[menuFocusedOn]) * menuHeight) / menuHeight
EndIf
Else
subMenuFocusOpacity = 0
EndIf
EndSub

Sub UpdateMenuOnMouseDown
'Update Menu onMouseDown
If menuFocusedOn <> 0 Then
isMenuSelected = -isMenuSelected 'toggle on Click 1/-1
menuFocusOpacityIndex = isMenuSelected
EndIf

priorMenuFocus = 0
If isMenuSelected = -1 Then
If mseY > menuHeight Or mseX > totalMenuWidth Then
menuFocusOpacityIndex = 0
priorMenuFocus = menuFocusedOn
EndIf
EndIf

'Update SubMenu onMouseDown
If isMenuSelected = 1 Then
subMenuOpacity = 100
subMenuFocusZoomX = subMenuWidth[menuFocusedOn] / menuFocusWidth
subMenuBackgroundZoomY = (Array.GetItemCount(subMenu[menuFocusedOn]) * menuHeight) / menuHeight '******
Else
subMenuOpacity = 0
subMenuFocusOpacity = 0
EndIf

'OnMenuClicked event {non async Event} - pass the selection to If menuClicked
If isMenuSelected = -1 And subMenuFocusedOn > 0 Then
menuSelection = menuFocusedOn
subMenuSelection = subMenuFocusedOn

If menuSelection > 0 And subMenuSelection > 0 Then '***OnMenuClicked Event***
menuClicked = "True" 'non async event. Sequential
EndIf

menuFocusedOn = 0
subMenuFocusedOn = 0

'Unlock the selected Menu after no mouseMove between clicks
ElseIf isMenuSelected = -1 And mseY > menuHeight Or isMenuSelected = -1 And mseX > totalMenuWidth Then '****wip here
menuFocusedOn = 0
EndIf
EndSub

Sub UpdateMenuFrame
'Update Menu Focus - Main Bar
Shapes.SetOpacity(menuFocus, menuFocusOpacity[menuFocusOpacityIndex])
Shapes.Zoom(menuFocus, menuFocusZoomX, 1)
Shapes.Move(menuFocus, menuFocusX[menuFocusedOn] + (menuWidth[menuFocusedOn] - menuFocusWidth) /2, 0)

'Update SubMenu - Got Focus
Shapes.SetOpacity(subMenuBackground, subMenuOpacity)
Shapes.Zoom(subMenuBackground, subMenuFocusZoomX, subMenuBackgroundZoomY)

Y = menuHeight + ((Array.GetItemCount(subMenu[menuFocusedOn]) * menuHeight) - menuHeight) / 2 'wip put in update program
Shapes.Move(subMenuBackground, menuFocusX[menuFocusedOn] + (subMenuWidth[menuFocusedOn] - menuFocusWidth) /2, Y)

For i = Array.GetItemCount(subMenu[menuFocusedOn]) To 1 Step -1
Shapes.SetOpacity(subMenuText[menuFocusedOn][i], subMenuOpacity)
EndFor

'Update SubMenu - Lost Focus
Shapes.SetOpacity(subMenuBackground[priorMenuFocus], 0) 'check if index needed
For i = Array.GetItemCount(subMenu[priorMenuFocus]) To 1 Step -1
Shapes.SetOpacity(subMenuText[priorMenuFocus][i], 0)
EndFor

'Update SubMenu Focus
Shapes.SetOpacity(subMenuFocus, subMenuFocusOpacity)
Shapes.Zoom(subMenuFocus, subMenuFocusZoomX, 1)
Shapes.Move(subMenuFocus, menuFocusX[menuFocusedOn] + (subMenuWidth[menuFocusedOn] - menuFocusWidth) /2, subMenuFocusTop)
EndSub