home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
TE2SC121.ZIP
/
UserMenu.Scr
< prev
next >
Wrap
Text File
|
1992-07-21
|
16KB
|
508 lines
;; -------------------------------------------------------------------------
;;
;; UserMenu.Scr -- Copyright (c) 1992, Oberon Software, Mankato Mn
;; Author: Brady Flowers, 07/09/92
;;
;; Usage: This script allows the creation of a popup menu with up to
;; ten items. The user may use the up and down arrows and ENTER
;; key to select items or may press the letter or number corresponding
;; to the first character of an item (these must be unique for this
;; to work as expected). If the user presses ESCape the menu is
;; aborted.
;;
;; The calling script must define at least a subset of this file's
;; global variables identically to the way they are defined herein.
;; These variables are used for input and output parameters.
;;
;; The following variables should be set on entry:
;; usrmnuItems -- total number of menu items (1 .. 10)
;; usrmnuSelect -- initially selected item (1 .. usrmnuItems)
;; if this is invalid, 1 is assumed
;; usrmnuTop -- top row of menu dialog
;; usrmnuLeft -- left column of menu dialog
;; note: dialog dimensions are calculated
;; automatically
;; usrmnuAttr -- 'normal' color attribute (defaults to
;; the standard TE/2 dialog normal attribute if
;; not specified
;; usrmnuHiAttr -- 'selected' color attribute (defaults to
;; the standard TE/2 dialog highligh attribute if
;; not specified
;; usrmnuTitle -- title string for the menu -- automatically
;; centered on the top row of the menu dialog
;; usrmnuItem1 thru
;; usrmnuItem10 -- fill in as many of these as you specified
;; in usrmnuItems, extra ones are ignored
;; the first character of each item should
;; be unique if you want mnemonic matching to
;; work well.
;;
;; The return code of this script is in usrmnuSelect. If the
;; user made a selection, the value of usrmnuSelect on exit will
;; be the item selected. If the user pressed ESCape to exit the
;; menu, the value will be zero.
;;
;;
;; Example:
;;
;; ;; MenuTest.scr
;; global integer usrmnuItems = 4
;; global integer usrmnuSelect = 1
;; global string usrmnuTitle = "Please Select One"
;; global string usrmnuItem1 = "Apples "
;; global string usrmnuItem2 = "Bananas "
;; global string usrmnuItem3 = "Coconuts "
;; global string usrmnuItem4 = "Dates "
;; global integer usrmnuTop = 10
;; global integer usrmnuLeft = 20
;; global integer usrmnuAttr = 0x1f
;; global integer usrmnuHiAttr = 0x71
;;
;; program
;; run("UserMenu")
;; if usrmnuSelect == 0
;; message("^M^JMenu choice aborted^M^J")
;; else
;; message("^M^JYou selected item %d^M^J", usrmnuSelect)
;; endif
;; end
;;
;;
;; -------------------------------------------------------------------------
;; -------------------------------------------------------------------------
;; GLOBAL variable
global integer usrmnuSelect
global integer usrmnuTop
global integer usrmnuLeft
global integer usrmnuAttr
global integer usrmnuHiAttr
global integer usrmnuItems
global string usrmnuTitle
global string usrmnuItem1
global string usrmnuItem2
global string usrmnuItem3
global string usrmnuItem4
global string usrmnuItem5
global string usrmnuItem6
global string usrmnuItem7
global string usrmnuItem8
global string usrmnuItem9
global string usrmnuItem10
;; -------------------------------------------------------------------------
;; LOCAL Variables
integer usrmnuBottom ;; Computed from usrmnuTop + usrmnuItems
integer usrmnuRight ;; Computed from usrmnuLeft + string lengths
integer usrmnuDLog ;; Dialog handle for menu box
integer maxwid ;; Will be set to length of the longest string
integer keyin ;; User keystroke for NavigateMenu
integer fMatchedMnemonic ;; Return code from MatchMnemonic
integer mattr ;; Temporary color attribute holder
integer i ;; Temporary utility variable
;; -------------------------------------------------------------------------
;; -----------------------------------------------------------------
;; Using the defined Top and Left co-ordinates, the number of menu
;; items, and the length of the logest item (or title), this routine
;; computes usrmnuBottom and usrmnuRight for use by other routines
;; -----------------------------------------------------------------
subroutine ComputeBottomRight
maxwid = strlen(usrmnuTitle)
if usrmnuItems > 0
i = strlen(usrmnuItem1)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 1
i = strlen(usrmnuItem2)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 2
i = strlen(usrmnuItem3)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 3
i = strlen(usrmnuItem4)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 4
i = strlen(usrmnuItem5)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 5
i = strlen(usrmnuItem6)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 6
i = strlen(usrmnuItem7)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 7
i = strlen(usrmnuItem8)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 8
i = strlen(usrmnuItem9)
if i > maxWid
maxwid = i;
endif
endif
if usrmnuItems > 9
i = strlen(usrmnuItem10)
if i > maxWid
maxwid = i;
endif
endif
usrmnuBottom = usrmnuTop + usrmnuItems + 4
usrmnuRight = usrmnuLeft + maxwid + 4
endsub
;; -----------------------------------------------------------------
;; Display or redisplay the menu. This routine displays the menu
;; items only (highlighting the appropriate one). It is called
;; at the beginning and after each keystroke that changes the menu
;; highlighted item. The menu dialog box and title are already
;; in place before the first call to this routine.
;; -----------------------------------------------------------------
subroutine DisplayMenu
if usrmnuItems > 0
if usrmnuSelect == 0
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+3, usrmnuLeft+2, mattr, "%s", usrmnuItem1)
endif
if usrmnuItems > 1
if usrmnuSelect == 1
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+4, usrmnuLeft+2, mattr, "%s", usrmnuItem2)
endif
if usrmnuItems > 2
if usrmnuSelect == 2
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+5, usrmnuLeft+2, mattr, "%s", usrmnuItem3)
endif
if usrmnuItems > 3
if usrmnuSelect == 3
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+6, usrmnuLeft+2, mattr, "%s", usrmnuItem4)
endif
if usrmnuItems > 4
if usrmnuSelect == 4
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+7, usrmnuLeft+2, mattr, "%s", usrmnuItem5)
endif
if usrmnuItems > 5
if usrmnuSelect == 5
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+8, usrmnuLeft+2, mattr, "%s", usrmnuItem6)
endif
if usrmnuItems > 6
if usrmnuSelect == 6
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+9, usrmnuLeft+2, mattr, "%s", usrmnuItem7)
endif
if usrmnuItems > 7
if usrmnuSelect == 7
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+10, usrmnuLeft+2, mattr, "%s", usrmnuItem8)
endif
if usrmnuItems > 8
if usrmnuSelect == 8
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+11, usrmnuLeft+2, mattr, "%s", usrmnuItem9)
endif
if usrmnuItems > 9
if usrmnuSelect == 9
mattr = usrmnuHiAttr
else
mattr = usrmnuAttr
endif
strput(usrmnuTop+12, usrmnuLeft+2, mattr, "%s", usrmnuItem10)
endif
endsub
;; -----------------------------------------------------------------
;; This routine scans the menu items for the first item who's first
;; character matches the current value of 'keyin'. Upper/lower case
;; conversion is handled. 'fMatchMnemonic' is set to 1 if a match
;; is found and usrmnuSelect is adjusted to the found item.
;;
;; Notice the method used for uppercase conversion. An alternative
;; would be to use:
;; i = asciival(toupper(usrmnuItemX))
;; or even:
;; i = asciival(toupper(strleft(usrmnuItemX, 1)))
;; but, in this specialized case, doing it in-line "by hand" is
;; probably quicker than re-entering the parser that many times.
;; -----------------------------------------------------------------
subroutine MatchMnemonic
fMatchedMnemonic = 0
if (keyin >= 'a') AND (keyin <= 'z')
keyin = keyin - 32
endif
if usrmnuItems > 0
i = asciival(usrmnuItem1)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 0
return
endif
endif
if usrmnuItems > 1
i = asciival(usrmnuItem2)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 1
return
endif
endif
if usrmnuItems > 2
i = asciival(usrmnuItem3)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 2
return
endif
endif
if usrmnuItems > 3
i = asciival(usrmnuItem4)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 3
return
endif
endif
if usrmnuItems > 4
i = asciival(usrmnuItem5)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 4
return
endif
endif
if usrmnuItems > 5
i = asciival(usrmnuItem6)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 5
return
endif
endif
if usrmnuItems > 6
i = asciival(usrmnuItem7)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 6
return
endif
endif
if usrmnuItems > 7
i = asciival(usrmnuItem8)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 7
return
endif
endif
if usrmnuItems > 8
i = asciival(usrmnuItem9)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 8
return
endif
endif
if usrmnuItems > 9
i = asciival(usrmnuItem10)
if (i >= 'a') AND (i <= 'z')
i = i - 32
endif
if i == keyin
fMatchedMnemonic = 1
usrmnuSelect = 9
return
endif
endif
endsub
;; -----------------------------------------------------------------
;; Collects keystrokes and maintains the menu.
;; -----------------------------------------------------------------
subroutine NavigateMenu
do
keyin = getc()
if (keyin == '^M') OR (keyin == '^[')
break
elseif (keyin & 0x000000ff)
gosub MatchMnemonic
if fMatchedMnemonic
gosub DisplayMenu
keyin = '^M'
break
else
beep(1760, 50)
endif
else
keyin = (keyin >> 8) & 0x000000ff
if keyin == 72 ; UP
usrmnuSelect = usrmnuSelect - 1
if usrmnuSelect < 0
usrmnuSelect = usrmnuItems - 1
endif
gosub DisplayMenu
elseif keyin == 80 ; DOWN
usrmnuSelect = usrmnuSelect + 1
if usrmnuSelect >= usrmnuItems
usrmnuSelect = 0
endif
gosub DisplayMenu
else
beep(1760, 50)
endif
endif
loop
if keyin == '^M'
;; user selected an item, adjust 'usrmnuSelect' back up to be 1-based
usrmnuSelect = usrmnuSelect + 1
else
;; user pressed ESCape, set 'usrmnuSelect' to 0
usrmnuSelect = 0
endif
endsub
;; -----------------------------------------------------------------
;; Main driver for the menu
;; -----------------------------------------------------------------
subroutine UserMenu
;; Make sure defaults are set if they are needed
if usrmnuAttr == 0
usrmnuAttr = DLogNormAttr
endif
if usrmnuHiAttr == 0
usrmnuHiAttr = DLogHiAttr
endif
;; Note that usrmnuSelect is maintained internally as zero-based and
;; will be changed back to one-based upon successful exit
usrmnuSelect = usrmnuSelect - 1
if (usrmnuSelect < 0) OR (usrmnuSelect >= usrmnuItems)
usrmnuSelect = 0
endif
gosub ComputeBottomRight
usrmnuDLog = opendialog(usrmnuTop, usrmnuLeft, usrmnuBottom, usrmnuRight, usrmnuAttr)
;; Place the title on the dialog
i = usrmnuLeft + ((usrmnuRight - usrmnuLeft + 1 - strlen(usrmnuTitle)) / 2)
strput(usrmnuTop+1, i, usrmnuAttr, "%s", usrmnuTitle)
;; Show it and run it
gosub DisplayMenu
gosub Navigatemenu
closedialog(usrmnuDLog)
endsub
program
if (usrmnuItems < 1) OR (usrmnuItems > 10)
errormsg("Invalid number of Menu Items for UserMenu", "Must be from 1 to 10 items")
usrmnuSelect = 0
else
gosub UserMenu
endif
end