home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / luschsrc.sit / window.c < prev    next >
Text File  |  1990-05-23  |  11KB  |  542 lines

  1.  /********************************************************************************
  2.  *    window.c
  3.  *
  4.  *    Window Management Package
  5.  *
  6.  *    Written by Paco Xander Nathan
  7.  *    ⌐1990, Motorola Inc.  Public domain source code.
  8.  ********************************************************************************/
  9.  
  10. #include "applic.h"
  11. #include "window.h"
  12. #include "dialog.h"
  13. #include "context.h"
  14. #include "document.h"
  15. #include "error.h"
  16. #include "text.h"
  17. #include "list.h"
  18.  
  19. #include "test.h"
  20.  
  21.  
  22. #define MAXPTRS    50
  23.  
  24.  
  25. typedef struct  {
  26.     short count;
  27.     WindowPtr wind[MAXPTRS];
  28. } WindPtrList;
  29.  
  30.  
  31. /* Local Data Structures
  32.  */
  33. static WindPtrList
  34.     windList;
  35.  
  36.  
  37. /* External Data Structures
  38.  */
  39. WindowPtr
  40.     wPtrText = NULL, 
  41.     wPtrTest = NULL,
  42.     wPtrGnos = NULL;
  43.  
  44. Rect 
  45.     dragArea,
  46.     growArea;
  47.     
  48. Boolean
  49.     windTrip = FALSE;
  50.  
  51.  
  52. /* Local Function Prototypes
  53.  */
  54. #ifdef PROTOTYPES
  55. void WindInvalGrow (WindowPtr theWindow);
  56. #endif
  57.  
  58.  
  59. /* Invalidate the grow box and scroll bar rectangles for the given window
  60.  */
  61. static void
  62. WindInvalGrow (theWindow)
  63.     register WindowPtr theWindow;
  64. {
  65.     Rect inval;
  66.     
  67.     /* Invalidate the verticle scroll
  68.      */
  69.     inval = theWindow->portRect;
  70.     inval.left = inval.right - 16;
  71.     InvalRect(&inval);
  72.  
  73.     /* Invalidate the horizontal scroll
  74.      */
  75.     inval = theWindow->portRect;
  76.     inval.top = inval.bottom - 16;
  77.     InvalRect(&inval);
  78. }
  79.  
  80.  
  81. /* Check if the front window is a modeless dialog that belongs to our application
  82.  */
  83. Boolean
  84. WindIsDlog (theWindow)
  85.     register WindowPtr theWindow;
  86. {
  87.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  88.  
  89.     return (theWindow != NULL) && (((WindowPeek) theWindow)->windowKind >= 0) && (infoPtr->kind == wkDlog);
  90. }
  91.  
  92.  
  93. /* Check if the front window belongs to our application
  94.  */
  95. Boolean
  96. WindIsApp (theWindow)
  97.     register WindowPtr theWindow;
  98. {
  99.     return (theWindow != NULL) && (((WindowPeek) theWindow)->windowKind >= 0);
  100. }
  101.  
  102.  
  103. /* Check if the front window belongs to a DA
  104.  */
  105. Boolean
  106. WindIsDA (theWindow)
  107.     register WindowPtr theWindow;
  108. {
  109.     return (theWindow != NULL) && (((WindowPeek) theWindow)->windowKind < 0);
  110. }
  111.  
  112.  
  113. /* Resize the window
  114.  */
  115. void
  116. WindGrow (theWindow, theEvent)
  117.     register WindowPtr theWindow;
  118.     register EventRecord *theEvent;
  119. {
  120.     GrafPtr savePort;
  121.     register long newSize;
  122.     register short newH, newV;
  123.  
  124.     GetPort(&savePort);
  125.     SetPort(theWindow);
  126.  
  127.     if (newSize = GrowWindow(theWindow, theEvent->where, &growArea)) {
  128.         newV = Max(HiWord(newSize), 20);
  129.         newH = Max(LoWord(newSize), 20);
  130.  
  131.         /* Resize the window, adjust window dimensions
  132.          */
  133.         SizeWindow(theWindow, newH, newV, TRUE);
  134.         WindAdjust(theWindow);
  135.         InvalRect(&theWindow->portRect);
  136.     }
  137.  
  138.     SetPort(savePort);
  139. }
  140.  
  141.  
  142. /* Zoom the window in or out
  143.  */
  144. void
  145. WindZoom (theWindow, thePart)
  146.     register WindowPtr theWindow;
  147.     register short thePart;
  148. {
  149.     GrafPtr savePort;
  150.  
  151.     GetPort(&savePort);
  152.     SetPort(theWindow);
  153.  
  154.     /* Zoom the window and adjust the window rect dimensions
  155.      */
  156.     HideWindow(theWindow);
  157.  
  158.     ZoomWindow(theWindow, thePart, TRUE);
  159.     WindAdjust(theWindow);
  160.     /* WindInvalGrow(theWindow); */
  161.  
  162.     ShowWindow(theWindow);
  163.     SetPort(savePort);
  164. }
  165.  
  166.  
  167. /* Reposition a window in the center of the screen
  168.  */
  169. void
  170. WindCenter (theWindow)
  171.     register WindowPtr theWindow;
  172.     register short hWind, vWind, hScrn, vScrn;
  173.  
  174.     hScrn = screenBits.bounds.right - screenBits.bounds.left;
  175.     vScrn = screenBits.bounds.bottom - screenBits.bounds.top;
  176.  
  177.     hWind = theWindow->portRect.right - theWindow->portRect.left;
  178.     vWind = theWindow->portRect.bottom - theWindow->portRect.top;
  179.  
  180.     /* Reset the horizontal and the vertical position
  181.      */
  182.     MoveWindow(theWindow, (hScrn - hWind) / 2, ((vScrn - vWind) / 3) + MBarHeight, FALSE);
  183. }
  184.  
  185.  
  186. /* Moves and sizes window to new location
  187.  */
  188. void 
  189. WindPlace (theWindow, left, top, right, bottom)
  190.     register WindowPtr theWindow;
  191.     register short left, top, right, bottom;
  192. {
  193.     /* Move window to a specified location in global coordinates
  194.      */
  195.     MoveWindow(theWindow, left, top, FALSE);
  196.     SizeWindow(theWindow, right - left, bottom - top, TRUE);
  197.     WindAdjust(theWindow);
  198. }
  199.  
  200.  
  201. /* Stacks windows diagonally based on constraint rect
  202.  */
  203. void
  204. WindTileStack ()
  205. {
  206.     register WORD width, height, vStagger, hStagger, i, j;
  207.     register WindowPtr theWindow = FrontWindow();
  208.     register WORD numWindows = 0;
  209.     GrafPtr savePort;
  210.  
  211.     GetPort(&savePort);
  212.  
  213.     /* Now we take a trip through the looking glass to build the list of
  214.      * OUR windows
  215.      */
  216.     while (theWindow != NULL) {
  217.         if (((WindowPeek) theWindow)->visible)
  218.                 windList.wind[numWindows++] = theWindow;
  219.  
  220.         theWindow = (WindowPtr) ((WindowPeek) theWindow)->nextWindow;
  221.     }
  222.  
  223.     if ((numWindows > 1) && (numWindows <= MAXPTRS)) {
  224.         height = (dragArea.bottom - dragArea.top) / 2;
  225.         width = (dragArea.right - dragArea.left) / 2;
  226.         vStagger = (height / (numWindows - 1)) + 1;
  227.         hStagger = (width / (numWindows - 1)) + 1;
  228.     
  229.         for (i = numWindows - 1; i >= 0; i--) {
  230.             if (theWindow = windList.wind[i]) {        
  231.                 SetPort(theWindow);
  232.                 WindActivate(theWindow, FALSE);
  233.  
  234.                 j = numWindows - i - 1;
  235.                 MoveWindow(theWindow, dragArea.left + (hStagger * j), dragArea.top + (vStagger * j) + 20, FALSE);
  236.             }
  237.         }
  238.         
  239.         SelectWindow(theWindow);
  240.     }
  241.     
  242.     /* Thank you for coming, see you later
  243.      */
  244.     windTrip = FALSE;
  245.     SetPort(savePort);
  246. }
  247.  
  248.  
  249. /* Draw an application window - switch on particular window to draw all the fancy
  250.  * bells and whistles
  251.  */
  252. void
  253. WindReDraw (theWindow)
  254.     register WindowPtr theWindow;
  255. {
  256.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  257.  
  258.     /* Determine which kind of window this is, then lock and update
  259.      */
  260.     switch(infoPtr->kind) {
  261.     case wkText:
  262.         TEUpdate(&theWindow->portRect, infoPtr->item.text.teHdl);
  263.         DrawControls(theWindow);
  264.         break;
  265.  
  266.     case wkList:
  267.         ListDraw(theWindow, TRUE);
  268.         break;
  269.         
  270.     default:
  271.         break;
  272.     }
  273. }
  274.  
  275.  
  276. /* Update a window
  277.  */
  278. void
  279. WindUpdate (theWindow)
  280.     register WindowPtr theWindow;
  281. {
  282.     GrafPtr savePort;
  283.  
  284.     GetPort(&savePort);
  285.     SetPort(theWindow);
  286.  
  287.     BeginUpdate(theWindow);
  288.  
  289.     if (!EmptyRgn(theWindow->visRgn)) {
  290.         ClipRect(&theWindow->portRect);
  291.         EraseRect(&theWindow->portRect);
  292.  
  293.         WindReDraw(theWindow);
  294.         /* DrawGrowIcon(theWindow); */
  295.  
  296.         /* Specially handle custom windows
  297.          */
  298.         if (theWindow == wPtrTest)
  299.             TestDraw();
  300.     }
  301.  
  302.     EndUpdate(theWindow);
  303.     SetPort(savePort);
  304. }
  305.  
  306.  
  307. /* Handle an activate/deactivate event
  308.  */
  309. void
  310. WindActivate (theWindow, isActive)
  311.     register WindowPtr theWindow;
  312.     register Boolean isActive;
  313. {
  314.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  315.     GrafPtr savePort;
  316.  
  317.     GetPort(&savePort);
  318.     SetPort(theWindow);
  319.  
  320.     /* Determine which kind of window this is, then lock and activate/deactivate
  321.      */
  322.     switch(infoPtr->kind) {
  323.     case wkText:
  324.         TextActivate(isActive, theWindow);
  325.         break;
  326.  
  327.     case wkList:
  328.         LActivate(isActive, infoPtr->item.list);
  329.         break;
  330.         
  331.     default:
  332.         break;
  333.     }
  334.  
  335.     /* Redraw the grow box
  336.      */
  337.     /* WindInvalGrow(theWindow); */
  338.  
  339.     SetPort(savePort);
  340. }
  341.  
  342.     
  343. /* Determine which kind of window to adjust
  344.  */
  345. void
  346. WindAdjust (theWindow)
  347.     register WindowPtr theWindow;
  348. {
  349.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  350.  
  351.     switch (infoPtr->kind) {
  352.     case wkText:
  353.         TextAdjust(theWindow);
  354.         break;
  355.  
  356.     case wkList:
  357.         ListAdjust(theWindow);
  358.         break;
  359.  
  360.     default:
  361.         break;
  362.     }
  363.  
  364.     /* Reset cliprect to new size.
  365.      */
  366.     ClipRect(&(theWindow->portRect));
  367. }
  368.  
  369.  
  370. /* Decide how to handle a mouse click in the content of a window
  371.  */
  372. void
  373. WindContent (theWindow, theEvent)
  374.     register WindowPtr theWindow;
  375.     register EventRecord *theEvent;
  376. {
  377.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  378.     GrafPtr savePort;
  379.     Point thePoint;
  380.  
  381.     /* Convert to global coordinates
  382.      */
  383.     GetPort(&savePort);
  384.     SetPort(theWindow);
  385.  
  386.     thePoint = theEvent->where;
  387.     GlobalToLocal(&thePoint);    
  388.  
  389.     if (theWindow == wPtrTest)
  390.         TestClick(thePoint);
  391.  
  392.     switch (infoPtr->kind) {
  393.     case wkText:
  394.         /* Click in one of the text windows
  395.          */
  396.         TextContent(theWindow, theEvent->modifiers, thePoint);
  397.         break;
  398.         
  399.     case wkList:
  400.         /* Click in one of the list windows
  401.          */
  402.         ListContent(theWindow, theEvent->modifiers, thePoint);
  403.         break;
  404.         
  405.     default:
  406.         break;
  407.     }
  408.     
  409.     SetPort(savePort);
  410. }
  411.  
  412.  
  413. /* Open or close a window context, depending on how "pleaseOpen" is set
  414.  */
  415. void 
  416. WindSwitch (theWindow, pleaseOpen)
  417.     register WindowPtr theWindow;
  418.     register Boolean pleaseOpen;
  419. {
  420.     register WindowPtr frontWind = FrontWindow();
  421.  
  422.     /* Open/Close the specified window
  423.      */
  424.     if (pleaseOpen) {
  425.         if (!((WindowPeek) theWindow)->visible) {
  426.             ShowHide(theWindow, TRUE);
  427.             windTrip = TRUE;
  428.         }
  429.  
  430.         if (theWindow != frontWind)
  431.             SelectWindow(theWindow);
  432.     }
  433.     else {
  434.         if (((WindowPeek) theWindow)->visible) {
  435.             WindActivate(theWindow, FALSE);
  436.             ShowHide(theWindow, FALSE);
  437.             windTrip = TRUE;
  438.         }
  439.     }
  440. }
  441.  
  442.  
  443. /* Allocate a new window based on the specified window template
  444.  */
  445. WindowPtr
  446. WindAllocate (windID, isActive)
  447.     register short windID;
  448.     register Boolean isActive;
  449. {
  450.     register WindowPtr theWindow;
  451.     register InfoPtr infoPtr;
  452.     register Rect bounds;
  453.     static short offset = 0;
  454.     GrafPtr savePort;
  455.  
  456.     /* Create the window record from the window template resources
  457.      */
  458.     if (laMachine.hasColor)
  459.         theWindow = (WindowPtr) GetNewCWindow(windID, NULL, -1L);
  460.     else
  461.         theWindow = (WindowPtr) GetNewWindow(windID, NULL, -1L);
  462.     
  463.     if (theWindow) {
  464.         GetPort(&savePort);
  465.         SetPort(theWindow);
  466.  
  467.         if (infoPtr = (InfoPtr) ErrNewPtr(sizeof(InfoRecord))) {
  468.         infoPtr->kind = wkNone;
  469.             infoPtr->active = isActive;
  470.             infoPtr->dirty = infoPtr->named = FALSE;
  471.             SetWRefCon(theWindow, (long) infoPtr);
  472.  
  473.             offset += 10;
  474.             bounds.left = dragArea.left + offset;
  475.             bounds.top = dragArea.top + offset + 30;
  476.             bounds.right = bounds.left + (theWindow->portRect.right - theWindow->portRect.left);
  477.             bounds.bottom = bounds.top + (theWindow->portRect.bottom - theWindow->portRect.top);
  478.             WindPlace(theWindow, bounds.left, bounds.top, bounds.right, bounds.bottom);
  479.         }
  480.         else {
  481.             DisposeWindow(theWindow);
  482.             theWindow = NULL;
  483.         }
  484.  
  485.         SetPort(savePort);
  486.     }
  487.     
  488.     return theWindow;
  489. }
  490.  
  491.  
  492. /* Close the specified window
  493.  */
  494. void
  495. WindClose (theWindow)
  496.     register WindowPtr theWindow;
  497. {
  498.     register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
  499.  
  500.     if ((theWindow == wPtrText) || (theWindow == dPtrAnal))
  501.         WindSwitch(theWindow, FALSE);
  502.     else if (theWindow == wPtrTest)
  503.         WindZapPort(theWindow, FALSE);
  504.     else if (infoPtr->kind == wkText) {
  505.         /* Deallocate a text window
  506.          */
  507.         DocClose(theWindow);
  508.         WindZapPort(theWindow, FALSE);
  509.         TEDispose(infoPtr->item.text.teHdl);
  510.         DisposeControl(infoPtr->item.text.scroll);
  511.         DisposPtr(infoPtr);
  512.         DisposeWindow(theWindow);
  513.     }
  514.     else if (infoPtr->kind == wkList) {
  515.         /* Deallocate a list window
  516.          */
  517.         WindZapPort(theWindow, FALSE);
  518.         LDispose(infoPtr->item.list);
  519.         DisposPtr(infoPtr);
  520.         DisposeWindow(theWindow);
  521.     }
  522.     else if (infoPtr->kind == wkDlog) {
  523.         /* Deallocate a modeless dialog window
  524.          */
  525.         DlogDispose(theWindow);
  526.     }
  527. }
  528.  
  529.  
  530. /* Zap the specified port open or closed
  531.  */
  532. void
  533. WindZapPort (wind, up)
  534.     register WindowPtr wind;
  535.     register Boolean up;
  536. {
  537.     /* Can't give it all away...
  538.      */
  539.     ShowHide(wind, up);
  540. }
  541.