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.