home *** CD-ROM | disk | FTP | other *** search
- $COMPILE UNIT ".\VERTMENU.PBU"
- $CODE SEG "SCRNLIB"
- $CPU 8086 ' Make compatible with XT systems
- $LIB ALL OFF ' Turn off all PowerBASIC libraries
- $ERROR ALL OFF ' Turn off all PowerBASIC error checking
- $OPTIMIZE SIZE ' Optimize for smaller code
-
- DEFINT A-Z ' Required for all numeric functions, forces PB to not
- ' include floating point in UNIT (makes it smaller)
-
- '+-----------------------------------------------------------------+
- '| This component of PB3BOXES is Copyright Nathan C. Durland III |
- '| All rights reserved |
- '+-----------------------------------------------------------------+
-
- $INCLUDE ".\PB3BOXES.HDR"
-
- SUB VerticalMenu(MenuList$(), Choice%, BYVAL DisplayMode%, _
- BYVAL HighAttr%, BYVAL MenuTimer%, _
- BYVAL ProcTimer%, BYVAL ProcAddr AS DWORD) LOCAL PUBLIC
- '╒════════════════════════════════════════════════════════════════════════════╕
- '│ This is the routine to call for simple one-choice vertical menus │
- '│ │
- '│ See TagMenu for a more complete definition of the paramters │
- '╘════════════════════════════════════════════════════════════════════════════╛
-
- Junk$ = "ONE"
- CALL TagMenu(MenuList$(), Junk$, DisplayMode%, _
- HighAttr%,MenuTimer%, ProcTimer%, ProcAddr)
-
- Choice% = INSTR(junk$,"1")
-
- END SUB
-
-
- SUB TagMenu(MenuList$(), TagList$, BYVAL DisplayMode%, _
- BYVAL HighAttr%, BYVAL MenuTimeOut%, _
- BYVAL ProcTimeOut%, BYVAL ProcAddr AS DWORD) PUBLIC
- '╒════════════════════════════════════════════════════════════════════════════╕
- '│ This routine will display a list of items -- MenuList$() -- on the screen │
- '│ and will toggle the corresponding element of TagMenuChoice%() from %True │
- '│ to %False, as appropriate. Each tagged entry will have a "" next to it. │
- '│ │
- '│ The user can toggle the choice of an item by pressing the INS or the │
- '│ DEL key. CTRL-INS & CTRL-DEL will select/deselect all items. │
- '│ │
- '│ The ENTER key will terminate the call. ESC also terminates, but will set │
- '│ the ItemsTagged% parameter to 0. │
- '│ │
- '│ - The Home Key will move the menu to the top, │
- '│ - The End key will proceed to the bottom. │
- '╞════════════════════════════════════════════════════════════════════════════╡
- '│Using TagMenu really involves 3 CALL statements: │
- '│ 1. call MakeBox to create a box to place the menu in. Make sure the │
- '│ box is at least 4 characters wider than the widest menu list item. │
- '│ 2. call TagMenu. │
- '│ 3. call RemoveBox. │
- '╞════════════════════════════════════════════════════════════════════════════╡
- '│PowerBASIC calling parameters: │
- '│ │
- '│ MenuList$() -- the items to display on the screen. The last element in │
- '│ the array must be set to "" │
- '│ TagList$ -- A string of "0" and "1", with a lenght equal to the │
- '│ number of items in the menu. "1" corresponds to a │
- '│ tagged item. If this string is eqal to "ONE" when this │
- '│ routine is called, then the user will only be allowed │
- '│ to make one choice. │
- '│ DisplayMode% -- if 0, then the choices are centered in the box. │
- '│ -- if 1, the choices are left justified │
- '│ -- if 2, the choices are left justified, and have a │
- '│ letter next to them. Pressing the letter highlights │
- '│ that choice. The letters are based on the items position│
- '│ in the menu screen │
- '│ HighAttr% -- The color attribute to use for highlighted items │
- '│ MenuTimeOut% -- a timeout value (seconds). If no choice is made before │
- '│ this runs out, the menu exits and returns Choice% = 0. │
- '│ Set MenuTimer% to 0 for no time out. A message is │
- '│ displayed on the bottom of the screen. │
- '│ ProcTimeOut% -- Another timer. This counts how long before the routine │
- '│ pointed to by ProcAddr should be called. Set it to 0 │
- '│ for no timed routine. Handy for print spoolers, etc │
- '│ ProcAddr -- A DWORD value returned by CODEPTR32 that points to a │
- '│ routine that you'd like done every ProcTimeOut% seconds │
- '╘════════════════════════════════════════════════════════════════════════════╛
-
-
- JustOne% = (TagList$ = "ONE")
- MenuRow% = BoxParms%(CurrentBox%,1) ' Get current box size & paramters
- MenuCol% = BoxParms%(CurrentBox%,2)
- MenuRows% = BoxParms%(CurrentBox%,3)
- MenuCols% = BoxParms%(CurrentBox%,4)
- MenuAttr% = BoxParms%(CurrentBox%,5)
-
- '╒════════════════════════════════════════════════════════════════╕
- '│ We're might have to change these, so we want to save them now │
- '╘════════════════════════════════════════════════════════════════╛
- OldMenuCol% = MenuCol%
- OldMenuRows% = MenuRows%
- OldMenuCols% = MenuCols%
-
- IF BoxParms%(CurrentBox%,6) > 0 THEN ' Account for the border
- INCR MenuRow%,1
- DECR MenuRows%,2
- INCR MenuCol%,1
- DECR MenuCols%,2
- END IF
-
- MenuLen% = MenuRows% ' set some other vars that we need
- ARRAY SCAN MenuList$(1), = "", TO ItemCnt%
- IF ItemCnt% = 0 THEN
- ItemCnt% = UBOUND(MenuList$())
- ELSE
- DECR ItemCnt%,1
- END IF
-
- IF ItemCnt% < MenuLen% THEN
- MenuLen% = ItemCnt%
- MenuRows% = ItemCnt%
- BoxParams%(CurrentBox%,3) = ItemCnt% + 2 ' set this so that only the area
- END IF ' with menu items on it scrolls
-
- IF DisplayMode% = 2 THEN ' put the letters in place for
- FOR x% = 1 TO MenuLen% ' the menu
- CALL PrtBox(x%,1,CHR$(64+x%,32),HighAttr%)
- NEXT x%
- BoxParms%(CurrentBox%,2) = MenuCol% + 1
- BoxParms%(CurrentBox%,4) = MenuCol% - 1 ' change this so letters don't
- MenuCol% = MenuCol% + 2 ' scroll with box
- MenuCols% = MenuCols% - 2
- END IF
-
- TagList$ = TagList$ + STRING$(ItemCnt%,"0")
- TagList$ = LEFT$(TagList$,ItemCnt%)
-
- ItemPtr% = 1 'Array member currently pointed to
- curntpos% = 1 'Position in the on-screen menu
- TheCnt% = ItemsTagged%
- TopItem% = 1
- BottomItem% = MenuLen%
-
- GOSUB FillTagMenu
- MenuTimer! = -1
- ProcTimer! = -1
- IF MenuTimeOut% > 0 THEN MenuTimer! = TIMER + MenuTimeOut%
- IF ProcTimeOut% > 0 THEN ProcTimer! = TIMER + ProcTimeOut%
- Terminated% = %False
- WHILE NOT Terminated%
-
- ' Highlight the current item
- CALL QATTR((MenuRow%+curntPos%-1), MenuCol%,1, MenuCols%, HighAttr%)
-
- ' Get a keypress from the user, and do other stuff while we are waiting
- WHILE NOT INSTAT
- IF (MenuTimer! > 0) AND (TIMER > MenuTimer!) THEN
- TagList$ = STRING$(ItemCnt%,"0")
- EXIT SUB
- END IF
-
- IF (ProcTimer! > 0) AND (TIMER > ProcTimer!) THEN
- CALL DWORD ProcAddr
- ProcTimer! = TIMER + ProcTimeOut%
- END IF
- WEND
-
- a$ = INKEY$ ' get the key, then
- IF LEN(a$) = 1 THEN ' assign the ascii value to
- ans% = ASC(UCASE$(a$)) ' our response.
- ELSE ' for two byte keys, response is
- ans% = 255 + ASC(RIGHT$(a$,1)) ' 255 + the ascii value of
- END IF ' the second byte
-
- IF MenuTimeOut% > 0 THEN MenuTimer! = TIMER + MenuTimeOut%
- IF ProcTimeOut% > 0 THEN ProcTimer! = TIMER + ProcTimeOut%
-
- IF JustOne% THEN ' When choosing just one item, we
- IF ans% = %Space THEN ans% = 0 ' ignore space, plus, minus
- IF ans% = %InsKey THEN ans% = 0 ' ctrl+ and ctrl-
- IF ans% = %DelKey THEN ans% = 0
- IF ans% = %CtrlIns THEN ans% = 0
- IF ans% = %CtrlDel THEN ans% = 0
- END IF
- IF Ans% = 0 THEN ITERATE
-
- 'We've got a key press, so Un-highlight the current item
- CALL QATTR((MenuRow%+curntPos%-1), MenuCol%,1, MenuCols%, MenuAttr%)
- IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
-
- ' Now process the keystroke.
-
- IF ans% = %Enter THEN ' we're done, get out
- Terminated% = %True
- IF JustOne% THEN
- MID$(TagList$,ItemPtr%,1) = "1"
- ELSE
- ItemsTagged% = TALLY(TagList$,"1")
- IF ItemsTagged% = 0 THEN MID$(TagList$,ItemPtr%,1) = "1"
- END IF
- ELSEIF ans% = %Esc THEN ' We're abandoning.
- TagList$ = STRING$(ItemCnt%,"0")
- Terminated% = %True
- ELSEIF (ans% = %DelKey) OR _ ' del or minus untags
- (ans% = ASC("-")) THEN
- MID$(TagList$,ItemPtr%,1) = "0"
- CALL PrtBox(curntpos%,1," ",-1)
- IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
- (curntpos% < MenuLen%) THEN
- INCR curntpos%, 1
- INCR ItemPtr%, 1
- END IF
- ELSEIF (ans% = %InsKey) OR _ ' insert or Plus tags
- (ans% = ASC("+")) THEN
- MID$(TagList$,ItemPtr%,1) = "1"
- CALL PrtBox(curntpos%,1,"",HighAttr%)
- IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
- (curntpos% < MenuLen%) THEN
- INCR curntpos%, 1
- INCR ItemPtr%, 1
- END IF
- ELSEIF ans% = %Space THEN ' Space is a toggle
- a$ = MID$(TagList$,ItemPtr%,1)
- IF a$ = "0" THEN
- MID$(TagList$,ItemPtr%,1) = "1"
- CALL PrtBox(curntpos%,1,"",HighAttr%)
- ELSE
- MID$(TagList$,ItemPtr%,1) = "0"
- CALL PrtBox(curntpos%,1," ",MenuAttr%)
- END IF
- IF (ItemPtr% < ItemCnt%) AND _ ' and go to next item
- (curntpos% < MenuLen%) THEN
- INCR curntpos%, 1
- INCR ItemPtr%, 1
- END IF
- ELSEIF ans% = %PgUp THEN ' page up
- IF TopItem% > 1 Then
- TopItem% = TopItem% - MenuLen%
- IF TopItem% < 1 THEN TopItem% = 1
- BottomItem% = TopItem% + MenuLen%
- ItemPtr% = TopItem%
- curntpos% = 1
- GOSUB FillTagMenu
- END IF
- ELSEIF ans% = %PgDn THEN ' page down
- IF BottomItem% < ItemCnt% Then
- BottomItem% = BottomItem% + MenuLen% + 1
- IF BottomItem% > ItemCnt% THEN BottomItem% = ItemCnt% + 1
- TopItem% = BottomItem% - MenuLen%
- ItemPtr% = TopItem%
- curntpos% = 1
- GOSUB FillTagMenu
- END IF
- ELSEIF ans% = %UpArrow THEN ' go up one item
- IF curntpos% > 1 THEN ' not at top, so it's easy
- DECR curntpos%, 1
- DECR ItemPtr%, 1
- ELSEIF ItemPtr% > 1 THEN 'if we aren't at the first item
- CALL ScrollBox(0,1) ' scroll the box down
- DECR ItemPtr%,1 ' and adjust the pointers
- DECR TopItem%,1 ' the line will get redisplayed
- DECR BottomItem%,1 ' at the top of the loop
- IF DisplayMode% = 0 THEN ' center the item
- CALL PrtBox(curntpos%,0,MenuList$(ItemPtr%),-1)
- ELSE ' left justify
- CALL PrtBox(curntpos%,2,MenuList$(ItemPtr%),-1)
- END IF
- IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
- END IF
- ELSEIF ans% = %DownArrow THEN ' go down an item
- IF curntpos% < MenuLen% THEN ' not at bottom, so it's easy
- INCR curntpos%, 1
- INCR ItemPtr%, 1
- ELSEIF ItemPtr% < ItemCnt% THEN 'if this isn't the last item
- CALL ScrollBox(1,1) ' Scroll the box up, and adjust
- INCR ItemPtr%,1 ' the pointers. The line will
- INCR TopItem%,1 ' redisplay at the top of the
- INCR BottomItem%,1 ' keyin loop
- IF DisplayMode% = 0 THEN ' center the item
- CALL PrtBox(curntpos%,0,MenuList$(ItemPtr%),-1)
- ELSE ' left justify
- CALL PrtBox(curntpos%,2,MenuList$(ItemPtr%),-1)
- END IF
- IF MID$(TagList$,ItemPtr%,1) = "1" THEN CALL PrtBox(curntpos%,1,"",HighAttr%)
- END IF
- ELSEIF ans% = %HomeKey THEN ' go to top of item list
- ItemPtr% = 1
- curntpos% = 1
- TopItem% = 1
- BottomItem% = TopItem% + MenuLen%
- GOSUB FillTagMenu
- ELSEIF ans% = %EndKey THEN ' go to bottom of item list
- ItemPtr% = ItemCnt%
- curntpos% = MenuLen%
- BottomItem% = ItemCnt%
- TopItem% = BottomItem% - MenuLen%
- GOSUB FillTagMenu
- ELSEIF ans% = %CtrlDel THEN ' Untag everything
- TagList$ = STRING$(ItemCnt%,"0")
- GOSUB FillTagMenu
- ELSEIF ans% = %CtrlIns THEN ' tag everything
- TagList$ = STRING$(ItemCnt%,"1")
- GOSUB FillTagMenu
- ELSE
- IF (ans% > 64) AND (ans% < 91) THEN
- a% = TopItem% + (ans% - 65)
- MID$(TagList$,a%,1) = "1"
- IF JustOne% THEN Terminated% = %True
- curntpos% = a%
- END IF
- END IF
-
- WEND
- BoxParms%(CurrentBox%,2) = OldMenuCol%
- BoxParms%(CurrentBox%,3) = OldMenuRows%
- BoxParms%(CurrentBox%,4) = OldMenuCols%
-
- EXIT SUB 'Good bye!
-
-
- FillTagMenu:
- '╒═════════════════════════════════════════════════════════════════════════╕
- '│This sub fills the empty box with menu items, based on the current value │
- '│of ItemPtr% and MenuLen% │
- '╘═════════════════════════════════════════════════════════════════════════╛
- IF TopItem% < 1 THEN TopItem% = 1
- BottomItem% = TopItem% + MenuLen% - 1
- IF BottomItem% > ItemCnt% THEN BottomItem% = ItemCnt%
-
- CALL ClearBox(-1,-1)
- FOR ThisItem% = TopItem% to BottomItem%
- x% = ThisItem% - TopItem% + 1
- IF DisplayMode% = 0 THEN ' center the item
- CALL PrtBox(x%,0,MenuList$(ThisItem%),-1)
- ELSE ' left justify
- CALL PrtBox(x%,2,MenuList$(ThisItem%),-1)
- END IF
- IF MID$(TagList$,ThisItem%,1) = "1" THEN CALL PrtBox(x%,1,"",HighAttr%)
- NEXT ThisItem%
-
- RETURN
-
- END SUB