This is ClockView.m in view mode; [Download] [Up]
//
// ClockView.m
//
// Matt Pharr- pharr@cs.yale.edu
//
#import "ClockView.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 ClockView
- oneStep
{
time_t tTime;
struct tm *currentTime;
int i;
currentLocation.x += moveVector.x; // move the x and y positions of the image
currentLocation.y += moveVector.y; // as indicated by the move vectors
if (currentLocation.x <= bounds.origin.x) // keep it ON the screen
moveVector.x= randBetween(1.0, 5.0);
if (currentLocation.x + currentSize.width >= (bounds.size.width - bounds.origin.x))
moveVector.x= (-1) * randBetween(1.0, 5.0);
if (currentLocation.y <= bounds.origin.y)
moveVector.y= randBetween(1.0, 5.0);
if (currentLocation.y + currentSize.height >= (bounds.size.height - bounds.origin.y))
moveVector.y= (-1) * randBetween(1.0, 5.0);
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...
if ([currentImage lockFocus] == YES) {
PSsetgray(0.0);
PSrectfill(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
[theFont set];
PSsetgray(.333); // give it a little shadow
for(i=1; i < 4; ++i) {
PSmoveto(10.0 + i, 140.0 - i);
PSshow(theTime);
}
PSmoveto(10.0, 138.0);
[self chooseColor];
PSshow(theTime);
[currentImage unlockFocus];
}
}
[currentImage composite:NX_SOVER toPoint:¤tLocation];
usleep(20000); // could reduce this without adding flicker. 20000 makes for
// a pretty comfortable speed, though.
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;
}
- drawSelf:(const NXRect *)rects :(int)rectCount
{
if (!rects || !rectCount) {
return self;
}
PSsetgray(0);
NXRectFill(rects);
return self;
}
- init
{
[super init];
currentLocation.x= 400.0;
currentLocation.y= 400.0;
moveVector.x= randBetween(1.0, 5.0);
moveVector.y= randBetween(1.0, 5.0);
*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.