home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / demo / winddemo.sit / wind.c.bin / wind.c
Encoding:
C/C++ Source or Header  |  1989-04-23  |  10.2 KB  |  431 lines  |  [TEXT/KAHL]

  1. /*
  2.  * wind.c - WindDemo: a demo of a custom Window Definition.
  3.  *
  4.  * How to build this program:
  5.  *    1) In the "iconproj" project, create the CODE resource, "icon.wdef".
  6.  *    2) Run RMaker on the file "wind.r".
  7.  *    4) In the "windproj" project, Build the Application, WindDemo.
  8.  *
  9.  *
  10.  * The interesting parts of this program are:
  11.  *
  12.  *    1) In doevent(), when growing a window (just before calling SizeWindow()),
  13.  *    it forces small windows to be the size of an icon;
  14.  *
  15.  *    2) In drawwindow(), any small window gets an icon drawn it in
  16.  *    instead of its normal stuff.
  17.  *
  18.  * The rest of this program is just boilerplate
  19.  * (and not very pretty code anyway!)
  20.  */
  21.  
  22. #include <MacTypes.h>
  23. #include <Quickdraw.h>
  24. #include <MemoryMgr.h>
  25. #include <WindowMgr.h>
  26. #include <DialogMgr.h>
  27. #include <MenuMgr.h>
  28. #include <EventMgr.h>
  29. #include <DeskMgr.h>
  30. #include <ControlMgr.h>
  31. #include <TextEdit.h>
  32. #include <PackageMgr.h>
  33. #include <ToolboxUtil.h>
  34. #include <pascal.h>
  35.  
  36. /*
  37.  * SMALLWIDTH,
  38.  * SMALLHEIGHT    - largest dimensions of a collapsed-state window.
  39.  *  Any window larger than this (in both dimensions) is a standard window.
  40.  *
  41.  * These numbers come from the iconwind WDEF.
  42.  */
  43.  
  44. #define SMALLWIDTH    63
  45. #define SMALLHEIGHT    15
  46.  
  47. /*
  48.  * ICONSIZE    - the width/height of an icon.
  49.  * This program forces any collapsed window to the size of an icon.
  50.  */
  51.  
  52. #define ICONSIZE 32
  53.  
  54. #define APPLEMENU    1    /* Menu ID for Apple menu    */
  55. #define FILEMENU    2    /* ...File menu                */
  56. #define LASTMENU    2    /* Number of menus            */
  57.  
  58. #define DLG_ABOUT    256    /* ResID of the About... dialog */
  59.  
  60. /*
  61.  * *FILE - items in the FILE menu
  62.  */
  63.  
  64. #define NEWFILE        1    /* create a new window */
  65. #define QUITFILE    2    /* quit the program */
  66.  
  67. MenuHandle mymenus[LASTMENU + 1]; /* menus[1..LASTMENU]    */
  68.  
  69. #define maxStackSize 8192    /* max size of our stack */
  70.  
  71. /*
  72.  * screenport - used to keep the current port from ever dangling.
  73.  *   This is a port for the whole screen.
  74.  */
  75.  
  76. GrafPtr screenport;
  77.  
  78. #define NUM_WINDOWS 3                /* number of window's in the program */
  79. WindowPtr windoc[NUM_WINDOWS];        /* the program's windows    */
  80.  
  81. #define WINDOWID    260        /* Resource ID of my first window */
  82. #define ICONID        260        /* Resource ID of the icon to plot */
  83.  
  84. /*
  85.  * main() - run the program.
  86.  */
  87.  
  88. main()
  89. {
  90.     int widx;                    /* index into wrecord[] */
  91.     long *stackbaseptr;            /* points to current stack base */
  92.     int i;
  93.  
  94.     /*
  95.      * Initialize our memory,
  96.      * then init the Toolbox managers (order is important).
  97.      */
  98.  
  99.     stackbaseptr = (long *) 0x908;
  100.     SetApplLimit((Ptr) (*stackbaseptr - maxStackSize));
  101.     MaxApplZone();
  102.     MoreMasters();
  103.     MoreMasters();
  104.  
  105.     InitGraf(&thePort);
  106.     InitFonts();
  107.     InitWindows();
  108.     InitMenus();
  109.     TEInit();
  110.     InitDialogs((ProcPtr) 0);
  111.     DILoad();
  112.     SetEventMask(everyEvent - keyUpMask);
  113.     InitCursor();
  114.     GetWMgrPort(&screenport);
  115.     SetPort(screenport);
  116.  
  117.     /*
  118.      * Setup our menus.
  119.      */
  120.  
  121.     for (i = 1; i <= LASTMENU; i++) {
  122.         mymenus[i] = GetMenu(i);
  123.         InsertMenu(mymenus[i], 0);
  124.     }
  125.     DrawMenuBar();
  126.  
  127.     /*
  128.      * Create our first window.
  129.      */
  130.     
  131.     makewindow();
  132.  
  133.     while (doevent())
  134.         ;
  135.     InitCursor();
  136.     SetEventMask(everyEvent - keyUpMask);
  137. }
  138.  
  139. /*
  140.  * makewindow() - create a new window.
  141.  */
  142.  
  143. makewindow()
  144. {
  145.     static WindowRecord wrecord[NUM_WINDOWS]; /* Storage for window records. */
  146.     int widx;
  147.     
  148.     for (widx = 0; widx < NUM_WINDOWS && windoc[widx]; ++widx)
  149.         ;
  150.     if (widx < NUM_WINDOWS) {
  151.         windoc[widx] = GetNewWindow(WINDOWID + widx, &wrecord[widx], (long) -1);
  152.     }
  153. }
  154.  
  155. /*
  156.  * unmakewindow() - destroy (close) a window.
  157.  */
  158.  
  159. unmakewindow(windp)
  160. WindowPtr windp;        /* the window to destroy */
  161. {
  162.     int widx;
  163.  
  164.     for (widx = 0; widx < NUM_WINDOWS && windoc[widx] != windp; ++widx)
  165.         ;
  166.     if (widx < NUM_WINDOWS) {
  167.         CloseWindow(windp);
  168.         windoc[widx] = (WindowPtr) 0;
  169.     }
  170. }
  171.  
  172. /*
  173.  * doevent() - one loop through the main event handler
  174.  */
  175.  
  176. int        /* "do another event"    */
  177. doevent()
  178. {
  179.     GrafPtr saveport;
  180.     EventRecord myevent;    /* the event to handle */
  181.     WindowPtr whichwindow;    /* Points to window of MouseDown */
  182.     char whichchar;            /* the character typed */
  183.     long menucommand;        /* a menu command to do (menu + item) */
  184.     int windowcode;            /* What mouse was in when event posted */
  185.     Rect dragrect;            /* Bounds of window dragging */
  186.     Rect limits;            /* limits to growth */
  187.     long newdims;            /* new width & height of the window    */
  188.     int newwidth, newheight; /* newdims split into width and height */
  189.     int userdone;            /* True when user wants to exit program */
  190.  
  191.     userdone = FALSE;
  192.     SystemTask();            /* give the system a moment of time    */
  193.  
  194.     if (!GetNextEvent(everyEvent, &myevent)) {
  195.         /* We're idle. */
  196.     } else if ((myevent.modifiers & cmdKey) &&
  197.       (myevent.what == keyDown || myevent.what == autoKey)) {
  198.     
  199.         /*
  200.          * It's a command-key keystroke.
  201.          * (command keystrokes are handled here since dialogs can't)
  202.          */
  203.     
  204.         whichchar = (char) (myevent.message & charCodeMask);
  205.         menucommand = MenuKey(whichchar);
  206.         userdone = docommand(menucommand);
  207.     } else if (IsDialogEvent(&myevent)) {
  208.         /* here's where we'd handle modeless dialog events */
  209.     } else {
  210.         switch (myevent.what) {
  211.         case updateEvt:            /* update the appropriate window */
  212.             BeginUpdate((WindowPtr)(myevent.message));
  213.             GetPort(&saveport);
  214.             SetPort((WindowPtr)(myevent.message));
  215.             
  216.             drawwindow((WindowPtr)(myevent.message));
  217.             
  218.             SetPort(saveport);
  219.             EndUpdate((WindowPtr)(myevent.message));
  220.             break;
  221.         case activateEvt:        /* activate or deactivate window */
  222.             if (myevent.modifiers & 1) {
  223.                 SetPort((WindowPtr) myevent.message);
  224.                 InvalRect(&thePort->portRect);
  225.             } else {
  226.                 InvalRect(&thePort->portRect);
  227.                 SetPort(screenport);
  228.             }
  229.             break;
  230.         case mouseDown:            /* a mouse click someplace    */
  231.             windowcode = FindWindow(myevent.where, &whichwindow);
  232.             
  233.             switch (windowcode) {
  234.             case inSysWindow:        /* a DA's window */
  235.                 SystemClick(&myevent, whichwindow);
  236.                 break;
  237.             case inMenuBar:            /* a menu item */
  238.                 menucommand = MenuSelect(myevent.where);
  239.                 userdone = docommand(menucommand);
  240.                 break;
  241.             case inDrag:            /* Title Bar */
  242.  
  243.                 /*
  244.                  * Drag the window around.
  245.                  *
  246.                  * If the clicked window wasn't selected
  247.                  * (and this wasn't a command-click), select it.
  248.                  */
  249.  
  250.                 if (whichwindow != FrontWindow() &&
  251.                   (myevent.modifiers & cmdKey) == 0) {
  252.                     SelectWindow(whichwindow);
  253.                 }
  254.  
  255.                 dragrect.left = 4;
  256.                 dragrect.top = 24;
  257.                 dragrect.right = screenBits.bounds.right - 4;
  258.                 dragrect.bottom = screenBits.bounds.bottom - 4;
  259.  
  260.                 DragWindow(whichwindow, myevent.where, &dragrect);
  261.                 break;
  262.             case inGoAway:            /* Close box    */
  263.                 if (TrackGoAway(whichwindow, myevent.where)) {
  264.                     unmakewindow(whichwindow);
  265.                 }
  266.                 break;
  267.             case inZoomIn:
  268.             case inZoomOut:            /* Zoom box    */
  269.                 if (TrackBox(whichwindow, myevent.where, windowcode)) {
  270.                     EraseRect(&whichwindow->portRect);
  271.                     ZoomWindow(whichwindow, windowcode, FALSE);
  272.                 }
  273.                 break;
  274.             case inGrow:            /* in the grow region */
  275.                 limits.top = 15;
  276.                 limits.left = 15;
  277.                 limits.bottom =
  278.                   screenport->portRect.bottom - screenport->portRect.top;
  279.                 limits.right =
  280.                   screenport->portRect.right - screenport->portRect.left;
  281.  
  282.                 limits.right++;        /* (to compensate for a toolbox bug) */
  283.                 limits.bottom++;    /* (ditto) */
  284.                 
  285.                 newdims = GrowWindow(whichwindow, myevent.where, &limits);
  286.                 if (newdims != 0L) {
  287.                 
  288.                     /**********
  289.                      * Here's one of the two interesting parts of this program:
  290.                      *
  291.                      * If the new window size is small, it is forced to be
  292.                      * the size of an icon.
  293.                      **********/
  294.                      
  295.                     newwidth = LoWord(newdims);
  296.                     newheight = HiWord(newdims);
  297.                     
  298.                     if (newwidth <= SMALLWIDTH || newheight <= SMALLHEIGHT) {
  299.                         newwidth = ICONSIZE;
  300.                         newheight = ICONSIZE;
  301.                     }
  302.                     SizeWindow(whichwindow, newwidth, newheight, -1);
  303.                     InvalRect(&thePort->portRect);
  304.                 }
  305.                 break;
  306.             case inContent:            /* Somewhere in the window */
  307.                 if (whichwindow != FrontWindow()) {
  308.                     /* the window isn't active - just activate it */
  309.                     SelectWindow(whichwindow);
  310.                 } else {
  311.  
  312.                     /*
  313.                      * The window is active,
  314.                      *   interpret the mouse-down in this window's context.
  315.                      */
  316.  
  317.                     GlobalToLocal(&myevent.where);
  318.                 }
  319.             }
  320.             break;
  321.         }
  322.     }
  323.     return(!userdone);
  324. }
  325.  
  326. /*
  327.  * docommand() - handle a command given through a menu selection.
  328.  */
  329.  
  330. int        /* "the command was 'quit' */
  331. docommand(mresult)
  332. long    mresult;    /* the command to execute (a menu item)    */
  333. {
  334.     int themenu;        /* menu the mouse chose */
  335.     int theitem;        /* item in that menu */
  336.     int     returns;        /* value to be returned */
  337.     short itemhit;        
  338.     DialogPtr reportptr;
  339.  
  340.     returns = FALSE;
  341.     themenu = HiWord(mresult);
  342.     theitem = LoWord(mresult);
  343.     
  344.     switch (themenu) {
  345.     case APPLEMENU:            /* Tell about the program */
  346.         reportptr = GetNewDialog(DLG_ABOUT, (char *) 0, (long) -1);
  347.         ModalDialog((ProcPtr) 0, &itemhit);
  348.         DisposDialog(reportptr);
  349.         break;
  350.  
  351.     case FILEMENU:
  352.         switch (theitem) {
  353.         case NEWFILE:        /* create a new window (if we can) */
  354.             makewindow();
  355.             break;
  356.         case QUITFILE:        /* quit the program */
  357.             returns = TRUE;
  358.             break;
  359.         }
  360.         break;
  361.     }
  362.     HiliteMenu(0);
  363.     return(returns);
  364. }
  365.  
  366. /*
  367.  * drawwindow() - draw the given window's contents into the current port.
  368.  */
  369.  
  370. drawwindow(windp)
  371. WindowPtr windp;
  372. {
  373.     int widx;
  374.     Handle iconh;    /* an icon to draw */
  375.     Rect tmprect;    /* a temporary rectangle */
  376.     RgnHandle oldclip;    /* original clip region to restore */
  377.     
  378.     for (widx = 0; widx < NUM_WINDOWS && windp != windoc[widx]; ++widx)
  379.         ;
  380.     if (widx >= NUM_WINDOWS) return;
  381.  
  382.     EraseRgn(thePort->visRgn);
  383.     
  384.  
  385.     /**********
  386.      * Here's the other interesting part of this program:
  387.      *
  388.      * If the window is small, an icon is drawn in it
  389.      * (rather than its normal stuff).
  390.      **********/
  391.      
  392.     if (thePort->portRect.right - thePort->portRect.left <= SMALLWIDTH ||
  393.       thePort->portRect.bottom - thePort->portRect.top <= SMALLHEIGHT) {
  394.         
  395.         /*
  396.          * It's a collapsed window -- draw our icon in it.
  397.          */
  398.         
  399.         tmprect.left = 0;
  400.         tmprect.top = 0;
  401.         tmprect.right = tmprect.left + 32;
  402.         tmprect.bottom = tmprect.top + 32;
  403.         iconh = GetIcon(ICONID);
  404.         PlotIcon(&tmprect, iconh);
  405.  
  406.     } else {
  407.     
  408.         /*
  409.          * It's a standard window -- draw something interesting
  410.          * excluding the scrollbar area.
  411.          */
  412.         
  413.         tmprect = thePort->portRect;
  414.         tmprect.right -= 15;
  415.         tmprect.bottom -= 15;
  416.         oldclip = NewRgn();
  417.         if (oldclip) {
  418.             GetClip(oldclip);
  419.             RectRgn(thePort->clipRgn, &tmprect);
  420.             SectRgn(oldclip, thePort->clipRgn, thePort->clipRgn);
  421.         }
  422.         TextBox("The WDEF acts like a standard window until it shrinks \
  423. past a certain point.", 75L, &tmprect, teJustLeft);
  424.         if (oldclip) {
  425.             SetClip(oldclip);
  426.             DisposeRgn(oldclip);
  427.         }
  428.         DrawGrowIcon(windp);
  429.     }
  430. }
  431.