home *** CD-ROM | disk | FTP | other *** search
- // ClockView.m
- // By Jayson Adams, NeXT Developer Support Team
- // You may freely copy, distribute and reuse the code in this example.
- // NeXT disclaims any warranty of any kind, expressed or implied, as to its
- // fitness for any particular use.
-
- #import <math.h>
- #import <appkit/Application.h>
- #import <appkit/Slider.h>
- #import <appkit/NXImage.h>
- #import "ClockView.h"
- #import <Date.h>
-
- typedef struct _TimerStruct {
- Date *date;
- ClockView *view;
- } TimerStruct, *TimerStructPtr;
- static TimerStruct t_timerStruct;
- static long t_start,t_now;
- static long t_min,t_sec;
-
- #define ABS(x) (x < 0 ? -(x) : (x))
-
- void MinuteSecondTimer(DPSTimedEntry teNumber, double now,
- TimerStructPtr ts)
- {
- /* Display the current time */
- t_now = [ts->date sysTime];
-
- t_min = (t_now - t_start) / 60;
- t_sec = t_now - t_start - 60 * t_min;
- t_min %= 60;
-
- [ts->view display];
- }
-
- @implementation ClockView
-
-
- /* instance methods */
-
- - initFrame:(NXRect *)frameRect
- {
- NXSize oneSize, twoSize;
- int i;
- char *numberNames[] = {"DigitalZero", "DigitalOne", "DigitalTwo",
- "DigitalThree", "DigitalFour", "DigitalFive",
- "DigitalSix", "DigitalSeven", "DigitalEight",
- "DigitalNine", ""};
-
- [super initFrame : frameRect];
-
- /* get the images we'll use in drawSelf:: */
- clockImage = [NXImage findImageNamed : "Clock"];
-
- for (i = 0; *numberNames[i]; i++)
- numbers[i] = [NXImage findImageNamed:numberNames[i]];
-
- colon = [NXImage findImageNamed : "Colon"];
- amImage = [NXImage findImageNamed : "AM"];
- pmImage = [NXImage findImageNamed : "PM"];
-
- /* compute the colon's location (it never changes) */
- [numbers[1] getSize : &oneSize];
- [numbers[2] getSize : &twoSize];
- colonPosition_clock.x = oneSize.width + twoSize.width + 4.0;
- colonPosition_clock.y = ceil((bounds.size.height - twoSize.height) / 2.0);
- /* Center the ':' for the timer */
- colonPosition_timer.x = bounds.size.width / 2.0;
- colonPosition_timer.y = colonPosition_clock.y;
-
- /* Init the date to the current time */
- dateObj = [[Date alloc] initFromNow];
- /* Check my time to see if it is AM or PM */
- if ([dateObj hours] < 12)
- meridianImage = amImage;
- else
- meridianImage = pmImage;
-
- return self;
- }
-
- /* Date initialization methods */
- - setDate : (short) d : (short) m : (short) y
- {
- if([dateObj initFromDate : d : m : y] == nil)
- return nil;
- /* Check my time to see if it is AM or PM */
- if ([dateObj hours] < 12)
- meridianImage = amImage;
- else
- meridianImage = pmImage;
- [self display];
- return self;
- }
-
- - setTime : (short) hr : (short) min : (short) sec
- {
- if([dateObj setTime : hr : min : sec] == nil)
- return nil;
- /* Check my time to see if it is AM or PM */
- if ([dateObj hours] < 12)
- meridianImage = amImage;
- else
- meridianImage = pmImage;
- [self display];
- return self;
- }
-
- - now
- {
- if([dateObj initFromNow] == nil)
- return nil;
- [self display];
- return self;
- }
-
- - startMinSecTimer : sender
- {
- t_start = [dateObj sysTime];
- t_timerStruct.date = dateObj;
- t_timerStruct.view = self;
- /* Start the proc which updates the display every second */
- min_sec_timer = DPSAddTimedEntry(1.0, MinuteSecondTimer, &t_timerStruct,
- NX_MODALRESPTHRESHOLD);
- timerActive = YES;
- [self display];
-
- return self;
- }
-
- - endTimer : sender
- {
- DPSRemoveTimedEntry(min_sec_timer);
- timerActive = NO;
- return self;
- }
-
- - drawSelf:(NXRect *)rects :(int)count
- {
- NXPoint position;
- NXSize size, hoursTensSize = {0.0, 0.0}, hoursUnitsSize;
- int t0,t1;
-
- /* Set the hour & minute (minute & second) positions
- depending on the timer state */
- if(timerActive == YES)
- {
- t0 = t_min;
- t1 = t_sec;
- }
- else
- {
- t0 = [dateObj hours];
- if(t0 > 12)
- t0 %= 12;
- t1 = [dateObj minutes];
- }
-
- /* draw the background */
- [clockImage composite:NX_COPY toPoint:&(bounds.origin)];
-
- /* AM or PM */
- if(timerActive == NO)
- {
- [meridianImage getSize:&size];
- position.x = bounds.size.width - size.width - 4.0;
- position.y = floor((bounds.size.height - size.height) / 2.0);
- [meridianImage composite:NX_COPY toPoint:&position];
- }
-
- /* compute starting position for all drawing; the colon is stationary */
- if(timerActive == NO)
- position = colonPosition_clock;
- else
- position = colonPosition_timer;
-
- if (t0 / 10)
- {
- [numbers[t0 / 10] getSize:&hoursTensSize];
- }
- [numbers[t0 % 10] getSize:&hoursUnitsSize];
- position.x -= hoursTensSize.width + hoursUnitsSize.width;
-
- /* draw the hours tens digit */
- if (t0 / 10)
- {
- [numbers[t0 / 10] composite:NX_COPY toPoint:&position];
- position.x += hoursTensSize.width;
- }
-
- /* hours units digit */
- [numbers[t0 % 10] composite:NX_COPY toPoint:&position];
- position.x += hoursUnitsSize.width;
-
- /* draw the colon */
- [[colon getSize:&size] composite:NX_COPY toPoint:&position];
- position.x += size.width;
-
- /* tens digit of minutes */
- [[numbers[t1 / 10] getSize:&size] composite:NX_COPY
- toPoint:&position];
- position.x += size.width;
-
- /* minutes units digit */
- [numbers[t1 % 10] composite:NX_COPY toPoint:&position];
-
- return self;
- }
-
- @end
-