Documentation Archive Developer
Search

ADC Home > Reference Library > Technical Notes > Legacy Documents > Mac OS 9 & Earlier >

Legacy Documentclose button

Important: This document is part of the Legacy section of the ADC Reference Library. This information should not be used for new development.

Current information on this Reference Library topic can be found here:

List Manager Q&As

CONTENTS

This Technical Note contains a collection of archived Q&As relating to a specific topic--questions sent the Developer Support Center (DSC) along with answers from the DSC engineers. Current Q&A's can be found on the Macintosh Technical Q&A's web site.

[Oct 01 1990]






Avoid Macintosh List Manager for manipulating large matrices

Avoid using the Macintosh List Manager for manipulating large matrices like spreadsheet cells.

The Macintosh List Manager becomes ungainly when handling more than about 500 cells. With several thousand cells, such as a 100x100 matrix, it becomes downright klunky.

Using standard techniques, the List Manager can store only 32K of data in a list. For 10,000 cells, this gives you only about 3.2 characters in a cell. It's possible to switch to a system where each cell contains a pointer to text to be drawn, but with only 3.2 characters, it's not possible to store a full pointer (4 bytes). After about 500 cells, the time needed to actually set the data in the cells becomes noticeable, on the order of 10 to 15 seconds.

Finally, the List Manager has some pretty fundamental restrictions. You cannot, for instance, create variable-width rows or columns, or hide a single row or column from a list.

For manipulating large matrices, you're much better off bypassing the List Manager entirely and writing your own spreadsheet-type mechanism. Consider caching the cells to a temporary file, depending on your memory requirements. You'll need to use the Control Manager to set up and process scroll bars, and you should use QuickDraw to draw the contents of the cells.

Basically, writing a spreadsheet shares many of the same necessary functions and problems as writing a text editor (replacing TextEdit). Neither one is simple, but both are possible.

Back to top

Creating Macintosh columns with various widths

Date Written: 2/8/91

Last reviewed: 6/14/93

How can I create a Macintosh List Manager list with different size cells for some columns and different size cells for other columns?

The List Manager doesn't allow variable-sized cells. One cell size fits all, or not! The List Manager was designed for simple lists (such the standard get file dialog), but not for spreadsheets. The source of the limitation is found in the ListRec as documented in Inside Macintosh Volume IV. The cellSize is a single variable (a Point). If multiple column widths were allowed, some sort of array would be required to store the width for each column, and you can see from looking at the ListRec data structure that no provision was made for this.

You can write your own List definition procedure, which can display alternative data types (PICTS, ICONS, or perhaps some data type of your own devising), but these are still limited to one cell size for the entire list. If you wish to have columns with various widths, you will need to treat each column as a separate list, or handle the lists entirely yourself as spreadsheet and database applications do.

Back to top

Code for putting a list in a modal dialog box

Date Written: 1/23/92

Last reviewed: 6/14/93

How do I put a list in a Macintosh modal dialog box?

The sample code below puts a list in a modal dialog. There are several points to note to ensure success: You need to pass a draw procedure to the modal dialog for your list item. It's important to test for mousedown events in your modal dialog filter, because the List Manager doesn't check to see if you're kidding when you tell it you have a mousedown (that's what calling lClick does...). Also, calling Setport on your dialog in your filter procedure is not done for you automatically and is important when using GlobalToLocal.

The sample also tests lGetSelect to see that it works OK on these lists (it does). The dialog in question simply needs two items in its ditl, a button as item 1 and a user item as item 2. This should work for any sized user item.

pascal listDraw(WindowPtr theWindow, short itemNo)
{
    short       aItemType;
    Handle      aControl;
    Rect        aRect;
    Rect        dBounds;
    Point       aPoint;

    GetDItem((DialogPtr)theWindow,itemNo,&aItemType,&aControl,&aRect);

    PenNormal();
    InsetRect(&aRect,-1,-1);
    FrameRect(&aRect);
    LUpdate(theWindow->visRgn,(ListHandle)GetWRefCon(theWindow));
}

pascal Boolean MyFilter( DialogPtr theDialog, EventRecord *theEvent,
                         short *itemHit)
{
    short       aItemType;
    Handle      aControl;
    Rect        aRect;
    Rect        dBounds;
    Point       aPoint;

    SetPort(theDialog);
    GetDItem(theDialog,2,&aItemType,&aControl,&aRect);
    aPoint = theEvent->where;
    GlobalToLocal(&aPoint);
    if (PtInRect(aPoint,&aRect))
      if (theEvent->what==mouseDown) {
          *itemHit = 2;
        LClick(aPoint,theEvent->modifiers,
               (ListHandle)GetWRefCon((WindowPtr)theDialog));
        return true;
    };
    return false ;
}

void DialogFiddle()
{
    DialogPtr   aDLog;
    short       aItemType;
    Handle      aControl;
    Rect        aRect;
    Rect        dBounds;
    Point       aPoint;
    ListHandle  myList;
    Str255      dummy = ""Unselected Item"";
    Str255      wally = ""I am Selected!"";

    aDLog = GetNewDialog(987,(Ptr) 0, (WindowPtr) -1);
    GetDItem(aDLog,2,&aItemType,&aControl,&aRect);
    SetDItem(aDLog,2,aItemType,(Handle)&listDraw,&aRect);
    aRect.right -= 16;
    dBounds.top = 0;
    dBounds.bottom = 0;
    dBounds.left = 0;
    dBounds.right = 1;
    aPoint.h = 0;
    aPoint.v = 0;
    myList = LNew(&aRect,&dBounds,aPoint,0,(WindowPtr)aDLog,
                  true,false,false,true);
    aItemType = LAddRow(5,0,myList);
    LSetCell(&dummy,15,aPoint,myList);
    aPoint.v+=1;
    LSetCell(&dummy,15,aPoint,myList);
    aPoint.v+=1;
    LSetCell(&dummy,15,aPoint,myList);
    aPoint.v+=1;
    LSetCell(&dummy,15,aPoint,myList);
    aPoint.v+=1;
    LSetCell(&dummy,15,aPoint,myList);
    (**myList).selFlags = -128;
    SetWRefCon((WindowPtr)aDLog,(long)myList);
    do {
        aPoint.h = 0;
        aPoint.v = 0;
        ModalDialog(&MyFilter,&aItemType);
        if (aItemType=2)
          if (LGetSelect(true,&aPoint,myList))
            LSetCell(&wally,14,aPoint,myList);
    } while (aItemType==2);
    DisposDialog(aDLog);

Back to top

Downloadables

Acrobat gif

Acrobat version of this Note (44K).

Download