Files
harbour-core/harbour/contrib/hbnf/menutonf.prg
Viktor Szakats 2832c55881 2009-07-09 23:14 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* include/hbvmpub.h
  * include/extend.api
  * include/hbwince.h
  * include/hb_io.h
  * include/hbdefs.h
  * include/hbsetup.h
  * include/hbinit.h
  * include/clipdefs.h
  * include/hbmath.h
  * include/hbzlib.h
  * include/hbregex.h
  * include/hbexprb.c
  * source/pp/hbpp.c
  * source/lang/msgrukoi.c
  * source/lang/msgzhgb.c
  * source/lang/msgruwin.c
  * source/lang/msgelwin.c
  * source/lang/msgro.c
  * source/lang/msghriso.c
  * source/lang/msgcskam.c
  * source/lang/msggl.c
  * source/lang/msges.c
  * source/lang/msgde.c
  * source/lang/msgru866.c
  * source/lang/msgcs852.c
  * source/lang/msgplmaz.c
  * source/lang/msgpliso.c
  * source/lang/msgplwin.c
  * source/lang/msgid.c
  * source/lang/msgel.c
  * source/lang/msgdewin.c
  * source/lang/msghr437.c
  * source/lang/msghr852.c
  * source/lang/msgcsiso.c
  * source/lang/msgcswin.c
  * source/lang/msgeswin.c
  * source/vm/macro.c
  * source/vm/mainwin.c
  * source/vm/maindll.c
  * source/vm/itemapi.c
  * source/vm/hvm.c
  * source/vm/cmdarg.c
  * source/vm/mainstd.c
  * source/vm/maindllp.c
  * source/vm/fm.c
  * source/vm/extrap.c
  * source/vm/thread.c
  * source/vm/main.c
  * source/vm/break.c
  * source/vm/dynlibhb.c
  * source/vm/set.c
  * source/vm/classes.c
  * source/debug/dbgtwin.prg
  * source/debug/dbgtmenu.prg
  * source/debug/dbgmenu.prg
  * source/debug/dbgthsh.prg
  * source/debug/dbgwa.prg
  * source/common/hbgete.c
  * source/common/hbver.c
  * source/common/hbprintf.c
  * source/common/hbfsapi.c
  * source/common/hbverdsp.c
  * source/common/hbwince.c
  * source/common/hbfopen.c
  * source/common/hbdate.c
  * source/macro/macroa.c
  * source/macro/macrob.c
  * source/rtl/lennum.c
  * source/rtl/gtdos/gtdos.c
  * source/rtl/setposbs.c
  * source/rtl/gtwin/gtwin.c
  * source/rtl/typefile.prg
  * source/rtl/math.c
  * source/rtl/getsys53.prg
  * source/rtl/tobject.prg
  * source/rtl/gtcrs/gtcrs.c
  * source/rtl/gtcrs/gtcrs.h
  * source/rtl/philesx.c
  * source/rtl/filehb.c
  * source/rtl/hbtoken.c
  * source/rtl/fstemp.c
  * source/rtl/ampm.c
  * source/rtl/maxrow.c
  * source/rtl/hbstrfmt.c
  * source/rtl/transfrm.c
  * source/rtl/gttone.c
  * source/rtl/datec.c
  * source/rtl/fserr.c
  * source/rtl/pushbtn.prg
  * source/rtl/memvarbl.prg
  * source/rtl/hbregexc.c
  * source/rtl/profiler.prg
  * source/rtl/hbini.prg
  * source/rtl/dbedit.prg
  * source/rtl/filesys.c
  * source/rtl/lang.c
  * source/rtl/einstv52.prg
  * source/rtl/hbbit.c
  * source/rtl/isprint.c
  * source/rtl/altd.prg
  * source/rtl/diskspac.c
  * source/rtl/console.c
  * source/rtl/gtos2/gtos2.c
  * source/rtl/adir.prg
  * source/rtl/gui.prg
  * source/rtl/hbgtcore.c
  * source/rtl/dirdrive.c
  * source/rtl/wait.prg
  * source/rtl/mlcfunc.c
  * source/rtl/scrollbr.prg
  * source/rtl/gtapiu.c
  * source/rtl/tbrowsys.prg
  * source/rtl/oemansi.c
  * source/rtl/philes53.c
  * source/rtl/color53.prg
  * source/rtl/xsavescr.c
  * source/rtl/tgetlist.prg
  * source/rtl/gtsln/mousesln.c
  * source/rtl/gtsln/kbsln.c
  * source/rtl/gtsln/gtsln.h
  * source/rtl/disksphb.c
  * source/rtl/tlabel.prg
  * source/rtl/radiogrp.prg
  * source/rtl/scrrow.c
  * source/rtl/net.c
  * source/rtl/stuff.c
  * source/rtl/checkbox.prg
  * source/rtl/filebuf.c
  * source/rtl/mtran.c
  * source/rtl/gete.c
  * source/rtl/hbproces.c
  * source/rtl/gtwvt/gtwvt.c
  * source/rtl/fssize.c
  * source/rtl/memofile.c
  * source/rtl/hbffind.c
  * source/rtl/tmenuitm.prg
  * source/rtl/gtsys.c
  * source/rtl/devoutp.prg
  * source/codepage/uckoi8.c
  * source/codepage/uckoi8u.c
  * source/codepage/cphu852s.c
  * source/codepage/cpes850c.c
  * source/codepage/cphuisos.c
  * source/codepage/ucmaz.c
  * source/codepage/cptr857.c
  * source/codepage/ucmik.c
  * source/codepage/cphr437.c
  * source/codepage/cphuwins.c
  * source/rdd/dbjoin.prg
  * source/rdd/dbnubs.c
  * source/rdd/dbfuncs.prg
  * source/rdd/dbtotal.prg
  * source/rdd/dbstrux.prg
  * source/rdd/dbsort.prg
  * source/rdd/dbfcdx/dbfcdx1.c
  * source/rdd/hbsix/sxcompr.c
  * source/compiler/hbmain.c
  * source/compiler/expropta.c
  * source/compiler/exproptb.c
  * source/compiler/fixflex.c
  * source/compiler/compi18n.c
  * source/compiler/gencobj.c
  * source/compiler/hbopt.c
  * source/compiler/hbgenerr.c
  * utils/hbtest/rt_main.h
  * utils/hbtest/rt_main.ch
  * utils/hbtest/rt_trans.prg
  * utils/hbtest/rt_misc.prg
  * utils/hbtest/rt_vars.ch
  * contrib/gtalleg/gtalleg.c
  * contrib/gtalleg/ssf.h
  * contrib/hbmysql/mysqlold.c
  * contrib/hbmysql/mysql.c
  * contrib/hbct/charlist.c
  * contrib/hbct/ctnet.c
  * contrib/hbct/charonly.c
  * contrib/hbct/ctset.c
  * contrib/hbct/ctset.h
  * contrib/hbct/cterror.ch
  * contrib/hbct/ftoc.c
  * contrib/hbct/charevod.c
  * contrib/hbct/exponent.c
  * contrib/hbct/dattime3.c
  * contrib/hbct/ct.prg
  * contrib/hbct/cursor.c
  * contrib/hbct/color.c
  * contrib/hbct/charone.c
  * contrib/hbct/numconv.prg
  * contrib/hbct/cttime.prg
  * contrib/hbct/ctstr.h
  * contrib/hbct/atnum.c
  * contrib/hbct/disk.c
  * contrib/hbct/misc1.c
  * contrib/hbct/print.c
  * contrib/xhb/hblog.ch
  * contrib/xhb/bkgtsks.c
  * contrib/xhb/wintypes.ch
  * contrib/xhb/classex.ch
  * contrib/xhb/hbcomprs.c
  * contrib/xhb/ttable.ch
  * contrib/xhb/hbcompat.ch
  * contrib/xhb/arrayblk.prg
  * contrib/xhb/hbctypes.ch
  * contrib/xhb/xhbextrn.ch
  * contrib/xhb/filestat.c
  * contrib/xhb/hblogdef.ch
  * contrib/xhb/xhbcopyf.c
  * contrib/xhb/hbserv.c
  * contrib/xhb/xhbfunc.c
  * contrib/hbodbc/odbcold.c
  * contrib/hbtpathy/telepath.ch
  * contrib/hbmzip/hbmzip.c
  * contrib/hbblat/hbblat.ch
  * contrib/hbxbp/xbpfiledialog.prg
  * contrib/hbxbp/gra.ch
  * contrib/hbxbp/xbpwindow.prg
  * contrib/hbxbp/xbp.ch
  * contrib/hbxbp/xbphtmlviewer.prg
  * contrib/hbxbp/xbptoolbar.prg
  * contrib/hbxbp/appevent.ch
  * contrib/hbxbp/xbpgeneric.prg
  * contrib/xpp/philesx.c
  * contrib/hbnf/acctyear.prg
  * contrib/hbnf/byteneg.prg
  * contrib/hbnf/isshare.prg
  * contrib/hbnf/kspeed.c
  * contrib/hbnf/prtscr.c
  * contrib/hbnf/ftshadow.c
  * contrib/hbnf/descendn.c
  * contrib/hbnf/scancode.prg
  * contrib/hbnf/vidmode.prg
  * contrib/hbnf/acctadj.prg
  * contrib/hbnf/vidcur.prg
  * contrib/hbnf/iamidle.c
  * contrib/hbnf/acctmnth.prg
  * contrib/hbnf/madd.prg
  * contrib/hbnf/fttext.c
  * contrib/hbnf/mouse1.prg
  * contrib/hbnf/settime.prg
  * contrib/hbnf/page.prg
  * contrib/hbnf/setkeys.c
  * contrib/hbnf/month.prg
  * contrib/hbnf/acctweek.prg
  * contrib/hbnf/acctqtr.prg
  * contrib/hbnf/dosver.prg
  * contrib/hbnf/metaph.prg
  * contrib/hbnf/menu1.prg
  * contrib/hbnf/byteand.prg
  * contrib/hbnf/bytexor.prg
  * contrib/hbnf/byteor.prg
  * contrib/hbnf/asum.prg
  * contrib/hbnf/wda.prg
  * contrib/hbnf/aavg.prg
  * contrib/hbnf/mouse.c
  * contrib/hbnf/setdate.prg
  * contrib/hbnf/amedian.prg
  * contrib/hbnf/blink.prg
  * contrib/hbnf/getvid.c
  * contrib/hbnf/getver.c
  * contrib/hbnf/nwuid.prg
  * contrib/hbnf/aemaxlen.prg
  * contrib/hbnf/bitset.prg
  * contrib/hbnf/nwlstat.prg
  * contrib/hbnf/tempfile.prg
  * contrib/hbnf/diskfunc.prg
  * contrib/hbnf/d2e.prg
  * contrib/hbnf/mouse2.prg
  * contrib/hbnf/firstday.prg
  * contrib/hbnf/menutonf.prg
  * contrib/hbnf/pvid.prg
  * contrib/hbnf/isbit.prg
  * contrib/hbnf/datecnfg.prg
  * contrib/hbnf/putkey.c
  * contrib/hbnf/getenvrn.c
  * contrib/hbnf/bytenot.prg
  * contrib/hbnf/aeminlen.prg
  * contrib/hbnf/year.prg
  * contrib/hbnf/ftmenuto.ch
  * contrib/hbnf/rmdir.c
  * contrib/hbnf/sysmem.prg
  * contrib/hbnf/bitclr.prg
  * contrib/hbnf/setlastk.c
  * contrib/hbnf/clrsel.prg
  * contrib/hbcurl/hbcurl.ch
  * contrib/gtwvg/gtwvg.c
  * contrib/gtwvg/wvgax.prg
  * contrib/gtwvg/gtwvg.h
  * contrib/gtwvg/wvggui.c
  * contrib/gtwvg/wvggui.h
  * contrib/gtwvg/wvgwin.c
  * contrib/gtwvg/wvgutils.c
  * contrib/gtwvg/wvgcore.c
  * contrib/gtwvg/wvgtabpg.prg
  * contrib/gtwvg/wvgsink.c
  * contrib/gtwvg/wvgwing.c
  * contrib/hbclipsm/num.c
  * contrib/hbclipsm/stack.c
  * contrib/rddads/rddads.h
  * contrib/rddads/ads1.c
  * contrib/hbfimage/fi_winfu.c
  * contrib/hbfimage/fi_wrp.c
  * contrib/hbgd/gd.ch
  * contrib/hbgd/gdchart.prg
  * contrib/hbgd/gdimage.prg
  * contrib/hbgd/gdwrp.c
  * contrib/hbmisc/nconvert.prg
  * contrib/hbmisc/stringsx.c
  * contrib/hbmisc/spd.c
  * contrib/hbmisc/stringp.prg
  * contrib/hbwin/win_prn2.c
  * contrib/hbwin/wapi_commctrl.c
  * contrib/hbwin/wapi_winbase.c
  * contrib/hbwin/wapi_winuser.c
  * contrib/hbwin/hbwinole.h
  * contrib/hbwin/win_dll.c
  * contrib/hbwin/axfunc.prg
  * contrib/hbwin/win_prn1.c
  * contrib/hbvpdf/hbvpdf.ch
  * examples/hboleold/win_ole.c
    * Formatting:
       - Removing EOL whitespaces.
       - Removing extra empty lines at EOF.
       - Adding EOL at EOF if missing.
      (except in foreign code)
2009-07-09 21:22:22 +00:00

593 lines
19 KiB
Plaintext

/*
* $Id$
*/
/*
* File......: menuto.prg
* Author....: Ted Means
* CIS ID....: 73067,3332
*
* This is an original work by Ted Means and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* Rev 1.5 16 Oct 1992 00:20:28 GLENN
* Cleaned up documentation header.
*
* Rev 1.4 16 Oct 1992 00:08:44 GLENN
* Just making sure we had Ted's latest revision.
*
* Rev 1.3 13 Oct 1992 20:45:46 GLENN
* Complete rewrite by Ted Means, dumping assembler version for a
* Clipper version.
*
* Rev 1.2 15 Aug 1991 23:03:54 GLENN
* Forest Belt proofread/edited/cleaned up doc
*
* Rev 1.1 14 Jun 1991 19:52:16 GLENN
* Minor edit to file header
*
* Rev 1.0 01 Apr 1991 01:01:42 GLENN
* Nanforum Toolkit
*
*/
/* $DOC$
* $FUNCNAME$
* FT_Prompt()
* $CATEGORY$
* Menus/Prompts
* $ONELINER$
* Define a menu item for use with FT_MenuTo()
* $SYNTAX$
* #include "ftmenuto.ch"
*
* @ <nRow>, <nCol> PROMPT <cPrompt> ;
* [COLOR <cColor>] ;
* [MESSAGE <cMessage>] ;
* [MSGROW <nMsgRow>] ;
* [MSGCOL <nMsgCol>] ;
* [MSGCOLOR <cMsgColor>] ;
* [TRIGGER <nTrigger>] ;
* [TRIGGERCOLOR <cTriggerColor>] ;
* [HOME <nHome>] ;
* [END <nEnd>] ;
* [UP <nUp>] ;
* [DOWN <nDown>] ;
* [LEFT <nLeft>] ;
* [RIGHT <nRight>] ;
* [EXECUTE <bExec>] ;
*
* $ARGUMENTS$
* <nRow> is the row at which the prompt is to appear.
*
* <nCol> is the column at which the prompt will appear.
*
* <cPrompt> is the menu item string.
*
* <cColor> is optional and is the color attribute of the prompt. Note
* that two colors are required; one for the standard setting and one
* for the enhanced setting (i.e. the light bar color). See the example
* below if this isn't clear. If <cColor> is not specified then the
* current SetColor() value is used by default.
*
* <cMessage> is optional and is the message associated with the
* prompt. If not specified, then no message will be displayed.
*
* <nMsgRow> is optional and is the row at which the message, if any,
* will appear. If not specified, the default is the current setting
* of the SET MESSAGE TO command.
*
* <nMsgCol> is optional and is the column at which the message, if
* any, will appear. If not specified, the default is either zero or
* centered, depending on the current setting of the CENTER option of
* the SET MESSAGE TO command.
*
* <cMsgColor> is optional and is the color attribute of the message.
* If not specified, the default is the same as the prompt color.
*
* <nTrigger> is optional and is the position within the prompt string
* where the trigger character is located. If not specified, the
* default is one.
*
* <cTriggerColor> is optional and is the color attribute of the trigger
* character. Note that two colors are required; one for the standard
* setting and one for the enhanced setting (i.e. the light bar color).
* See the example below if this isn't clear. If <cTriggerColor> is not
* specified then the default is the same color as the rest of the
* prompt.
*
* <nHome> is optional and specifies which prompt becomes active
* when the home key is pressed. If not specified, the default is
* the first prompt.
*
* <nEnd> is optional and specifies which prompt becomes active
* when the end key is pressed. If not specified, the default is
* the last prompt.
*
* <nUp> is optional and specifies which prompt becomes active
* when the up arrow key is pressed. If not specified, the
* default is the previous prompt. The current setting of SET
* WRAP TO is obeyed.
*
* <nDown> is optional and specifies which prompt becomes
* active when the down arrow key is pressed. If not
* specified, the default is the next prompt. The current
* setting of SET WRAP TO is obeyed.
*
* <nRight> is optional and specifies which prompt becomes
* active when the right arrow key is pressed. If not
* specified, the default is the next prompt. The current
* setting of SET WRAP TO is obeyed.
*
* <nLeft> is optional and specifies which prompt becomes
* active when the left arrow is pressed. If not specified,
* the default is the previous prompt. The current setting of
* SET WRAP TO is obeyed.
*
* <bExec> is optional and is a code block to evaluate whenever
* the menu item to which it belongs is selected.
* $DESCRIPTION$
* Clipper's @...PROMPT and MENU TO commands are fine as far as
* they go. But many times you need more flexibility. As
* you'll no doubt notice if you read the argument list, this
* function is almost completely flexible. You can adjust
* locations and colors for every part of the prompt and its
* associated message. In addition, since you can control the
* effect of the arrow keys, you can allow both horizontal and
* vertical movement, or even disable certain arrow keys if you
* so desire. Support for nested menus is also available, since
* the prompts are stored in stack-based static arrays.
*
* Note that this command can also be called using function-style
* syntax. See the entry for FT_PROMPT() for further details.
*
* This enhanced version of @...PROMPT requires the inclusion of
* the header file ftmenuto.ch in any source file that uses it.
* It is may be used in place of the standard Clipper @...PROMPT
* command. However, in the interests of functionality it is NOT
* 100% compatible. No whining! If compatibility is such a big
* deal then use the standard Clipper commands.
*
* $EXAMPLES$
* #include "ftmenuto.ch"
*
* // Simple prompt
* @ 1, 1 PROMPT "Menu choice #1"
*
* // Prompt with color
* @ 3, 1 PROMPT "Menu choice #2" COLOR "W+/R,W+/B"
*
* // Prompt with a message
* @ 5, 1 PROMPT "Menu choice #3" MESSAGE "Go to lunch"
*
* // Prompt with pinpoint message control
* @ 7, 1 PROMPT "Menu choice #4" MESSAGE "Drop Dead" ;
* MSGROW 22 MSGCOL 4 MSGCOLOR "GR+/N"
*
* // Prompt with a trigger character ("#" character)
* @11, 1 PROMPT "Menu choice #6" TRIGGER 13
*
* // Prompt with trigger character color control
* @13, 1 PROMPT "Menu Choice #7" TRIGGER 13 TRIGGERCOLOR "R+/BG,G+/N"
*
* // Prompt with right and left arrow keys disabled
* @15, 1 PROMPT "Menu Choice #8" RIGHT 8 LEFT 8
* $INCLUDE$
* ftmenuto.ch
* $SEEALSO$
*
* $END$
*/
#include "setcurs.ch"
#include "inkey.ch"
#xcommand if <true> then <action> => ;
if <true> ; <action> ; end
#xtranslate display( <row>, <col>, <stuff>, <color> ) => ;
setpos( <row>, <col> ) ; dispout( <stuff>, <color> )
#xtranslate EnhColor( <colorspec> ) => ;
substr( <colorspec>, at( ",", <colorspec> ) + 1 )
#xtranslate isOkay( <exp> ) => ;
( <exp> \> 0 .and. <exp> \<= nCount )
#xtranslate isBetween( <val>, <lower>, <upper> ) => ;
( <val> \>= <lower> .and. <val> \<= <upper> )
#define nTriggerInkey asc( upper( substr( cPrompt, nTrigger, 1 ) ) )
#define cTrigger substr( cPrompt, nTrigger, 1 )
#define nCurrent nMenu,nActive
#define nLast nMenu,nPrev
// These arrays hold information about each menu item
static aRow := {{}}
static aCol := {{}}
static aPrompt := {{}}
static aColor := {{}}
static aMsgRow := {{}}
static aMsgCol := {{}}
static aMessage := {{}}
static aMsgColor := {{}}
static aTrigger := {{}}
static aTriggerInkey := {{}}
static aTriggerColor := {{}}
static aHome := {{}}
static aEnd := {{}}
static aUp := {{}}
static aDown := {{}}
static aLeft := {{}}
static aRight := {{}}
static aExecute := {{}}
static nLevel := 1
function FT_Prompt( nRow, nCol, cPrompt, cColor, ;
nMsgRow, nMsgCol, cMessage, cMsgColor, ;
nTrigger, cTriggerColor, nHome, nEnd, ;
nUp, nDown, nLeft, nRight, bExecute )
// If the prompt color setting is not specified, use default
if cColor == NIL then cColor := setcolor()
// If no message is supplied, set message values to NIL
if cMessage == NIL
nMsgRow := nMsgCol := cMsgColor := NIL
else
// If message row not supplied, use the default
if nMsgRow == NIL then nMsgRow := set( _SET_MESSAGE )
// If message column not supplied, use the default
if nMsgCol == NIL
if set( _SET_MCENTER )
nMsgCol := int( ( maxcol() + 1 - len( cPrompt ) ) / 2 )
else
nMsgCol := 0
endif
endif
// If message color not specified, use the default
if cMsgColor == NIL then cMsgColor := cColor
endif
// If trigger values not specifed, set the defaults
if nTrigger == NIL then nTrigger := 1
if cTriggerColor == NIL then cTriggerColor := cColor
// Now add elements to the static arrays -- nLevel indicates the recursion
// level, which allows for nested menus.
aadd( aRow[ nLevel ], nRow )
aadd( aCol[ nLevel ], nCol )
aadd( aPrompt[ nLevel ], cPrompt )
aadd( aColor[ nLevel ], cColor )
aadd( aMsgRow[ nLevel ], nMsgRow )
aadd( aMsgCol[ nLevel ], nMsgCol )
aadd( aMessage[ nLevel ], cMessage )
aadd( aMsgColor[ nLevel ], cMsgColor )
aadd( aTrigger[ nLevel ], nTrigger )
aadd( aTriggerInkey[ nLevel ], nTriggerInkey )
aadd( aTriggerColor[ nLevel ], cTriggerColor )
aadd( aHome[ nLevel ], nHome )
aadd( aEnd[ nLevel ], nEnd )
aadd( aUp[ nLevel ], nUp )
aadd( aDown[ nLevel ], nDown )
aadd( aLeft[ nLevel ], nLeft )
aadd( aRight[ nLevel ], nRight )
aadd( aExecute[ nLevel ], bExecute )
// Now display the prompt for the sake of compatibility
dispbegin()
display( nRow, nCol, cPrompt, cColor )
display( nRow, nCol - 1 + nTrigger, cTrigger, cTriggerColor )
dispend()
return NIL
/* $DOC$
* $FUNCNAME$
* FT_MenuTo()
* $CATEGORY$
* Menus/Prompts
* $ONELINER$
* Execute light bar menu using prompts created with @...PROMPT
* $SYNTAX$
* #include "ftmenuto.ch"
*
* MENU TO <var> [COLD]
* $ARGUMENTS$
* <var> is the name of the variable to which the result of the menu
* selection should be assigned.
*
* [COLD] is optional and if specified indicates that trigger characters
* should be treated as "cold," i.e. rather than causing the menu item
* to be selected it only causes the light bar to move to that selection.
* $DESCRIPTION$
* This enhanced version of MENU TO requires the inclusion of the header
* file ftmenuto.ch in any source file that uses it. It may be used in
* place of the standard Clipper MENU TO command. However, in the
* interests of functionality it is NOT 100% compatible (in particular,
* you should make sure that the target memvar exists before executing
* the menu -- the Clipper version will create a PRIVATE memvar for you
* if it does not already exist, but this version does not). No whining!
* If compatibility is such a big deal then use the standard Clipper
* command.
*
* Note that this command can also be called using function-style
* syntax. See the entry for FT_MENUTO() for further details.
* $EXAMPLES$
* #include "ftmenuto.ch"
*
* // Simple command
*
* MENU TO memvar
*
* $INCLUDE$
* ftmenuto.ch
* $SEEALSO$
* FT_Prompt()
* $END$
*/
function FT_MenuTo( bGetSet, cReadVar, lCold )
local nMenu := nLevel++
local nActive
local nCount := len( aRow[ nMenu ] )
local lChoice := .F.
local nCursor := set( _SET_CURSOR,SC_NONE )
local nKey,bKey,nScan,lWrap,cScreen,nPrev
// Validate the incoming parameters and assign some reasonable defaults
// to prevent a crash later.
cReadVar := iif( cReadVar == NIL, "", upper( cReadVar ) )
if bGetSet == NIL then bGetSet := {|| 1}
// Eval the incoming getset block to initialize nActive, which indicates
// the menu prompt which is to be active when the menu is first displayed.
// If nActive is outside the appropriate limits, a value of 1 is assigned.
nActive := eval( bGetSet )
if ( nActive < 1 .or. nActive > nCount ) then nActive := 1
// Increment the recursion level in case a hotkey procedure
// calls FT_Prompt(). This will cause a new set of prompts
// to be created without disturbing the current set.
aadd( aRow, {} )
aadd( aCol, {} )
aadd( aPrompt, {} )
aadd( aColor, {} )
aadd( aMsgRow, {} )
aadd( aMsgCol, {} )
aadd( aMessage, {} )
aadd( aMsgColor, {} )
aadd( aTrigger, {} )
aadd( aTriggerInkey, {} )
aadd( aTriggerColor, {} )
aadd( aUp, {} )
aadd( aDown, {} )
aadd( aLeft, {} )
aadd( aRight, {} )
aadd( aExecute, {} )
// Loop until Enter or Esc is pressed
while .not. lChoice
// Evaluate the getset block to update the target memory variable
// in case it needs to be examined by a hotkey procedure.
eval( bGetSet,nActive )
// Get the current setting of SET WRAP so that the desired menu behavior
// can be implemented.
lWrap := set( _SET_WRAP )
// If a message is to be displayed, save the current screen contents
// and then display the message, otherwise set the screen buffer to NIL.
dispbegin()
if aMessage[ nCurrent ] != NIL
cScreen := savescreen( aMsgRow[ nCurrent ], aMsgCol[ nCurrent ], ;
aMsgRow[ nCurrent ], aMsgCol[ nCurrent ] + ;
len( aMessage[ nCurrent ] ) - 1 )
display( aMsgRow[ nCurrent ], aMsgCol[ nCurrent ], ;
aMessage[ nCurrent ], aMsgColor[ nCurrent ] )
else
cScreen := NIL
endif
// Display the prompt using the designated colors for the prompt and
// the trigger character.
display( aRow[ nCurrent ], aCol[ nCurrent ], ;
aPrompt[ nCurrent ], EnhColor( aColor[ nCurrent ] ) )
display( aRow[ nCurrent ], ;
aCol[ nCurrent ] - 1 + aTrigger[ nCurrent ], ;
substr( aPrompt[ nCurrent ], aTrigger[ nCurrent ], 1 ), ;
EnhColor( aTriggerColor[ nCurrent ] ) )
dispend()
// Wait for a keystroke
nKey := inkey( 0 )
// If the key was an alphabetic char, convert to uppercase
if isBetween( nKey,97,122 ) then nKey -= 32
// Set nPrev to the currently active menu item
nPrev := nActive
do case
// Check for a hotkey, and evaluate the associated block if present.
case ( bKey := setkey( nKey ) ) != NIL
eval( bKey, ProcName( 1 ), ProcLine( 1 ), cReadVar )
// If Enter was pressed, either exit the menu or evaluate the
// associated code block.
case nKey == K_ENTER
if aExecute[ nCurrent ] != NIL
eval( aExecute[ nCurrent ] )
else
lChoice := .T.
endif
// If ESC was pressed, set the selected item to zero and exit.
case nKey == K_ESC
lChoice := .T.
nActive := 0
// If Home was pressed, go to the designated menu item.
case nKey == K_HOME
nActive := iif( aHome[ nCurrent ] == NIL, 1, aHome[ nCurrent ] )
// If End was pressed, go to the designated menu item.
case nKey == K_END
nActive := iif( aEnd[ nCurrent ] == NIL, nCount, aEnd[ nCurrent ] )
// If Up Arrow was pressed, go to the designated menu item.
case nKey == K_UP
if aUp[ nCurrent ] == NIL
if --nActive < 1 then nActive := iif( lWrap, nCount, 1 )
else
if isOkay( aUp[ nCurrent ] ) then nActive := aUp[ nCurrent ]
endif
// If Down Arrow was pressed, go to the designated menu item.
case nKey == K_DOWN
if aDown[ nCurrent ] == NIL
if ++nActive > nCount then nActive := iif( lWrap, 1, nCount )
else
if isOkay( aDown[ nCurrent ] ) then nActive := aDown[ nCurrent ]
endif
// If Left Arrow was pressed, go to the designated menu item.
case nKey == K_LEFT
if aLeft[ nCurrent ] == NIL
if --nActive < 1 then nActive := iif( lWrap, nCount, 1 )
else
if isOkay( aLeft[ nCurrent ] ) then nActive := aLeft[ nCurrent ]
endif
// If Right Arrow was pressed, go to the designated menu item.
case nKey == K_RIGHT
if aRight[ nCurrent ] == NIL
if ++nActive > nCount then nActive := iif( lWrap, 1, nCount )
else
if isOkay( aRight[ nCurrent ] ) then nActive := aRight[ nCurrent ]
endif
// If a trigger letter was pressed, handle it based on the COLD
// parameter.
case ( nScan := ascan( aTriggerInkey[ nMenu ], nKey ) ) > 0
nActive := nScan
if .not. lCold then FT_PutKey( K_ENTER )
endcase
// Erase the highlight bar in preparation for the next iteration
if .not. lChoice
dispbegin()
display( aRow[ nLast ], aCol[ nLast ], ;
aPrompt[ nLast ], aColor[ nLast ] )
display( aRow[ nLast ], aCol[ nLast ] - 1 + aTrigger[ nLast ], ;
substr( aPrompt[ nLast ], aTrigger[ nLast ], 1 ), ;
aTriggerColor[ nLast ] )
if cScreen != NIL then restscreen( aMsgRow[ nLast ], ;
aMsgCol[ nLast ], ;
aMsgRow[ nLast ], ;
aMsgCol[ nLast ] ;
+ len( aMessage[ nLast ] ) - 1, ;
cScreen )
dispend()
endif
end
// Now that we're exiting, decrement the recursion level and erase all
// the prompt information for the current invocation.
nLevel--
asize( aRow, nLevel )
asize( aCol, nLevel )
asize( aPrompt, nLevel )
asize( aColor, nLevel )
asize( aMsgRow, nLevel )
asize( aMsgCol, nLevel )
asize( aMessage, nLevel )
asize( aMsgColor, nLevel )
asize( aTrigger, nLevel )
asize( aTriggerInkey, nLevel )
asize( aTriggerColor, nLevel )
asize( aUp, nLevel )
asize( aDown, nLevel )
asize( aLeft, nLevel )
asize( aRight, nLevel )
asize( aExecute, nLevel )
aRow[ nLevel ] := {}
aCol[ nLevel ] := {}
aPrompt[ nLevel ] := {}
aColor[ nLevel ] := {}
aMsgRow[ nLevel ] := {}
aMsgCol[ nLevel ] := {}
aMessage[ nLevel ] := {}
aMsgColor[ nLevel ] := {}
aTrigger[ nLevel ] := {}
aTriggerInkey[ nLevel ] := {}
aTriggerColor[ nLevel ] := {}
aUp[ nLevel ] := {}
aDown[ nLevel ] := {}
aLeft[ nLevel ] := {}
aRight[ nLevel ] := {}
aExecute[ nLevel ] := {}
set( _SET_CURSOR, nCursor )
eval( bGetSet, nActive )
return nActive