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

  1.  
  2. #import "SlideShowView.h"
  3. #import "Thinker.h"
  4. #import <appkit/TextField.h>
  5. #import <appkit/Slider.h>
  6. #import <appkit/Button.h>
  7. #import <appkit/NXImage.h>
  8. #import <math.h>
  9. #import <libc.h>
  10. #import <dpsclient/wraps.h>
  11. #import <appkit/OpenPanel.h>
  12. #import <appkit/Panel.h>
  13. #import <appkit/publicWraps.h>
  14. #import <c.h>
  15. #import <defaults/defaults.h>
  16. #import <sys/file.h>
  17.  
  18. @implementation SlideShowView
  19.  
  20. #define    DOBOUNCE    "ssSlideShowDoBounce"    
  21. #define    SECSPERSLIDE    "ssSlideShowSecsPerSlide"
  22. #define    SLIDESPATH    "ssSlideShowSlidesFile"
  23. #define    FILEEXTENSION    "anim"
  24.  
  25. // x & y periods in milliseconds
  26. #define X_PERIOD 20000.0
  27. #define Y_PERIOD 19000.0
  28.  
  29. #define PI 3.1415926535
  30.  
  31. #define SCREEN_WIDTH 1120
  32. #define SCREEN_HEIGHT 832
  33.  
  34. #define MAX_IMAGE_WIDTH 1120
  35. #define MAX_IMAGE_HEIGHT 832
  36.  
  37. #define MAX_X_SPEED (26)
  38. #define MAX_Y_SPEED (26)
  39.  
  40. #define BUFFER_WIDTH (MAX_IMAGE_WIDTH + MAX_X_SPEED + 1)
  41. #define BUFFER_HEIGHT (MAX_IMAGE_HEIGHT + MAX_Y_SPEED + 1)
  42.  
  43.  
  44.  
  45. // do the next image if the time is right
  46. - oneStep
  47. {
  48.     NXRect black = {0,0,0,0};
  49.     NXRect imageRect;
  50.     BRECT new;
  51.     
  52.     then = now;
  53.     now = currentTimeInMs();
  54.  
  55.     /* animate by selecting a new image to blit */
  56.     [self incrementImageNumber];
  57.     
  58.     if ( bounce ) {
  59.         // calculate new image x & y position
  60.         xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0) 
  61.             * maxCoord.x;
  62.         ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0) 
  63.             * maxCoord.y;
  64.         
  65.         
  66.         if (xpos < (old.l - MAX_X_SPEED)) xpos = old.l - MAX_X_SPEED;
  67.         else if (xpos > (old.l + MAX_X_SPEED)) xpos = old.l + MAX_X_SPEED;
  68.     
  69.         if (ypos < (old.b - MAX_Y_SPEED)) ypos = old.b - MAX_Y_SPEED;
  70.         else if (ypos > (old.b + MAX_Y_SPEED)) ypos = old.b + MAX_Y_SPEED;
  71.     }
  72.     else {
  73.         NXRect    vRect;
  74.         [self getVisibleRect:&vRect];
  75.         xpos = ( vRect.size.width - currentImageSize.width ) / 2;
  76.         ypos = ( vRect.size.height - currentImageSize.height ) / 2;
  77.     }
  78.     
  79.     /* animate new image to blit */
  80.     new.l = floor(xpos);
  81.     new.b = floor(ypos);
  82.     new.r = new.l + currentImageSize.width;
  83.     new.t = new.b + currentImageSize.height;
  84.     
  85.     imageRect.origin.x = 0;
  86.     imageRect.origin.y = 0;
  87.     imageRect.size.width = currentImageSize.width;
  88.     imageRect.size.height = currentImageSize.height;
  89.     
  90.     redrawTo.x = MIN(new.l, old.l);
  91.     redrawTo.y = MIN(new.b, old.b);
  92.  
  93.     redraw.origin.x = 0;
  94.     redraw.origin.y = 0;
  95.     redraw.size.width = (MAX(new.r, old.r)) - redrawTo.x + 1;
  96.     redraw.size.height = (MAX(new.t, old.t)) - redrawTo.y + 1;
  97.     
  98.     black.size= redraw.size;
  99.  
  100.     imageTo.x = new.l - redrawTo.x;
  101.     imageTo.y = new.b - redrawTo.y;
  102.  
  103.     [buffer lockFocus];
  104.     
  105.     PSsetgray(0);
  106.     NXRectFill(&black);
  107.     [currentImage composite:NX_SOVER fromRect:&imageRect toPoint:&imageTo];
  108.  
  109.     [buffer unlockFocus];
  110.         
  111.     // Now bring it onto the screen
  112.     
  113.     [buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo];
  114.  
  115.     old = new;
  116.  
  117.     return self;
  118. }
  119.  
  120.  
  121.  
  122. static BOOL noSSSlidesFile = FALSE;
  123.  
  124. - initFrame:(const NXRect *)frameRect
  125. {
  126.     const char    *ssSlideShowDoBounce,
  127.             *ssSlideShowSecsPerSlide,
  128.             *slidesPath;
  129.     static char    moduleDirectory[MAXPATHLEN];
  130.         
  131.  
  132.     NXRect        black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
  133.  
  134.     [super initFrame:frameRect];
  135.     [self allocateGState];        // For faster lock/unlockFocus
  136.     [self setClipping:NO];        // even faster...
  137.  
  138.     //in this case, I only need one buffer for several Views
  139.     if (!(buffer = [NXImage findImageNamed:"worldBuffer"]))
  140.     {
  141.         buffer = [[NXImage alloc] initSize:&black.size];
  142.         [buffer setName:"worldBuffer"];
  143.     }
  144.     
  145.     if ([buffer lockFocus])
  146.     {
  147.         PSsetgray(0);
  148.         NXRectFill(&black);
  149.         [buffer unlockFocus];
  150.     }
  151.  
  152.  
  153.     ssSlideShowDoBounce = NXGetDefaultValue([NXApp appName], DOBOUNCE);
  154.     if (ssSlideShowDoBounce == NULL) bounce = YES;
  155.     else { bounce = (!strcmp(ssSlideShowDoBounce,"1")) ? YES : NO; }
  156.     
  157.     ssSlideShowSecsPerSlide = NXGetDefaultValue([NXApp appName], SECSPERSLIDE);
  158.     if (ssSlideShowSecsPerSlide == NULL) secsPerSlide = 5;
  159.     else secsPerSlide = atoi(ssSlideShowSecsPerSlide);
  160.     
  161.     ssslidesPath = (char *)malloc(sizeof(char)*MAXPATHLEN);
  162.     slidesPath = NXGetDefaultValue([NXApp appName], SLIDESPATH);
  163.     if (slidesPath != NULL) strcpy(ssslidesPath, slidesPath);
  164.  
  165.     if ( (![self readSlidesFromFile:ssslidesPath]) || (slidesPath == NULL) )
  166.     {
  167.         sprintf(moduleDirectory,"%s/SlideShow.%s", [(BSThinker()) moduleDirectory:"SlideShow"], FILEEXTENSION);
  168.         strcpy(ssslidesPath, moduleDirectory);
  169.         [self readSlidesFromFile:ssslidesPath];
  170.     }
  171.     
  172.     return self;
  173. }
  174.  
  175. - readSlidesFromFile:(const char *)slidesPath
  176. {
  177.     int        i, f;
  178.     id        local_image;
  179.     NXSize        localImageSize,
  180.             newMaxImageSize;
  181.     id        newImageList;
  182.     char        slideFrame[MAXPATHLEN];
  183.  
  184.     // construct the image list
  185.     newImageList = [[List alloc] init];
  186.     for (i=0; ; i++)
  187.     {    
  188.         sprintf(slideFrame, "%s/%d.tiff", slidesPath, i+1);
  189.         if (!(local_image = [NXImage findImageNamed:slideFrame]))
  190.         {
  191.             if ((f=open(slideFrame, O_RDONLY)) < 0) break;
  192.             close(f);
  193.  
  194.             local_image = [[NXImage alloc] initFromFile:slideFrame];
  195.             if (local_image == NULL) break;    // never null, even if no file
  196.             [local_image setName:slideFrame];
  197.         }
  198.  
  199.         [newImageList addObject:local_image];
  200.         
  201.         [local_image getSize: &localImageSize];
  202.         newMaxImageSize.width = MAX(newMaxImageSize.width, localImageSize.width);
  203.         newMaxImageSize.height = MAX(newMaxImageSize.height, localImageSize.height);
  204.     }
  205.  
  206.     if (i == 0)
  207.     {
  208.         if (!slidesPath) NXRunAlertPanel([NXApp appName], "Could not open %s", NULL, NULL, NULL, slidesPath);
  209.         noSSSlidesFile = TRUE;
  210.         NXBeep();
  211.         [[pathTextField selectText:self] setStringValue:ssslidesPath];
  212.         return nil;
  213.     }
  214.     else {
  215.         maxImageSize = newMaxImageSize;
  216.         numberOfFrames = i;
  217.         currentFrame = 0;
  218.     
  219.         [[imageList freeObjects] free];
  220.         imageList = newImageList;
  221.  
  222.         if (ssslidesPath != slidesPath) strcpy(ssslidesPath, slidesPath);
  223.         [[pathTextField selectText:self] setStringValue:ssslidesPath];
  224.         NXWriteDefault([NXApp appName], SLIDESPATH, ssslidesPath);
  225.     }
  226.     
  227.     nextRotationTime = 0;
  228.     [self newViewSize];
  229.  
  230.     return self;
  231. }
  232.  
  233. - sizeTo:(NXCoord)width :(NXCoord)height
  234. {
  235.     [super sizeTo:width :height];
  236.     [self newViewSize];
  237.     return self;
  238. }
  239.  
  240. - drawSelf:(const NXRect *)rects :(int)rectCount
  241. {
  242.     return self;
  243. }
  244.  
  245. - newViewSize
  246. {
  247.     //this is called every time View size changes
  248.     NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT };
  249.  
  250.     then = now = currentTimeInMs();
  251.  
  252.     if (oldSize.width == bounds.size.width &&
  253.             oldSize.height == bounds.size.height)
  254.         return self;
  255.     else
  256.     {
  257.         oldSize.width = bounds.size.width;
  258.         oldSize.height = bounds.size.height;
  259.     }
  260.     
  261.     maxCoord.x = bounds.size.width - maxImageSize.width;
  262.     maxCoord.y = bounds.size.height - maxImageSize.height;
  263.     if (maxCoord.x < 0) maxCoord.x = 0;
  264.     if (maxCoord.y < 0) maxCoord.y = 0;
  265.  
  266.  
  267.     old.l = old.r = maxCoord.x/2;
  268.     old.b = old.t = maxCoord.y/2;
  269.     imageTo.x = imageTo.y = 0;
  270.  
  271.     if ([buffer lockFocus])
  272.     {
  273.         PSsetgray(0);
  274.         NXRectFill(&black);
  275.         [buffer unlockFocus];
  276.     }
  277.  
  278.     return self;
  279. }
  280.  
  281. - incrementImageNumber
  282. {
  283.     if (now > nextRotationTime)
  284.     {
  285.         if (++currentFrame >= numberOfFrames) currentFrame = 0;
  286.         currentImage = [imageList objectAt:currentFrame];
  287.         [currentImage getSize:¤tImageSize];
  288.         nextRotationTime = now + (850 * secsPerSlide);
  289.     }
  290.  
  291.     return self;
  292. }
  293.  
  294. - (const char *)windowTitle
  295. {
  296.     return "SlideShow View by Kamlesh Trivedi";
  297. }
  298.  
  299. - didLockFocus
  300. {
  301.     return self;
  302. }
  303.  
  304. - inspector:sender
  305. {
  306.     char buf[MAXPATHLEN];
  307.     
  308.     if (!inspectorView)
  309.     {
  310.         sprintf(buf,"%s/SlideShow.nib",[sender moduleDirectory:"SlideShow"]);
  311.         [NXApp loadNibFile:buf owner:self withNames:NO];
  312.         
  313.         [bounceButton setState:bounce];
  314.         [secsPerSlideSlider setIntValue:secsPerSlide];
  315.         [secsPerSlideTextField setIntValue:secsPerSlide];
  316.         [[pathTextField selectText:self] setStringValue:ssslidesPath];
  317.     }
  318.     return inspectorView;
  319. }
  320.  
  321. //--------------------------------
  322. - bounceButtonHit:sender
  323. {
  324.     bounce = [sender state];
  325.     
  326.     NXWriteDefault([NXApp appName], DOBOUNCE, (bounce) ? "1" : "0");
  327.  
  328.     nextRotationTime = now;
  329.     return self;
  330. }
  331.  
  332. - setSecsPerSlide:sender
  333. {
  334.     char    spsStr[10];
  335.  
  336.     secsPerSlide = [sender intValue];
  337.     [secsPerSlideTextField takeIntValueFrom:sender];
  338.     
  339.     sprintf(spsStr, "%d", secsPerSlide);
  340.     NXWriteDefault([NXApp appName], SECSPERSLIDE, spsStr);
  341.  
  342.     nextRotationTime = now;
  343.     return self;
  344. }
  345.  
  346. - pathButtonHit:sender;
  347. {
  348.     id        openPanel;
  349.     const char*    types[] = { FILEEXTENSION,  (const char*)0 };
  350.     
  351.     openPanel = [OpenPanel new];
  352.     [openPanel setTitle:"Open Slides"];
  353.     [openPanel allowMultipleFiles:NO];
  354.     if ( [openPanel runModalForTypes:types] ) {
  355.         const char* const    *filenames;
  356.     
  357.         for ( filenames = [openPanel filenames]; *filenames; filenames ++ ) {
  358.             char    pathname[MAXPATHLEN];
  359.             
  360.             sprintf(pathname, "%s/%s", [openPanel directory], *filenames);
  361.             [self readSlidesFromFile:pathname];
  362.         }
  363.     }
  364.     nextRotationTime = now;
  365.     return self;
  366. }
  367.  
  368. - pathSet:sender
  369. {
  370.     const char    *filenames;
  371.     
  372.     filenames = [sender stringValue];
  373.     [self readSlidesFromFile:filenames];
  374.     nextRotationTime = now;
  375.     return self;
  376. }
  377. @end
  378.