home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / ARTAbrot 1.21 / ARTAbrot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-08  |  10.9 KB  |  330 lines  |  [TEXT/MPS ]

  1. /************************************************************************/
  2. /*                                                                        */
  3. /*    FILE:        ARTAbrot.c -- Main windows code for ARTA Mandelbrot        */
  4. /*                    program.                                            */
  5. /*                                                                        */
  6. /*    PURPOSE:    Display Mandelbrot graphics.                            */
  7. /*                                                                        */
  8. /*    AUTHOR:        George T. Warner                                        */
  9. /*                                                                        */
  10. /*    REVISIONS:                                                            */
  11. /*    08/22/93    First version.                                            */
  12. /*                                                                        */
  13. /************************************************************************/
  14.  
  15. #include "ComUtil_ARTAbrot.h"    /* Common */
  16.  
  17. #include "AB_Alert.h"    /* Alert */
  18. #include "ARTAbrot.h"    /* This file */
  19. #include "brotcode.h"
  20.  
  21. #pragma segment ARTAbrot
  22.  
  23. static ControlHandle    ScrollHHandle;        /* Scrollbar for horz scrolling */
  24. static ControlHandle    ScrollVHandle;        /* Scrollbar for vert scrolling */
  25. static RGBColor    WindowBackColor;            /* Background window color */
  26. /* Offscreen pixMap stuff. */
  27. GWorldPtr offscreenGWorld = NIL;    /* Off screen graphics world. */
  28. Rect    GWorldBounds;            /* Boundaries of graphics world. */
  29. extern int xpix, ypix;
  30. extern double distance_per_pixel;
  31.  
  32.  
  33. /* Routine: Init_ARTAbrot */
  34. /* Purpose: Initialize our window data to not in use yet */
  35.  
  36. void Init_ARTAbrot()
  37. {
  38.     WPtr_ARTAbrot = nil;                    /* Make sure other routines know we are not valid yet */
  39.  
  40.     ScrollHHandle = nil;                    /* Scrollbar is not valid yet */
  41.     ScrollVHandle = nil;                    /* Scrollbar is not valid yet */
  42.  
  43.     WindowBackColor.red  = 0xFFFF;  WindowBackColor.green  = 0xFFFF;  WindowBackColor.blue  = 0xFFFF;/* Set the color */
  44. }
  45.  
  46. /* ======================================================= */
  47.  
  48. /* Routine: Close_ARTAbrot */
  49. /* Purpose: Close out the window */
  50.  
  51. void Close_ARTAbrot(WindowPtr whichWindow)
  52. {
  53.     /* See if we should close this window */
  54.     if ((WPtr_ARTAbrot != NIL) && ((WPtr_ARTAbrot == whichWindow) || (whichWindow == (WindowPtr)-1))) {
  55.         DisposeWindow(WPtr_ARTAbrot);        /* Clear window and controls */
  56.         WPtr_ARTAbrot = nil;                /* Make sure other routines know we are closed */
  57.         DisposeGWorld(offscreenGWorld);
  58.         offscreenGWorld = NIL;
  59.     }
  60. }
  61.  
  62. /* ======================================================= */
  63.  
  64. /* Routine: Resized_ARTAbrot */
  65. /* Purpose: We were resized or zoomed, update the scrolling scrollbars */
  66.  
  67. void Resized_ARTAbrot(WindowPtr whichWindow)
  68. {
  69. WindowPtr    SavePort;                        /* Place to save the last port */
  70. Rect    temp2Rect;                            /* temp rectangle */
  71. QDErr result;
  72. long row_bytes;    /* Used for PixMap calculations. */
  73. long bytes2erase;
  74. unsigned char *base_addr;
  75.  
  76.     if (WPtr_ARTAbrot == whichWindow) {        /* Only do if the window is us */
  77.         GetPort(&SavePort);                    /* Save the current port */
  78.         SetPort(WPtr_ARTAbrot);                /* Set the port to my window */
  79.     
  80.         temp2Rect = WPtr_ARTAbrot->portRect;    /* Get the window rectangle */
  81.         EraseRect(&temp2Rect);                    /* Erase the new window area */
  82.         InvalRect(&temp2Rect);                    /* Set to update the new window area */
  83.  
  84.         /* Dispose old GWorld. */
  85.         DisposeGWorld(offscreenGWorld);
  86.         offscreenGWorld = NIL;
  87.         /* Allocate memory for offscreen bitmap. */
  88.         /* left, top, right, bottom */
  89.         SetRect(&GWorldBounds, 0, 0, (WPtr_ARTAbrot->portRect.right - WPtr_ARTAbrot->portRect.left)-SCROLLBARWIDTH, (WPtr_ARTAbrot->portRect.bottom - WPtr_ARTAbrot->portRect.top)-SCROLLBARWIDTH);
  90.         result = NewGWorld(&offscreenGWorld, 8, &GWorldBounds, NIL, NIL, NIL);
  91.         if (result) {
  92.             DisposeWindow(WPtr_ARTAbrot); 
  93.             WPtr_ARTAbrot = NIL;
  94.             /* Report an error message here. */
  95.         }
  96.         else {
  97.             /* First clear the offscreen GWorld. */
  98.             /* Lock the offscreen GWorld. */
  99.             LockPixels(offscreenGWorld->portPixMap);
  100.             row_bytes = ((**(offscreenGWorld->portPixMap)).rowBytes) & 0x3fff;
  101.             base_addr = (unsigned char *)GetPixBaseAddr(offscreenGWorld->portPixMap);
  102.             bytes2erase = row_bytes * GWorldBounds.bottom;
  103.             do {
  104.                 *base_addr++ = 0;
  105.             } while (--bytes2erase);
  106.             UnlockPixels(offscreenGWorld->portPixMap);
  107.             start_brot();                    /* Calculate new Mandelbrot. */
  108.         }
  109.     
  110.         SetPort(SavePort);                                /* Restore the old port */
  111.     }
  112. }
  113.  
  114. /* ======================================================= */
  115.  
  116. /* Routine: Moved_ARTAbrot */
  117. /* Purpose: We were moved, possibly to another screen and screen depth */
  118.  
  119. void Moved_ARTAbrot(WindowPtr whichWindow)
  120. {
  121. WindowPtr    SavePort;                        /* Place to save the last port */
  122.     
  123.     if (WPtr_ARTAbrot == whichWindow) {        /* Only do if the window is us */
  124.         GetPort(&SavePort);                    /* Save the current port */
  125.         SetPort(WPtr_ARTAbrot);                /*  Set the port to my window  */
  126.     
  127.         SetPort(SavePort);                                /* Restore the old port */
  128.     }
  129. }
  130.  
  131. /* ======================================================= */
  132.  
  133. /* Routine: Update_ARTAbrot */
  134. /* Purpose: Update our window */
  135.  
  136. void Update_ARTAbrot(WindowPtr whichWindow)
  137. {
  138. WindowPtr    SavePort;                                /* Place to save the last port */
  139.  
  140.     /* Handle the update to our window */
  141.     if ((WPtr_ARTAbrot != NIL) && (WPtr_ARTAbrot == whichWindow)) {
  142.         GetPort(&SavePort);                    /* Save the current port */
  143.         SetPort(WPtr_ARTAbrot );            /* Set the port to my window */
  144.  
  145.         DrawControls(WPtr_ARTAbrot);        /* Draw all the controls */
  146.         DrawGrowIcon(WPtr_ARTAbrot );        /* Draw the Grow box */
  147.         DrawControls(WPtr_ARTAbrot);        /* Draw all the controls */
  148.         /* Restore image. */
  149.         if (LockPixels(offscreenGWorld->portPixMap)) {
  150.             CopyBits((BitMap *)*offscreenGWorld->portPixMap, &(WPtr_ARTAbrot->portBits), &(GWorldBounds), &(GWorldBounds), srcCopy, 0);
  151.             UnlockPixels(offscreenGWorld->portPixMap);
  152.         }
  153.         SetPort(SavePort);                    /* Restore the old port */
  154.     }
  155. }
  156.  
  157. /* ======================================================= */
  158.  
  159. /* Routine: Open_ARTAbrot */
  160. /* Purpose: Open our window */
  161.  
  162. void Open_ARTAbrot()
  163. {
  164. QDErr result;
  165. long row_bytes;    /* Used for PixMap calculations. */
  166. long bytes2erase;
  167. unsigned char *base_addr;
  168.  
  169.     if (WPtr_ARTAbrot == NIL) {                    /* See if already opened */
  170.         WPtr_ARTAbrot = GetNewCWindow(Res_W_ARTAbrot,nil, (WindowPtr)-1);/* Get the COLOR window from the resource file */
  171.         SetPort(WPtr_ARTAbrot);                    /* Prepare to write into our window */
  172.  
  173.         ShowWindow(WPtr_ARTAbrot);                /* Show the window now */
  174.         /* Allocate memory for offscreen bitmap. */
  175.         /* left, top, right, bottom */
  176.         SetRect(&GWorldBounds, 0, 0, (WPtr_ARTAbrot->portRect.right - WPtr_ARTAbrot->portRect.left)-SCROLLBARWIDTH, (WPtr_ARTAbrot->portRect.bottom - WPtr_ARTAbrot->portRect.top)-SCROLLBARWIDTH);
  177.         result = NewGWorld(&offscreenGWorld, 8, &GWorldBounds, NIL, NIL, NIL);
  178.         if (result) {
  179.             DisposeWindow(WPtr_ARTAbrot); 
  180.             WPtr_ARTAbrot = NIL;
  181.             /* Report an error message here. */
  182.         }
  183.         else {
  184.             /* First clear the offscreen GWorld. */
  185.             /* Lock the offscreen GWorld. */
  186.             LockPixels(offscreenGWorld->portPixMap);
  187.             row_bytes = ((**(offscreenGWorld->portPixMap)).rowBytes) & 0x3fff;
  188.             base_addr = (unsigned char *)GetPixBaseAddr(offscreenGWorld->portPixMap);
  189.             bytes2erase = row_bytes * GWorldBounds.bottom;
  190.             do {
  191.                 *base_addr++ = 0;
  192.             } while (--bytes2erase);
  193.             UnlockPixels(offscreenGWorld->portPixMap);
  194.  
  195.             start_brot();                    /* Calculate new Mandelbrot. */
  196.         }
  197.         SelectWindow(WPtr_ARTAbrot);        /* Already open, so show it */
  198.     }
  199.     else {
  200.         SelectWindow(WPtr_ARTAbrot);         /* Already open, so show it */
  201.         if (new_coordinates)
  202.             start_brot();                    /* Calculate new Mandelbrot. */
  203.         else {
  204.             /* Restore image. */
  205.             if (LockPixels(offscreenGWorld->portPixMap)) {
  206.                 CopyBits((BitMap *)*offscreenGWorld->portPixMap, &(WPtr_ARTAbrot->portBits), &(GWorldBounds), &(GWorldBounds), srcCopy, 0);
  207.                 UnlockPixels(offscreenGWorld->portPixMap);
  208.             }
  209.         }
  210.     }
  211. }
  212.  
  213. /* ======================================================= */
  214.  
  215. /* Routine: Activate_ARTAbrot */
  216. /* Purpose: We activated or deactivated */
  217.  
  218. void Activate_ARTAbrot(WindowPtr whichWindow,Boolean Do_An_Activate)
  219. {
  220. WindowPtr    SavePort;                                /* Place to save the last port */
  221.  
  222. if (WPtr_ARTAbrot == whichWindow)                    /*  Only do if the window is us  */
  223.     {
  224.     GetPort(&SavePort);                            /* Save the current port */
  225.     SetPort(whichWindow);                            /* Set the port to my window */
  226.  
  227.     DrawGrowIcon(whichWindow);                        /* Draw the grow Icon */
  228.  
  229.     if (Do_An_Activate)                            /* Handle the activate */
  230.         {
  231.         }
  232.     else
  233.         {
  234.         if (theInput != nil)                        /* See if there is already a TE area */
  235.             {
  236.             TEDeactivate(theInput);                /* Yes, so turn it off */
  237.             }                                    /* End of IF */
  238.         theInput = nil;                            /* Deactivate the TE area */
  239.         }                                        /* End of IF */
  240.  
  241.     SetPort(SavePort);                                /* Restore the old port */
  242.     }                                            /* End of IF */
  243. }
  244.  
  245. /* ======================================================= */
  246.  
  247. /* Routine: Do_ARTAbrot */
  248. /* Purpose: Handle action to our window, like controls */
  249.  
  250. void Do_ARTAbrot(EventRecord *myEvent)
  251. {
  252. short    code;                            /* Location of event in window or controls */
  253. WindowPtr    whichWindow;                /* Window pointer where event happened */
  254. Point    myPt;                            /* Point where event happened */
  255. ControlHandle    theControl;                /* Handle for a control */
  256. Rect        rDrag;
  257. PenState    xpenSave;
  258. float        ratio;                        /* Aspect ratio of window. */
  259. Point        newPt;
  260. short        oldBottom, oldRight;
  261.  
  262.     /* Get where in window and which window */
  263.     code = FindWindow(myEvent->where, &whichWindow);
  264.  
  265.     if (WPtr_ARTAbrot == whichWindow) {            /* Handle only when the window is valid */
  266.         code = FindWindow(myEvent->where, &whichWindow);/* Get where in window and which window */
  267.     
  268.         if ((myEvent->what == mouseDown) && (WPtr_ARTAbrot == whichWindow)) {
  269.             myPt = myEvent->where;                    /* Get mouse position */
  270.             GlobalToLocal(&myPt);                    /* Make it relative */
  271.  
  272.             rDrag.top = myPt.v;
  273.             rDrag.left = myPt.h;
  274.             rDrag.bottom = myPt.v;
  275.             rDrag.right = myPt.h;
  276.             ratio = (float) xpix / (float) ypix;
  277.             
  278.             GetPenState(&xpenSave);
  279.             PenMode(patXor);
  280.             FrameRect(&rDrag);
  281.             while (StillDown()) {
  282.                 GetMouse(&newPt);
  283.                 if (newPt.h != myPt.h || newPt.v != myPt.v) {
  284.                     
  285.                     myPt = newPt;
  286.                     FrameRect(&rDrag);
  287.                     oldBottom = rDrag.bottom;
  288.                     oldRight = rDrag.right;
  289.                     
  290.                     rDrag.bottom = newPt.v;
  291.                     if (rDrag.bottom > ypix)    /* Don't let it go off the bottom of the window. */
  292.                         rDrag.bottom = ypix;
  293.                         
  294.                     /* Force the rectangle to have the same aspect ratio as the window. */
  295.                     rDrag.right = rDrag.left + ratio * (rDrag.bottom - rDrag.top);
  296.                     
  297.                     if (rDrag.right > xpix) {    /* Don't let it go off the right of the window. */
  298.                         rDrag.bottom = oldBottom;
  299.                         rDrag.right = oldRight;
  300.                     }
  301.                     FrameRect(&rDrag);
  302.                 }
  303.             }
  304.             FrameRect(&rDrag);
  305.             SetPenState(&xpenSave);
  306.             
  307.             /* Don't do anything if the rectangle is empty. */
  308.             if (rDrag.top < rDrag.bottom && rDrag.left < rDrag.right) {
  309.                 fxcenter += distance_per_pixel * (rDrag.left + rDrag.right - xpix) / 2.;
  310.                 fycenter += distance_per_pixel * (rDrag.top + rDrag.bottom - ypix) / 2.;
  311.                 fwidth = fwidth * (rDrag.right - rDrag.left);
  312.                 fwidth = fwidth / xpix;
  313.                 new_coordinates=TRUE;
  314.                 /* Open a Window */
  315.                 Add_UserEvent(UserEvent_Open_Window,Res_W_ARTAbrot,0,0,nil);
  316.             }
  317.         }
  318.     }
  319.  
  320.     if ((WPtr_ARTAbrot == whichWindow) && (code == inContent)) {    /* for our window */
  321.         code = FindControl(myPt, whichWindow, &theControl);/* Get type of control */
  322.  
  323.         if (code != 0)                                /* Check type of control */
  324.             code = TrackControl(theControl,myPt, (ProcPtr)-1);/* Track the control */
  325.  
  326.     }
  327. }
  328.  
  329. /* ======================================================= */
  330.