ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

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.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]