This is DigitalClockView.m in view mode; [Download] [Up]
// // DigitalClockView.m // rev 1.1 // // Matt Pharr- pharr@cs.yale.edu // NeXTMail welcome // #import "DigitalClockView.h" #import <appkit/graphics.h> #import <libc.h> #import <dpsclient/wraps.h> #import <time.h> #import <strings.h> #import <appkit/NXImage.h> #import <appkit/Font.h> #import <appkit/publicWraps.h> @implementation DigitalClockView - fixPosition { if (currentLocation.x + currentSize.width >= bounds.size.width) currentLocation.x = bounds.size.width - currentSize.width; if (currentLocation.x <= bounds.origin.x) currentLocation.x = 0; if (currentLocation.y + currentSize.height >= bounds.size.height) currentLocation.y = bounds.size.height - currentSize.height; if (currentLocation.y <= bounds.origin.y) currentLocation.y = 0; return self; } - bounceIfNeeded { if (currentLocation.x <= bounds.origin.x) // keep it ON the screen moveVector.x= randBetween(0.5, 1.5); if (currentLocation.x + currentSize.width >= bounds.size.width) moveVector.x= (-1) * randBetween(0.5, 1.5); if (currentLocation.y <= bounds.origin.y) moveVector.y= randBetween(0.5, 1.5); if (currentLocation.y + currentSize.height >= bounds.size.height) moveVector.y= (-1) * randBetween(0.5, 1.5); return self; } - chooseColor { float dr, dg, db; if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) { currGrey= 1.0; // boring city... PSsetgray(currGrey); } else { dr= randBetween(-.1, .1); // randomly move the red, green, and blue dg= randBetween(-.1, .1); // components of the color around between db= randBetween(-.1, .1); // 0 and 1. There is a minor bummer in that // you only see the effect of the color // change once a second, because it only // draws the time into the bitmap when the // time changes. Would be an easy modification // to get it to redraw the bitmap more // frequently, but its probably not worth // the trouble. Depending on how this ends // up looking in color (wish I knew!), it // might be better to replace everything // between the else and the PSsetrgbcolor // with just a PSsetrgbcolor(), with constant // arguments... currR += dr; currG += dg; currB += db; if (currR < 0.0) currR= 0.0; if (currR > 1.0) currR= 1.0; if (currG < 0.0) currG= 0.0; if (currG > 1.0) currG= 1.0; if (currB < 0.0) currB= 0.0; if (currB > 1.0) currB= 1.0; PSsetrgbcolor(currR, currG, currB); } return self; } - oneStep { time_t tTime; struct tm *currentTime; currentLocation.x += moveVector.x; // move the x and y positions of the image currentLocation.y += moveVector.y; // as indicated by the move vectors [self bounceIfNeeded]; [self fixPosition]; time(&tTime); currentTime= localtime(&tTime); strftime(theTime, 10, "%H:%M:%S", currentTime); if (strcmp(theTime, lastTime) != 0) { // if the time has changed... strcpy(lastTime, theTime); currentLocation.x += moveVector.x; // move it one more time so it's not so jerky currentLocation.y += moveVector.y; // when the time changes... [self bounceIfNeeded]; [self fixPosition]; if ([currentImage lockFocus] == YES) { PSsetgray(0.0); PSrectfill(0, 0, currentSize.width, currentSize.height); [theFont set]; PSsetgray(.333); // give it a little shadow PSmoveto(14, 136); PSshow(theTime); PSmoveto(10.0, 138.0); [self chooseColor]; PSshow(theTime); // to be really fancy, it would be good to fix the // kerning on 1's by hand, so the next number was // printed closer, but this is pretty minor... // Some people have also expressed an interest in // non-military time, and AM/PM instead. If BackSpace // ever gives me a view to work with to let the user // configure the modules, this will be an option. [currentImage unlockFocus]; } } [currentImage composite:NX_COPY toPoint:¤tLocation]; usleep((1*1000000)/68); // sleep a few vblanks return self; } - (const char *)windowTitle { return "Digital Clock"; } - drawSelf:(const NXRect *)rects :(int)rectCount { if (!rects || !rectCount) { return self; } PSsetgray(0); NXRectFill(rects); return self; } - initFrame:(const NXRect *)frameRect { [super initFrame:frameRect]; currentLocation.x= 400.0; currentLocation.y= 400.0; moveVector.x= randBetween(0.5, 1.5); moveVector.y= randBetween(0.5, 1.5); *theTime= '\0'; *lastTime= '\0'; theFont= [Font newFont:"Times-Roman" size:180.0]; currGrey= currR= currG= currB= .5; currentSize.width= [theFont getWidthOf:"88:88:88"] + 17.0; // keep the bitmap a currentSize.height= 180.0; // little on the big size, // so there is extra black // around the edges, so that // the previous drawing // is automagically erased. currentImage= [[NXImage alloc] initSize:¤tSize]; [currentImage setFlipped:YES]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.