This is SlideShowView.m in view mode; [Download] [Up]
#import "SlideShowView.h" #import "Thinker.h" #import <appkit/TextField.h> #import <appkit/Slider.h> #import <appkit/Button.h> #import <appkit/NXImage.h> #import <math.h> #import <libc.h> #import <dpsclient/wraps.h> #import <appkit/OpenPanel.h> #import <appkit/Panel.h> #import <appkit/publicWraps.h> #import <c.h> #import <defaults/defaults.h> #import <sys/file.h> @implementation SlideShowView #define DOBOUNCE "ssSlideShowDoBounce" #define SECSPERSLIDE "ssSlideShowSecsPerSlide" #define SLIDESPATH "ssSlideShowSlidesFile" #define FILEEXTENSION "anim" // x & y periods in milliseconds #define X_PERIOD 20000.0 #define Y_PERIOD 19000.0 #define PI 3.1415926535 #define SCREEN_WIDTH 1120 #define SCREEN_HEIGHT 832 #define MAX_IMAGE_WIDTH 1120 #define MAX_IMAGE_HEIGHT 832 #define MAX_X_SPEED (26) #define MAX_Y_SPEED (26) #define BUFFER_WIDTH (MAX_IMAGE_WIDTH + MAX_X_SPEED + 1) #define BUFFER_HEIGHT (MAX_IMAGE_HEIGHT + MAX_Y_SPEED + 1) // do the next image if the time is right - oneStep { NXRect black = {0,0,0,0}; NXRect imageRect; BRECT new; then = now; now = currentTimeInMs(); /* animate by selecting a new image to blit */ [self incrementImageNumber]; if ( bounce ) { // calculate new image x & y position xpos = ((1 + sin(((float)now) / X_PERIOD * 2. * PI))/2.0) * maxCoord.x; ypos = ((1 + sin(((float)now) / Y_PERIOD * 2. * PI))/2.0) * maxCoord.y; if (xpos < (old.l - MAX_X_SPEED)) xpos = old.l - MAX_X_SPEED; else if (xpos > (old.l + MAX_X_SPEED)) xpos = old.l + MAX_X_SPEED; if (ypos < (old.b - MAX_Y_SPEED)) ypos = old.b - MAX_Y_SPEED; else if (ypos > (old.b + MAX_Y_SPEED)) ypos = old.b + MAX_Y_SPEED; } else { NXRect vRect; [self getVisibleRect:&vRect]; xpos = ( vRect.size.width - currentImageSize.width ) / 2; ypos = ( vRect.size.height - currentImageSize.height ) / 2; } /* animate new image to blit */ new.l = floor(xpos); new.b = floor(ypos); new.r = new.l + currentImageSize.width; new.t = new.b + currentImageSize.height; imageRect.origin.x = 0; imageRect.origin.y = 0; imageRect.size.width = currentImageSize.width; imageRect.size.height = currentImageSize.height; redrawTo.x = MIN(new.l, old.l); redrawTo.y = MIN(new.b, old.b); redraw.origin.x = 0; redraw.origin.y = 0; redraw.size.width = (MAX(new.r, old.r)) - redrawTo.x + 1; redraw.size.height = (MAX(new.t, old.t)) - redrawTo.y + 1; black.size= redraw.size; imageTo.x = new.l - redrawTo.x; imageTo.y = new.b - redrawTo.y; [buffer lockFocus]; PSsetgray(0); NXRectFill(&black); [currentImage composite:NX_SOVER fromRect:&imageRect toPoint:&imageTo]; [buffer unlockFocus]; // Now bring it onto the screen [buffer composite:NX_COPY fromRect:&redraw toPoint:&redrawTo]; old = new; return self; } static BOOL noSSSlidesFile = FALSE; - initFrame:(const NXRect *)frameRect { const char *ssSlideShowDoBounce, *ssSlideShowSecsPerSlide, *slidesPath; static char moduleDirectory[MAXPATHLEN]; NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT }; [super initFrame:frameRect]; [self allocateGState]; // For faster lock/unlockFocus [self setClipping:NO]; // even faster... //in this case, I only need one buffer for several Views if (!(buffer = [NXImage findImageNamed:"worldBuffer"])) { buffer = [[NXImage alloc] initSize:&black.size]; [buffer setName:"worldBuffer"]; } if ([buffer lockFocus]) { PSsetgray(0); NXRectFill(&black); [buffer unlockFocus]; } ssSlideShowDoBounce = NXGetDefaultValue([NXApp appName], DOBOUNCE); if (ssSlideShowDoBounce == NULL) bounce = YES; else { bounce = (!strcmp(ssSlideShowDoBounce,"1")) ? YES : NO; } ssSlideShowSecsPerSlide = NXGetDefaultValue([NXApp appName], SECSPERSLIDE); if (ssSlideShowSecsPerSlide == NULL) secsPerSlide = 5; else secsPerSlide = atoi(ssSlideShowSecsPerSlide); ssslidesPath = (char *)malloc(sizeof(char)*MAXPATHLEN); slidesPath = NXGetDefaultValue([NXApp appName], SLIDESPATH); if (slidesPath != NULL) strcpy(ssslidesPath, slidesPath); if ( (![self readSlidesFromFile:ssslidesPath]) || (slidesPath == NULL) ) { sprintf(moduleDirectory,"%s/SlideShow.%s", [(BSThinker()) moduleDirectory:"SlideShow"], FILEEXTENSION); strcpy(ssslidesPath, moduleDirectory); [self readSlidesFromFile:ssslidesPath]; } return self; } - readSlidesFromFile:(const char *)slidesPath { int i, f; id local_image; NXSize localImageSize, newMaxImageSize; id newImageList; char slideFrame[MAXPATHLEN]; // construct the image list newImageList = [[List alloc] init]; for (i=0; ; i++) { sprintf(slideFrame, "%s/%d.tiff", slidesPath, i+1); if (!(local_image = [NXImage findImageNamed:slideFrame])) { if ((f=open(slideFrame, O_RDONLY)) < 0) break; close(f); local_image = [[NXImage alloc] initFromFile:slideFrame]; if (local_image == NULL) break; // never null, even if no file [local_image setName:slideFrame]; } [newImageList addObject:local_image]; [local_image getSize: &localImageSize]; newMaxImageSize.width = MAX(newMaxImageSize.width, localImageSize.width); newMaxImageSize.height = MAX(newMaxImageSize.height, localImageSize.height); } if (i == 0) { if (!slidesPath) NXRunAlertPanel([NXApp appName], "Could not open %s", NULL, NULL, NULL, slidesPath); noSSSlidesFile = TRUE; NXBeep(); [[pathTextField selectText:self] setStringValue:ssslidesPath]; return nil; } else { maxImageSize = newMaxImageSize; numberOfFrames = i; currentFrame = 0; [[imageList freeObjects] free]; imageList = newImageList; if (ssslidesPath != slidesPath) strcpy(ssslidesPath, slidesPath); [[pathTextField selectText:self] setStringValue:ssslidesPath]; NXWriteDefault([NXApp appName], SLIDESPATH, ssslidesPath); } nextRotationTime = 0; [self newViewSize]; return self; } - sizeTo:(NXCoord)width :(NXCoord)height { [super sizeTo:width :height]; [self newViewSize]; return self; } - drawSelf:(const NXRect *)rects :(int)rectCount { return self; } - newViewSize { //this is called every time View size changes NXRect black = {0, 0, BUFFER_WIDTH, BUFFER_HEIGHT }; then = now = currentTimeInMs(); if (oldSize.width == bounds.size.width && oldSize.height == bounds.size.height) return self; else { oldSize.width = bounds.size.width; oldSize.height = bounds.size.height; } maxCoord.x = bounds.size.width - maxImageSize.width; maxCoord.y = bounds.size.height - maxImageSize.height; if (maxCoord.x < 0) maxCoord.x = 0; if (maxCoord.y < 0) maxCoord.y = 0; old.l = old.r = maxCoord.x/2; old.b = old.t = maxCoord.y/2; imageTo.x = imageTo.y = 0; if ([buffer lockFocus]) { PSsetgray(0); NXRectFill(&black); [buffer unlockFocus]; } return self; } - incrementImageNumber { if (now > nextRotationTime) { if (++currentFrame >= numberOfFrames) currentFrame = 0; currentImage = [imageList objectAt:currentFrame]; [currentImage getSize:¤tImageSize]; nextRotationTime = now + (850 * secsPerSlide); } return self; } - (const char *)windowTitle { return "SlideShow View by Kamlesh Trivedi"; } - didLockFocus { return self; } - inspector:sender { char buf[MAXPATHLEN]; if (!inspectorView) { sprintf(buf,"%s/SlideShow.nib",[sender moduleDirectory:"SlideShow"]); [NXApp loadNibFile:buf owner:self withNames:NO]; [bounceButton setState:bounce]; [secsPerSlideSlider setIntValue:secsPerSlide]; [secsPerSlideTextField setIntValue:secsPerSlide]; [[pathTextField selectText:self] setStringValue:ssslidesPath]; } return inspectorView; } //-------------------------------- - bounceButtonHit:sender { bounce = [sender state]; NXWriteDefault([NXApp appName], DOBOUNCE, (bounce) ? "1" : "0"); nextRotationTime = now; return self; } - setSecsPerSlide:sender { char spsStr[10]; secsPerSlide = [sender intValue]; [secsPerSlideTextField takeIntValueFrom:sender]; sprintf(spsStr, "%d", secsPerSlide); NXWriteDefault([NXApp appName], SECSPERSLIDE, spsStr); nextRotationTime = now; return self; } - pathButtonHit:sender; { id openPanel; const char* types[] = { FILEEXTENSION, (const char*)0 }; openPanel = [OpenPanel new]; [openPanel setTitle:"Open Slides"]; [openPanel allowMultipleFiles:NO]; if ( [openPanel runModalForTypes:types] ) { const char* const *filenames; for ( filenames = [openPanel filenames]; *filenames; filenames ++ ) { char pathname[MAXPATHLEN]; sprintf(pathname, "%s/%s", [openPanel directory], *filenames); [self readSlidesFromFile:pathname]; } } nextRotationTime = now; return self; } - pathSet:sender { const char *filenames; filenames = [sender stringValue]; [self readSlidesFromFile:filenames]; nextRotationTime = now; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.