Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: More Macintosh Toolbox /
Chapter 4 - List Manager / Using the List Manager


Working With List Selections

The List Manager provides routines that make it easy to determine what the selection
is or to change the selection, whether your list allows just one item to be selected at a time or allows many items to be selected. The List Manager also provides a routine that allows you to automatically scroll the first selected cell to the upper-left corner of the list's visible rectangle. In addition, you can write your own routine to scroll a list just enough so that a particular cell is visible.

Your application can use the LGetSelect function to determine whether a given cell is selected or to find the next selected cell. Your application can use the LSetSelect procedure to select or deselect a given cell.

Listing 4-7 shows an application-defined procedure that finds the first cell in a selection.

Listing 4-7 Finding the first selected cell in a list

FUNCTION MyGetFirstSelectedCell (theList: ListHandle;
                                 VAR theCell: Cell): Boolean;
BEGIN
   SetPt(theCell, 0, 0);
   MyGetFirstSelectedCell := LGetSelect(TRUE, theCell, theList);
END;
The first parameter (TRUE) passed to the LGetSelect function indicates that LGetSelect should search the list (beginning with the cell specified in the second parameter) for the first selected cell. If you pass TRUE as the first parameter, LGetSelect sets the cell specified in the second parameter to the coordinates of the first selected cell that it finds, or it returns FALSE if no cells including or after the cell specified by the second parameter are selected. If you pass FALSE as the first parameter to LGetSelect, then the function returns TRUE only if the cell specified in the second parameter is selected. The MyGetFirstSelectedCell function defined in Listing 4-7 thus returns TRUE only if at least one cell is selected, in which case the second parameter to the function is set to the coordinates of that cell.

Finding the last selected cell in a list is slightly more complex. Listing 4-8 illustrates how this might be done.

Listing 4-8 Finding the last selected cell in a list

PROCEDURE MyGetLastSelectedCell (theList: ListHandle;
                                 VAR theCell: Cell);
VAR
   aCell:            Cell;
   moreCellsInList:  Boolean;
BEGIN
   IF MyGetFirstSelectedCell(theList, aCell) THEN
   REPEAT
      theCell := aCell;
      moreCellsInList := LNextCell(TRUE, TRUE, aCell, theList);
   UNTIL NOT LGetSelect(TRUE, aCell, theList);
END;
The MyGetLastSelectedCell procedure goes from one selected cell to the next until there are no more selected cells. It calls the LNextCell function to move from one cell to the next cell in the list. If it did not do this, then the procedure would loop infinitely, since LGetSelect would repeatedly return TRUE for the first selected cell. The first two parameters to LNextCell indicate whether the function should return the next cell in the current row, the next cell in the current column, or, if both are set to TRUE, the next cell regardless of location.

Your application can use the LSetSelect procedure to set or deselect a cell by passing TRUE or FALSE, respectively, as the first parameter to the routine. Listing 4-9 illustrates a useful procedure that uses LSetSelect and LGetSelect to select a single cell in a list while deselecting all other cells.

Listing 4-9 Selecting a cell and deselecting other cells

PROCEDURE MySelectOneCell (theList: ListHandle; theCell: Cell);
VAR
   nextSelectedCell:    Cell;
   moreCellsInList:     Boolean;
BEGIN
   IF MyGetFirstSelectedCell(theList, nextSelectedCell) THEN
   WHILE LGetSelect(TRUE, nextSelectedCell, theList) DO
   BEGIN                   {move to next selected cell...}
      IF (nextSelectedCell.h <> theCell.h) OR
            (nextSelectedCell.v <> theCell.v) THEN
                           {...and remove cell from selection}
         LSetSelect(FALSE, nextSelectedCell, theList)
      ELSE
         moreCellsInList := 
                           {move to next cell}
            LNextCell(TRUE, TRUE, nextSelectedCell, theList);
   END;
   LSetSelect(TRUE, theCell, theList);
END;
The MySelectOneCell procedure defined in Listing 4-9 deselects each selected cell, except that if it encounters the cell that is ultimately to be selected, then it does not deselect that cell. This prevents an annoying flickering that would otherwise occur if you were to call MySelectOneCell to select a cell already selected.

The List Manager provides the LAutoScroll procedure to enable your application to scroll the first selected cell to the upper-left corner of the list's visible rectangle--for example:

LAutoScroll(myList);
Sometimes, you might want your application to scroll a list just enough so that a certain cell (such as a cell the user has just selected using the keyboard) is visible. For example, this is how the Standard File Package responds if the user presses the Down Arrow key when the currently selected item is on the bottom of the list's visible rectangle. You can mimic this effect by calling the LScroll procedure, which requires that your application indicate how many columns and rows to scroll. Negative numbers indicate scrolling up or to the left. Positive numbers indicate scrolling down or to the right. Listing 4-10 illustrates the use of the LScroll procedure.

Listing 4-10 Scrolling so that a particular cell is visible

PROCEDURE MyMakeCellVisible (theList: ListHandle; theCell: Cell);
VAR
   visibleRect:      Rect;    {rectangle enclosing visible cells}
   dCols, dRows:     Integer; {number of rows to scroll}
BEGIN
   visibleRect := theList^^.visible;
   IF NOT PtInRect(theCell, visibleRect) THEN
   BEGIN                      {cell is not already visible}
      WITH theCell, visibleRect DO
      BEGIN
         IF h > right - 1 THEN
            dCols := h - right + 1     {move to left}
         ELSE IF h < left THEN
            dCols := h - left;         {move to right}
         IF v > bottom - 1 THEN
            dRows := v - bottom + 1    {move up}
         ELSE IF v < top THEN
            dRows := v - top;          {move down}
      END;
      LScroll(dCols, dRows, theList);
   END;
END;
The MyMakeCellVisible procedure defined in Listing 4-10 simply computes the number of cells between the last visible row and column and the selected cell. Note that the last visible column for a list is equal to theList^^.visible.right - 1, and the last visible row is theList^^.visible.bottom - 1.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
6 JUL 1996