home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / progrmng / transklc.sit / ManyWind.c.bin / ManyWind.c
Encoding:
C/C++ Source or Header  |  1989-01-29  |  6.8 KB  |  276 lines  |  [TEXT/KAHL]

  1. /*
  2.     ManyWind TransSkel demonstration
  3.     
  4.     This application allows up to twenty windows to be created at once,
  5.     with the New item under the File menu.  The name of each window
  6.     appears under the Windows menu (which is not created until at least
  7.     one window exists).  Selecting the window name from the Windows menu
  8.     brings the window to the front.  For every window created, Skel is
  9.     told to create a new handler.  If the window's close box is clicked,
  10.     the handler removes the window name from the Windows menu, disposes
  11.     of the window, and removes itself from the window handler list.  If
  12.     the window was the last window, the Windows menu handler removes
  13.     itself from the menu handler list.
  14.     
  15.     When the first window is created, a Color menu also appears.  This
  16.     allows the color of the content region of the frontmost window to
  17.     be changed.  It goes away when the last window is closed.
  18.     
  19.     To quit, select Quit from the File menu or type command-Q.
  20.  
  21.     ManyWind demonstrates dynamic window and menu creation and disposal.
  22.     It also shows how handler procedures may be shared among handlers
  23.     for different windows.
  24.  
  25.     The project should include this file, TransSkel.c (or a project
  26.     built from TransSkel.c), and MacTraps.
  27.  
  28.     21 Apr 1988        Paul DuBois
  29.     29 Jan 1989 Conversion for TransSkel 2.0.  Integer should be a
  30.                 typedef for compiler 2-byte integer type.  Longint should
  31.                 be a typedef for the 4-byte integer type.
  32. */
  33.  
  34. # include    <WindowMgr.h>
  35. # include    <MenuMgr.h>
  36.  
  37. # define    nil    (0L)
  38. # define    maxWind    20    /* maximum number of windows existing at once */
  39.  
  40. typedef    int        Integer;
  41. typedef long    Longint;
  42.  
  43.  
  44. enum                /* menu numbers */
  45. {
  46.     aMenuNum = 1,    /* Apple menu */
  47.     fMenuNum,        /* File menu */
  48.     wMenuNum,        /* Windows menu */
  49.     cMenuNum        /* Color menu */
  50. };
  51.  
  52.  
  53. enum                /* File menu item numbers */
  54. {
  55.     new = 1,
  56.     /* --- */
  57.     quit = 3
  58. };
  59.  
  60. enum                /* Color menu items numbers */
  61. {
  62.     cWhite = 1,
  63.     cLtGray,
  64.     cGray,
  65.     cDkGray,
  66.     cBlack
  67. };
  68.  
  69.  
  70. MenuHandle    fileMenu;
  71. MenuHandle    windowMenu;
  72. MenuHandle    colorMenu;
  73.  
  74. Integer    windCount = 0;    /* number of currently existing windows */
  75. Longint    windNum = 0;    /* id of last window created */
  76.  
  77. Integer    DoWindowMenu(), DoColorMenu(), DoMClobber();
  78.  
  79.  
  80. DoWUpdate ()
  81. {
  82. GrafPtr    thePort;
  83.  
  84.     GetPort (&thePort);
  85.     EraseRect (&thePort->portRect);    /* repaint w/background pattern */
  86. }
  87.  
  88.  
  89. /*
  90.     Mouse was clicked in close box.  Remove the window handler (which
  91.     causes the window to be disposed of), and delete the window title
  92.     from the Windows menu.  If the window was the last one, delete the
  93.     Windows and Color menus entirely.
  94.  
  95.     Skel makes sure the port is pointing to the appropriate window, so
  96.     this procedure can determine which window had its close box clicked,
  97.     without being told explicitly.
  98. */
  99.  
  100. DoWClose ()
  101. {
  102. GrafPtr        thePort;
  103. MenuHandle    m;
  104. Integer        i, mItems;
  105. Str255        iTitle, wTitle;
  106.  
  107.     GetPort (&thePort);                /* grafport of window to be closed */
  108.     GetWTitle ((WindowPtr) thePort, wTitle);
  109.     SkelRmveWind ((WindowPtr) thePort);
  110.     if (--windCount == 0)
  111.     {
  112.         SkelRmveMenu (windowMenu);    /* last window - clobber menus */
  113.         SkelRmveMenu (colorMenu);
  114.     }
  115.     else
  116.     {
  117.         /* just take out of menu */
  118.         m = NewMenu (wMenuNum, "\pWindows");
  119.         for (i = 1, mItems = CountMItems (windowMenu); i <= mItems; ++i)
  120.         {
  121.             GetItem (windowMenu, i, iTitle);
  122.             if (!EqualString (iTitle, wTitle, false, true))
  123.                 AppendMenu (m, iTitle);
  124.         };
  125.         SkelRmveMenu (windowMenu);    /* remove old Windows menu */
  126.         windowMenu = m;                /* and install new one */
  127.         (void) SkelMenu (windowMenu, DoWindowMenu, DoMClobber, true);
  128.     }
  129.     EnableItem (fileMenu, new);    /* can always create at least one more now */
  130. }
  131.  
  132.  
  133. /*
  134.     Dispose of window.  Skel makes sure the port is pointing to the
  135.     appropriate window, so this procedure can determine which window
  136.     is to be disposed, of without being told explicitly.
  137. */
  138.  
  139. DoWClobber ()
  140. {
  141. GrafPtr    thePort;
  142.  
  143.     GetPort (&thePort);                /* grafport of window to dispose of */
  144.     DisposeWindow ((WindowPtr) thePort);
  145. }
  146.  
  147.  
  148. DoMClobber (theMenu)
  149. MenuHandle    theMenu;
  150. {
  151.     DisposeMenu (theMenu);
  152. }
  153.  
  154.  
  155. /*
  156.     Make new window.  Locate at (100, 100) if no other windows, else
  157.     offset slightly from front window.  The window title is the next
  158.     window number (1, 2, 3, ...).  If this is the first window, create
  159.     the Windows and Color menus.  Add the window title as the last item
  160.     of the Windows menu.
  161.  
  162.     If the maximum window count is reached, disable New in the
  163.     File menu.
  164. */
  165.  
  166.  
  167. MakeWindow ()
  168. {
  169. WindowPtr    w;
  170. Rect        r, r2;
  171. Str255        s;
  172.  
  173.     SetRect (&r, 0, 0, 200, 150);
  174.     if ((w = FrontWindow ()) == nil)
  175.         OffsetRect (&r, 100, 100);
  176.     else
  177.     {
  178.         r2 = w->portBits.bounds;
  179.         OffsetRect (&r, 20 - r2.left, 20 - r2.top);
  180.         if (r.left > 480 || r.top > 300)    /* keep on screen */
  181.             OffsetRect (&r, 40 - r.left, 40 - r.top);
  182.     }
  183.     NumToString (++windNum, s);
  184.     w = NewWindow (nil, &r, s, true, noGrowDocProc, -1L, true, 0L);
  185.     (void) SkelWindow (w,
  186.                 nil,        /* mouseclicks */
  187.                 nil,        /* key clicks */
  188.                 DoWUpdate,    /* updates */
  189.                 nil,        /* activate/deactivate events */
  190.                 DoWClose,    /* close window, remove from menu */
  191.                 DoWClobber,    /* dispose of window */
  192.                 nil,        /* idle proc */
  193.                 false);        /* irrelevant, since no idle proc */
  194.  
  195.     if (windCount++ == 0)    /* if first window, create new menus */
  196.     {
  197.         colorMenu = NewMenu (cMenuNum, "\pColor");
  198.         AppendMenu (colorMenu, "\pWhite;Light Gray;Gray;Dark Gray;Black");
  199.         (void) SkelMenu (colorMenu, DoColorMenu, DoMClobber, false);
  200.         windowMenu = NewMenu (wMenuNum, "\pWindows");
  201.         (void) SkelMenu (windowMenu, DoWindowMenu, DoMClobber, true);
  202.     }
  203.     AppendMenu (windowMenu, s);
  204.     if (windCount == maxWind)
  205.         DisableItem (fileMenu, new);
  206.  
  207. }
  208.  
  209.  
  210. DoFileMenu (item)
  211. Integer    item;
  212. {
  213.  
  214.     switch (item)
  215.     {
  216.         case quit: SkelWhoa (); break;    /* tell SkelMain to quit */
  217.         case new: MakeWindow (); break;    /* make a new window */
  218.     }
  219. }
  220.  
  221.  
  222. DoWindowMenu (item)
  223. Integer    item;
  224. {
  225. Str255        iTitle, wTitle;
  226. WindowPeek    w;
  227.  
  228.     GetItem (windowMenu, item, iTitle);    /* get window name */
  229.     for (w = (WindowPeek) FrontWindow (); w != nil; w = w->nextWindow)
  230.     {
  231.         GetWTitle (w, wTitle);
  232.         if (EqualString (iTitle, wTitle, false, true))
  233.         {
  234.             SelectWindow (w);
  235.             break;
  236.         }
  237.     }
  238. }
  239.  
  240.  
  241. /*
  242.     Change the background pattern of the frontmost window.  Ignore
  243.     if the front window is a DA window.
  244. */
  245.  
  246. DoColorMenu (item)
  247. Integer    item;
  248. {
  249. WindowPtr    w;
  250.  
  251.     w = FrontWindow ();
  252.     if (((WindowPeek) w)->windowKind < 0) return;    /* front is DA window */
  253.     switch (item)
  254.     {
  255.         case cWhite:    BackPat (white); break;
  256.         case cLtGray:    BackPat (ltGray); break;
  257.         case cGray:        BackPat (gray); break;
  258.         case cDkGray:    BackPat (dkGray); break;
  259.         case cBlack:    BackPat (black); break;
  260.     }
  261.     EraseRect (&w->portRect);
  262. }
  263.  
  264.  
  265. main ()
  266. {
  267.     SkelInit (6, nil);                            /* initialize */
  268.     SkelApple (nil, nil);                        /* handle desk accessories */
  269.     fileMenu = NewMenu (fMenuNum, "\pFile");    /* make File menu handler */
  270.     AppendMenu (fileMenu, "\pNew/N;(-;Quit/Q");
  271.     SkelGrowBounds (nil, 50, 10, 500, 300);
  272.     (void) SkelMenu (fileMenu, DoFileMenu, DoMClobber, true);
  273.     SkelMain ();                                /* loop 'til Quit selected */
  274.     SkelClobber ();                                /* clean up */
  275. }
  276.