home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / ScreenSavers / BackSpaceViews / SpheresView.BackModule / SpheresView.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  6.0 KB  |  242 lines

  1. //
  2. // SpheresView.m
  3. //
  4. // Revised for NS3.0 20 Oct 1992
  5. // Matt Pharr- pharr@cs.yale.edu
  6. //
  7.  
  8. #import "SpheresView.h"
  9. #import "SpheresWrap.c"
  10. #import <appkit/appkit.h>
  11. #import <defaults/defaults.h>
  12. #import <dpsclient/wraps.h>
  13. #import <libc.h>
  14. #import <stdlib.h>
  15.  
  16. #define MAXSIZE        125
  17. #define SHOW_FILLS      1
  18. #define DONT_SHOW_FILLS    0
  19.  
  20. @implementation SpheresView
  21.  
  22. - oneStep
  23. {
  24.     float red= 0.0, green= 0.0, blue= 0.0;
  25.     float color= 0.0;
  26.     NXPoint position;
  27.     NXPoint hilight;
  28.     int radius= 100;
  29.     float dx= 0.0, dy= 0.0;
  30.     float dcolor= 0.0;
  31.     float dred= 0.0, dgreen= 0.0, dblue= 0.0;
  32.     
  33.     if (++nDrawn >= nSpheres) {
  34.         usleep(1000000);
  35.         nDrawn= 0;
  36.         PSsetgray(0.0);
  37.         NXRectFill(&bounds);
  38.     }
  39.     
  40.     /* decide where to put the sphere after we draw it.. */
  41.     position.x= (int)randBetween(bounds.origin.x - MAXSIZE / 2, 
  42.                                  bounds.origin.x + bounds.size.width - MAXSIZE/2);
  43.     position.y= (int)randBetween(bounds.origin.y - MAXSIZE / 2, 
  44.                                  bounds.origin.y + bounds.size.height - MAXSIZE/2);
  45.  
  46.     radius= (int)randBetween(30, MAXSIZE);
  47.  
  48.     /* where to put the hilight on the sphere- always in the same relative
  49.        place */
  50.     hilight.x= .4 * radius;
  51.     hilight.y= .6 * radius;
  52.  
  53.     /* distance by which we need to move each time when drawing the big highlight.
  54.        basically what we do is start at the position of the hilight and draw a little
  55.        circle that is all white there. Then we move out away from there and draw
  56.        bigger and bigger circles that become darker and darker, until they hit the
  57.        color we pick for the sphere below. This gives us the 3-d shading effect.
  58.        Actually, though, we do the above in reverse, so as not to draw over the 
  59.        circles- we're actually drawing smaller and smaller concentric, filled circles.
  60.        N.B. there's probably a more efficient way to do this...
  61.        */
  62.     
  63.     dx= hilight.x / radius;
  64.     dy= hilight.y / radius;
  65.  
  66.     if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
  67.         /* Black and White machines */
  68.         color= randBetween(0.0, .4);
  69.         dcolor= (1 - color) / radius;
  70.     }
  71.     
  72.     else { 
  73.         red= randBetween(0.0, .4);
  74.         dred= (1 - red) / radius;
  75.         
  76.         green= randBetween(0.0, .4);
  77.         dgreen= (1 - green) / radius;
  78.  
  79.         blue= randBetween(0.0, .4);
  80.         dblue= (1 - blue) / radius;
  81.     }
  82.  
  83.     
  84.     if (showFills == NO) {
  85.         if ([myImage lockFocus] == YES) {
  86.             /* clear out the NXImage, but leave a transparent background, so when we
  87.                draw it on the screen below, the square in which the sphere is drawn doesn't
  88.                cover up other spheres on the screen unless we have actively drawn in
  89.                the bitmap first...
  90.                */
  91.             
  92.             PSsetgray(0.0);
  93.             PSsetalpha(0.0);
  94.             NXRectFill(&bounds);
  95.             
  96.             if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
  97.                 /* draw a sphere in black and white... */
  98.                 drawSphereBW(color, radius, dcolor, dx, dy, MAXSIZE);
  99.             }
  100.             else {
  101.                 /* or in color... */
  102.                 drawSphereCL(red, green, blue, radius, dred, dgreen, dblue, dx, dy, MAXSIZE);
  103.             }
  104.             
  105.             [myImage unlockFocus];
  106.             /* and put it on the screen... */
  107.             [myImage composite:NX_SOVER toPoint:&position];
  108.         }
  109.     }
  110.     
  111.     if (showFills == YES) {
  112.         NXRectClip(&bounds);
  113.         /* need to do this for drawing it in a normal window... */
  114.     
  115.         PStranslate(position.x, position.y);
  116.         
  117.         if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {
  118.             /* draw a sphere in black and white... */
  119.             drawSphereBW(color, radius, dcolor, dx, dy, MAXSIZE);
  120.         }
  121.         else {
  122.             /* or in color... */
  123.             drawSphereCL(red, green, blue, radius, dred, dgreen, dblue, dx, dy, MAXSIZE);
  124.         }
  125.             
  126.         PStranslate(-position.x, -position.y);
  127.     }
  128.  
  129.     return self;
  130. }
  131.  
  132.  
  133. - initFrame:(const NXRect *)frameRect
  134. {
  135.     NXSize imageSize;
  136.     
  137.     [super initFrame:frameRect];
  138.  
  139.     [self inspector:self];
  140.  
  141.     if ((NXGetDefaultValue([NXApp appName], "sphereNumber") == NULL) ||
  142.         (NXGetDefaultValue([NXApp appName], "sphereShowFill") == NULL)) {
  143.         NXWriteDefault([NXApp appName], "sphereNumber", "50");
  144.         nSpheres= 50;
  145.         NXWriteDefault([NXApp appName], "sphereShowFill", "NO");
  146.         showFills= NO;
  147.     }
  148.     else {
  149.         nSpheres= atoi(NXGetDefaultValue([NXApp appName], "sphereNumber"));
  150.         if (strcmp(NXGetDefaultValue([NXApp appName], "sphereShowFill"), "YES") == 0) {
  151.             showFills= YES;
  152.         }
  153.         else {
  154.             showFills= NO;
  155.         }
  156.     }
  157.  
  158.     [theSlider setIntValue:nSpheres];
  159.     [theSlider update];
  160.     
  161.     if (showFills == YES) {
  162.         [checkBox setState:SHOW_FILLS];
  163.     }
  164.     else {
  165.         [checkBox setState:DONT_SHOW_FILLS];
  166.     }
  167.     [checkBox update];
  168.     
  169.     
  170.     imageSize.width= 2 * MAXSIZE;
  171.     imageSize.height= 2 * MAXSIZE;
  172.     myImage= [[NXImage alloc] initSize:&imageSize];
  173.     
  174.     nDrawn= 0;
  175.     
  176.     return self;
  177. }
  178.  
  179.  
  180. - drawSelf:(const NXRect *)rects :(int)rectCount
  181. {
  182.     if (!rects || !rectCount) {
  183.         return self;
  184.     }
  185.  
  186.     PSsetgray(0.0);
  187.     NXRectFill(rects);
  188.  
  189.     return self;
  190. }
  191.  
  192.  
  193. - (const char *)windowTitle
  194. {
  195.     return "Spheres";
  196. }
  197.  
  198.  
  199. - inspector:sender
  200. {
  201.     char buf[MAXPATHLEN];
  202.  
  203.     if (!sharedInspectorPanel) {
  204.         sprintf(buf,"%s/%s",[(BSThinker()) moduleDirectory:"Spheres"],"Spheres.nib");
  205.         [NXApp loadNibFile:buf owner:self withNames:NO];
  206.     }
  207.  
  208.     return sharedInspectorPanel;
  209. }
  210.  
  211.  
  212. -setNumber:sender
  213. {
  214.     char temp[20];
  215.     
  216.     nSpheres= [sender intValue];
  217.     
  218.     sprintf(temp, "%d", nSpheres);
  219.     NXWriteDefault([NXApp appName], "sphereNumber", temp);
  220.  
  221.     return self;
  222. }
  223.  
  224.  
  225. -setShowFills:sender
  226. {
  227.     if ([sender state] == SHOW_FILLS) {
  228.         showFills= YES;
  229.         NXWriteDefault([NXApp appName], "sphereShowFill", "YES");
  230.     }
  231.     else {
  232.         showFills= NO;
  233.         NXWriteDefault([NXApp appName], "sphereShowFill", "NO");
  234.     }
  235.     
  236.     return self;
  237. }
  238.  
  239.  
  240. @end
  241.  
  242.