home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-01-07 | 52.6 KB | 1,429 lines | [TEXT/MPS ] |
- /*
-
- Sample Source Code by Jack A. Littleton
-
- Example List Manager Application--TextList
- -------------------------------------------
-
- TextList.c -- C source code for CTextList
- This file and all files in this package are copyright © 1989 by
- Jack A. Littleton, All rights reserved.
- Version 1.0 - December 3, 1989
-
- This package includes:
- TextList.c -- This file
- TextList.p -- Pascal source code
- TextList.a -- Assembly source code
- TextList.r -- Rez source code for all TextList applications
- PTextList.r -- Pascal-specific Rez source code
- CTextList.r -- C-specific Rez source code
- PTextList.make -- Makefile for Pascal TextList application
- CTextList.make -- Makefile for C TextList application
- ATextList.make -- Makefile for Assembly TextList application
-
- NumList.p -- Pascal source code for NumList application
- NumLDEF.p -- Pascal source code for NumList List Definition proc
- NumList.c -- C source code
- NumLDEF.c -- C source code for List Definition procedure
- NumList.a -- Assembly source code
- NumLDEF.a -- Assembly source code for List Definition proc
- NumList.r -- Rez source code for all TextList applications
- PNumList.make -- Makefile for Pascal NumList application
- CNumList.make -- Makefile for C NumList application
- ANumList.make -- Makefile for Assembly NumList application
-
- SampleList.txt -- Documentation for this package
-
- ABOUT TextList.c:
- This is the C source code for PTextList, a C implementation of an
- application that uses the List Manager. This implementation uses the only
- List Definition (LDEF) that is supplied with the system (LDEF #0), which
- can handle only text in the cells.
-
- The application handles multiple windows with a single list in each window.
- The list has both vertical and horizontal scroll bars. The cell size, font,
- font size, and number of cells per row can be set by the user. A "List"
- menu allows you to set flags that affect how the list reacts to mouse
- clicks (the selFlags field in the ListHandle). The items that are set in
- the List menu do not take affect until you create a new list. When a new
- window is created, the application looks at which items in the List menu
- have been selected, and creates the list with those characteristics. Note
- that changes in the List menu do not affect previously created lists. This
- means that you can have several different lists open with different
- characteristics, allowing you to see the differences.
-
- The "Edit" menus allows cut/paste, but not through normal scrap techniques.
- Cells can be cut/pasted from one window to another, but not from CTextList
- to another application. This was implemented to show how to get, set and
- clear data from a cell.
-
- Find is supported in the "File" menu. This uses the LSearch procedure to
- find a match in the list.
-
- The windows and list support growing and zooming.
-
- Other important notes on implementation are given in the documentation for
- the appropriate routine.
-
- A NOTE: This is just an example of a program that uses the List Manager. It
- is not meant to be a full-blown application, and may not be suitable as
- a template for a new application. It is just meant to show as many List
- Manager routines as possible. In fact, this program was written as
- research for a programming tutorial and was never planned as a application.
-
- BUGS AND OTHER INSECTS:
- Window title -- The window title in the DoNew() procedure acts really wierd.
- The way the window is supposed to work is the word "Untitled", followed by
- a dash, then the window number. In the C version, however, several garbage
- characters are inserted between the dash and the window number. I have
- spent several days trying to fix this problem to no avail. This kind of
- problem with strings is one reason why I really dislike C.
-
- Crash after quitting -- Here's another one for the "Believe it or not" file.
- When the font is changed to a font that is not supplied with the Apple
- System disk (i.e. not Chicago, Geneva, New York, Times, Courier, etc.), the
- program will crash when a menu item is selected after quitting, but only
- while still in the MPW Shell, and while there were windows (lists) open.
- In other words, this only happens when the program CTextList is launched
- from within the MPW Shell.
- */
-
- #include <Types.h> /* Mac type definitions */
- #include <Resources.h> /* Resource Manager headers */
- #include <QuickDraw.h> /* QuickDraw headers */
- #include <Windows.h> /* Window Manager headers */
- #include <OSUtils.h> /* OS Utilities headers */
- #include <Controls.h> /* Control Manager headers */
- #include <Desk.h> /* Desk Manager headers */
- #include <Dialogs.h> /* Dialog Manager headers */
- #include <Events.h> /* Event Manager headers */
- #include <Fonts.h> /* Font Manager (for GetFNum) */
- #include <Lists.h> /* List Manager headers */
- #include <Memory.h> /* Memory Manager headers */
- #include <Menus.h> /* Menu Manager headers */
- #include <Packages.h> /* Package Manager (for NumToString, etc.) */
- #include <SegLoad.h> /* Segment Loader Manager (for UnloadSeg) */
- #include <TextEdit.h> /* TextEdit (for TEInit) */
- #include <ToolUtils.h> /* Toolbox Utilities Manager */
- #include <Traps.h> /* Trap addresses */
-
- #include <StdIO.h>
- #include <String.h>
-
- /* MENU RESOURCE CONSTANTS */
- #define NumMenus 5 /* Number of menus */
-
- #define AppleMenu 1111 /* Resource ID of apple menu */
- #define AppleID 1 /* Index ID of apple menu */
-
- #define FileMenu 1112 /* Resource ID of File menu */
- #define FileID 2 /* Index ID of apple menu */
- #define NewItem 1 /* Item ID for "New List" */
- #define CloseItem 2 /* Item ID for "Close" */
- #define AddItem 3 /* Item ID for "New Row" */
- #define DeleteItem 4 /* Item ID for "Delete Row" */
- #define FindItem 5 /* Item ID for "Find" */
- #define Quit 6 /* Item ID for "Quit" */
-
- #define EditMenu 1113 /* Resource ID of Edit menu */
- #define EditID 3 /* Index ID of Edit menu */
- #define UndoItem 1 /* Item ID of "Undo" */
- #define CutItem 3 /* Item ID of "Cut" */
- #define CopyItem 4 /* Item ID of "Copy" */
- #define PasteItem 5 /* Item ID of "Paste" */
- #define ClearItem 6 /* Item ID of "Clear" */
- #define SClipItem 8 /* Item ID of "Show Clipboard" */
-
- #define ListMenu 1114 /* Resource ID of List Menu */
- #define ListID 4 /* Index ID of List Menu */
- #define OneSelItem 1 /* Item ID of "One Selection Only" */
- #define DragWOShItem 2 /* Item ID of "Drag w/o Shift */
- #define NoDJointItem 3 /* Item ID of "No Disjoing Select." */
- #define NoExtendItem 4 /* Item ID of "Don't Extent" */
- #define NoExpandItem 5 /* Item ID of "Don't Exp. as Rect" */
- #define UseSenseItem 6 /* Item ID of "Use Sense" */
- #define NoHliteItem 7 /* Item ID of "Don't Hilite MT cells" */
-
- #define CellMenu 1115 /* Resource ID of Cell Menu */
- #define CellID 5 /* Index ID of Cell Menu */
- #define IndentItem 1 /* Item ID of "Indentation…" */
- #define CSizeItem 2 /* Item ID of "Cell Size…" */
- #define FSizeItem 4 /* Item ID of "Font Size…" */
-
- #define FontSMenu 1 /* Resource ID of "Font" sub-menu */
-
- /* DIALOG/ALERT BOX CONSTANTS */
- #define CellDlog 128 /* Res ID of CellSize/Indentation dialog */
- #define FontSDlog 129 /* Res ID of Find dialog */
- #define FindDlog 130 /* Res ID of FontSize/Cells per Col dilaog */
- #define AboutDlog 1112 /* Res ID of About dialog */
-
- /* STRING RESOURCE CONSTANTS */
- #define theStrList 128 /* Res ID of string list */
- #define indentInd 1 /* Index ID for "Indentation" */
- #define vertInd 2 /* Index ID for "vertical" */
- #define horizInd 3 /* Index ID for "horizontal" */
- #define cSizeInd 4 /* Index ID for "Cell Size" */
-
- #define theWind 1113
-
- extern _DataInit();
-
- typedef struct {
- WindowRecord docWindow;
- ListHandle docList;
- } DocumentRecord, *DocumentPeek;
-
- Rect gDragArea; /* Area in which a window can be dragged */
- Rect gGrowArea; /* Minimum area a window can be shrunk to */
- WindowPtr gActvWindow; /* The active window */
- DocumentPeek gWindInfo; /* Information about the window */
- MenuHandle gMenuItem[NumMenus];/* An array of the application's menus */
- EventRecord gEvents; /* The event record returned by GetNextEvent */
- Boolean gFinished; /* Flag set when program is to terminate */
- Ptr gClipboard; /* Pointer to our private scrap */
- short gClipLen; /* Size of the private scrap */
- MenuHandle gFontSMenu; /* Handle to the font sub-menu */
- Str255 gFontName; /* Name of the current font */
- short gFontItem; /* Item ID of the current font */
- short gFontSize; /* Size of the current font */
- short gNumWind; /* Number of open windows */
-
- void DoNew();
-
- /*
- # Initialize -- Initialize toolbox managers, menus and global variables
- #
- # Called by -- Main
- #
- # Description -- First, the application's heap zone is expanded and a block
- # of master pointers are allocated, then the toolbox managers are
- # initialized. Then the menus are called from the resource fork
- # and inserted into the menu bar. The "Font" menu is initialized
- # next by looking for the defualt font in the font menu. If the
- # font is not found, then the applicationFont is used instead.
- # Finally, the global variables are defined, and a new window
- # is displayed.
- */
- void Initialize()
-
- {
- short i; /* for loop control variable */
- short menuID; /* Menu ID of menu being added */
- Str255 *dfltString = "\pCourier"; /* Name of default font */
- Str255 theString; /* Font name returned by GetItem */
- short numItems; /* Number of items in font menu */
- GrafPtr screenPort; /* Returned by GetWMgrPort */
- Rect screenArea; /* The screen dimensions */
-
- MaxApplZone();
- MoreMasters(); /* Get a block of master pointers */
- InitGraf(&qd.thePort); /* Initialize QuickDraw */
- InitFonts(); /* Initialize font Manager */
- InitCursor(); /* Initialize cursor (to arrow) */
- InitWindows(); /* Initialize window manager */
- InitMenus(); /* Initialize menu manager */
- TEInit(); /* Initialize TextEdit */
- InitDialogs(nil); /* Initialize Dialog Manager */
-
- FlushEvents(everyEvent,0); /* Empty the event queue */
- GetWMgrPort(screenPort); /* Get the window manager's port */
- SetPort(screenPort); /* Set up the graf port */
- screenArea = qd.screenBits.bounds; /* Get the size of the screen */
- SetRect(&gDragArea, 5, 25, /* Set the area in which a window */
- qd.screenBits.bounds.right - 5, /* can be dragged */
- qd.screenBits.bounds.bottom - 10);
- SetRect(&gGrowArea, 65, 65, /* Set the minimum size a window */
- qd.screenBits.bounds.right - 5, /* can be shrunk to */
- qd.screenBits.bounds.right - 10);
-
- menuID = 1111; /* Initialize to the first menu's res ID */
- for (i=1;i<=NumMenus;i++) /* For each menu the application owns: */
- {
- gMenuItem[i] = GetMenu(menuID++); /* Get the menu, then increment menu ID */
- InsertMenu(gMenuItem[i],0); /* Insert the menu in the menu bar */
- }
- AddResMenu(gMenuItem[AppleID],'DRVR'); /* Add DA resources to the apple menu */
- gFontSMenu = GetMenu(FontSMenu); /* Get the font sub-menu */
- AddResMenu(gFontSMenu, 'FONT'); /* Add the font resources to the font sub-menu */
- InsertMenu(gFontSMenu, -1); /* Insert the font sub-menu */
- numItems = CountMItems(gFontSMenu); /* Find how many items are in the font menu */
- for (i=1;i<=numItems;i++) /* Keep looping until default font is found */
- {
- GETITEM(gFontSMenu, i, &theString); /* Get the name of the item */
- if (EQUALSTRING(&theString, dfltString, false, false)) /* If it is the default font */
- {
- CheckItem(gFontSMenu, i, true); /* Check the item */
- gFontItem = i; /* Set the global itemID variable */
- gFontName = theString; /* Set the global font name variable */
- }
- }
- DrawMenuBar(); /* Draw the menu bar */
- gActvWindow = nil; /* There is no window open */
- gClipboard = NewPtr(256); /* Initialize space for the private scrap */
- gFontSize = 10; /* Initialize the default font size */
- gFinished = false; /* Initialize the finished flag */
- gNumWind = 0; /* Initialize the window counter */
- DoNew(); /* Open an Untitled window */
- return;
- }
-
- /*
- # DoAboutBox -- Show dialog box with program information
- #
- # Called by -- DoAppleMenu
- #
- # Description -- Displays a dialog box, usually containing a picture that
- # gives information about the program. The dialog terminates
- # after the user clicks in the dialog.
- */
- void DoAboutBox()
-
- {
- Boolean doneDialog; /* Set to true if finished with dialog */
- DialogPtr doDialog; /* The dialog pointer */
- short itemHit; /* Item returned by ModalDialog() */
- WindowPtr thisPort; /* Port active when called */
-
- doneDialog = false; /* Initialize flag */
- GetPort(&thisPort); /* Get current port */
- doDialog = GetNewDialog(AboutDlog,nil,(DialogPtr)-1); /* Get the dialog */
- SetPort(doDialog); /* Set the Dialog's port */
-
- do /* while (doneDialog != true */ /* Keep looping until finished */
- {
- ModalDialog(nil, &itemHit); /* Find which item was clicked in */
- switch (itemHit)
- {
- case 1:
- doneDialog = true; /* If the OK button was hit, the quit */
- break;
- }
- } while (doneDialog != true);
-
- DisposDialog(doDialog); /* Get rid of the dialog */
- HiliteMenu(0); /* Unhilite the apple menu */
- SetPort(thisPort); /* Restore the port */
- return;
- }
-
- /*
- # DoAppleMenu -- An item was selected from the Apple (DA) menu
- #
- # Called by -- HandleMenuSelect
- #
- # Description -- There are two cases that need to be checked. If the itemID
- # passed as a parameter is 1, then call the DoAboutBox routine.
- # If the item ID is not one, then it is assumed that a Desk
- # Accessory was selected, and the DA should be opened. Note that
- # item 2 should be a dashed line that is disabled; therefore
- # itemID should never be 2.
- */
- void DoAppleMenu(itemID)
- short itemID;
-
- {
- short result; /* Result returned by GetDeskAcc--ignored */
- Str255 dAName; /* Name of item selected-passed to OpenDeskAcc */
-
- if (itemID == 1) /* If the About… item was picked, then */
- DoAboutBox(); /* Bring up the About box */
- else
- { /* Otherwise, a DA was selected */
- GetItem(gMenuItem[AppleID], itemID, &dAName); /* Get the name of the DA */
- result = OpenDeskAcc(&dAName); /* And open it--ignore the result */
- HiliteMenu(0); /* Unhilite the menu */
- }
- return;
- }
-
- /*
- # DoUnhilite -- Dim menu items when no list is present
- #
- # Called by -- DoClose (only when last window is closed)
- #
- # Description -- This routine dims menu items that can cause errors when
- # selected with no list present (i.e. any menu item that calls a
- # routine that expects a valid ListHandle)
- */
- void DoUnhilite()
-
- {
- DisableItem(gMenuItem[FileID], 2);
- DisableItem(gMenuItem[FileID], 3);
- DisableItem(gMenuItem[FileID], 4);
- DisableItem(gMenuItem[FileID], 5);
- return;
- }
-
- /*
- # DoHilite -- Hilite menu items when a new list is created
- #
- # Called by -- DoNew (when no windows were present before DoNew call)
- #
- # Description -- This routines hilites the menu items dimmed by DoUnhilite
- # when a new window is created and it is the only window (i.e.
- # gNumWind = 0 before window was created)
- */
- void DoHilite()
- {
- EnableItem(gMenuItem[FileID], 2);
- EnableItem(gMenuItem[FileID], 3);
- EnableItem(gMenuItem[FileID], 4);
- EnableItem(gMenuItem[FileID], 5);
- return;
- }
-
- /*
- # DoNew -- Create a new window and list
- #
- # Called by -- Initialize and DoFileMenu
- #
- # Description -- This routine allocates space for a new document record,
- # which is used in the wStorage parameter in the GetNewWindow
- # call. A new window is then created. If one or more windows
- # are present before the new window is created, the window size
- # is scaled down to allow windows behind the new window to be
- # visible. After scaling, the window is assigned a name in the
- # format : Untitled—<window number>, and then the window is
- # finally drawn.
- #
- # LIST MANAGER SPECIFICS:
- # ---- ------- ---------
- # Setting selFlags -- Before the list is created, each of the items in the
- # List menu is looked at to see if the user has selected that
- # item. If the item is checked, the constant representing that
- # flag is added to a flag constant that is later added to the
- # selFlags field in the ListHandle.
- #
- # Creating the list -- After the menu items have been scanned, a new list is
- # created with the List Manager routine LNew. RView is the
- # enclosing rectangle of the list, which is the same as the
- # window the list is in, except for a 15 pixel margin on the
- # bottom and right sides of the window to allow space for the
- # scroll bars. DataBounds is the number of cells the list is
- # initialized with.
- #
- # Drawing the list -- Once the window and list have been drawn, the List
- # manager routine LDoDraw is called, which draws the list when
- # necessary.
- */
- void DoNew()
-
- {
- short fNum; /* The font number used for the list */
- short theMark; /* Returned by GetItemMark */
- char flags; /* Flags for the ListHandle */
- char numStr[1]; /* String version of the window number */
- char temp[255]; /* Temporary string for window title */
- char windTitle[255]; /* Title of the new window */
- Rect rView; /* Size of the initial list */
- Rect dataBounds; /* Number of cells in the initial list */
- Point cSize; /* Size of the cells in the list */
- Ptr windRec; /* Window storage pointer */
-
- windRec = NewPtr(sizeof(DocumentRecord)); /* Allocate space for document record */
- gActvWindow = GetNewWindow(1113, windRec, (WindowPtr)-1); /* Get a new window */
- gActvWindow->portRect.top = gActvWindow->portRect.top + (gNumWind * 20); /* Set the sieze */
- gActvWindow->portRect.left = gActvWindow->portRect.left + (gNumWind * 20);
- SetPort(gActvWindow); /* Set the port to the new window */
- if (gNumWind == 0) /* If this is the only window, then hilite */
- DoHilite(); /* the necessary menu items */
- gNumWind += 1; /* Increment the number of windows */
- NumToString((long)gNumWind, &numStr[0]); /* Create the window title */
- SetWTitle(gActvWindow, strcat("Untitled—", &numStr[0]));
- gWindInfo = (DocumentPeek)gActvWindow; /* Get the document record pointer */
- GETFNUM(&gFontName, &fNum); /* Get the font number of the current font */
- gActvWindow->txFont = fNum; /* Set the current font */
- gActvWindow->txSize = gFontSize; /* And font size */
- rView = gActvWindow->portRect; /* Create the rView rectangle for LNew */
- rView.right -= 15; /* Remember to allow enough space for the */
- rView.bottom -= 15; /* scroll bars */
- ShowWindow(gActvWindow); /* Make the windows visible */
- SetRect(&dataBounds, 0, 0, 4, 1); /* Set the number of default cells */
- SetPt(&cSize, 100, 16); /* Set the default cell size */
-
- flags = 0; /* Initialize flags */
- GetItemMark(gMenuItem[ListID], 1, &theMark); /* lOnlyOne bit */
- if (theMark == checkMark)
- flags += lOnlyOne;
- GetItemMark(gMenuItem[ListID], 2, &theMark); /*lExtendDrag bit */
- if (theMark == checkMark)
- flags += lExtendDrag;
- GetItemMark(gMenuItem[ListID], 3, &theMark); /* lNoDisjoint bit */
- if (theMark == checkMark)
- flags += lNoDisjoint;
- GetItemMark(gMenuItem[ListID], 4, &theMark); /* lNoExtend bit */
- if (theMark == checkMark)
- flags += lNoExtend;
- GetItemMark(gMenuItem[ListID], 5, &theMark); /* lNoRect bit */
- if (theMark == checkMark)
- flags += lNoRect;
- GetItemMark(gMenuItem[ListID], 6, &theMark); /* lUseSense bit */
- if (theMark == checkMark)
- flags += lUseSense;
- GetItemMark(gMenuItem[ListID], 7, &theMark); /* lNoNilHilite bit */
- if (theMark == checkMark)
- flags += lNoNilHilite;
-
- /* vvv Create a new list vvv */
- gWindInfo->docList = LNEW(&rView, &dataBounds, cSize,
- 0, gActvWindow, true, false, true, true);
- (*gWindInfo->docList)->selFlags = flags; /* Set the selFlags field */
- LDoDraw(true, gWindInfo->docList); /* Allow drawing */
- return;
- }
-
- /*
- # DoClose -- Handle closing a window and disposing of its contents
- #
- # Called by -- DoFileMenu and HandleMouseDown
- #
- # Description -- This routine is called when "Close" is selected from the
- # "File" menu, or the mouse is clicked in the go away region of
- # the window. Any contents of the window should be handled
- # (i.e. disposed) before the window is closed. Before doing any
- # closing, the windowKind field should be checked. If it is
- # negative, the window to be closed belongs to a desk accessory.
- # When this happens, call CloseDeskAcc and pass the value in
- # windowKind. If a window is closed, and no other windows belong
- # to the application, the gNumWind variable is set to zero, and
- # the DoUnhilite procedure is called to dim the necessary menu
- # items.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Disposing of the list -- Before closing the window, you need to call
- # LDispose to get rid of the list.
- */
- void DoClose()
-
- {
- WindowPtr testWindow; /* The window to be closed */
- DocumentPeek whatWindow; /* Information about the window */
-
- testWindow = FrontWindow(); /* Get the frontmost window */
- whatWindow = (DocumentPeek)testWindow; /* Get information of the window */
- if ((whatWindow->docWindow).windowKind > 0) /* If it is an application… */
- {
- LDispose(whatWindow->docList); /* Get rid of the list */
- CloseWindow(testWindow); /* Get rid of the window */
- gActvWindow = FrontWindow(); /* Get the new frontmost window */
- if (gActvWindow == nil) /* If there is no front window */
- {
- gNumWind = 0; /* Reset the window counter */
- DoUnhilite(); /* Unhilight the appropriate menus */
- }
- else /* If there is a front window */
- {
- SelectWindow(gActvWindow); /* Make sure it is selected */
- gWindInfo = (DocumentPeek)gActvWindow;/* Get information about the new window */
- }
- }
- else /* If the window is not an app… */
- { /* It is a DA */
- CloseDeskAcc((whatWindow->docWindow).windowKind); /* Close the DA */
- }
- HiliteMenu(0);
- return;
- }
-
- /*
- # DoQuit -- Stop the application
- #
- # Called by -- DoFileMenu
- #
- # Description -- The main function of this routine is to set the "finished"
- # flag so the main event loop will stop looping. I also close
- # all the windows and it's associated items. I know that I don't
- # have to do this because the system will get rid of all the
- # application's memory when it quits, but hey, I like to clean
- # up afterwards.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Disposing of the list -- BEFORE closing the window, you must get rid of the
- # list by calling LDispose.
- */
- void DoQuit()
-
- {
- short errNo; /* Returned by FSClose */
- WindowPtr testWindow; /* False when cancel is chosen */
- DocumentPeek windPeek; /* Document record of top window */
- Boolean stopLoop; /* Flag to stop window-closing loop */
-
- stopLoop = false; /* Initialize loop flag */
- testWindow = FrontWindow(); /* Get the top window */
- windPeek = (DocumentPeek)testWindow; /* Get the top window's doc record */
- if (testWindow != nil) /* If there is a window active */
- {
- do
- {
- LDispose(windPeek->docList); /* Get rid of the list */
- CloseWindow(testWindow); /* Get rid of the window */
- testWindow = FrontWindow(); /* Get the new front window */
- if (testWindow != nil) /* If there is still a front window */
- windPeek = (DocumentPeek)testWindow; /* Get window information */
- else
- stopLoop = true; /* Otherwise, stop. */
- }
- while (stopLoop != true);
- }
- gFinished = true; /* Stop running the program */
- return;
- }
-
- /*
- # DoFind -- A List Manager specific routine that searches for data in a cell
- #
- # Called By -- DoFileMenu
- #
- # Description -- This routine puts up a dialog box that the user will type
- # the text to be found into. After the user clicks the OK button,
- # the List Manager routine LSearch to find the cell (if any) that
- # data is located in. Note that theCell must be initialized to
- # (0,0) because the LSearch routine starts searching at theCell.
- */
- void DoFind()
-
- {
- DialogPtr theDialog; /* Pointer to the dialog box */
- short itemHit; /* Item returned by ModalDialog */
- Boolean doneDialog; /* ModalDialog loop flag */
- short theType; /* Returned by GetDitem--not used */
- short dataLen; /* Length of the find text */
- Cell theCell; /* The cell the text is found in */
- Handle item; /* A handle to the dialog editText item */
- Rect box; /* Returned by GetDItem--not used */
- char theString[255]; /* The find text */
- DialogRecord dStorage; /* The dialog record */
-
- theDialog = GetNewDialog(FindDlog, &dStorage, (DialogPtr)-1); /* Get the dialog */
- doneDialog = false; /* Initialize the loop flag */
- do /* while (doneDialog != true */ /* Keep looping until finished with dialog */
- {
- ModalDialog(nil, &itemHit); /* Get item clicked in */
- switch (itemHit)
- {
- case 1: /* If the OK button was hit, then */
- doneDialog = true; /* Set the flag to quit the dialog */
- GetDItem(theDialog, 2, &theType, &item, &box); /* Get the editText item */
- GetIText(item, &theString[0]); /* Get the find text */
- dataLen = strlen(&theString[0]);/* Set the length of the scrap */
- SetPt(&theCell, 0, 0); /* Initialize the cell */
- if (LSearch(&theString[0], dataLen, nil, &theCell, gWindInfo->docList))
- LSetSelect(true, &theCell, gWindInfo->docList);
- else
- SysBeep(20); /* Beep if nothing was found */
- break;
- }
- } while (doneDialog != true);
- CloseDialog(theDialog); /* Get rid of the dialog */
- return;
- }
-
- /*
- # DoFileMenu -- Respond to the user selecting an item in the File Menu
- #
- # Called By -- HandleMenuSelect
- #
- # Description -- This routine is simply a case statement that calls a routine
- # that handles the selected item
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Adding a row -- When the itemID "AddItem" is passed in the item ID parameter,
- # the case statement simply calls LAddRow to add another row. The
- # rowNum parameter is passed 32767 to ensure that the row is added
- # to the end of the list.
- # Deleting a row -- When the item ID "DeleteItem" is passed in the item ID
- # parameter, the case statement finds which cell (if any) is
- # selected, then calls LDelRow to delete the row the selected
- # cell is in.
- */
- void DoFileMenu(itemID)
- short itemID;
-
- {
- short newRow; /* Number of the new row */
- Cell theCell; /* Generic cell variable */
-
- switch (itemID)
- {
- case NewItem: /* Get a new list */
- DoNew();
- break;
-
- case CloseItem: /* Close a list */
- DoClose(&gActvWindow);
- break;
-
- case AddItem: /* Add a new row */
- newRow = LAddRow(1, 32767, gWindInfo->docList);
- break;
-
- case DeleteItem: /* Get rid of a new row */
- SetPt(&theCell, 0, 0); /* Initialize theCell to the first cell in the list */
- if (LGetSelect(true, &theCell, gWindInfo->docList)) /* If a cell is selected */
- {
- LDelRow(1, theCell.v, gWindInfo->docList); /* Delete the row that cell is in */
- }
- break;
-
- case FindItem: /* Find data in a cell */
- DoFind();
- break;
-
- case Quit: /* Quit the program */
- DoQuit();
- break;
- }
- HiliteMenu(0);
- return;
- }
-
- /*
- # DoEditMenu -- Respond to the user selecting an item from the Edit menu
- #
- # Called By -- HandleMenuSelect
- #
- # Description -- The routine is a case statement that handles all the items
- # in the edit menu.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Cutting a cell -- Cut was implemented by using LGetCell to get the data,
- # then calling LClrCell to clear the cell.
- # Copying a cell -- Same as cutting, but LClrCell wasn't called.
- # Pasting a cell -- Paste was implemented by using LSetCell.
- # Clearing a cell -- Clear was implemented by using LClrCell.
- # About LGetSelect -- Before LGetSelect is called, the theCell parameter is
- # initialized to the first cell in the list (0,0). The reason
- # for this is that LGetSelect finds the first cell that is
- # hilighted that is *equal to or greater than* the theCell
- # parameter. Therefore, if you want to find the first cell in
- # the entire list, set the theCell parameter to (0,0).
- */
- void DoEditMenu(itemID)
- short itemID;
-
- {
- Cell theCell; /* Generic cell variable */
- short dataLen; /* Length of data in the private scrap */
-
- if (gActvWindow != nil) /* If a window exists, then */
- {
- switch(itemID)
- {
- case UndoItem: /* Undo is not supported */
- break;
-
- case CutItem: /* Cut data from a cell */
- SetPt(&theCell, 0, 0); /* Initialize theCell to the first cell in the list */
- if (LGetSelect(true, &theCell, gWindInfo->docList)) /* Find the selected cell */
- {
- gClipLen = 256; /* Initialize the scrap length */
- LGetCell(gClipboard, &gClipLen, &theCell, gWindInfo->docList); /* Get the data */
- LClrCell(&theCell, gWindInfo->docList); /* Clear data in the cell */
- LDraw(&theCell, gWindInfo->docList); /* Draw the cell */
- }
- else
- SysBeep(20);
- break;
-
- case CopyItem: /* Copy data from a cell */
- SetPt(&theCell, 0, 0);
- if (LGetSelect(true, &theCell, gWindInfo->docList))
- {
- gClipLen = 256;
- LGetCell(gClipboard, &gClipLen, &theCell, gWindInfo->docList);
- LDraw(&theCell, gWindInfo->docList);
- }
- else
- SysBeep(20);
- break;
-
- case ClearItem: /* Clear data from a cell */
- SetPt(&theCell, 0, 0);
- if (LGetSelect(true, &theCell, gWindInfo->docList))
- {
- LClrCell(&theCell, gWindInfo->docList);
- LDraw(&theCell, gWindInfo->docList);
- }
- else
- SysBeep(20);
- break;
-
- case PasteItem: /* Paste data into a cell */
- SetPt(&theCell, 0, 0);
- if (LGetSelect(true, &theCell, gWindInfo->docList))
- {
- LSetCell(gClipboard, gClipLen, &theCell, gWindInfo->docList);
- LDraw(&theCell, gWindInfo->docList);
- }
- else
- SysBeep(20);
- break;
- }
- }
- HiliteMenu(0);
- return;
- }
-
- /*
- # DoListMenu -- Respond to the user selecting an item from the List menu
- #
- # Called By -- HandleMenuSelect
- #
- # Description -- This routine simply checks or unchecks the menu item passed
- # as a parameter. When a new list is created, these menu items
- # are polled to see which flags should be set.
- */
- void DoListMenu(itemID)
- short itemID;
-
- {
- short theMark; /* Mark returned by GetItemMark */
-
- GetItemMark(gMenuItem[ListID], itemID, &theMark); /* Get the mark of the item */
- if (theMark == checkMark) /* If it is a check mark then */
- CheckItem(gMenuItem[ListID], itemID, false); /* Uncheck the item */
- else
- CheckItem(gMenuItem[ListID], itemID, true); /* Otherwise check it */
- HiliteMenu(0);
- return;
- }
-
- /*
- # DoFontMenu -- Respond to a user selecting an item in the Font sub menu
- #
- # Called By -- HandleMenuSelect
- #
- # Description -- When an item is selected, the "old" Font name is unchecked,
- # the new font is set, and it checked in the menu. Then the
- # font name and item global variables are set.
- */
- void DoFontMenu(itemID)
- short itemID;
- {
- Str255 *theString; /* Name of the font selected */
-
- CheckItem(gFontSMenu, gFontItem, false); /* Uncheck the current font name */
- GETITEM(gFontSMenu, itemID, theString); /* Get the name of the selected font */
- CheckItem(gFontSMenu, itemID, true); /* Check the item */
- gFontName = *theString; /* Set the global font var */
- gFontItem = itemID; /* Set the global item Id */
- HiliteMenu(0);
- return;
- }
-
- /*
- # DoCellMenu -- Respond to the user selecting an item in the Cell menu
- #
- # Called by -- HandleMenuSelect
- #
- # Description -- This routine sends the itemID to a case statement where it
- # is handled. If the itemID is "IndentItem", then the vertical
- # and horizontal coordinates are retrieved from the dialog box
- # used to ask the user for the coordinates, then sets the indent
- # field of the ListHandle to those coordinates. If itemID is
- # CSizeItem, then the coordinates of the cell size are retrieved
- # from the dialog box, then set by using LCellSize. If itemID is
- # FSizeItem, then the font size entered in the dialog box is
- # set in the txSize field of the grafPort. This change does not
- # take affect until a new list is created.
- */
- void DoCellMenu(itemID)
- short itemID;
- {
- Str255 theString; /* String returned by GetIndString/GetIText */
- DialogRecord dStorage; /* Storage for the dialog record */
- DialogPtr theDialog; /* Pointer to the dialog */
- short theType; /* Not used--passed to GetDItem */
- Handle item; /* Handle to item, returned by GetDItem */
- Rect box; /* Not used--passed to GetDItem */
- Point origIndent; /* Data indent before changing */
- long vertIndent; /* Vertical indentation set by user */
- long horizIndent; /* Horizontal indentation set by user */
- short itemHit; /* Item number returned by ModalDialog */
- Boolean doneDialog; /* Flag set when user is done with dialog */
- Handle vertItem; /* Handle to vertical indent. text box */
- Handle horizItem; /* Handle to horizontal indent. text box */
-
- doneDialog = false; /* Initialize the doneDialog flag */
- switch(itemID)
- {
- case IndentItem: /* Set the indent field of the List */
- if (gActvWindow != nil) /* If a window is present… */
- {
- /* Draw a dialog and set the editText items */
- theDialog = GetNewDialog(CellDlog, &dStorage, (DialogPtr)-1);
- GetDItem(theDialog, 4, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, vertInd);
- SETITEXT(item, &theString);
- GetDItem(theDialog, 5, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, horizInd);
- SETITEXT(item, &theString);
- GetDItem(theDialog, 6, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, indentInd);
- SETITEXT(item, &theString);
- origIndent = (*gWindInfo->docList)->indent;
- vertIndent = origIndent.v;
- horizIndent = origIndent.h;
- GetDItem(theDialog, 2, &theType, &vertItem, &box);
- NUMTOSTRING(vertIndent, &theString);
- SETITEXT(vertItem, &theString);
- GetDItem(theDialog, 3, &theType, &horizItem, &box);
- NUMTOSTRING(horizIndent, &theString);
- SETITEXT(horizItem, &theString);
- ShowWindow(theDialog);
- do /* while (doneDialog != true */
- {
- /* When an event occurs, check if the OK button was hit */
- ModalDialog(nil, &itemHit);
- switch (itemHit)
- {
- case 1:
- /* If the OK button was hit, get the editText items and set the indent field */
- doneDialog = true;
- GETITEXT(vertItem, &theString);
- STRINGTONUM(&theString, &vertIndent);
- GETITEXT(horizItem, &theString);
- STRINGTONUM(&theString, &horizIndent);
- SetPt(&origIndent, (short)horizIndent, (short)vertIndent);
- (*gWindInfo->docList)->indent = origIndent;
- LUpdate(gActvWindow->visRgn, gWindInfo->docList);
- break;
- }
- }
- while (doneDialog != true);
- CloseDialog(theDialog);
- }
- else
- SysBeep(20);
- break;
-
- case CSizeItem: /* Set the cell size */
- if (gActvWindow != nil)
- {
- theDialog = GetNewDialog(CellDlog, &dStorage, (DialogPtr)-1);
- GetDItem(theDialog, 4, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, vertInd);
- SETITEXT(item, &theString);
- GetDItem(theDialog, 5, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, horizInd);
- SETITEXT(item, &theString);
- GetDItem(theDialog, 6, &theType, &item, &box);
- GETINDSTRING(&theString, theStrList, cSizeInd);
- SETITEXT(item, &theString);
- origIndent = (*gWindInfo->docList)->cellSize;
- vertIndent = origIndent.v;
- horizIndent = origIndent.h;
- GetDItem(theDialog, 2, &theType, &vertItem, &box);
- NUMTOSTRING(vertIndent, &theString);
- SETITEXT(vertItem, &theString);
- GetDItem(theDialog, 3, &theType, &horizItem, &box);
- NUMTOSTRING(horizIndent, &theString);
- SETITEXT(horizItem, &theString);
- ShowWindow(theDialog);
- do /* while (doneDialog != true */
- {
- ModalDialog(nil, &itemHit);
- switch (itemHit)
- {
- case 1:
- /* If the OK button was hit, get the editText items the user set,
- and call LCellSize to change the cell size */
- doneDialog = true;
- GETITEXT(vertItem, &theString);
- STRINGTONUM(&theString, &vertIndent);
- GETITEXT(horizItem, &theString);
- STRINGTONUM(&theString, &horizIndent);
- SetPt(&origIndent, (short)horizIndent, (short)vertIndent);
- LCellSize(&origIndent, gWindInfo->docList);
- break;
- }
- }
- while (doneDialog != true);
- CloseDialog(theDialog);
- }
- else
- SysBeep(20);
- break;
-
- case FSizeItem: /* Set the font size */
- theDialog = GetNewDialog(FontSDlog, &dStorage, (DialogPtr)-1);
- GetDItem(theDialog, 2, &theType, &item, &box);
- SETITEXT(item, "\p10");
- ShowWindow(theDialog);
- do /* while (doneDialog != true */
- {
- ModalDialog(nil, &itemHit);
- switch (itemHit)
- {
- case 1:
- /* If the OK button was hit, get the editText item and set the font size */
- doneDialog = true;
- GETITEXT(item, &theString);
- STRINGTONUM(&theString, &horizIndent);
- gFontSize = (short)horizIndent;
- break;
- }
- }
- while (doneDialog != true);
- CloseDialog(theDialog);
- break;
- }
- HiliteMenu(0);
- }
-
- /*
- # HandleMenuSelect -- Determines which menu was selected from
- #
- # Called By -- HandleMouseDown/HandleKeyDown
- #
- # Description -- This routines finds the menuID and itemID of the item
- # selected by the user. The menu information is passed in the
- # parameter menuInfo. The high-order word contains the menuID
- # and the low-order word holds the itemID. These items are
- # extracted by using HiWord and LoWord, respectively. The menuID
- # is sent to a case statement which calls a routine that handles
- # that menu.
- */
- void HandleMenuSelect(menuInfo)
- long menuInfo;
-
- {
- short menuID; /* Menu's resource ID */
- short itemID; /* ID of item selected */
-
- menuID = HiWord(menuInfo); /* High order word holds menu ID */
- itemID = LoWord(menuInfo); /* Low order word holds item ID */
-
- if (menuID != 0) /* If a real, existing menu was selected */
- switch (menuID) /* Then handle the event in the menu */
- {
- case AppleMenu: /* The apple menu was selected */
- DoAppleMenu(itemID);
- break;
-
- case FileMenu: /* The File menu was selected */
- DoFileMenu(itemID);
- break;
-
- case EditMenu: /* The Edit menu was selected */
- DoEditMenu(itemID);
- break;
-
- case ListMenu: /* The List menu was selected */
- DoListMenu(itemID);
- break;
-
- case CellMenu: /* The Cell menu was selected */
- DoCellMenu(itemID);
- break;
-
- case FontSMenu: /* The Font submenu was selected */
- DoFontMenu(itemID);
- }
- }
-
- /*
- # HandleContent -- Respond to a mouse event inside a window
- #
- # Called By -- HandleMouseDown
- #
- # Description -- When a mouse-down event occurs in the content portion of a
- # window (when FindWindow returns inContent), the application must
- # take appropriate action:
- # 1. Make The Window Active - If the window passed in the
- # whichWindow parameter is not the active window, then
- # it must be made active by calling SelectWindow.
- # The global window pointer and document record must
- # reflect the changes.
- # 2. If the window is already active, you need to find if
- # the click occurred inside an object in the window
- # such as a TextEdit box, control, or indicator. Note
- # that the TextEdit, Control and List Managers
- # (among others) require the mouse down loaction in
- # local coordinates, so the routine GlobalToLocal
- # is called to get the local point coordinates.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Click occurs in the list -- A check must be made to see if the mouse down
- # occurred in the list. You do this by getting the list rect
- # from the rView field in the ListHandle and calling PtInRect.
- # Remember that rView returns the rect coordinates in the LOCAL
- # coordinate system, so the point returned by GlobalToLocal
- # should be used.
- # If the mouse down was in the list, then call the List
- # Manager routine LClick. This routine will handle any actions
- # needed in the list (selecting, moving scroll bars) according
- # to the list definition procedure (LDEF).
- # IMPORTANT NOTE: The rView rectangle DOES NOT include the
- # scroll bars. Before using PtInRect to find if the click
- # occurred in the list, add 15 to the bottom and right fields of
- # the rect to include the scroll bars. If you don't do this, the
- # list will not scroll.
- */
- void HandleContent(whichWindow)
- WindowPtr whichWindow;
-
- {
- Point thePoint; /* Events.where in local coordinates */
- Rect theRect; /* The area the list occupies */
- Boolean yorn; /* Junk result from LClick */
-
- gActvWindow = FrontWindow(); /* Get the frontmost window */
- thePoint = gEvents.where; /* Set up a point to be converted to local */
- GlobalToLocal(&thePoint); /* Convert to local coordinates */
- if (whichWindow != gActvWindow) /* If the window selected isn't frontmost */
- {
- SelectWindow(whichWindow); /* Make it the frontmost window */
- gActvWindow = whichWindow; /* Set the global VAR */
- gWindInfo = (DocumentPeek)gActvWindow; /* Set the window information */
- }
-
- if (gWindInfo->docList != nil) /* If a list exists, then */
- {
- theRect = (*gWindInfo->docList)->rView; /* Get the bounding rect of the list */
- theRect.right += 15; /* Account for the vertical and */
- theRect.bottom += 15; /* horizontal scroll bars */
- if (PtInRect(&thePoint, &theRect)) /* If the mouse click was in the list, then */
- yorn = LClick(&thePoint, gEvents.modifiers, gWindInfo->docList); /* Tell the list it was clicked in */
- }
- }
-
- /*
- # HandleGrow -- Respond to a mouse down event in the grow icon
- #
- # Called by -- HandleMouseDown
- #
- # Description -- When a mouse down event occurs in the grow icon (when
- # FindWindow returns inGrow) the application must grow the
- # window, following the movements of the mouse. This i
- # this is accomplished by calling GrowWindow, which returns the
- # new width and height of the window (or 0 if no change was
- # made). The width is in the low-order word of the long result
- # and the height is in the high-order word. These values are
- # extracted using LoWord and HiWord. After getting this result,
- # SizeWindow is called, passing the height and width returned by
- # GrowWindow. After this is done, the window is marked as "dirty"
- # and updated by calling InvalRect.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # Growing the list -- You can use the height and width values returned by
- # GrowWindow in the ListManager routine LSize, remembering to
- # subtract room for the scroll bars, if any.
- */
- void HandleGrow(whichWindow)
- WindowPtr whichWindow;
-
- {
- long windSize; /* The new size of window after it is grown */
- short vert; /* The vertical component of growth */
- short horiz; /* The horizontal component of growth */
-
- windSize = GrowWindow(whichWindow,&gEvents.where,&gGrowArea); /* Grow the window */
- vert = HiWord(windSize); /* High order word holds vertical change */
- horiz = LoWord(windSize); /* Low order word holds horizontal change */
- SizeWindow(whichWindow, horiz, vert, true); /* Make changes to the window */
- LSize(horiz-15, vert-15, gWindInfo->docList);/* Make changes to the list */
- InvalRect(&whichWindow->portRect); /* Get the window ready for updating */
- }
-
- /*
- # HandleMouseDown -- Take care of a mouse-down event.
- #
- # Called by -- Main program
- #
- # Description -- The major block of the program is a case statement that
- # branches to the constant returned by the window manager
- # function FindWindow. Most of the events are handled inside the
- # case statement; a few have external routines. The routines
- # that are called from this routine are:
- # HandleMenuSelect (inMenuBar)
- # HandleContent (inContent)
- # HandleGrow (inGrow)
- */
- void HandleMouseDown()
-
- {
- WindowPtr whichWindow; /* WindowPtr returned by FindWindow */
- DocumentPeek windPeek; /* Information about window */
- long menuInfo; /* Menu Information returned by MenuSelect */
- short dPartCode; /* Part code returned by FindWindow */
- short width; /* Vertical change made by zooming */
- short height; /* Horizontal change made by zooming */
- Rect zoomRect; /* Window rect after zooming */
-
- dPartCode = FindWindow(&gEvents.where, &whichWindow); /* Find where click occrred */
- switch (dPartCode)
- {
- case inMenuBar: /* Click occurred in menu bar */
- menuInfo = MenuSelect(&gEvents.where); /* Get menuID, item ID */
- HandleMenuSelect(menuInfo);
- break;
-
- case inContent: /* Click in content region */
- HandleContent(whichWindow);
- break;
-
- case inDrag: /* Click in drag region */
- DragWindow(whichWindow, &gEvents.where, &gDragArea); /* Drag the window */
- break;
-
- case inGrow: /* Click in grow icon */
- HandleGrow(whichWindow);
- break;
-
- case inGoAway: /* Click in close box */
- if (TrackGoAway(whichWindow, &gEvents.where)) /* If mouse pressed and released */
- DoClose(); /* inside box, then close the window */
- break;
-
- case inSysWindow: /* Click in DA window */
- SystemClick(&gEvents, whichWindow);
- break;
-
- case inZoomIn: /* Click in zoom box */
- case inZoomOut:
- if (TrackBox(whichWindow,&gEvents.where,dPartCode))
- { /* If mouse pressed and released in box, then */
- windPeek = (DocumentPeek)whichWindow; /* Get window info */
- ZoomWindow(whichWindow,dPartCode,true); /* Zoom the window */
- zoomRect = whichWindow->portRect; /* Get new window coordinates */
- width = zoomRect.right - zoomRect.left; /* Find width and height of window */
- height = zoomRect.bottom - zoomRect.top;/* Call LSize to zoom list */
- LSize(width-15, height-15, windPeek->docList);
- InvalRect(&whichWindow->portRect); /* Mark window as needing update */
- }
- break;
- }
- return;
- }
-
- /*
- # HandleUpdateEvt -- Do a window update
- #
- # Called by -- main event loop
- #
- # Description -- When GetNextEvent returns updateEvt, this routine is called
- # to redraw the contents of a window.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # LUpdate -- The List Manager routine LUpdate is called to re-draw the window
- # that needs updating.
- */
- void HandleUpdateEvt()
-
- {
- short yorn; /* for loop control variable */
- WindowPtr theWindow; /* Window to be updated */
- DocumentPeek theList; /* Information about the window */
- GrafPtr savePort; /* Active port when called */
-
- theWindow = (WindowPtr)gEvents.message; /* Get the window to be updated */
- theList = (DocumentPeek)theWindow; /* Find window information */
- GetPort(&savePort); /* Save this port */
- SetPort(theWindow); /* Get the window's port, in case it's different */
-
- BeginUpdate(theWindow); /* Start the update */
- EraseRect(&(theWindow->portRect)); /* Erase the window */
- LUpdate(theWindow->visRgn, theList->docList); /* Update the list */
- DrawGrowIcon(theWindow); /* Draw the grow icon */
- EndUpdate(theWindow); /* End the update */
- SetPort(savePort); /* Resore the original port */
- }
-
- /*
- # HandleActivateEvt -- Make a window active, deactivate another window
- #
- # Called by -- main event loop
- #
- # Description -- When an activate event is needed, GetNextEvent returns
- # activateEvt, plus a flag in the modifiers field. If the flag
- # is an activate flag (bit 0 is 1 -- see Inside Mac), then
- # a grow icon (if any) is drawn, and scroll bars (if any) are
- # made active. If the flag is a deactivate flag (bit 0 is 0),
- # then the grow icon is erased and any scroll bars are inactivated.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # LActivate -- The list manager routine LActivate is called to make a list
- # either active or inactive.
- */
- void HandleActivateEvt()
-
- {
- WindowPtr theWindow; /* Window that is active/inactive */
- DocumentPeek windPeek; /* Information about the window */
- Rect invH; /* Grow icon rect to be erased */
-
- theWindow = (WindowPtr)gEvents.message; /* The window to be (in)activated */
- windPeek = (DocumentPeek)theWindow; /* Get window information */
- if ((gEvents.modifiers & 1) == 1) /* If it is an activate event, then */
- {
- SetPort(theWindow); /* Set the port to the window's */
- gActvWindow = theWindow; /* Make this window the active one */
- LActivate(true, windPeek->docList); /* Activate the list */
- DrawGrowIcon(theWindow); /* Draw the grow icon */
- }
- else /* If this is a deactivate event */
- {
- LActivate(false, windPeek->docList); /* Inactivate the list */
- SetRect(&invH, theWindow->portRect.right - 14, /* Create the grow icon rect */
- theWindow->portRect.bottom - 14,
- theWindow->portRect.right,
- theWindow->portRect.bottom);
- EraseRect(&invH); /* Erase the grow icon */
- }
- }
-
- /*
- # HandleKeyDown -- Respond to a key being pressed.
- #
- # Called by -- main event loop
- #
- # Description -- There are several special cases to be checked for this
- # routine. If the command key is depressed when the key is down,
- # then the key down event is a command key equivalent, and the
- # character that represents the key is passed to the Menu Manager
- # routine MenuKey.
- # If the command key is not pressed, then the character should be
- # passed to the application. There are several non-printin keys
- # that need to be handled specially. These keys are the carrriage
- # return (13), tab (9), backspace (8), and enter (3). If the key
- # pressed wansn't any of these keys, then the character should be
- # sent to the application.
- #
- # LIST MANAGER SPECIFICS
- # ---- ------- ---------
- # The following special cases are handled in the following way:
- # CR -- Advance one row in same column
- # Tab -- Advance one column in the same row. If the current cell is the
- # last cell in the row, then go to the first column in the next row.
- # (For more information on how CR's and tabs are handled, see the
- # description of LNextCell in the List Manager chapter of Inside
- # Macintosh.)
- # Backspace -- Delete data in the cell
- # Enter -- Unselect the currently selected cell.
- # Any printing character -- add the character to the data for the cell.
- */
- void HandleKeyDown(modifiers)
- short modifiers;
-
- {
- char theKey; /* The key that was depressed */
- Cell theCell; /* Generic cell variable */
- Ptr dataPtr; /* Pointer to data in cell */
- short dataLen; /* Length of data in cell */
- long menuInfo; /* Returned by menu key */
-
- if ((modifiers & cmdKey) == cmdKey) /* If the command key was down, then */
- {
- menuInfo = MenuKey(LoWord(gEvents.message & charCodeMask)); /* Get the menuID, item ID */
- HandleMenuSelect(menuInfo);
- }
- else /* Command key not down */
- {
- SetPt(&theCell, 0, 0); /* Initialize theCell parameter */
- if (LGetSelect(true, &theCell, gWindInfo->docList))
- {
- theKey = LoWord(gEvents.message & charCodeMask);
- switch(theKey)
- {
- case 13: /* Carriage return */
- LSetSelect(false, &theCell, gWindInfo->docList);
- if (LNextCell(false, true, &theCell, gWindInfo->docList))
- LSetSelect(true, &theCell, gWindInfo->docList);
- else
- {
- theCell.v = 0;
- LSetSelect(true, &theCell, gWindInfo->docList);
- }
- break;
-
- case 9: /* Tab pressed */
- LSetSelect(false, &theCell, gWindInfo->docList);
- if (LNextCell(true,true, &theCell, gWindInfo->docList))
- LSetSelect(true, &theCell, gWindInfo->docList);
- else
- {
- theCell.v = 0;
- LSetSelect(true, &theCell, gWindInfo->docList);
- }
- break;
-
- case 8: /* Backspace */
- dataLen = 256;
- LGetCell(dataPtr, &dataLen, &theCell, gWindInfo->docList);
- if (dataLen !=0)
- LSetCell(dataPtr, dataLen-1, &theCell, gWindInfo->docList);
- break;
-
- case 3: /* Enter */
- LSetSelect(false, &theCell, gWindInfo->docList);
- break;
-
- default: /* Printable char */
- LAddToCell(&theKey, 1, &theCell, gWindInfo->docList);
- LDraw(&theCell, gWindInfo->docList);
- break;
- }
- }
- }
- }
-
- /*
- # The Main Program
- #
- # Called by -- The entry point
- #
- # Description -- The main program is used to initialize any variables and
- # data structures. After this, the program enters an "event
- # loop". The event loop calls SystemTask, which handles DA's and
- # other system necessities, then calls GetNextEvent, which returns
- # an event constant when an event occurs.
- */
- void main()
-
- {
- UnloadSeg((Ptr) _DataInit);
- Initialize();
- do
- {
- SystemTask();
- if (GetNextEvent(everyEvent, &gEvents)) /* Find which event occurred */
- {
- switch (gEvents.what)
- {
- case mouseDown: /* Mouse button pressed */
- HandleMouseDown();
- break;
-
- case keyDown: /* Key pressed */
- HandleKeyDown(gEvents.modifiers);
- break;
-
- case autoKey:
- break;
-
- case updateEvt: /* Window needs updating */
- HandleUpdateEvt();
- break;
-
- case activateEvt: /* Window needs activating */
- HandleActivateEvt();
- break;
-
- default:
- break;
- }
- }
- } while (gFinished != true);
- }