|
|
|
|
||
|
DEFINITION MODULE Selector; (******************************************************************* Module Selector (Version 1.0) Copyright (c) 1995-2006 by Andreas Fischlin and ETH Zurich. Purpose Modal dialog to select items from a scrollable list of items. Remarks -- Programming o Design Andreas Fischlin 28/10/1995 o Implementation Andreas Fischlin 28/10/1995 ETH Zurich Systems Ecology CHN E 35.1 Universitaetstrasse 16 8092 Zurich SWITZERLAND URLs: <mailto:RAMSES@env.ethz.ch> <http://www.sysecol.ethz.ch> <http://www.sysecol.ethz.ch/SimSoftware/RAMSES> Last revision of definition: 19/06/1998 AF *******************************************************************) FROM SYSTEM IMPORT ADDRESS; FROM Lists IMPORT SelectionMode; (*******************************) (*##### Selector Type #####*) (*******************************) TYPE Item = ADDRESS; FirstItemProc = PROCEDURE (): Item; NextItemProc = PROCEDURE (Item): Item; ItemExistsProc = PROCEDURE (Item): BOOLEAN; GetItemIdentProc = PROCEDURE (Item, VAR ARRAY OF CHAR); MarkItemProc = PROCEDURE (Item, BOOLEAN); SelectorSetup = RECORD selectorTitle, checkBoxText: ARRAY [0..127] OF CHAR; firstItem: FirstItemProc; nextItem: NextItemProc; itemExists: ItemExistsProc; getItemIdent: GetItemIdentProc; markItem: MarkItemProc; selMode: SelectionMode; END(*RECORD*); (**********************************************) (*##### Explanations and Sample Code #####*) (**********************************************) (*==================================================================== For your convenience a typical setup might look as follows: TYPE MyItem = POINTER TO ItemDescr; ItemDescr = RECORD next: MyItem; ident: ARRAY [0..63] OF CHAR; mark: BOOLEAN; (*. ... your other fields .*) END(*RECORD*); VAR myRoot: MyItem; PROCEDURE MyFirstItem (): Item; BEGIN RETURN myRoot END MyFirstItem; PROCEDURE MyNextItem (i: Item): Item; VAR myi: MyItem; BEGIN myi := i; RETURN myi^.next END MyNextItem; PROCEDURE MyItemExists (i: Item): BOOLEAN; BEGIN RETURN i<>NIL END MyItemExists; PROCEDURE MyGetItemIdent (i: Item; VAR ident: ARRAY OF CHAR); VAR myi: MyItem; BEGIN myi := i; AssignString(myi^.ident, ident); END MyGetItemIdent; PROCEDURE MyMarkItem (i: Item; mark: BOOLEAN); VAR myi: MyItem; BEGIN myi := i; myi^.mark := mark; END MyMarkItem; Note, above routines all assume as a warranted precondition the existence or otherwise proper value settings of the actual item arguments of type ItemPtr at all times. These preconditions are warranted as long as you don't change the list of items while executing the selector and that you don't use above procedures for anything else than the selector. This is because the selector can't pass you non-existing items. However, if you use above procedures also for other purposes, e.g. MyItemExists, you ought to write them more sophisticated, e.g. such as testing for the existence of the item at the beginning of the routine etc. And to actually ask the user for making a selection use a procedure similar to the following: PROCEDURE AskUserToSelect; VAR setup: SelectorSetup; myChkBox,ok: BOOLEAN; BEGIN (* AskUserToSelect *) WITH setup DO selectorTitle := "Selector"; checkBoxText := "Checking"; firstItem := MyFirstItem; nextItem := MyNextItem; itemExists := MyItemExists; getItemIdent := MyGetItemIdent; markItem := MyMarkItem; selMode := multipleDisconnected; END(*WITH*); ExecuteSelector(setup,myChkBox,ok); IF ok THEN (*. ... e.g. call OperateOnSelected (see below) .*) END(*IF*); END AskUserToSelect; Finally, to learn about the selection the user made and to perform some operation with these operands use a procedure similar to this one: PROCEDURE OperateOnSelected; VAR myi: MyItem; BEGIN (* OperateOnSelected *) myi:= myRoot; WHILE (myi<>NIL) DO IF (myi^.mark) THEN (*. ... do whatever is appropriate if it was selected .*) END(*IF*); myi := myi^.next; END(*WHILE*); END OperateOnSelected; ====================================================================*) (**********************************) (*##### Selector Dialogs #####*) (**********************************) PROCEDURE ExecuteSelector (ssu: SelectorSetup; VAR checkBoxVar, okButtonPressed: BOOLEAN ); (* Displays a modal dialog window which allows the user to select any items (including multiple selection) from a list of items as defined by the routines specified in ssu. Upon returning from this routine, find the selected items by searching in your list for marked items if okButtonPressed. Note that ExecuteSelector always clears first all marks. checkBoxVar use is optional (i.e. will only be displayed if ssu.checkBoxText is not the empty string). *) (**************************************) (*##### Easy-to-use Selector #####*) (**************************************) PROCEDURE ChooseFromList (selectorTitle: ARRAY OF CHAR; VAR(*speed-up*) strList: ARRAY OF CHAR; VAR selection: ARRAY OF CHAR; delim: CHAR; selMode: SelectionMode); (* Easy selection routine based on ExecuteSelector. It features the selector with the title 'selectorTitle' and lets you select according to mode 'selMode' any of the items you pass as actual argument in 'strList'. It then returns the result of the selection in 'selection'. Items are expected to be separated by the delimiter 'delim', typically '|'; this of course also true for the result in 'selection' in case 'selMode' is either 'multipleAdjacent' or 'multipleDisconnected'. It setups internally a list as described above and nothing else than just a call to this routine is required to make a selection. Ex.: title = "Please select one goddess:"; listOfGods := "Isis|Diana|Athena"; ChooseFromList(title,listOfGods,selection,"|",single); returns in selection "Isis" if the user selected it. If the user cancelled the dialog or refused to choose a goddess, the empty string is returned in 'selection'. If 'selMode' = multipleDisconnected, ChooseFromList may return in 'selection' "Isis|Athena" if the user selected the first and the last goddesses. *) END Selector.
|
||
|
|
|