This is Clock.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "Clock.h" #import <appkit/Application.h> #import <appkit/NXImage.h> #import <appkit/View.h> #import <soundkit/Sound.h> #import <sys/time.h> #import <math.h> #import <dpsclient/wraps.h> #import <appkit/Font.h> #import <string.h> #define STANDARD 3 #define ANALOG 4 #define GRANITE 5 #define DIGITAL 1 #define DIAGNAL 2 #define NUMBERED 6 #define BLACK 7 #define FIRST DIGITAL #define LAST BLACK #define MAX (LAST - FIRST + 2) #define WDIAG (64.0 * sqrt(2.0)) NXPoint zero = {0.0, 0.0}; NXRect rect; // Sort of a do everything kind of Rectangle NXRect inside = { 0.0,0.0,64,64}; @implementation Clock - setUpIcon { int startover; NXSize size = { 64.0, 64.0 }; [self lockFocus]; [back composite:NX_COPY toPoint:&zero]; do { startover = 0; switch(ctype) { case DIGITAL: PSsetgray(NX_BLACK); tFont = [Font newFont:"Times-Roman" size:18 style:0 matrix:NX_IDENTITYMATRIX]; dFont = [Font newFont:"Helvetica" size:8 style:0 matrix:NX_IDENTITYMATRIX]; image = [image free]; // This doesn't need an image break; case DIAGNAL: PSsetgray(NX_BLACK); tFont = [Font newFont:"Times-Roman" size:30.0 style:0 matrix:NX_IDENTITYMATRIX]; [self setSeconds:NO]; image = [image free]; break; default: if (image) image = [image free]; #ifdef BAD image = [NXImage findImageNamed:[self getSectionName:ctype]]; #else image = [[NXImage alloc] initFromSection:[self getSectionName:ctype]]; [image setScalable:YES]; [image setSize:&size]; #endif #ifdef BAD if (image == nil) #else if (![image composite:NX_SOVER toPoint:&zero]) #endif { ctype = FIRST; startover = YES; } break; } } while (startover == YES); [self unlockFocus]; return self; } - init { [super initFrame:&inside]; [self setOpaque:YES]; back = [[NXImage alloc] initFromSection:"blank"]; timer = DPSAddTimedEntry(1.0, doStep, self, NX_BASETHRESHOLD); return self; } - free { [image free]; [back free]; DPSRemoveTimedEntry(timer); [snd free]; [tFont free]; [dFont free]; return [super free]; } - setType:(int)TYPE; { ctype = TYPE; [self setUpIcon]; return self; } - (int)getType { return (ctype); } float centerstring(id theFont, char *theString, float width) { return ((width / 2.0) - ([theFont getWidthOf:theString] / 2.0)); } - (const char *)getSectionName:(int)TYPE { static char tmp[10]; switch(TYPE) { case STANDARD: return ("standard.tiff"); break; case ANALOG: return ("analog.tiff"); break; case GRANITE: return ("granite.tiff"); break; case DIGITAL: return ("digital.tiff"); break; case DIAGNAL: return ("diagnal.tiff"); break; case NUMBERED: return ("analognumber.tiff"); break; case BLACK: return ( "black.tiff"); break; } sprintf(tmp,"%d.tiff",TYPE - MAX + 1); return (tmp); // I don't know what it so return it } void doStep(DPSTimedEntry teNum, double now, void *userData) { [(id)userData display]; } -drawSelf:(const NXRect *)rectangle :(int)rectCount { #define HOUR 15.0 #define MIN 22.0 #define SEC 24.0 struct tm *curTime; long theTime; int min, hour, sec, yy, dd, mm, day; float secang, minang, hourang; char *month[12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; char *Day[7] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; char tmp[80], ap[3]; // find the current time time(&theTime); curTime = localtime(&theTime); // set the variables equal to the current time sec = curTime->tm_sec; hour = curTime->tm_hour; min = curTime->tm_min; yy = curTime->tm_year; dd = curTime->tm_mday; mm = curTime->tm_mon; day = curTime->tm_wday; if (min == 0 && sec == 0 && Cflag) [snd play]; [back composite:NX_COPY toPoint:&zero]; if (image) [image composite:NX_SOVER toPoint:&zero]; switch(ctype) { case STANDARD: if (Mflag) if (Sflag) sprintf(tmp,"%02d:%02d:%02d",hour,min,sec); else sprintf(tmp,"%02d:%02d",hour,min); else { if (hour<12) { sprintf(ap,"am"); if (hour == 0) hour = 12; } else { sprintf(ap,"pm"); if (hour > 12) hour -= 12; } sprintf(tmp,"%d:%02d %s",hour,min,ap); } tFont = [Font newFont:"Times-Italic" size:14 style:0 matrix:NX_IDENTITYMATRIX]; [tFont set]; // Need to get the current context PSsetgray(NX_WHITE); PSmoveto(centerstring(tFont,tmp,64.0),47); PSshow(tmp); PSsetgray(NX_BLACK); dFont = [Font newFont:"Helvetica" size:8 style:0 matrix:NX_IDENTITYMATRIX]; [dFont set]; PSmoveto(centerstring(dFont,Day[day],64.0),34.0); PSshow(Day[day]); dFont = [Font newFont:"Times-Roman" size:24 style:0 matrix:NX_IDENTITYMATRIX]; [dFont set]; sprintf(tmp,"%d",dd); PSmoveto(centerstring(dFont,tmp,64.0),17); PSshow(tmp); dFont = [Font newFont:"Helvetica-Oblique" size:9 style:0 matrix:NX_IDENTITYMATRIX]; [dFont set]; PSmoveto(centerstring(dFont,month[mm],64.0),10); PSshow(month[mm]); break; case DIGITAL: if (Mflag) if (Sflag) sprintf(tmp,"%d:%02d:%02d",hour,min,sec); else sprintf(tmp,"%d:%02d",hour,min); else { if (hour>12) hour = hour - 12; if (hour==0) hour = 12; // Better way? if (Sflag) sprintf(tmp,"%d:%02d:%02d",hour,min,sec); else sprintf(tmp,"%d:%02d",hour,min); } [tFont set]; PSmoveto(centerstring(tFont,tmp,64.0),26.0); PSshow(tmp); sprintf(tmp,"%s %s %d",Day[day],month[mm],dd); [dFont set]; PSmoveto(centerstring(dFont,tmp,64.0),19.0); PSshow(tmp); break; case DIAGNAL: if (!Mflag) { if (hour>12) hour = hour - 12; if (hour==0) hour = 12; // Better way? } sprintf(tmp,"%d:%02d",hour,min); [tFont set]; PSrotate(45.0); PSmoveto(centerstring(tFont,tmp,(float) WDIAG), -8.7); PSshow(tmp); break; default: // This is where the analog clocks are handled // Thanks to Scott Hess for the formulas. I was too lazy to figure them out. secang = (float)(sec*6*M_PI/180.0); minang = (float)(min*6*M_PI/180.0); hourang= ((hour)%12)*30*M_PI/180.0+minang/12; PStranslate(32.0, 32.0); if (!Bflag) { if (Sflag) { PSsetlinewidth(0.0); if (ctype == GRANITE) PSsetgray(NX_WHITE); else if (ctype == BLACK) PSsetgray(NX_DKGRAY); else PSsetgray(NX_DKGRAY); PSmoveto(0.0,0.0); PSlineto(sin(secang)*SEC, cos(secang)*SEC); PSstroke(); // All of these strokes are needed since each of the lines is different } // Draw the minute hand if (ctype == BLACK) PSsetgray(NX_LTGRAY); else PSsetgray(NX_BLACK); PSsetlinewidth(0.0); PSmoveto((float)sin( minang)*MIN, (float)cos( minang)*MIN); PSlineto(0.0, 0.0); PSstroke(); // Draw the hour hand PSsetlinewidth(1.5); PSmoveto(0.0, 0.0); PSlineto(sin(hourang)*HOUR,cos(hourang)*HOUR); } else { /* More code from Scott Hess' Clocks program */ PSsetlinewidth(0.0); if (ctype == BLACK) PSsetgray(NX_LTGRAY); else PSsetgray(NX_BLACK); PSmoveto(sin (minang)*MIN, cos(minang)*MIN); if (Sflag) PScurveto(0,0,0,0,sin(secang)*SEC,cos(secang)*SEC); PScurveto( 0,0,0,0,sin(hourang)*HOUR,cos(hourang)*HOUR); PScurveto( 0,0,0,0,sin(minang)*MIN,cos(minang)*MIN); } PSstroke(); PStranslate(-32.0, -32.0); break; } return self; } - setMilitary:(BOOL)flag { Mflag = flag; return self; } - (BOOL)getMilitary { return Mflag; } - setSeconds:(BOOL)flag { float timeOut; // Must always set the seconds even if you want them off. This is where the timer is done Sflag = flag; if (Sflag) timeOut = 1.0; else timeOut = 60.0; if (timer != NULL) DPSRemoveTimedEntry(timer); // I don't know what a bunch of these buggers will do timer = DPSAddTimedEntry(timeOut,doStep,self,NX_BASETHRESHOLD); return self; } - (BOOL)getSeconds { return Sflag; } - setChime:(BOOL)flag { Cflag = flag; return self; } - (BOOL)getChime; { return Cflag; } - setBezier:(BOOL)flag { Bflag = flag; return self; } - (BOOL)getBezier; { return Bflag; } - setChimeFile:(char *)file; { snd = [Sound removeSoundForName:"chime"]; snd = [Sound addName:"chime" fromSoundfile:file]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.