home *** CD-ROM | disk | FTP | other *** search
- /* ListDemo.c */
- /*
- *
- * Demo my homemade LDEF. The program lets you open
- * a file and display all of the icons in it. You
- * can't do anything else, though it would be easy
- * to allow you to copy an icon to the clipboard.
- *
- * Copyright 1990 Martin Minow and MacTutor.
- */
- #include "iconicLDEF.h"
-
- #define FORMAT COMPILED /* Define program */
- /*
- * These values configure the demo program: that way
- * we only need to write one piece of code.
- */
- #define COMPILED 0
- #define FAKE_RESOURCE 1
- #define TRUE_RESOURCE 2
- #if FORMAT == FAKE_RESOURCE || FORMAT == TRUE_RESOURCE
- #define LDEF_ID 128
- #else
- #define LDEF_ID 0 /* Start with Mac LDEF */
- #endif
- #define RESOURCE 'ICN#'
- #define iconSize 32 /* Pixels per icon */
- #define sBarWidth 15 /* For grow button */
- #define iconCols 4
- #define iconRows 4
- #define hOffsetDelta 16 /* For multiple windows */
- #define vOffsetDelta 0
- #define hOffsetMax (hOffsetDelta * 10)
- #define vOffsetMax (vOffsetDelta * 10)
-
- /*
- * Menu organization
- */
- enum Menus {
- MENU_Apple = 1,
- MENU_File = 256,
- MENU_Edit = 257
- };
-
- enum Apple_Menu {
- Apple_About = 1
- };
-
- enum File_Menu {
- File_Open = 1,
- File_Close,
- File_DrawAsText,
- File_Debug,
- Unused,
- File_Quit
- };
-
- #define width(r) ((r).right - (r).left)
- #define height(r) ((r).bottom - (r).top)
-
- /*
- * All the information about a document
- * is stored here. Note that, when the
- * toolbox selects a window, we can
- * immediately recover the document.
- */
- typedef struct {
- WindowRecord window;
- ListHandle list;
- } DocumentRecord, *DocumentPtr;
- /*
- * The current window is always stored in a local
- * WindowPtr variable named "window." If it's ours,
- * we can access the document by casting window to
- * DocumentPtr and de-referencing it.
- */
- #define DOC (*((DocumentPtr) window))
-
- /*
- * isOurWindow is TRUE if its argument is our document.
- */
- #define isOurWindow(window) ( \
- (window) != NIL \
- && ((WindowPeek) (window))->windowKind == userKind \
- )
-
- MenuHandle apple_menu;
- MenuHandle file_menu;
- Boolean drawAsText; /* For iconicLDEF() */
- int hOffset, vOffset;
-
- void main(void);
- Boolean do_mouse(EventRecord);
- Boolean handle_events(void);
- void do_command(long);
- void setup(void);
- void open_document(void);
- void close_document(WindowPtr);
- Boolean new_document(void *, int);
- Boolean initialize_list(WindowPtr);
- void read_icons(WindowPtr, int);
-
- #if FORMAT == FAKE_RESOURCE
- void setup_LDEF(int);
- #endif
- #if FORMAT == COMPILED
- void add_LDEF(ListHandle);
- void remove_LDEF(ListHandle);
- #endif
- void iconicLDEF();
-
- /*
- * main()
- * Initialize the program and run the event loop.
- */
- void
- main()
- {
- EventRecord event;
- WindowPtr window;
- GrafPtr save_port;
- Rect box;
-
- setup();
- for (;;) {
- SystemTask();
- while (GetNextEvent(everyEvent, &event)
- && event.what != nullEvent) {
- if (event.what == activateEvt
- || event.what == updateEvt)
- window = (WindowPtr) event.message;
- else {
- window = FrontWindow();
- }
- switch (event.what) {
- case mouseDown:
- do_mouse(event);
- break;
- case activateEvt:
- if (isOurWindow(window)) {
- SetPort(window); /* Or InvalRect crashes! */
- LActivate(
- event.modifiers & activeFlag,
- DOC.list
- );
- /*
- * For some reason, LActivate doesn't redraw
- * the scroll bars. The correct solution
- * is left as a puzzle for the reader.
- */
- if (event.modifiers & activeFlag) {
- ControlHandle handle;
- Rect box;
-
- handle = (**DOC.list).vScroll;
- if (handle != NIL) {
- box = (**handle).contrlRect;
- InvalRect(&box);
- }
- }
-
- }
- break;
- case updateEvt:
- if (isOurWindow(window)) {
- GetPort(&save_port);
- SetPort(window);
- BeginUpdate(window);
- EraseRect(&window->portRect);
- box = (**DOC.list).rView;
- InsetRect(&box, -1, -1);
- FrameRect(&box);
- LDoDraw(TRUE, DOC.list);
- LUpdate(window->visRgn, DOC.list);
- EndUpdate(window);
- SetPort(save_port);
- }
- break;
- default:
- break;
- }
- }
- }
- }
-
- /*
- * do_mouse(event)
- * Process a mouse button press, calling handlers as
- * needed.
- */
- static Boolean
- do_mouse(event)
- EventRecord event;
- {
- WindowPtr window;
- register int which_part;
- Rect box;
- int item;
- Point mouse;
- int result;
- long new, choice;
- Str255 name;
- GrafPtr save_port;
-
- which_part = FindWindow(event.where, &window);
- switch (which_part) {
- case inDesk:
- SysBeep(2);
- break;
- case inMenuBar:
- choice = MenuSelect(event.where);
- item = LoWord(choice);
- switch (HiWord(choice)) {
- case MENU_Apple:
- GetItem(apple_menu, item, &name);
- if (item == Apple_About)
- SysBeep(10); /* No List About */
- else {
- GetPort(&save_port);
- OpenDeskAcc(name);
- SetPort(save_port);
- }
- break;
- case MENU_File:
- window = FrontWindow();
- switch (item) {
- case File_Open:
- open_document();
- break;
- case File_Close:
- close_document(window);
- break;
- case File_Debug:
- Debugger();
- break;
- case File_DrawAsText:
- drawAsText = !drawAsText;
- CheckItem(file_menu, File_DrawAsText, drawAsText);
- if (isOurWindow(window))
- InvalRect(&(*window).portRect);
- break;
- case File_Quit:
- ExitToShell();
- }
- default:
- break;
- }
- HiliteMenu(0);
- break;
- case inDrag:
- box = screenBits.bounds;
- box.top += GetMBarHeight();
- InsetRect(&box, 4, 4);
- DragWindow(window, event.where, &box);
- break;
- case inContent:
- if (FrontWindow() != window)
- SelectWindow(window);
- else {
- SetPort(window);
- if (isOurWindow(window)) {
- mouse = event.where;
- GlobalToLocal(&mouse);
- result = LClick(mouse, event.modifiers, DOC.list);
- (void) LLastClick(DOC.list);
- }
- }
- break;
- case inGoAway:
- if (isOurWindow(window)
- && TrackGoAway(window, event.where))
- close_document(window);
- break;
- }
- return (FALSE);
- }
-
- /*
- * open_document()
- * Ask for a file (allow all files). Open its resource
- * fork (if possible). If we succeed, create a new
- * window and look for all ICN# resources.
- */
- void
- open_document()
- {
- SFReply reply;
- int file;
- static Point where = { 85, 85 };
-
- SFGetFile(
- where, /* Where on the screen */
- NIL, /* Unused */
- NIL, /* no file filter */
- -1, /* Allow all file types */
- NIL, /* … thus no typeList */
- NIL, /* no dialog hook */
- &reply /* reply goes here */
- );
- if (reply.good) {
- SetVol(NIL, reply.vRefNum);
- SetCursor(*GetCursor(watchCursor));
- if ((file = OpenResFile(reply.fName)) == -1)
- SysBeep(10); /* No resource fork */
- else {
- if (new_document(reply.fName, file) == FALSE)
- SysBeep(10); /* No memory */
- CloseResFile(file);
- }
- SetCursor(&arrow);
- }
- }
-
- /*
- * close_document()
- * Close the document in the current (front) window.
- * Dump the handles that were stored in the list's cells.
- */
- void
- close_document(window)
- WindowPtr window;
- {
- IconInfo iconInfo;
- short size;
- Cell cell;
-
- if (isOurWindow(window) == FALSE)
- Debugger();
- SetCursor(*GetCursor(watchCursor));
- /*
- * Iterate over all cells in the list.
- */
- cell.h = cell.v = 0;
- do {
- size = sizeof iconInfo;
- LGetCell(&iconInfo, &size, cell, DOC.list);
- if (size == sizeof iconInfo) /* Non-empty cell? */
- DisposHandle(iconInfo.handle);
- } while (LNextCell(TRUE, TRUE, &cell, DOC.list));
- #if FORMAT == COMPILED
- remove_LDEF(DOC.list);
- #endif
- LDispose(DOC.list);
- CloseWindow(window);
- DisposPtr(window);
- SetCursor(&arrow);
- }
-
- /*
- * setup()
- * One-time initialization.
- */
- void
- setup()
- {
- InitGraf(&thePort);
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(NIL);
- InitCursor();
- MaxApplZone();
- apple_menu = NewMenu(MENU_Apple, "\p\024");
- file_menu = NewMenu(MENU_File, "\pFile");
- AppendMenu(apple_menu, "\p(No List Demo About;(-");
- AddResMenu(apple_menu, 'DRVR');
- AppendMenu(
- file_menu,
- "\pOpen\311/O;Close;Draw As Text;Debug/.;(-;Quit/Q"
- );
- InsertMenu(apple_menu, 0);
- InsertMenu(file_menu, 0);
- DrawMenuBar();
- #if FORMAT == FAKE_RESOURCE
- setup_LDEF(LDEF_ID);
- #endif
- if (new_document("\pList Demo", -1) == FALSE) {
- SysBeep(10);
- ExitToShell();
- }
- }
-
- /*
- * new_document()
- * Build a document: get memory for the WindowRecord and
- * our attached information. Offset the window with
- * respect to other windows and make the window. If
- * this succeeds, initialize the document's list. If
- * that succeeds, read the icons.
- */
- Boolean
- new_document(title, resFile)
- void *title; /* Pascal string */
- int resFile; /* Open resource file, if any */
- {
- WindowPtr window;
- DocumentPtr doc;
- Rect box;
- static long sequence; /* Identify windows */
-
- doc = (DocumentPtr) NewPtr(sizeof (DocumentRecord));
- if (doc == NIL)
- return (FALSE);
- /*
- * Locate the window and get its shape. This could
- * probably be done better.
- */
- box.left = 0;
- box.top = GetMBarHeight() * 2;
- box.right = box.left
- + (iconSize * iconCols)
- + sBarWidth
- + 2;
- box.bottom = box.top
- + (iconSize * iconRows)
- + 2;
- OffsetRect(&box, hOffset, vOffset);
- if (box.bottom > screenBits.bounds.bottom
- || box.right > screenBits.bounds.right) {
- OffsetRect(&box, -hOffset, -vOffset);
- hOffset = 0;
- vOffset = 0;
- }
- hOffset += hOffsetDelta;
- if (hOffset >= hOffsetMax)
- hOffset = 0;
- vOffset += vOffsetDelta;
- if (vOffset >= vOffsetMax)
- vOffset = 0;
- window = NewWindow(
- doc, /* Allocated storage */
- &box, /* Display Rect */
- title, /* Title */
- TRUE, /* Visible on creation */
- noGrowDocProc, /* Window type */
- -1L, /* Show in front */
- TRUE, /* GoAway box */
- ++sequence /* RefCon (debug only) */
- );
- if (window == NIL) {
- DisposPtr(doc);
- return (FALSE);
- }
- if (initialize_list(window) == FALSE) {
- CloseWindow(window);
- DisposPtr(doc);
- return (FALSE);
- }
- SetPort(window);
- TextFont(applFont);
- TextSize(9);
- read_icons(window, resFile);
- return (TRUE);
- }
-
- /*
- * initialize_list()
- * Build a list whose cells will hold our icon records.
- * If our LDEF is completely compiled, call add_LDEF
- * after creation.
- */
- Boolean
- initialize_list(window)
- WindowPtr window;
- {
- int type;
- Handle handle;
- int *jump;
- Rect box;
- Point cell;
- Rect dimension;
-
- box = (*window).portRect;
- InsetRect(&box, 1, 1); /* Room for frame */
- box.right -= sBarWidth;
- SetPt(&cell, iconSize, iconSize);
- box.bottom =
- box.top + (height(box) / cell.v) * cell.v;
- box.right =
- box.left + (width(box) / cell.h) * cell.h;
- SetRect(&dimension, 0, 0, box.right / cell.h, 0);
- DOC.list = LNew(
- &box, /* Display rectangle */
- &dimension, /* Shape (rows, cols) */
- cell, /* Cell shape on screen */
- LDEF_ID, /* List handler, if any */
- window, /* The window */
- TRUE, /* Drawing's ok */
- FALSE, /* No grow box */
- FALSE, /* No horizontal scroll */
- TRUE /* Vertical scroll */
- );
- if (DOC.list == NIL)
- return (FALSE);
- (**DOC.list).selFlags = lOnlyOne;
- #if FORMAT == COMPILED
- add_LDEF(DOC.list);
- #endif
- (**DOC.list).refCon = (long) iconicLDEF;
- return (TRUE);
- }
-
- /*
- * read_icons()
- * Fill the list with the icon handles and resource ids.
- */
- void
- read_icons(window, resFile)
- WindowPtr window;
- int resFile;
- {
- int n_icons;
- int i;
- int n_rows, n_cols;
- Cell cell;
- ResType type;
- IconInfo iconInfo;
- Str255 name;
-
- LDoDraw(FALSE, DOC.list);
- if (resFile != -1) {
- UseResFile(resFile);
- n_icons = Count1Resources(RESOURCE);
- }
- else {
- n_icons = CountResources(RESOURCE);
- }
- n_cols = (**DOC.list).dataBounds.right;
- n_rows = (n_icons + (n_cols - 1)) / n_cols;
- /*
- * Note that we can have empty cells in the last row.
- * The drawing routine must check for this case.
- */
- if (n_rows > 0)
- LAddRow(n_rows, 0, DOC.list);
- for (i = 0; i < n_icons; i++) {
- if (resFile != -1)
- iconInfo.handle = Get1IndResource(RESOURCE, i + 1);
- else {
- iconInfo.handle = GetIndResource(RESOURCE, i + 1);
- }
- if (iconInfo.handle == NIL)
- iconInfo.number = -1;
- else {
- GetResInfo(
- iconInfo.handle, &iconInfo.number, &type, name);
- DetachResource(iconInfo.handle);
- }
- cell.v = i / n_cols;
- cell.h = i % n_cols;
- LSetCell(&iconInfo, sizeof iconInfo, cell, DOC.list);
- #if 0 /* Debug: watch the icons as they're read in */
- {
- Rect rect;
- SetRect(&rect, 1, 1, 33, 33);
- PlotIcon(&rect, iconInfo.handle);
- }
- #endif
- }
- LDoDraw(TRUE, DOC.list);
- InvalRect(&(**DOC.list).rView);
- }
-
-