Expanded Lists
Volume Number: 9
Issue Number: 8
Column Tag: C Workshop
Related Info: List Manager
Expanding the List Manager
Adding graphics to lists with Custom LDEFs
By Mark W. Batten, Washington, DC
Note: Source code files accompanying article are located on MacTech CD-ROM or
source code disks.
The List Manager is not e specially well-named. The term “list” suggests one
column of text, as in a shopping list or an address list. In fact, the List Manager is
much more flexible: it can maintain information in rows and columns, as in a
spreadsheet, and can manage data of any kind, including graphics.
The purpose of this article is to demonstrate two simple list definition
procedures, or LDEFs, that extend the List Manager’s text-only list to include
graphics. First, we’ll create a list of icons with text underneath, sort of like those
that appear in Finder windows. Second, we’ll develop a list that puts a small icon next
to each entry, the way the standard Open and Save dialog boxes do.
Setting up the application for our LDEFs
When using a custom LDEF, the List Manager leaves the drawing of each cell --
and the interpretation of the data in the cell -- entirely up to you. So to create a list
that has both text and graphics in a list, all you have to do is put the graphics data and
text in each cell. The LDEF will then interpret the data when it draws the cell. In our
example, we just have the application stuff the icon data into the cell, followed by the
text (a Pascal string), using List Manager routines:
/* 1 */
LSetCell(IconPtr,128,theCell,LH);
LAddToCell(IconName,(int)IconName[0]+1,theCell,LH);
Example 1: The Icon List
The List Manager sends four different kinds of messages to LDEFs: “initialize,”
“draw,” “highlight,” and “close.” The initialize and close routines are rarely needed
unless your LDEF needs to allocate its own memory for storage; we’ll focus here on the
draw and highlight routines to show how they interpret the icon and text data.
Our first example is a list of icons with text underneath. Such a list has lots of
uses: showing the user the files in an individual directory, or in an archive file; asking
the user to choose from among a list of options; or any time you want to present a list
of items in a graphically appealing way. Let’s examine the DoDraw routine in detail.
/* 2 */
doDraw(select,r,offset,LH)
Boolean select;
Rect *r;
int offset;
ListHandle LH;
{
The List Manager sends an LDrawMsg for each cell in the list, so the DoDraw
routine’s task is to draw one cell. The cell to draw is passed to the LDEF in two
parameters: the Rect r is the rectangle in which to draw the cell, and offset holds the
offset into the list’s cell data where the information for this cell begins.
The routine begins with a number of cosmetic effects: it fills the cell with a gray
pattern, and then draws a border around the icon. These obviously aren’t essential,
but are included here because they help the icon stand out against the background and to
give it a three-dimensional appearance:
/* 3 */
FillRect(r,grey);
r->top+=(r->bottom-r->top-32)/2;
r.left+=(r->right-r->left-32)/2;
r->bottom=r->top+32;
r->right=r->left+32;
InsetRect(r,-4,-4);
r1=*r;
FillRect(r,wite);
FrameRect(r);
InsetRect(r,3,3);
FrameRect(r);
InsetRect(r,1,1);
PenPat(dark);
for(i=1;i<3;i++){
MoveTo(r->left-(i+1),r->bottom+i);
LineTo(r->right+i,r->bottom+i);
MoveTo(r->right+i,r->top-(i+1));
LineTo(r->right+i,r->bottom+i);
}
PenNormal();
Now we draw the icon. To do so, we have to set up a BitMap that we can pass to
CopyBits. Because each cell begins with icon data (which the application put there,
remember?), the BitMap’s baseAddr should point to the beginning of the cell’s data.
The other BitMap fields are easy, since they’re determined by the size of an icon:
/* 4 */
HLock((**LH).cells);
icon.baseAddr=(char *)(*(**LH).cells)+offset;
SetRect(&icon.bounds,0,0,32,32);
icon.rowBytes=4;