Function AChoice() Foundation
Displays and allows selection from a list box.
AChoice( <nTop> , ;
<nLeft> , ;
<nBottom> , ;
<nRight> , ;
<aItems> , ;
[<alSelectable>], ;
[<bcUserFunc>] , ;
[<nStartItem>] , ;
[<nStartRow> ] ) --> nElement
If the user exits AChoice() by pressing the return key, the return value of AChoice() is an integer corresponding to the position of the selected element in <aItems>. If the user terminates AChoice() by pressing the Esc key, the return value is zero.
The function AChoice() allows the selection of a value from a one dimensional array. It is suitable for generating menus, programming combo boxes or displaying lists. The elements contained in the array <aItems> are displayed in a window. When the array has more elements than the number of rows in the window, the window contents are scrolled using the arrow keys to allow the user to select an element not currently visible within the window. If <aItems> contains character strings, pressing the first letter of the character string causes the highlight to jump directly to the next element beginning with that character.
Elements in <aItems> are displayed in the system colors set with SetColor(). All selectable elements are displayed in the default color (first color value), the current element is displayed in the "highlighted" color (second color value) and unselectable elements are displayed in the "not selected" color (fifth color value).
Cursor navigation in AChoice() depends on the user function or code block specified. When <bcUserFunc> is not included, navigation occurs using the following keys:
Key | Inkey constants | Action |
---|---|---|
Up Arrow | K_UP | Previous element |
Down Arrow | K_DOWN | Next element |
Left Arrow | K_LEFT | Terminates AChoice() |
Right Arrow | K_RIGHT | Terminates AChoice() |
Home | K_HOME | First element |
End | K_END | Last element |
Page Up | K_PGUP | Next screen up |
Page Down | K_PGDN | Next screen down |
Ctrl+Home | K_CTRL_HOME | Beginning of the window |
Ctrl+End | K_CTRL_END | End of the window |
Ctrl+Page Up | K_CTRL_PGUP | First element |
Ctrl+Page Down | K_CTRL_PGDN | Last element |
Return | K_RETURN | Selects element |
Esc | K_ESC | Terminates AChoice() |
Letter | Cursor to next element beginning with this letter |
If the function SetMouse(.T.) is called before calling Achoice(), a selection can also be made using the mouse. Mouse navigation in Achoice() is as follows:
Action | Description |
---|---|
Single left click | Highlight is moved to the mouse pointer |
Double left click | Selection is made, Achoice() exits |
Press left mouse button and drag mouse | Highlight follows the mouse pointer if pointer moves out of the Achoice(), window, Achoice() scrolls the list |
If Achoice() is used with Xbase Parts in the hybrid mode, events for an Xbase Part are automatically sent to the applicable Xbase Part and are not processed by Achoice().
Achoice() with a user function
The optional argument <bcUserFunc> modifies the functionality of AChoice(). <bcUserFunc> contains either a character string with the name of a function or a code block.
If <bcUserFunc> contains a function name, the corresponding function must not be declared STATIC and must be specified as a character string without parentheses ().
When <bcUserFunc> contains a code block, it must contain the function call to the user function. If a code block is used, the user function within it can be declared STATIC.
The user function allows user specific configuration of individual keys for AChoice(). When a user function is included, AChoice() itself only processes the following keys:
Key | Inkey constant | Action |
---|---|---|
Up Arrow | K_UP | Previous element |
Down Arrow | K_DOWN | Next element |
Page Up | K_PGUP | Next screen up |
Page Down | K_PGDN | Next screen down |
Ctrl+Home | K_CTRL_HOME | Beginning of window |
Ctrl+End | K_CTRL_END | End of window |
Ctrl+Page Up | K_CTRL_PGUP | First element |
Ctrl+Page Down | K_CTRL_PGDN | Last element |
If a value is specified for <bcUserFunc> in the call to the function AChoice(), AChoice() calls the user function (or evaluates the code block) when any key is pressed which AChoice() does not automatically process. Configurable keys are processed in the user function and the RETURN value of the user function notifies AChoice() how it should react to the keypress.
When AChoice() calls the user function, it passes three numeric values to the user function: the current AChoice() mode, the current element in <aItems> and the current row within the window. The value of the current row is in relation to <nTop> and begins with zero.
The AChoice() mode designates the present condition of AChoice() and depends on the last key pressed or the last action executed by AChoice() prior to the call of the user function. In the header file Achoice.ch symbolic constants are defined which identify the different modes of AChoice():
Constants | Description |
---|---|
AC_IDLE | Idle, all keys processed |
AC_HITTOP | Attempt to move cursor to an element < 1 |
AC_HITBOTTOM | Attempt to move cursor to an element > Len(<aItems>) |
AC_EXCEPT | Key or event is unknown |
AC_NOITEM | No selectable elements available |
The mode AC_IDLE means that no more keys are available for processing and AChoice() is waiting for a new keypress. Each time AChoice() is unable to find another value in the keyboard buffer, the user function is called once and then AChoice() waits until a new key is pressed.
The modes AC_HITTOP and AC_HITBOTTOM signal that the user has tried to position the highlight before the first element or past the last element in <aItems>.
The mode AC_EXCEPT indicates that an unknown or configurable key code needs processing or that a mouse event occurred. The action AChoice() should execute after a configurable key press can be defined by the return value of the user function. The return value AC_CONT causes AChoice() to execute its default action. If the value returned is not equal to AC_CONT, AChoice() executes some other action. Symbolic constants are defined in the header file Achoice.ch for the possible return values of the user function and identify the various AChoice() actions that can be requested by the user function:
Constants | Action |
---|---|
AC_ABORT | Terminates AChoice() without selection |
AC_SELECT | Exits AChoice() with selection |
AC_CONT | Continues AChoice() |
AC_GOTO | Jumps to next element whose first letter matches the key |
// In the example, a simple call to AChoice() is shown.
// This selects a file name from an array created
// with Directory(). Only PRG files are listed. When a
// selection is made, the file is edited with MemoEdit().
PROCEDURE Main
LOCAL aFiles := Directory("*.PRG"), nChoice
// create a single
// dimensional array
AEval( aFiles, {|a,i| a:=Upper(a[1])},,,.T. )
nChoice := AChoice( 2, 2, 20, 13, aFiles )
IF nChoice > 0
MemoEdit( MemoRead( aFiles[ nChoice ] ) )
ENDIF
RETURN
// The example shows the function SelectFile() used for selecting
// files. The file names are retrieved using Directory() and
// displayed with AChoice(). In the user function StatusBar(),
// a status bar is displayed in the right window border
// which identifies the position of the current element
// in the array. Note the STATIC variables visible file-wide.
#include "Inkey.ch"
#include "Achoice.ch"
STATIC saFiles, snTop, snLeft, snBottom, snRight
FUNCTION SelectFile()
LOCAL nChoice, aGray, cScreen
saFiles := Directory("*.*") // create array
snTop := 2 // place coordinates in
snLeft := 2 // STATIC variables
snBottom:= 20
snRight := 13
AEval( saFiles, {|a,i| a:=Upper(a[1])},,, .T. )
aGray := Array( Len(saFiles) )
// EXE files are not
// selectable
AEval( saFiles, {|c,i| aGray[i]:= (! ".EXE" $ c) } )
// save screen
cScreen := SaveScreen(snTop-1, snLeft-1, snBottom+1, snRight+1)
// output border
DispBox( snTop-1, snLeft-1, snBottom+1, snRight+1 )
// allow file to be selected
nChoice := AChoice( snTop , snLeft, snBottom, snRight, ;
saFiles, aGray , "STATUSBAR" )
// restore screen
RestScreen(snTop-1, snLeft-1, snBottom+1, snRight+1, cScreen)
RETURN IIf( nChoice == 0, "", saFiles[ nChoice ] )
FUNCTION StatusBar( nMode, nElement, nRow )
LOCAL nReturn := AC_CONT // default: continues
LOCAL nKey := LastKey()
LOCAL nLen := Len( saFiles )
LOCAL nPos
DO CASE
CASE nMode == AC_IDLE // output status bar
IF nElement == 1 // determine position for
nPos := 1 // indicator
ELSEIF nElement == nLen
nPos := snBottom-snTop-1
ELSE
nPos := Round( (snBottom-snTop-1) * (nElement/nLen), 0 )
ENDIF
nPos := Max( 1, nPos )
DispBox( snTop, snRight+1, snBottom, snRight+1, Chr(176) )
@ snTop , snRight+1 SAY Chr(24) // arrow up
@ snBottom , snRight+1 SAY Chr(25) // arrow down
@ snTop+nPos, snRight+1 SAY Chr(219) // indicator
CASE nMode == AC_HITTOP // beginning is reached
Tone( 1000, 2 )
CASE nMode == AC_HITBOTTOM // end is reached
Tone( 500, 2 )
CASE nMode == AC_EXCEPT
DO CASE
CASE nKey == K_RETURN
nReturn := AC_SELECT // select element
CASE nKey == K_ESC
nReturn := AC_ABORT // terminate AChoice()
OTHERWISE
nReturn := AC_GOTO // jump to element
ENDCASE
ENDCASE
RETURN nReturn
// The example shows a simple text editor with a menu.
// The menu is called by the F10 key, and it permits
// reading and saving text files. Text is edited
// using MemoEdit(). The menu is created with AChoice().
// Selection of files occurs using the function SelectFile()
// from the previous example "AChoice() with user function".
#include "Inkey.ch"
STATIC saMenu, saGray, saMsg, saAction
STATIC scFileName := "TEST.TXT"
STATIC scText := ""
PROCEDURE TextEditor
SetColor( "N/BG,W+/B,,,N+/BG" )
CLS
saMenu := { "New file ", ; // menu items
"Open file ", ;
"Save ", ;
"Save As ", ;
"--------------", ; // line separator
"Quit" }
// line separator is
saGray := {.T.,.T.,.T.,.T.,.F.,.T.} // not selectable
// menu "Messages"
saMsg := { "Create new text file" , ;
"Opens and edit text file" , ;
"Save text to current file" , ;
"Saves text to another file" , ;
"" , ;
"Quit program" }
// menu actions in code blocks
saAction := { {|| NewFile() }, ;
{|| OpenFile() }, ;
{|| SaveFile() }, ;
{|| SaveFileAs() }, ;
, ;
{|| Quit() } }
SET KEY K_F10 TO MemoQuit() // F10 terminates MemoEdit()
scText := MemoRead( scFileName )
DO WHILE .T.
@ 0,0 SAY " Texteditor: F10 calls menu"
scText := MemoEdit( scText ) // edit text
TextMenu() // call menu
ENDDO
RETURN
PROCEDURE TextMenu() // display menu with AChoice()
LOCAL cScreen := SaveScreen(), nChoice
DispBox( 1, 1, 8, 17 )
nChoice := AChoice( 2, 2, 7, 16, saMenu, saGray )
RestScreen( ,,,, cScreen )
IF nChoice > 0 // selection is made which
Eval( saAction [nChoice] ) // causes action
ENDIF
RETURN
PROCEDURE MemoQuit() // terminate MemoEdit()
KEYBOARD Chr(K_CTRL_W)
RETURN
PROCEDURE Quit() // terminate the program
QUIT
RETURN
PROCEDURE NewFile() // create new file
LOCAL cFilename := GetFileName()
IF ! Empty( cFileName )
MemoWrit( scFileName, scText )
scFileName := cFileName
scText := ""
ENDIF
RETURN
PROCEDURE OpenFile() // open and read file
LOCAL cFilename := SelectFile() // function from previous example
IF ! Empty( cFileName )
MemoWrit( scFileName, scText )
scFileName := cFileName
scText := MemoRead( scFileName )
ENDIF
RETURN
PROCEDURE SaveFile() // save file
MemoWrit( scFileName, scText )
RETURN
PROCEDURE SaveFileAs() // save file with new name
LOCAL cFileName := GetFileName()
IF ! Empty( cFileName )
scFileName := cFilename
MemoWrit( scFileName, scText )
ENDIF
RETURN
FUNCTION GetFileName() // request file name
LOCAL cScreen := SaveScreen(), cFileName := Space(12)
@ 0,0 SAY "Enter file name:" GET cFileName
READ
RestScreen(,,,,cScreen)
RETURN cFileName
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.