home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / TE2SC121.ZIP / UserMenu.Scr < prev    next >
Text File  |  1992-07-21  |  16KB  |  508 lines

  1. ;; -------------------------------------------------------------------------
  2. ;;
  3. ;; UserMenu.Scr -- Copyright (c) 1992, Oberon Software, Mankato Mn
  4. ;;                 Author: Brady Flowers, 07/09/92
  5. ;;
  6. ;; Usage:  This script allows the creation of a popup menu with up to
  7. ;;         ten items.  The user may use the up and down arrows and ENTER
  8. ;;         key to select items or may press the letter or number corresponding
  9. ;;         to the first character of an item (these must be unique for this
  10. ;;         to work as expected).  If the user presses ESCape the menu is
  11. ;;         aborted.
  12. ;;
  13. ;;         The calling script must define at least a subset of this file's
  14. ;;         global variables identically to the way they are defined herein.
  15. ;;         These variables are used for input and output parameters.
  16. ;;
  17. ;;         The following variables should be set on entry:
  18. ;;              usrmnuItems  -- total number of menu items (1 .. 10)
  19. ;;              usrmnuSelect -- initially selected item (1 .. usrmnuItems)
  20. ;;                              if this is invalid, 1 is assumed
  21. ;;              usrmnuTop    -- top row of menu dialog
  22. ;;              usrmnuLeft   -- left column of menu dialog
  23. ;;                              note: dialog dimensions are calculated
  24. ;;                              automatically
  25. ;;              usrmnuAttr   -- 'normal' color attribute (defaults to
  26. ;;                              the standard TE/2 dialog normal attribute if
  27. ;;                              not specified
  28. ;;              usrmnuHiAttr -- 'selected' color attribute (defaults to
  29. ;;                              the standard TE/2 dialog highligh attribute if
  30. ;;                              not specified
  31. ;;              usrmnuTitle  -- title string for the menu -- automatically
  32. ;;                              centered on the top row of the menu dialog
  33. ;;              usrmnuItem1 thru
  34. ;;              usrmnuItem10 -- fill in as many of these as you specified
  35. ;;                              in usrmnuItems, extra ones are ignored
  36. ;;                              the first character of each item should
  37. ;;                              be unique if you want mnemonic matching to
  38. ;;                              work well.
  39. ;;
  40. ;;         The return code of this script is in usrmnuSelect.  If the
  41. ;;         user made a selection, the value of usrmnuSelect on exit will
  42. ;;         be the item selected.  If the user pressed ESCape to exit the
  43. ;;         menu, the value will be zero.
  44. ;;
  45. ;;
  46. ;;  Example:
  47. ;;
  48. ;;    ;; MenuTest.scr
  49. ;;    global integer usrmnuItems  = 4
  50. ;;    global integer usrmnuSelect = 1
  51. ;;    global string  usrmnuTitle  = "Please Select One"
  52. ;;    global string  usrmnuItem1  = "Apples           "
  53. ;;    global string  usrmnuItem2  = "Bananas          "
  54. ;;    global string  usrmnuItem3  = "Coconuts         "
  55. ;;    global string  usrmnuItem4  = "Dates            "
  56. ;;    global integer usrmnuTop    = 10
  57. ;;    global integer usrmnuLeft   = 20
  58. ;;    global integer usrmnuAttr   = 0x1f
  59. ;;    global integer usrmnuHiAttr = 0x71
  60. ;;
  61. ;;    program
  62. ;;      run("UserMenu")
  63. ;;      if usrmnuSelect == 0
  64. ;;        message("^M^JMenu choice aborted^M^J")
  65. ;;      else
  66. ;;        message("^M^JYou selected item %d^M^J", usrmnuSelect)
  67. ;;      endif
  68. ;;      end
  69. ;;
  70. ;;
  71. ;; -------------------------------------------------------------------------
  72.  
  73. ;; -------------------------------------------------------------------------
  74. ;; GLOBAL variable
  75. global integer usrmnuSelect
  76. global integer usrmnuTop
  77. global integer usrmnuLeft
  78. global integer usrmnuAttr
  79. global integer usrmnuHiAttr
  80. global integer usrmnuItems
  81. global string  usrmnuTitle
  82. global string  usrmnuItem1
  83. global string  usrmnuItem2
  84. global string  usrmnuItem3
  85. global string  usrmnuItem4
  86. global string  usrmnuItem5
  87. global string  usrmnuItem6
  88. global string  usrmnuItem7
  89. global string  usrmnuItem8
  90. global string  usrmnuItem9
  91. global string  usrmnuItem10
  92.  
  93. ;; -------------------------------------------------------------------------
  94. ;; LOCAL Variables
  95. integer usrmnuBottom        ;; Computed from usrmnuTop + usrmnuItems
  96. integer usrmnuRight         ;; Computed from usrmnuLeft + string lengths
  97. integer usrmnuDLog          ;; Dialog handle for menu box
  98. integer maxwid              ;; Will be set to length of the longest string
  99. integer keyin               ;; User keystroke for NavigateMenu
  100. integer fMatchedMnemonic    ;; Return code from MatchMnemonic
  101. integer mattr               ;; Temporary color attribute holder
  102. integer i                   ;; Temporary utility variable
  103.  
  104. ;; -------------------------------------------------------------------------
  105.  
  106.     ;; -----------------------------------------------------------------
  107.     ;; Using the defined Top and Left co-ordinates, the number of menu
  108.     ;; items, and the length of the logest item (or title), this routine
  109.     ;; computes usrmnuBottom and usrmnuRight for use by other routines
  110.     ;; -----------------------------------------------------------------
  111.  
  112. subroutine ComputeBottomRight
  113.  
  114.     maxwid = strlen(usrmnuTitle)
  115.     if usrmnuItems > 0
  116.         i = strlen(usrmnuItem1)
  117.         if i > maxWid
  118.             maxwid = i;
  119.         endif
  120.     endif
  121.     if usrmnuItems > 1
  122.         i = strlen(usrmnuItem2)
  123.         if i > maxWid
  124.             maxwid = i;
  125.         endif
  126.     endif
  127.     if usrmnuItems > 2
  128.         i = strlen(usrmnuItem3)
  129.         if i > maxWid
  130.             maxwid = i;
  131.         endif
  132.     endif
  133.     if usrmnuItems > 3
  134.         i = strlen(usrmnuItem4)
  135.         if i > maxWid
  136.             maxwid = i;
  137.         endif
  138.     endif
  139.     if usrmnuItems > 4
  140.         i = strlen(usrmnuItem5)
  141.         if i > maxWid
  142.             maxwid = i;
  143.         endif
  144.     endif
  145.     if usrmnuItems > 5
  146.         i = strlen(usrmnuItem6)
  147.         if i > maxWid
  148.             maxwid = i;
  149.         endif
  150.     endif
  151.     if usrmnuItems > 6
  152.         i = strlen(usrmnuItem7)
  153.         if i > maxWid
  154.             maxwid = i;
  155.         endif
  156.     endif
  157.     if usrmnuItems > 7
  158.         i = strlen(usrmnuItem8)
  159.         if i > maxWid
  160.             maxwid = i;
  161.         endif
  162.     endif
  163.     if usrmnuItems > 8
  164.         i = strlen(usrmnuItem9)
  165.         if i > maxWid
  166.             maxwid = i;
  167.         endif
  168.     endif
  169.     if usrmnuItems > 9
  170.         i = strlen(usrmnuItem10)
  171.         if i > maxWid
  172.             maxwid = i;
  173.         endif
  174.     endif
  175.  
  176.     usrmnuBottom = usrmnuTop + usrmnuItems + 4
  177.     usrmnuRight  = usrmnuLeft + maxwid + 4
  178.  
  179. endsub
  180.  
  181.  
  182.     ;; -----------------------------------------------------------------
  183.     ;; Display or redisplay the menu.  This routine displays the menu
  184.     ;; items only (highlighting the appropriate one).  It is called
  185.     ;; at the beginning and after each keystroke that changes the menu
  186.     ;; highlighted item.  The menu dialog box and title are already
  187.     ;; in place before the first call to this routine.
  188.     ;; -----------------------------------------------------------------
  189.  
  190. subroutine DisplayMenu
  191.  
  192.     if usrmnuItems > 0
  193.         if usrmnuSelect == 0
  194.             mattr = usrmnuHiAttr
  195.         else
  196.             mattr = usrmnuAttr
  197.         endif
  198.         strput(usrmnuTop+3, usrmnuLeft+2, mattr, "%s", usrmnuItem1)
  199.     endif
  200.     if usrmnuItems > 1
  201.         if usrmnuSelect == 1
  202.             mattr = usrmnuHiAttr
  203.         else
  204.             mattr = usrmnuAttr
  205.         endif
  206.         strput(usrmnuTop+4, usrmnuLeft+2, mattr, "%s", usrmnuItem2)
  207.     endif
  208.     if usrmnuItems > 2
  209.         if usrmnuSelect == 2
  210.             mattr = usrmnuHiAttr
  211.         else
  212.             mattr = usrmnuAttr
  213.         endif
  214.         strput(usrmnuTop+5, usrmnuLeft+2, mattr, "%s", usrmnuItem3)
  215.     endif
  216.     if usrmnuItems > 3
  217.         if usrmnuSelect == 3
  218.             mattr = usrmnuHiAttr
  219.         else
  220.             mattr = usrmnuAttr
  221.         endif
  222.         strput(usrmnuTop+6, usrmnuLeft+2, mattr, "%s", usrmnuItem4)
  223.     endif
  224.     if usrmnuItems > 4
  225.         if usrmnuSelect == 4
  226.             mattr = usrmnuHiAttr
  227.         else
  228.             mattr = usrmnuAttr
  229.         endif
  230.         strput(usrmnuTop+7, usrmnuLeft+2, mattr, "%s", usrmnuItem5)
  231.     endif
  232.     if usrmnuItems > 5
  233.         if usrmnuSelect == 5
  234.             mattr = usrmnuHiAttr
  235.         else
  236.             mattr = usrmnuAttr
  237.         endif
  238.         strput(usrmnuTop+8, usrmnuLeft+2, mattr, "%s", usrmnuItem6)
  239.     endif
  240.     if usrmnuItems > 6
  241.         if usrmnuSelect == 6
  242.             mattr = usrmnuHiAttr
  243.         else
  244.             mattr = usrmnuAttr
  245.         endif
  246.         strput(usrmnuTop+9, usrmnuLeft+2, mattr, "%s", usrmnuItem7)
  247.     endif
  248.     if usrmnuItems > 7
  249.         if usrmnuSelect == 7
  250.             mattr = usrmnuHiAttr
  251.         else
  252.             mattr = usrmnuAttr
  253.         endif
  254.         strput(usrmnuTop+10, usrmnuLeft+2, mattr, "%s", usrmnuItem8)
  255.     endif
  256.     if usrmnuItems > 8
  257.         if usrmnuSelect == 8
  258.             mattr = usrmnuHiAttr
  259.         else
  260.             mattr = usrmnuAttr
  261.         endif
  262.         strput(usrmnuTop+11, usrmnuLeft+2, mattr, "%s", usrmnuItem9)
  263.     endif
  264.     if usrmnuItems > 9
  265.         if usrmnuSelect == 9
  266.             mattr = usrmnuHiAttr
  267.         else
  268.             mattr = usrmnuAttr
  269.         endif
  270.         strput(usrmnuTop+12, usrmnuLeft+2, mattr, "%s", usrmnuItem10)
  271.     endif
  272.  
  273. endsub
  274.  
  275.  
  276.     ;; -----------------------------------------------------------------
  277.     ;; This routine scans the menu items for the first item who's first
  278.     ;; character matches the current value of 'keyin'.  Upper/lower case
  279.     ;; conversion is handled.  'fMatchMnemonic' is set to 1 if a match
  280.     ;; is found and usrmnuSelect is adjusted to the found item.
  281.     ;;
  282.     ;; Notice the method used for uppercase conversion.  An alternative
  283.     ;; would be to use:
  284.     ;;      i = asciival(toupper(usrmnuItemX))
  285.     ;; or even:
  286.     ;;      i = asciival(toupper(strleft(usrmnuItemX, 1)))
  287.     ;; but, in this specialized case, doing it in-line "by hand" is
  288.     ;; probably quicker than re-entering the parser that many times.
  289.     ;; -----------------------------------------------------------------
  290.  
  291. subroutine MatchMnemonic
  292.  
  293.     fMatchedMnemonic = 0
  294.     if (keyin >= 'a') AND (keyin <= 'z')
  295.         keyin = keyin - 32
  296.     endif
  297.     if usrmnuItems > 0
  298.         i = asciival(usrmnuItem1)
  299.         if (i >= 'a') AND (i <= 'z')
  300.             i = i - 32
  301.         endif
  302.         if i == keyin
  303.             fMatchedMnemonic = 1
  304.             usrmnuSelect = 0
  305.             return
  306.         endif
  307.     endif
  308.     if usrmnuItems > 1
  309.         i = asciival(usrmnuItem2)
  310.         if (i >= 'a') AND (i <= 'z')
  311.             i = i - 32
  312.         endif
  313.         if i == keyin
  314.             fMatchedMnemonic = 1
  315.             usrmnuSelect = 1
  316.             return
  317.         endif
  318.     endif
  319.     if usrmnuItems > 2
  320.         i = asciival(usrmnuItem3)
  321.         if (i >= 'a') AND (i <= 'z')
  322.             i = i - 32
  323.         endif
  324.         if i == keyin
  325.             fMatchedMnemonic = 1
  326.             usrmnuSelect = 2
  327.             return
  328.         endif
  329.     endif
  330.     if usrmnuItems > 3
  331.         i = asciival(usrmnuItem4)
  332.         if (i >= 'a') AND (i <= 'z')
  333.             i = i - 32
  334.         endif
  335.         if i == keyin
  336.             fMatchedMnemonic = 1
  337.             usrmnuSelect = 3
  338.             return
  339.         endif
  340.     endif
  341.     if usrmnuItems > 4
  342.         i = asciival(usrmnuItem5)
  343.         if (i >= 'a') AND (i <= 'z')
  344.             i = i - 32
  345.         endif
  346.         if i == keyin
  347.             fMatchedMnemonic = 1
  348.             usrmnuSelect = 4
  349.             return
  350.         endif
  351.     endif
  352.     if usrmnuItems > 5
  353.         i = asciival(usrmnuItem6)
  354.         if (i >= 'a') AND (i <= 'z')
  355.             i = i - 32
  356.         endif
  357.         if i == keyin
  358.             fMatchedMnemonic = 1
  359.             usrmnuSelect = 5
  360.             return
  361.         endif
  362.     endif
  363.     if usrmnuItems > 6
  364.         i = asciival(usrmnuItem7)
  365.         if (i >= 'a') AND (i <= 'z')
  366.             i = i - 32
  367.         endif
  368.         if i == keyin
  369.             fMatchedMnemonic = 1
  370.             usrmnuSelect = 6
  371.             return
  372.         endif
  373.     endif
  374.     if usrmnuItems > 7
  375.         i = asciival(usrmnuItem8)
  376.         if (i >= 'a') AND (i <= 'z')
  377.             i = i - 32
  378.         endif
  379.         if i == keyin
  380.             fMatchedMnemonic = 1
  381.             usrmnuSelect = 7
  382.             return
  383.         endif
  384.     endif
  385.     if usrmnuItems > 8
  386.         i = asciival(usrmnuItem9)
  387.         if (i >= 'a') AND (i <= 'z')
  388.             i = i - 32
  389.         endif
  390.         if i == keyin
  391.             fMatchedMnemonic = 1
  392.             usrmnuSelect = 8
  393.             return
  394.         endif
  395.     endif
  396.     if usrmnuItems > 9
  397.         i = asciival(usrmnuItem10)
  398.         if (i >= 'a') AND (i <= 'z')
  399.             i = i - 32
  400.         endif
  401.         if i == keyin
  402.             fMatchedMnemonic = 1
  403.             usrmnuSelect = 9
  404.             return
  405.         endif
  406.     endif
  407.  
  408. endsub
  409.  
  410.  
  411.     ;; -----------------------------------------------------------------
  412.     ;; Collects keystrokes and maintains the menu.
  413.     ;; -----------------------------------------------------------------
  414.  
  415. subroutine NavigateMenu
  416.  
  417.     do
  418.         keyin = getc()
  419.         if (keyin == '^M') OR (keyin == '^[')
  420.             break
  421.         elseif (keyin & 0x000000ff)
  422.             gosub MatchMnemonic
  423.             if fMatchedMnemonic
  424.                 gosub DisplayMenu
  425.                 keyin = '^M'
  426.                 break
  427.             else
  428.                 beep(1760, 50)
  429.             endif
  430.         else
  431.             keyin = (keyin >> 8) & 0x000000ff
  432.             if keyin == 72     ; UP
  433.                 usrmnuSelect = usrmnuSelect - 1
  434.                 if usrmnuSelect < 0
  435.                     usrmnuSelect = usrmnuItems - 1
  436.                 endif
  437.                 gosub DisplayMenu
  438.             elseif keyin == 80 ; DOWN
  439.                 usrmnuSelect = usrmnuSelect + 1
  440.                 if usrmnuSelect >= usrmnuItems
  441.                     usrmnuSelect = 0
  442.                 endif
  443.                 gosub DisplayMenu
  444.             else
  445.                 beep(1760, 50)
  446.             endif
  447.         endif
  448.  
  449.     loop
  450.  
  451.     if keyin == '^M'
  452.         ;; user selected an item, adjust 'usrmnuSelect' back up to be 1-based
  453.         usrmnuSelect = usrmnuSelect + 1
  454.     else
  455.         ;; user pressed ESCape, set 'usrmnuSelect' to 0
  456.         usrmnuSelect = 0
  457.     endif
  458.  
  459. endsub
  460.  
  461.  
  462.     ;; -----------------------------------------------------------------
  463.     ;; Main driver for the menu
  464.     ;; -----------------------------------------------------------------
  465.  
  466. subroutine UserMenu
  467.  
  468.     ;; Make sure defaults are set if they are needed
  469.     if usrmnuAttr == 0
  470.         usrmnuAttr   = DLogNormAttr
  471.     endif
  472.     if usrmnuHiAttr == 0
  473.         usrmnuHiAttr = DLogHiAttr
  474.     endif
  475.  
  476.     ;; Note that usrmnuSelect is maintained internally as zero-based and
  477.     ;; will be changed back to one-based upon successful exit
  478.     usrmnuSelect = usrmnuSelect - 1
  479.     if (usrmnuSelect < 0) OR (usrmnuSelect >= usrmnuItems)
  480.         usrmnuSelect = 0
  481.     endif
  482.  
  483.     gosub ComputeBottomRight
  484.     usrmnuDLog = opendialog(usrmnuTop, usrmnuLeft, usrmnuBottom, usrmnuRight, usrmnuAttr)
  485.  
  486.     ;; Place the title on the dialog
  487.     i = usrmnuLeft + ((usrmnuRight - usrmnuLeft + 1 - strlen(usrmnuTitle)) / 2)
  488.     strput(usrmnuTop+1, i, usrmnuAttr, "%s", usrmnuTitle)
  489.  
  490.     ;; Show it and run it
  491.     gosub DisplayMenu
  492.     gosub Navigatemenu
  493.     closedialog(usrmnuDLog)
  494.  
  495. endsub
  496.  
  497.  
  498. program
  499.  
  500.     if (usrmnuItems < 1) OR (usrmnuItems > 10)
  501.         errormsg("Invalid number of Menu Items for UserMenu", "Must be from 1 to 10 items")
  502.         usrmnuSelect = 0
  503.     else
  504.         gosub UserMenu
  505.     endif
  506.     end
  507.  
  508.