home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / Boxes / BoardDlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  4.6 KB  |  205 lines  |  [TEXT/KAHL]

  1. /*
  2.  * The size of the little squares in the board representation is determined from
  3.  * the size of the board userItem rectangle, which should be
  4.  *    (i) square
  5.  *    (ii) have a side length of maxSquares * (some integer) + 1
  6.  *
  7.  * This does not use the color manager used to manage the main window.
  8.  * That needs to be fixed if the color model is ever done correctly.
  9.  */
  10.  
  11. # include    "TransSkel.h"
  12.  
  13. # include    "Boxes.h"
  14.  
  15. # define    normalHilite    0
  16. # define    dimHilite        255
  17.  
  18. typedef enum        /* Board Size dialog item numbers */
  19. {
  20.     iOK = 1,        /* OK button */
  21.     iCancel,        /* Cancel button */
  22.     iBoard,            /* board sizing user item */
  23.     iTitle,            /* static text */
  24.     iOutline        /* user item for outlining OK button */
  25. };
  26.  
  27. static Rect        boardRect;
  28. static short    sqSize;
  29. static short    curCols, curRows;
  30. static short    state[maxSquares][maxSquares];
  31.  
  32.  
  33.  
  34. /*
  35.  * Set the state of the squares in the board representation and redraw any
  36.  * square that has changed state.  All squares are drawn if drawAnyway is
  37.  * true, whether they change state or not; this is necessary to cause the
  38.  * board to be drawn correctly the first time.
  39.  */
  40.  
  41. static void
  42. SetBoardState (short cols, short rows, Boolean drawAnyway)
  43. {
  44. short    h, v, oldState, newState;
  45. short    hPos, vPos;
  46. Rect    r;
  47.  
  48.     curCols = cols;
  49.     curRows = rows;
  50.     if (curCols < 0)            /* clip values to 0..maxSquares */
  51.         curCols = 0;
  52.     if (curCols > maxSquares)
  53.         curCols = maxSquares;
  54.     if (curRows < 0)
  55.         curRows = 0;
  56.     if (curRows > maxSquares)
  57.         curRows = maxSquares;
  58.     for (h = 0; h < maxSquares; h++)
  59.     {
  60.         for (v = 0; v < maxSquares; v++)
  61.         {
  62.             oldState = state[h][v];
  63.             state[h][v] = newState = (h < curCols & v < curRows);
  64.             /* redraw if always draw or if state has changed */
  65.             if (drawAnyway || oldState != newState)
  66.             {
  67.                 hPos = boardRect.left + 1 + h * sqSize;
  68.                 vPos = boardRect.top + 1 + v * sqSize;
  69.                 SetRect (&r, hPos + 1, vPos + 1, hPos + sqSize - 2, vPos + sqSize - 2);
  70.                 if (newState)
  71.                     PaintRect (&r);
  72.                 else
  73.                     EraseRect (&r);
  74.             }
  75.         }
  76.     }
  77. }
  78.  
  79.  
  80. /*
  81.  * Filter function for board dialog.  Checks for hits in the board
  82.  * size rectangle and follow the mouse as long as it's held down.
  83.  */
  84.  
  85. static pascal Boolean
  86. BoardFilter (DialogPtr dlog, EventRecord *evt, short *item)
  87. {
  88. Point    pt;
  89. short    cols, rows;
  90. char    c;
  91. short    hilite;
  92.  
  93.     if (evt->what == keyDown)
  94.     {
  95.         c = evt->message & charCodeMask;
  96.         if (c == '\r' || c == 3 /* enter */)
  97.         {
  98.             if (curCols * curRows > 0)    /* ignore if no squares selected */
  99.             {
  100.                 SkelFlashButton (SkelGetDlogCtl (dlog, iOK));
  101.                 *item = 1;
  102.                 return (true);
  103.             }
  104.             SysBeep (1);
  105.         }
  106.     }
  107.     else if (evt->what == mouseDown)
  108.     {
  109.         pt = evt->where;
  110.         GlobalToLocal (&pt);
  111.         if (PtInRect (pt, &boardRect))
  112.         {
  113.             for (;;)
  114.             {
  115.                 cols = ((pt.h - boardRect.left - 1) / sqSize) + 1;
  116.                 rows = ((pt.v - boardRect.top - 1) / sqSize) + 1;
  117.                 if (cols != curCols || rows != curRows)
  118.                     SetBoardState (cols, rows, false);
  119.                 if (!StillDown ())
  120.                     break;
  121.                 GetMouse (&pt);
  122.             }
  123.  
  124.             /*
  125.              * Dim OK button and button outline if board is empty.  Don't
  126.              * redraw unless button state actually changes.
  127.              */
  128.  
  129.             hilite = (curCols * curRows > 0 ? normalHilite : dimHilite);
  130.             if (SkelSetDlogCtlHilite (dlog, iOK, hilite))
  131.                 SkelDrawButtonOutline (SkelGetDlogCtl (dlog, iOK));
  132.         }
  133.     }
  134.     return (false);
  135. }
  136.  
  137.  
  138. static pascal void
  139. DrawBoardItem (DialogPtr dlog, short item)
  140. {
  141. Rect    r;
  142.  
  143.     SkelGetDlogRect (dlog, item, &r);
  144.     FrameRect (&r);
  145.     DrawGrid (maxSquares + 1, maxSquares + 1, r.left, r.top, sqSize, sqSize);
  146.     SetBoardState (curCols, curRows, true);
  147. }
  148.  
  149.  
  150. void
  151. BoardDialog (void)
  152. {
  153. ModalFilterProcPtr    filter;
  154. DialogPtr    dlog;
  155. GrafPtr        savePort;
  156. short        item = 0;
  157.  
  158.     dlog = GetNewDialog (boardDlog, nil, (WindowPtr) -1L);
  159.     if (dlog == (DialogPtr) nil)
  160.     {
  161.         SysBeep (1);
  162.         return;
  163.     }
  164.  
  165.     SkelPositionWindow (dlog, skelPositionOnParentDevice, horizRatio, vertRatio);
  166.     
  167.     SetCursor (&arrow);
  168.     GetPort (&savePort);
  169.     SetPort (dlog);
  170.  
  171.     /* get board rect and set draw proc for board userItem */
  172.     SkelGetDlogRect (dlog, iBoard, &boardRect);
  173.     SkelSetDlogProc (dlog, iBoard, DrawBoardItem);
  174.  
  175.  
  176.     /* install OK button outliner */
  177.     SkelSetDlogButtonOutliner (dlog, iOutline);
  178.  
  179.     /* these must be set before dialog is drawn in order */
  180.     /* that the board be drawn and hilited correctly */
  181.     sqSize = (boardRect.right - boardRect.left - 1 ) / maxSquares;
  182.     GetBoardSize (&curCols, &curRows);
  183.  
  184.     ShowWindow (dlog);
  185.     
  186.     for (;;)
  187.     {
  188.         /* 2nd arg to SkelDlogFilter is false since BoardFilter() handles cr/lf */
  189.         filter = SkelDlogFilter (BoardFilter, false);
  190.         SkelDlogCancelItem (iCancel);
  191.         ModalDialog (filter, &item);
  192.         SkelRmveDlogFilter ();
  193.         if (item == iOK || item == iCancel)
  194.             break;
  195.     }
  196.  
  197.     SetPort (savePort);
  198.     DisposeDialog (dlog);
  199.     if (item == iOK)
  200.     {
  201.         SetBoardSize (curCols, curRows);
  202.         NewGame ();
  203.     }
  204. }
  205.