[comp.sys.mac.programmer] One-Dimensional List Library

sec@berlin.acss.umn.edu (Stephen E. Collins) (01/19/89)

Since comp.mac.sources seems to be a dead newsgroup, I'm posting it here.

<-------------------------Cut here---------------------------->

Simplified One Dimensional List Routines
January 15, 1989
PUBLIC DOMAIN

Written by:  Stephen E. Collins
             ACSS Microcomputer & Workstation Systems Group
             University of Minnesota
             Minneapolis, MN  55455
             
             sec@ux.acss.umn.edu
             sec@umnacvx.BITNET
             
             
             
             
This library consists of four routines.
  CreateList:     Create a one dimensional list in a window.
  ListUpdate:     Redraw the list.
  ListClick:      Handle mouse events in the list rectangle
  ListSelection:  Determine which cell was selected by the user.
  

procedure CreateList(var List:Listhandle; DP:DialogPtr; var R:Rect; 
                   var S; Size: integer);
                   
Call this routine to create and draw a list in a window or dialog.
                   
List:   Handle to the list structure which is created.  This should be
        NIL or unset.  CreateList will allocate and return a ListHandle
        in this variable.
        
DP:     DialogPtr or WindowPtr; the pointer to the window or dialog in
        which the list is to be drawn.
        
R:      Rectangle into which the list is to be drawn.  The entire list,
        including the border and scroll bar will be within this rectangle.
        R.bottom will be adjusted and returned so as to avoid truncating
        the last visible cell in the list.
        
S:      Array of Str255 strings, each containing the string for one cell.

Size:   The number of strings to use from S.  That is, the number of cells
        in this list.
        
        
        
procedure ListUpdate(List:ListHandle);
        
Call this routine any time the list needs to be updated; typically in the
UpdateEvent procedure for the window that contains the list.  Pass the
ListHandle returned by CreateList.

List:   ListHandle returned by CreateList.




procedure ListClick(List:ListHandle; P: Point);

Call this routine any time a mouse click event is detected in the list rectangle
(argument R for CreateList).  

List:   ListHandle returned by CreateList.

P:      Coordinates of the mouse click.



procedure ListSelection(List:ListHandle; var W:integer);

Call this routine when you wish to determine which cell was selected;
normally immediately after calling ListClick.

List:   ListHandle returned by CreateList.

W:      Cell that is selected.  0 means nothing is selected.


+---------------------------------+---------------------------------+
Sample routine that handles a list in a modal dialog.
   
   
procedure DoDialog;

var
  theDialog : DialogPtr;    { Modal Dialog }
  Choice    : integer;      { item chosen in modal dialog }
  DList     : ListHandle;   { Handle to List Manager Structure }
  MousePt   : Point;        { ListClick needs mouse point }
  W         : integer;      { Which list item was chosen? }
  S         : Str255;       { Debug String }
  Box       : Rect;         { Rect of list item in dialog window }
  ItemType  : integer;      { GetDItem wants this, I don't }
  Item      : Handle;       { GetDItem wants this, I don't }
  SS        : array [1..10] of Str255;
  
begin  { DoDialog }

  theDialog := GetNewDialog(906, NIL, Pointer(-1));
  SetPort(theDialog);
  
  { Set up the list strings }
  SS[1] := 'First';
  SS[2] := 'Second';
  SS[3] := 'Third';
  SS[4] := 'Fourth';
  SS[5] := 'Fifth';
  SS[6] := 'Sixth';
  SS[7] := 'Seventh';
  SS[8] := 'Eighth';
  SS[9] := 'Ninth';
  SS[10] := 'Tenth';
  
  { Get the rectangle to contain the list; it is returned in BOX }
  GetDItem(theDialog, 3, ItemType, Item, Box);
  
  { Create and draw the list, use all ten strings }
  CreateList(DList, theDialog, Box, SS, 10);
  
  { Handle modal dialog until OK button is hit }
  repeat
    ModalDialog(Nil, Choice);
    
    case Choice of
      1 : ;
      2 : SysBeep(5);
      3 : begin
            GetMouse(MousePt);
            ListClick(DList, MousePt);
          end;
    end;
  until (Choice = 1);
  
  { Determine which list item is selected }
  ListSelection(DList, W);
  if (W > 0) then
  begin
    S := 'Picked ';
    DebugMessage(S, W);
  end;
  
  { Please do not litter }
  DisposDialog(theDialog);
  DisposHandle(Handle(DList));
  
end;  { of DoDialog }

****
*
****

type DLOG
,906
List Dialog
99 100 249 400 
Visible NoGoAway
1
0
906


type DITL
,906
3
BtnItem Enabled
33 182 65 262 
OK

BtnItem Enabled
83 185 115 265 
Beep

UserItem Enabled
33 26 119 129 
Nothing in here

****
*
****

+---------------------------------+---------------------------------+
Sample routine that handles a list in a window.


Global var
   theWindow: WindowPtr;
   theList  : ListHandle;
   
procedure MakeList;

var
  R         : Rect;     { Rectangle in which to draw the list }
  SS        : array [1..10] of Str255;

begin  { MakeList }

  { Use Monaco 9pt for this list, just for fun }
  SetPort(theWindow);
  TextFont(3);
  TextSize(9);
  
  { Set up list string array }
  SS[1] := 'First';
  SS[2] := 'Second';
  SS[3] := 'Third';
  SS[4] := 'Fourth';
  SS[5] := 'Fifth';
  SS[6] := 'Sixth';
  SS[7] := 'Seventh';
  SS[8] := 'Eighth';
  SS[9] := 'Ninth';
  SS[10] := 'Tenth';
  
  { Set up rect for the list }
  SetRect(R, 20, 20, 130, 100);
  
  { Create and draw the list; only use the first 7 strings }
  CreateList(theList, theWindow, R, SS, 7);
  
end;  { of MakeList }


procedure UserClicked;

var
  W         : integer;      { Which list cell was picked? }
  MousePt   : Point;        { Mouse click point }
  S         : Str255;

begin  { UserClicked }

  { Get the mouse click and ListClick will handle it }
  GetMouse(MousePt);
  ListClick(theList, MousePt);
  
  { Figure out which item in the list was selected }
  ListSelection(theList, W);
  if (W > 0) then
  begin
    S := 'Picked ';
    DebugMessage(S, W);
  end;
  
end;  { of UserClicked }


+---------------------------------+---------------------------------+

The following routines may be compliled directly to a Turbo Pascal Unit,
if desired.  Otherwise, include the routines themselves in your program.
Be sure to remove the comments around the procedure parameters if you
use the routines in this fashion.

+---------------------------------+---------------------------------+


Unit ListLib(906);

{ Written by:  Stephen E. Collins
               ACSS Microcomputer & Workstation Systems Group
               University of Minnesota
               Minneapolis, MN  55455
             
               sec@ux.acss.umn.edu
               sec@umnacvx.BITNET   }

{$U-}

INTERFACE


uses 
  MemTypes, Quickdraw, OSintf, ToolIntf, PackIntf;
  
procedure CreateList(var List:Listhandle; DP:DialogPtr; var R:Rect; 
                   var S; Size: integer);
procedure ListUpdate(List:ListHandle);
procedure ListClick(List:ListHandle; P: Point);
procedure ListSelection(List:ListHandle; var W:integer);

IMPLEMENTATION

procedure ListUpdate{(List:ListHandle)};

var
  LUpdateRgn    : RgnHandle;
  R             : Rect;
  OldPort       : GrafPtr;

begin  { ListUpdate }
  GetPort(OldPort);
  SetPort(List^^.Port);
  
  { Convince ListMgr to Redraw the list for us }
  R := List^^.rView;
  LDoDraw(true, List);
  LUpdateRgn := NewRgn;
  RectRgn(LUpdateRgn, R);
  LUpdate(LUpdateRgn, List);
  
  { Redraw the border }
  InsetRect(R, -1, -1);
  FrameRect(R);
  
  { Clean up the mess we've made }
  DisposeRgn(LUpdateRgn);
  SetPort(OldPort);
end;  { of ListUpdate }

procedure CreateList{(var List:Listhandle; DP:DialogPtr; var R:Rect; 
                   var S; Size: integer)};
                   
type
  Lines = array [1..127] of Str255;

var
  OldPort   : GrafPtr;
  i         : integer;
  Bounds    : Rect;         { Dimensions of list (cell count) }
  P         : Point;        { Width and Height of each cell }
  T         : Str255;       { Temporary string for setting cell values }
  Box       : Rect;         { Rect of cells only }
  F         : integer;      { Fudge Factor }
  WP        : WindowPtr;    { Window pointer to dialog or window to contain list }

begin  { CreateList }
  WP := WindowPtr(DP);
  GetPort(OldPort);
  SetPort(WP);
  
  { Set Box to exclude border and scroll bar }
  Box := R;
  InsetRect(Box, 1, 1);
  Box.Right := Box.Right - 15;
  
  { Set P.v to height of each cell, P.h to width of each cell }
  P.v := WP^.txSize + 3;
  if (P.v = 3) then  { Assume 12pt Chicago if unset }
  begin
    TextSize(12);
    P.v := 15;
  end;
  
  P.h := Box.Right - Box.Left;
  
  { Adjust Box and R to avoid truncating last visible cell }
  F := (Box.Bottom - Box.Top) DIV P.v;
  Box.Bottom := Box.Top + F*P.v;
  R.Bottom := R.Top + F*P.v + 1;
  
  { Create the Naked List handle }
  SetRect(Bounds, 0,0, 1,Size);
  List := LNew(Box, Bounds, P, 0, WP, FALSE, FALSE, FALSE, TRUE);
  
  { Set the strings into each List cell }
  P.h := 0;
  for i := 1 to Size do
  begin
    P.v := i-1;
    T := Lines(S)[i];
	   LSetCell(Pointer(Ord(@T)+1), Length(T), P, List);
  end;
  
  { Make sure it is drawn in the window }
  ListUpdate(List);
  
  { Don't leave any litter behind }
  SetPort(OldPort);
end;  { of CreateList }


procedure ListClick{(List:ListHandle; P: Point)};

var
  b         : boolean;
  OldPort   : GrafPtr;

begin  { ListClick }
  GetPort(OldPort);
  SetPort(List^^.Port);
  
  { Let ListMgr handle the mouse for us }
  b := LClick(P, 0, List);
  ListUpdate(List);
  
  SetPort(OldPort);
end;  { of ListClick }


procedure ListSelection{(List:ListHandle; var W:integer)};

var
  Pt : Point;

begin { ListSelection }
  SetPt(Pt, 0, 0);
  if LGetSelect(TRUE, Pt, List) then
    W := Pt.V + 1       { cell number that was selected }
  else
    W := 0;             { nothing is selected }
end;  { of ListSelection }   

END.

<-------------------------The End---------------------->

bytebug@dhw68k.cts.com (Roger L. Long) (01/28/89)

In article <284@berlin.acss.umn.edu> Stephen E. Collins writes:
>Since comp.mac.sources seems to be a dead newsgroup, I'm posting it here.

comp.sources.mac seems to be a dead newsgroup because:

	a) few people post source
	b) those few people who do post source usually post StuffIt archives
	   to comp.binaries.mac, which include binary things like Makefiles
	   (MPW) or Projects (LSC) or Resources.  Posting StuffIt archives
	   also:
		   i) is easier for people to download
		   ii) uses less net bandwidth
-- 
	Roger L. Long
	dhw68k!bytebug