This is ClockView.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ /* [yeah, right, the Interface Builder generated this. -scott] */ // My stuff. #import "ClockView.h" #import "Animator.h" // appkit stuff. #import <appkit/nextstd.h> // MAX() #import <appkit/Matrix.h> // For getting the clockType. // unix stuff. #import <math.h> // cos, sin, M_PI // dps stuff. #import <dpsclient/wraps.h> // PS*(). @implementation ClockView extern long time( long *); + newFrame:(NXRect *)r { self = [super newFrame:r]; [self setClockType:BEZIER]; [self setDialSize:.05]; return self; } - free { [animator stop:self]; [animator setTarget:nil]; return [super free]; } - takeDialSizeFrom:sender // set the dial size via slider. { return [self setDialSize:[sender floatValue]]; } - takeClockTypeFrom:sender // set the clock type via matrix. { return [self setClockType:[[sender selectedCell] tag]]; } - setDialSize:(float)size // Set programatically. { dialSize=size; return [self display]; } - setClockType:(int)type { clockType=type; return [self display]; } -(int)clockType // return the data. { return clockType; } -(float)dialSize { return dialSize; } // Draws the dials in the currently focussed region, etc. Makes little or // no sense if not used to draw in this view. Also, won't work nicely for non- // square views. - drawDials { float half=bounds.size.height/2.0; float secang=sec*6*M_PI/180.0; float minang=min*6*M_PI/180.0; float hourang=((hour)%12)*30*M_PI/180.0+minang/12; // define the size multiplier for each hand. #define HOUR (.4*half) #define MINUTE (.75*half) #define SECOND (.85*half) PSsetlinewidth( dialSize*half); PSsetlinecap( 1); // Rounded ends. PSsetlinejoin( 1); // Rounded joins. PStranslate( half, half); PSmoveto( sin( minang)*MINUTE, cos( minang)*MINUTE); switch( clockType) { case NORMAL : // "Normal" clock. PSlineto( 0, 0); PSlineto( sin( secang)*SECOND, cos( secang)*SECOND); PSlineto( 0, 0); PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR); break; case LINES : PSlineto( sin( secang)*SECOND, cos( secang)*SECOND); PSlineto( sin( hourang)*HOUR, cos( hourang)*HOUR); break; case CURVES : PScurveto( 0, 0, 0, 0, sin( secang)*SECOND, cos( secang)*SECOND); PScurveto( 0, 0, 0, 0, sin( hourang)*HOUR, cos( hourang)*HOUR); PScurveto( 0, 0, 0, 0, sin( minang)*MINUTE, cos( minang)*MINUTE); break; case BEZIER : PScurveto( sin( secang)*SECOND, cos( secang)*SECOND, 0, 0, sin( hourang)*HOUR, cos( hourang)*HOUR); break; } PSstroke(); PStranslate( -half, -half); return self; } - setAnimator:anObject { if( animator==anObject) // nip loops in the bud. return self; animator=anObject; [animator setTarget:self]; [animator setTiming:1.0]; [animator setThreshold:NX_MODALRESPTHRESHOLD]; // this makes it run smoother. why? return self; } - animate:sender { long clock; struct tm *t; [self lockFocus]; PSsetgray( NX_LTGRAY); // Erase the old time. [self drawDials]; time( &clock); // Snarf the new time. t=localtime( &clock); hour=t->tm_hour; min=t->tm_min; sec=t->tm_sec; PSsetgray( NX_BLACK); // Draw the new time. [self drawDials]; [self unlockFocus]; // Make it be. [[self window] flushWindow]; NXPing(); return self; } - animator { return animator; } - drawSelf:(NXRect *)r :(int)count { long clock; struct tm *t; int i; float half=bounds.size.height/2.0; #define TICKS (.95*half) time( &clock); // Snarf the time. t=localtime( &clock); hour=t->tm_hour; min=t->tm_min; sec=t->tm_sec; PSsetgray( NX_LTGRAY); // Clear the background. NXRectFill( &bounds); PSsetgray( NX_BLACK); // Draw the dials. [self drawDials]; PStranslate( half, half); // Then, draw the tick marks (assume linewidth/cap set by drawDials). PSnewpath(); for( i=0; i<12; i++, PSrotate( 30)) { PSmoveto( TICKS, 0); PSlineto( half, 0); } PSstroke(); [[self window] flushWindow]; NXPing(); return self; } // Here is a useful function - cut this out for your programs. This is a Window // delegate function which keeps the window from resizing to a non-square // size. It's not what I'd like, though - the resize bar still has that // section for resizing vertically only. When that occurs, you do not get // to do anything. I tried _making_ it resize, but that did not work. So, // this is what you get. - windowWillResize:sender toSize:(NXSize *)f { NXRect curFrame; [sender getFrame:&curFrame]; if( curFrame.size.width==f->width || curFrame.size.height==f->height) { *f=curFrame.size; return self; } f->width-=curFrame.size.width; f->height-=curFrame.size.height; f->width=f->height=MAX( f->width, f->height); f->width+=curFrame.size.width; f->height+=curFrame.size.height; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.