GLCDMenu
Porting to GLCD from original source LCD Menu where you will find also the tools to edit and create the user menu definition module including the documentation on the use of the module.
Now you can move the menu using the Initialize routine :
Sub Initialise(pItemActionEvent As TEvent, XMnuPos As Byte = 20, YMnuPos As Byte = 10, YMnuStep As Byte = 10, XMnuCurs As Byte = 10 )
where you can set the distance between the lines of the menu by the variable YMnuStep and the x position of the cursor by XMnuCurs.
The module is suitable for use with GLCD with higher resolution like 320x240 as the S1D13700 where is used the layer 1 by default.
{ ******************************************************************************** * Name : GLCDMenu * * Author : AndyO, * * Notice : Copyright (c) AndyO, xva3rjy * * Date : 13/07/2008 * * : 14/11/2014 Porting to GLCD * * Version : 1.0 * * Notes : See doc "LCD Menu Module.pdf" * * : Menu data stored in Const arrays which are declared in seperate * * : module indicated by #define MenuDataModule = "filename.BAS" in * * : main program * * : Porting in GLCD version from original source by Andy0 * * * * Original LCD source: * * http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.LCDMenuModule * ******************************************************************************** } Module GLCDMenu Include "GLCD.bas" #ifdef MenuDataModule Include MenuDataModule #else #error "No MenuDataModule defined in main program" #endif #option Menu_LCDLines = 4 'Number of lines on LCD display #option Menu_ShowMenuTitle = True 'Display Menu Name at top of screen? #option Menu_ShowScrollIndicators = True 'Show up and down scroll indicators? #option Menu_ScrollWrapping = False 'Scroll wraps from top to bottom? #option Menu_PointerCharacter = 126 'Character used as pointer #if Menu_LCDLines = 1 And Menu_ShowMenuTitle = True #error "Cannot show menu titles on 1 line LCD" #endif Type TEvent = Event() Private Const LCDLines As Byte = Menu_LCDLines, PointerCharacter As Byte = Menu_PointerCharacter #If Menu_ShowScrollIndicators = True 'Character definitions for Up Arrow and Down Arrow scroll indicators Private Const ScrollIndicators(16) As Byte=($04,$0E,$1F,$00,$00,$00,$00,$00, $00,$00,$00,$00,$00,$1F,$0E,$04) Private Const UpArrow = 0 Private Const DownArrow = 1 #EndIf Private Dim FItemActionEvent As TEvent 'Holds pointer to event code in main 'program which is run when an "action" 'menu item is selected Private Dim PointerPosition As Byte 'Position of pointer character (0 = 1st) Private Dim PointerLine As Byte 'Actual LCD line of pointer Private Dim ScrollPosition As Byte 'Number of lines the menu is scrolled by Private Dim CurrentMenu As Byte 'Index number of current menu Private Dim ParentID As Byte 'Index number of parent of current menu Private Dim FirstItemNumber As Byte 'First item number for current menu Private Dim LastItemNumber As Byte 'Last item number for current menu Public Dim SelectedMenuItem As Byte 'Index number of selected menu item '=============================================================================== 'Name: DrawMenu(pMenuNumber as byte) 'Purpose: Draws current menu, scrolled by ScrollPosition amount ' Private Dim xPos As Byte, yPos As Byte, yStep As Byte, xCurs As Byte Dim LineNumber As Byte 'Line number of LCD to write at Private Function GetYPos(p As Byte = 0) As Byte If p<>0 Then result = yPos + (p - 1) * yStep Else result = yPos + (LineNumber - 1) * yStep End If End Function Private Sub DrawMenu() Dim ItemNumber As Byte 'Index of menu item number to write #If Menu_ScrollWrapping = True Dim ItemsDrawn As Byte ItemsDrawn = 0 #EndIf #if GLCD_MODEL = S1D13700 GLCD.Cls(1) #else GLCD.Cls() #endif LineNumber = 1 ItemNumber = FirstItemNumber + ScrollPosition #If Menu_ShowMenuTitle = True GLCD.WriteStr(xPos, GetYPos() , mnuMenuName(CurrentMenu)) LineNumber = 2 #Endif Repeat GLCD.WriteStr(xPos, GetYPos() , mnuItemName(ItemNumber)) Inc(LineNumber) Inc(ItemNumber) #If Menu_ScrollWrapping = True Inc(ItemsDrawn) If ItemNumber > LastItemNumber Then ItemNumber = FirstItemNumber EndIf Until LineNumber > LCDLines Or ItemsDrawn > LastItemNumber - FirstItemNumber #Else Until LineNumber > LCDLines Or ItemNumber > LastItemNumber #EndIf #If Menu_ShowScrollIndicators = True #If Menu_ScrollWrapping = True #If Menu_ShowMenuTitle = True If LastItemNumber - FirstItemNumber > LCDLines - 1 Then GLCD.WriteAt(xCurs, GetYPos(LCDLines) , DownArrow) GLCD.WriteAt(xCurs, GetYPos(2) , UpArrow) #Else If LastItemNumber - FirstItemNumber > LCDLines Then GLCD.WriteAt(xCurs, GetYPos(LCDLines) , DownArrow) GLCD.WriteAt(xCurs, GetYPos(1) , UpArrow) #EndIf EndIf #Else If ItemNumber - 1 < LastItemNumber Then GLCD.WriteAt(xCurs, GetYPos(LCDLines) , DownArrow) EndIf If ScrollPosition > 0 Then #If Menu_ShowMenuTitle = True GLCD.WriteAt(xCurs, GetYPos(2) , UpArrow) #Else GLCD.WriteAt(xCurs, GetYPos(1) , UpArrow) #EndIf EndIf #EndIf #EndIf End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: DrawPointer(pOldPosition as byte) 'Purpose: Deletes pointer at pOldPosition and draws pointer at PointerPosition 'Notes: When pointer is at first menu item on screen, PointerPosition = 0 ' Pointer character determined by option "Menu_PointerCharacter", ' default = 126 (right arrow) Private Sub DrawPointer(pOldPosition As Byte) 'Actual LCD line which pointer is drawn on depends on whether 'Menu_ShowMenuTitle is enabled or not #If Menu_ShowMenuTitle Then PointerLine = PointerPosition + 2 GLCD.WriteAt(xCurs, GetYPos(pOldPosition + 2) , " ") GLCD.WriteAt(xCurs, GetYPos(PointerLine) , PointerCharacter) #Else PointerLine = PointerPosition + 1 GLCD.WriteAt(xCurs, GetYPos(pOldPosition + 1) , " ") GLCD.WriteAt(xCurs, GetYPos(PointerLine) , PointerCharacter) #EndIf End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: ShowMenu(pMenuNumber as byte = 0) 'Purpose: Display specified menu on LCD Public Sub ShowMenu(pMenuNumber As Byte = 0) 'Reset scroll and pointer positions ScrollPosition = 0 PointerPosition = 0 CurrentMenu = pMenuNumber ParentID = mnuParentMenuID(CurrentMenu) FirstItemNumber = mnuMenuItemStart(CurrentMenu) LastItemNumber = mnuMenuItemEnd(CurrentMenu) DrawMenu DrawPointer(0) End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: MoveDown() 'Purpose: Move pointer to next menu item, scrolling the menu if necessary Public Sub MoveDown() Dim CanScroll As Boolean 'First, determine if the menu can be scrolled down and set CanScroll - ' ' If Scroll Wrapping Not Enabled: Menu may only be scrolled down if the ' number of menu items left to display won't fit on the number of ' available LCD lines ' ' Note: Number of available lines depends on whether Menu_ShowMenuTitle is ' enabled or not ' ' If Scroll Wrapping Enabled: Can always scroll down #If Menu_ScrollWrapping = False CanScroll = False #If Menu_ShowMenuTitle = True Then If FirstItemNumber + ScrollPosition + LCDLines - 2 < LastItemNumber Then CanScroll = True EndIf #Else If FirstItemNumber + ScrollPosition + LCDLines - 1 < LastItemNumber Then CanScroll = True EndIf #EndIf #Else CanScroll = True #EndIf 'Scroll the menu if the following conditions exist - ' ' Menu can be scrolled down and pointer is on or below the second last ' line of the display ' OR ' Menu can be scrolled down and pointer is on the last menu item - this ' allows scroll wrapping If (PointerLine >= LCDLines - 1 Or PointerPosition = LastItemNumber - FirstItemNumber) And CanScroll = True Then Inc(ScrollPosition) #If Menu_ScrollWrapping = True 'If scroll wrapping and we've scrolled to the bottom then start again at 'the top If ScrollPosition > (LastItemNumber - FirstItemNumber) Then ScrollPosition = 0 EndIf #EndIf DrawMenu() DrawPointer(PointerPosition) 'If not scrolling the menu then move the pointer down if the following 'conditions exist - ' ' Pointer is not on the last line of the display ' AND ' Pointer isn't on the last menu item ElseIf PointerLine < LCDLines And PointerPosition + FirstItemNumber + ScrollPosition < LastItemNumber Then Inc(PointerPosition) 'Fix to ensure Up Arrow scroll indicator is shown on smaller displays 'when pointer moves down from top line #If (Menu_LCDLines < 4 Or Menu_ScrollWrapping = True) And Menu_ShowScrollIndicators = True DrawMenu() DrawPointer(PointerPosition) #Else DrawPointer(PointerPosition - 1) #EndIf End If End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: MoveUp() 'Purpose: Move pointer to previous menu item, scrolling menu if necessary Public Sub MoveUp() 'Routine decides whether to scroll the menu up or just move the pointer up 'depending on the current state: ' 'If there is a free LCD line above the pointer (i.e. one that doesn't have 'the menu title or a scroll indicator in it then move the pointer up; ' 'Otherwise, if the menu can be scrolled (either because scroll wrapping is 'on or because the current scroll position > 0) then scroll the menu up; ' 'If the menu can't be scrolled then move the pointer up, overwriting any 'scroll-up indicator. (If necessary, re-draw the scroll-down indicator). #If Menu_ShowMenuTitle = True #If Menu_ShowScrollIndicators = True If PointerLine > 3 Then #Else If PointerLine > 2 Then #EndIf Dec(PointerPosition) DrawPointer(PointerPosition + 1) #If Menu_ScrollWrapping = True Else If ScrollPosition > 0 Then Dec(ScrollPosition) Else ScrollPosition = LastItemNumber - FirstItemNumber EndIf DrawMenu() DrawPointer(PointerPosition) EndIf #Else ElseIf ScrollPosition > 0 Then Dec(ScrollPosition) DrawMenu() DrawPointer(PointerPosition) ElseIf PointerLine > 2 Then Dec(PointerPosition) #If Menu_LCDLines < 4 And Menu_ShowScrollIndicators = True DrawMenu() DrawPointer(PointerPosition) #Else DrawPointer(PointerPosition + 1) #EndIf EndIf #EndIf #Else #If Menu_ShowScrollIndicators = True If PointerLine > 2 Then #Else If PointerLine > 1 Then #EndIf Dec(PointerPosition) DrawPointer(PointerPosition + 1) #If Menu_ScrollWrapping = True Else If ScrollPosition > 0 Then Dec(ScrollPosition) Else ScrollPosition = LastItemNumber - FirstItemNumber EndIf DrawMenu() DrawPointer(PointerPosition) EndIf #Else ElseIf ScrollPosition > 0 Then Dec(ScrollPosition) DrawMenu() DrawPointer(PointerPosition) ElseIf PointerLine > 1 Then Dec(PointerPosition) #If Menu_LCDLines < 4 And Menu_ShowScrollIndicators = True DrawMenu() DrawPointer(PointerPosition) #Else DrawPointer(PointerPosition + 1) #EndIf EndIf #EndIf #EndIf End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: Back() 'Purpose: Show parent of current menu Public Sub Back() ShowMenu(ParentID) End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: SelectItem() 'Purpose: Carries out action of selected menu item. If menu item opens ' another menu then that menu is drawn. If menu item is an 'action' ' item then the event in the main program which handles the action is ' called Public Sub SelectItem() Dim ItemAction As Byte SelectedMenuItem = FirstItemNumber + ScrollPosition + PointerPosition #If Menu_ScrollWrapping = True If SelectedMenuItem > LastItemNumber Then SelectedMenuItem = SelectedMenuItem - (LastItemNumber - FirstItemNumber) - 1 EndIf #EndIf ItemAction = mnuItemAction(SelectedMenuItem) If ItemAction = 255 Then ParentID = CurrentMenu 'Means 'back' command will return to correct menu FItemActionEvent() 'Call event handler in main program Else ShowMenu(ItemAction) EndIf End Sub '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'Name: Initialise(pItemActionEvent as TEvent) 'Purpose: Sets name of main program event handler and loads custom scroll ' characters into LCD Public Sub Initialise(pItemActionEvent As TEvent, XMnuPos As Byte = 20, YMnuPos As Byte = 10, YMnuStep As Byte = 10, XMnuCurs As Byte = 10 ) xPos = XMnuPos yPos = YMnuPos yStep = YMnuStep xCurs = XMnuCurs FItemActionEvent = pItemActionEvent End Sub