Important: The information in this document is obsolete and should not be used for new development.
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 theLSetSelect
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 theLGetSelect
function indicates thatLGetSelect
should search the list (beginning with the cell specified in the second parameter) for the first selected cell. If you passTRUE
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 returnsFALSE
if no cells including or after the cell specified by the second parameter are selected. If you passFALSE
as the first parameter toLGetSelect
, then the function returnsTRUE
only if the cell specified in the second parameter is selected. TheMyGetFirstSelectedCell
function defined in Listing 4-7 thus returnsTRUE
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;TheMyGetLastSelectedCell
procedure goes from one selected cell to the next until there are no more selected cells. It calls theLNextCell
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, sinceLGetSelect
would repeatedly returnTRUE
for the first selected cell. The first two parameters toLNextCell
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 toTRUE
, the next cell regardless of location.Your application can use the
LSetSelect
procedure to set or deselect a cell by passingTRUE
orFALSE
, respectively, as the first parameter to the routine. Listing 4-9 illustrates a useful procedure that usesLSetSelect
andLGetSelect
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;TheMySelectOneCell
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 callMySelectOneCell
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 theLScroll
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 theLScroll
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;TheMyMakeCellVisible
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 totheList^^.visible.right - 1
, and the last visible row istheList^^.visible.bottom - 1
.