GLCDMenu

SwordfishUser.GLCDMenu History

Show minor edits - Show changes to output

Deleted lines 439-441:
   #If Menu_ShowScrollIndicators = True Then
        LCDI2C.Write(ScrollIndicators)
    #EndIf
Added lines 15-16:

The module is suitable for use with GLCD with higher resolution like 320x240 as the S1D13700 where is used the layer 1 by default.
Changed lines 1-2 from:
Porting to GLCD from original source [[http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.LCDMenuModule| LCD Menu]]
to:
Porting to GLCD from original source [[http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.LCDMenuModule| 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 :
Added lines 5-16:

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. 

=code [=
Added line 117:
#if GLCD_MODEL = S1D13700
Added lines 119-121:
#else   
    GLCD.Cls()
#endif   
Added lines 1-2:
Porting to GLCD from original source [[http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.LCDMenuModule| LCD Menu]]
Changed lines 8-9 from:
*  Notice  : Copyright (c) 2008 AndyO, xva3rjy                                           *
*          : All Rights Reserved       
                                      *
to:
*  Notice  : Copyright (c) AndyO, xva3rjy                                      *
Changed line 10 from:
*          : 14/11/2014 Porting original by Andy0 to GLCD
to:
*          : 14/11/2014 Porting to GLCD                                        *
Deleted line 12:
*          :                                                                  *
Changed lines 16-17 from:
*          :                                                                  *
*
          : Requires modified LCD.bas module with WriteConstStringAt()        *
to:
*          : Porting in GLCD version from original source by Andy0            *
*
                                                                              * 
* Original LCD source:                                                        *
* http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.LCDMenuModule
    *
Deleted line 0:
Changed lines 2-20 from:
to:
{
********************************************************************************
*  Name    : GLCDMenu                                                          *
*  Author  : AndyO,                                                            *
*  Notice  : Copyright (c) 2008 AndyO, xva3rjy                                          *
*          : All Rights Reserved                                              *
*  Date    : 13/07/2008                                                        *
*          : 14/11/2014 Porting original by Andy0 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                                                      *
*          :                                                                  *
*          : Requires modified LCD.bas module with WriteConstStringAt()        *
********************************************************************************
}

Changed line 22 from:
Include "glcd"
to:
Include "GLCD.bas"
Added lines 1-406:

=code [=

Module GLCDMenu
Include "glcd"

#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


    GLCD.Cls(1)
   
    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
    #If Menu_ShowScrollIndicators = True Then
        LCDI2C.Write(ScrollIndicators)
    #EndIf
End Sub
=]