home *** CD-ROM | disk | FTP | other *** search
/ Power CD-ROM!! 7 / POWERCD7.ISO / prgmming / clipper / gt_menu.prg < prev    next >
Text File  |  1993-10-14  |  7KB  |  288 lines

  1. /*
  2.     File......: GT_Menu.prg
  3.     Author....: Martin Bryant
  4.     BBS.......: The Dark Knight Returns
  5.     Net/Node..: 050/069
  6.     User Name.: Martin Bryant
  7.     Date......: 05/02/93
  8.     Revision..: 1.1
  9.  
  10.     This is an original work by Martin Bryant and is placed
  11.     in the public domain.
  12.  
  13.     Modification history:
  14.     ---------------------
  15.  
  16.     Rev 1.0 05/02/93
  17.     PD Revision.
  18.  
  19.     Rev 1.1 18/05/93
  20.     Fix Esc error.
  21. */
  22.  
  23. /*  $DOC$
  24.  *  $FUNCNAME$
  25.  *      GT_MENU()
  26.  *  $CATEGORY$
  27.  *      General
  28.  *  $ONELINER$
  29.  *      A general purpose menu function.
  30.  *  $SYNTAX$
  31.  *      GT_Menu(<aOptions>,[<aValids>],[<nTop>],[<nLeft>], ;
  32.  *              [<nStart>],[<cTitle>],[<cColour>],[<cBox>]) ;
  33.  *          -> nOption
  34.  *  $ARGUMENTS$
  35.  *      <aOptions> is an array of arrays. Each sub-array
  36.  *      contains the menu options to be displayed. Each sub
  37.  *      array is displayed alongside the previous.
  38.  *
  39.  *      <aValids> is a parrallel array of logical values
  40.  *      that specify the selectability of each option. This
  41.  *      will default to all options being selectable.
  42.  *
  43.  *      <nTop> and <nLeft> are the fixed top left corner
  44.  *      for the menu. If ommited the menu is centered on
  45.  *      the screen.
  46.  *
  47.  *      <nStart> is the option to start on.
  48.  *
  49.  *      <cTitle> is the title for the menu.
  50.  *
  51.  *      <cColour> is the colour settings to use. If
  52.  *      ommitted, the current colours are used.
  53.  *
  54.  *      <cBox> is a character string defining the box
  55.  *      characters to use. It should be eleven characters
  56.  *      long.
  57.  *  $RETURNS$
  58.  *      A numeric value equal to the option number selected.
  59.  *  $DESCRIPTION$
  60.  *      A general purpose menu function. Allows multiple
  61.  *      horizontal and verticle bars. The menu is
  62.  *      optionally boxed and titled.
  63.  *  $EXAMPLES$
  64.  *      // Simple menu with 3 options, all selectable
  65.  *      // positioned at 05, 10. The Highlite will start
  66.  *      // on position 2 and the title will be
  67.  *      // "Security Menu". The colours are specified as
  68.  *      // are the box lines.
  69.  *
  70.  *      nOption := GT_Menu( ;
  71.  *          {{  '1. Backup ', ;
  72.  *              '2. Restore', ;
  73.  *              'X.Exit    '}} ;
  74.  *          {{.T.,.T.,.T.}}, ;
  75.  *          05, ;
  76.  *          10, ;
  77.  *          2, ;
  78.  *          'Security Menu', ;
  79.  *          'R/W,N/R,W,W,N/W', ;
  80.  *          '╒═╕│╛═╘│ ╡╞')
  81.  *  $SEEALSO$
  82.  *      GT_CHOOSE()
  83.  *  $INCLUDE$
  84.  *
  85.  *  $END$
  86.  */
  87.  
  88. #include "GT_LIB.ch"
  89. #include "achoice.ch"
  90.  
  91. FUNCTION GT_Menu(aOptions,aValids,nTop,nLeft,nStart, ;
  92.     cTitle,cColour,cBox)
  93.  
  94. Local aColumns := {}
  95. Local cSaveColour := SETCOLOR()
  96. Local nBars := LEN(aOptions)
  97. Local nBottom  := 0
  98. Local nCount :=0
  99. Local nHeight :=0
  100. Local nKey :=0
  101. Local nOption := 0
  102. Local nRight := 0
  103. Local nWidth := 0
  104.  
  105. Default aOptions to {}
  106. Default aValids to AFILL(ARRAY(LEN(aOptions)),.T.)
  107. Default nTop to -1
  108. Default nLeft to -1
  109. Default nStart to 1
  110. Default cTitle to ''
  111. Default cColour to SETCOLOR()
  112. Default cBox to BOX_DS
  113.  
  114. //  Width and columns
  115. aColumns := ARRAY(nBars)
  116. FOR nCount := 1 TO nBars
  117.     aColumns[nCount] := nWidth
  118.     nWidth += LEN(aOptions[nCount][1])
  119. NEXT
  120.  
  121. //  Left ?
  122. IF nLeft < 0
  123.     nLeft := ROUND((MAXCOL() - nWidth) / 2,0)
  124. ENDIF
  125.  
  126. //  Adjust Columns
  127. FOR nCount := 1 TO nBars
  128.     aColumns[nCount] += nLeft
  129. NEXT
  130.  
  131. //  Height
  132. nHeight := LEN(aOptions[1])
  133.  
  134. //  Top ?
  135. IF nTop <  0
  136.     nTop := ROUND(((MAXROW() - nHeight) / 2) - 2,0) + 3
  137. ENDIF
  138.  
  139. //  nBottom
  140. nBottom := nTop + nHeight - 1
  141.  
  142. //  Right
  143. nRight := nLeft + nWidth - 01
  144.  
  145. //  Clear area
  146. SETCOLOR(cColour)
  147.  
  148. IF .NOT. EMPTY(cBox)
  149.  
  150.     GT_Window(nTop-3,nLeft-1,nBottom+1,nRight+1,cBox)
  151.  
  152.     @ nTop-1,nLeft-1 SAY SUBSTR(cBox,11,1) + ;
  153.         REPLICATE(SUBSTR(cBox,2,1),nRight-nLeft+1) + ;
  154.         SUBSTR(cBox,10,1)
  155.  
  156.     @ nTop-2, nLeft+2 SAY cTitle
  157.  
  158. ELSE
  159.  
  160.     SCROLL(nTop,nLeft,nBottom,nRight,0)
  161.  
  162. ENDIF
  163.  
  164. FOR nCount := 1 TO nBars
  165.     // Display menu all nBars
  166.     KEYBOARD CHR(K_LEFT)
  167.     ACHOICE(nTop,aColumns[nCount],nBottom, ;
  168.         aColumns[nCount]+LEN(aOptions[nCount][1])-1, ;
  169.         aOptions[nCount],aValids[nCount],'Ach_Menu')
  170.  
  171. NEXT
  172.  
  173. nOption := ((nStart-1) % LEN(aOptions[1])) + 1
  174. nStart := nOption
  175. nCount := INT((nStart-1) / LEN(aOptions[1])) + 1
  176. KEYBOARD CHR(0)
  177.  
  178. DO WHILE .T.
  179.  
  180.     nStart := nOption
  181.  
  182.     nOption := ACHOICE(nTop,aColumns[nCount],nBottom, ;
  183.         aColumns[nCount]+LEN(aOptions[nCount][1])-1, ;
  184.         aOptions[nCount],aValids[nCount],'Ach_Menu',nStart)
  185.  
  186.     nKey := LASTKEY()
  187.     DO CASE
  188.  
  189.         CASE nKey = K_ESC
  190.             // Esc to last option of last bar
  191.             IF nCount = nBars .AND. ROW() = nBottom
  192.                 EXIT
  193.             ELSE
  194.                 nCount := nBars
  195.                 nOption := LEN(aOptions[nBars])
  196.                 LOOP
  197.             ENDIF
  198.  
  199.         CASE nKey = K_LEFT
  200.             nCount --
  201.             IF nCount < 1
  202.                 nCount := nBars
  203.             ENDIF
  204.  
  205.         CASE nKey = K_RIGHT
  206.             nCount ++
  207.             IF nCount > nBars
  208.                 nCount := 1
  209.             ENDIF
  210.  
  211.             OTHERWISE
  212.             EXIT
  213.  
  214.     ENDCASE
  215.  
  216.     nOption := ROW() - nTop + 1
  217.  
  218. ENDDO
  219.  
  220. nOption := ROUND(ROW() - nTop + 1 + ((nCount - 1) * LEN(aOptions[1])),0)
  221.  
  222. SETCOLOR(cSaveColour)
  223.  
  224. /*
  225.     End of GT_Menu()
  226. */
  227. RETURN(nOption)
  228.  
  229. FUNCTION Ach_menu(nMode,nElement,nRow)
  230.  
  231. LOCAL nKey := LASTKEY()
  232. LOCAL nReturn := AC_CONT
  233.  
  234. Default nMode to AC_NOITEM
  235. Default nElement to 0
  236. Default nRow to nElement
  237.  
  238. DO CASE
  239.     CASE nMode = AC_IDLE
  240.         // Tum de tum
  241.  
  242.     CASE nMode = AC_HITTOP
  243.         // Goto bottom
  244.         KEYBOARD CHR(K_PGDN)
  245.  
  246.     CASE nMode = AC_HITBOTTOM
  247.         // Goto Top
  248.         KEYBOARD CHR(K_PGUP)
  249.  
  250.     CASE nMode = AC_EXCEPT
  251.         // Special Key
  252.         DO CASE
  253.             CASE nKey = K_RETURN
  254.                 // Select
  255.                 nReturn := AC_SELECT
  256.  
  257.             CASE nKey = K_ESC
  258.                 // Exit
  259.                 nReturn := AC_ABORT
  260.  
  261.             CASE ISALPHA(CHR(nKey)) .OR. ISDIGIT(CHR(nKey))
  262.                 // Goto
  263.                 nReturn := AC_GOTO
  264.  
  265.             CASE nKey = K_RIGHT
  266.                 // Exit (for multiple bar menus)
  267.                 nReturn := AC_ABORT
  268.  
  269.             CASE nKey = K_LEFT
  270.                 // Exit (for multiple bar menus)
  271.                 nReturn := AC_ABORT
  272.  
  273.             OTHERWISE
  274.                 // ?
  275.  
  276.         ENDCASE
  277.  
  278.     OTHERWISE
  279.         // Argh!
  280.         nReturn := AC_ABORT
  281.  
  282. ENDCASE
  283.  
  284. /*
  285.     End of Ach_menu()
  286. */
  287. RETURN(nReturn)
  288.