home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power CD-ROM!! 7
/
POWERCD7.ISO
/
prgmming
/
clipper
/
getchoic.prg
< prev
next >
Wrap
Text File
|
1994-08-29
|
8KB
|
298 lines
/*
* File......: getchoic.prg
* Author....: Andy M Leighton
* BBS.......: The Dark Knight Returns
* Net/Node..: 050/069
* User Name.: Andy Leighton
* Date......: 08/06/93
* Revision..: 1.0
* Log file..: $Logfile$
*
* This is an original work by Andy M Leighton and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* Rev 1.0 8/6/93
* Initial Revision
*/
/* $DOC$
* $FUNCNAME$
* @ <row>, <col> GET <var> [...] FROM <aChoices> [...]
* $CATEGORY$
* Get Reader
* $ONELINER$
* Get from an array of choices via a menu
* $SYNTAX$
* @ <row>, <col> GET <var> [...] FROM <aChoices> [....]
* $ARGUMENTS$
* Not Applicable
* $RETURNS$
* Not Applicable
* $DESCRIPTION$
* This is a get reader.
* It allows the user to choose a value from an array of strings.
* It correctly handles arrays that are longer than available
* screen space (see Examples).
* If the choices menu is too wide for the screen it will generate
* a meaningful error message
* The colours cannot be changed at the moment without altering the
* code. If someone wants to add an optional colours clause see the
* information about the cargo that follows.
*
* For those who are interested (it is not neccessary to know this
* to use the reader) the following data is stored in the cargo
* slot of the reader.
* oGet:cargo[1] - The array of menu choices
* oGet:cargo[2] - The current choice (only changes when in
* the getreader itself)
* oGet:cargo[3] - Colours array
* oGet:cargo[3][1] - Normal colour
* oGet:cargo[3][2] - Selection bar colour
* oGet:cargo[3][3] - Frame colour
*
* NOTE: this function is not standalone, you also need the following
* functions from the GTLIB - GT_AComp(), GT_SaveScr() and
* GT_RestScr()
*
* $EXAMPLES$
*
* local choices := { "Yes", "No", "Not Sure" }
* local choices2 := {}
* local var1 := ""
* local var2 := ""
* local i
*
* for i := 1 to 99
* aAdd(choices2, "Choice " + str(i, 2))
* next
*
* @ 10, 10 say "Choice 1" get var1 from choices
* @ 10, 50 say "Choice 2" get var2 from choices2
*
* GT_Read(getlist)
*
* $SEEALSO$
* $END$
*/
#include "gt_Lib.ch"
#include "error.ch"
// works a bit like the one in FuncKy
#translate aMaxStrLen(<a>) => len(GT_AComp(<a>, AC_MAXLEN))
function GT_ChoiceReader(oGet)
local cSaveScr
local cOldCols := setColor()
local oCurs := setCursor(SC_NONE)
// read the GET if the WHEN condition is satisfied
if GetPreValidate(oGet)
// activate the GET for reading and position
// cursor on the right side
oGet:setFocus()
oGet:pos := len(oGet:buffer)
// default the initial pointer to the current value
oGet:cargo[2] := ascan(oGet:cargo[1], oGet:original)
if oGet:cargo[2] == 0 // make the element pointer point to
oGet:cargo[2] := 1 // the first element of the array
endif
gGtSetColours(oGet)
cSaveScr := gGtsaveBack(oGet)
gGtdispChoices(oGet)
do while oGet:exitState == GE_NOEXIT
// check for initial typeout (no editable positions)
if oGet:typeOut
oGet:exitState := GE_ENTER
endif
// apply keystrokes until exit
do while oGet:exitState == GE_NOEXIT
gGtApplyKey(oGet, inkey(0))
gGtdispChoices(oGet)
enddo
// disallow exit if the VALID condition is not satisfied
if !GetPostValidate(oGet)
oGet:exitState := GE_NOEXIT
endif
enddo
GT_RestScr(cSaveScr)
setColor(cOldCols)
setCursor(oCurs)
// de-activate the GET
@ oGet:row, oGet:col say oGet:cargo[1][oGet:cargo[2]]
oGet:killFocus()
endif
return NIL
// Internal functions exist below this point
/*
* Apply keystrokes to the get
*
* *YOU* may want to change the keystrokes for PGUP and PGDN
* so that they page thru the menu
*/
static function gGtApplyKey(oGet, nKey)
local lTranBack := TRUE
do case
case nKey == K_UP
oGet:cargo[2] := max(oGet:cargo[2] - 1, 1)
lTranBack := FALSE
case nKey == K_DOWN
oGet:cargo[2] := min(oGet:cargo[2] + 1, len(oGet:cargo[1]))
lTranBack := FALSE
case nKey == K_HOME
oGet:cargo[2] := 1
lTranBack := FALSE
case nKey == K_END
oGet:cargo[2] := len(oGet:cargo[1])
lTranBack := FALSE
case nKey == K_SH_TAB
oGet:exitState := GE_UP
case nKey == K_TAB
oGet:exitState := GE_DOWN
case nKey == K_ENTER
oGet:exitState := GE_ENTER
case nKey == K_ESC
if Set(_SET_ESCAPE)
oGet:undo()
oGet:exitState := GE_ESCAPE
lTranBack := FALSE
endif
case nKey == K_PGUP
oGet:exitState := GE_WRITE
case nKey == K_PGDN
oGet:exitState := GE_WRITE
case nKey == K_CTRL_END
oGet:exitState := GE_BOTTOM
endcase
if lTranBack
oGet:varPut(oGet:cargo[1][oGet:cargo[2]])
endif
return NIL
/*
* displays a menu of choices with the current choice
* highlighted
*/
static function gGtdispChoices(oGet)
local nCLen := len(oGet:cargo[1])
local nCWid := aMaxStrLen(oGet:cargo[1])
local nLoop
static nSt := 1
if oGet:row + nClen > maxRow() - 1
nClen := maxRow() - 1 - oGet:row
endif
do while oGet:cargo[2] > (nSt + nCLen - 1)
nSt++
enddo
do while oGet:cargo[2] < nSt
nSt--
enddo
if len(oGet:cargo[1]) - nCLen < (nSt - 1)
nSt := len(oGet:cargo[1]) - nCLen
endif
dispBegin()
@ oGet:row - 1, oGet:col - 1, oGet:row + nCLen, oGet:col + nCWid ;
box B_SINGLE + " " color oGet:cargo[3][3]
for nLoop := nSt to nSt + nCLen - 1
if nLoop == oGet:cargo[2]
setColor(oGet:cargo[3][1])
else
setColor(oGet:cargo[3][2])
endif
@ oGet:row - nSt + nLoop, oGet:col say oGet:cargo[1][nLoop]
next
dispEnd()
return NIL
/*
* save the background where the menu is going to appear
*/
static function gGtsaveBack(oGet)
local nCLen := len(oGet:cargo[1])
local nCWid := aMaxStrLen(oGet:cargo[1])
local oError
if oGet:row + nClen > maxcol() - 1
nClen := maxcol() - 1 - oGet:row
endif
if nCWid + oGet:col > maxcol()
oError := ErrorNew()
oError:description := "Choices menu too wide for this screen postion"
oError:subcode := 1
oError:subsystem := "GT_ChoiceReader"
oError:severity := ES_ERROR
eval(ErrorBlock(),oError) // Fire up the error system
endif
return GT_SaveScr(oGet:row - 1, oGet:col - 1, ;
oGet:row + nCLen, oGet:col + nCWid)
/*
* if anyone can add the right clause and code to get the colors
* setting correctly please modify it.
*/
static function gGTSetColours(oGet)
oGet:cargo[3][1] := "GB/R"
oGet:cargo[3][2] := "R/BG"
oGet:cargo[3][3] := "GR+/BG"
return NIL