This is MiscClockView.m in view mode; [Download] [Up]
// // MiscClockView.m -- a simple view class for displaying date/time // Written by Scott Anguish Copyright (c) 1993 by Scott Anguish. // Version 1.2. All rights reserved. // // This notice may not be removed from this source code. // // This object is included in the MiscKit by permission from the author // and its use is governed by the MiscKit license, found in the file // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file // for a list of all applicable permissions and restrictions. // #import <sys/time.h> #import <appkit/appkit.h> #import "MiscClockView.h" @interface MiscClockView(private) - _setUp; @end @interface MiscClockView(Delegate) - dateChanged:sender; @end @implementation MiscClockView #define Misc_BuildHImage(a, b, c, d, e) NXSetRect(theRect, (b), (c), (d), (e)); \ (a)[0] = [[NXImage alloc] initFromImage:theImage rect:theRect]; \ theRect->origin.y += 137.0; \ (a)[1] = [[NXImage alloc] initFromImage:theImage rect:theRect]; #define Misc_BuildImage(a, b, c, d, e) NXSetRect(theRect, (b), (c), (d), (e)); \ a = [[NXImage alloc] initFromImage:theImage rect:theRect]; + initialize { [MiscClockView setVersion:4]; return self; } - _setUp { char buf[MAXPATHLEN + 1] = ""; NXRect rectStorage, *theRect = &rectStorage; NXSize oneSize, twoSize; if (theImage) return self; // don't want to leak! [[NXBundle bundleForClass:[self class]] getPath:buf forResource:"MiscClockStuff" ofType:"tiff"]; theImage = [[NXImage alloc] initFromFile:buf]; /* Yes this is ugly, and there is alot of extra junk in here, but to a * large degree at this point I didn't know where else to store these * co-ordinates where I wouldn't loose them! */ Misc_BuildHImage (imageA, 65.0, 0.0, 9.0, 11.0); Misc_BuildHImage (imageP, 74.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[1], 89.0, 0.0, 4.0, 11.0); Misc_BuildHImage (DigitalNumbers[2], 93.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[3], 104.0, 0.0, 8.0, 11.0); Misc_BuildHImage (DigitalNumbers[4], 112.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[5], 121.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[6], 130.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[7], 140.0, 0.0, 8.0, 11.0); Misc_BuildHImage (DigitalNumbers[8], 148.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[9], 157.0, 0.0, 9.0, 11.0); Misc_BuildHImage (DigitalNumbers[0], 166.0, 0.0, 9.0, 11.0); Misc_BuildHImage (imageColon, 175.0, 0.0, 3.0, 11.0); Misc_BuildHImage (imageAM, 179.0, 0.0, 12.0, 6.0); Misc_BuildHImage (imagePM, 192.0, 0.0, 11.0, 6.0); Misc_BuildHImage (DayNames[1], 0, 65, 19, 5); Misc_BuildHImage (DayNames[2], 0, 59, 19, 5); Misc_BuildHImage (DayNames[3], 0, 53, 19, 5); Misc_BuildHImage (DayNames[4], 0, 47, 19, 5); Misc_BuildHImage (DayNames[5], 0, 41, 19, 5); Misc_BuildHImage (DayNames[6], 0, 35, 19, 5); Misc_BuildHImage (DayNames[0], 0, 29, 19, 5); Misc_BuildHImage (MonthNames[0], 40, 66, 22, 5); Misc_BuildHImage (MonthNames[1], 40, 60, 22, 5); Misc_BuildHImage (MonthNames[2], 40, 54, 22, 5); Misc_BuildHImage (MonthNames[3], 40, 48, 22, 5); Misc_BuildHImage (MonthNames[4], 40, 42, 22, 5); Misc_BuildHImage (MonthNames[5], 40, 36, 22, 5); Misc_BuildHImage (MonthNames[6], 40, 30, 22, 5); Misc_BuildHImage (MonthNames[7], 40, 24, 22, 5); Misc_BuildHImage (MonthNames[8], 40, 18, 22, 5); Misc_BuildHImage (MonthNames[9], 40, 12, 22, 5); Misc_BuildHImage (MonthNames[10], 40, 6, 22, 5); Misc_BuildHImage (MonthNames[11], 40, 0, 22, 5); Misc_BuildHImage (DateNumbers[0], 172.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[1], 65.0, 14.0, 8.0, 17.0); Misc_BuildHImage (DateNumbers[2], 76.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[3], 88.0, 14.0, 9.0, 17.0); Misc_BuildHImage (DateNumbers[4], 100.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[5], 112.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[6], 124.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[7], 136.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[8], 148.0, 14.0, 10.0, 17.0); Misc_BuildHImage (DateNumbers[9], 160.0, 14.0, 10.0, 17.0); Misc_BuildHImage (YearNumbers[0], 12.0, 8.0, 6.0, 5.0); Misc_BuildHImage (YearNumbers[1], 0.0, 20.0, 2.0, 5.0); Misc_BuildHImage (YearNumbers[2], 2.0, 20.0, 5.0, 5.0); Misc_BuildHImage (YearNumbers[3], 7.0, 20.0, 5.0, 5.0); Misc_BuildHImage (YearNumbers[4], 12.0, 20.0, 5.0, 5.0); Misc_BuildHImage (YearNumbers[5], 0.0, 14.0, 5.0, 5.0); Misc_BuildHImage (YearNumbers[6], 5.0, 14.0, 6.0, 5.0); Misc_BuildHImage (YearNumbers[7], 11.0, 14.0, 5.0, 5.0); Misc_BuildHImage (YearNumbers[8], 0.0, 8.0, 6.0, 5.0); Misc_BuildHImage (YearNumbers[9], 6.0, 8.0, 6.0, 5.0); Misc_BuildHImage (YearColon, 18.0, 25.0, 1.0, 5.0); Misc_BuildImage (clockbase, 64, 72, 64, 64); [DigitalNumbers[1][0] getSize:&oneSize]; [DigitalNumbers[2][0] getSize:&twoSize]; colonPosition.x = oneSize.width + twoSize.width + 7.0; timedEntry = 0; if (keepingTime) { [self startClock:self]; } return self; } - initFrame:(const NXRect *)frameRect { [super initFrame:frameRect]; hidden=NO; keepingTime=NO; [self _setUp]; return self; } - awake { id ret = [super awake]; [self _setUp]; return ret; } - awakeFromNib { id ret = [super awake]; [self _setUp]; return ret; } - drawSelf:(const NXRect *)rects :(int)rectCount { NXPoint imageOrigin; NXSize size, theSize, tensSize = {0.0, 0.0}, onesSize, twoSize; id imageAyear, imageByear, imageCyear, imageDyear; float width, widthA, widthB, widthC; float imageAdjust; int currentYear, hrs; int highlight; highlight = 0; if (hidden) { PSsetgray(NX_LTGRAY); NXRectFill(&bounds); } [DigitalNumbers[1][highlight] getSize:&onesSize]; [DigitalNumbers[2][highlight] getSize:&twoSize]; if (!militaryTime) colonPosition.x = onesSize.width + twoSize.width + 7.0; else colonPosition.x = 30; if (showYear) { imageAdjust = 5; colonPosition.y = 51; } else { imageAdjust = 0; colonPosition.y = 46; } imageOrigin.x = 0; imageOrigin.y = 0 + imageAdjust; //(0) [clockbase composite:NX_COPY toPoint:&imageOrigin]; if (militaryTime) { hrs = hours; } else { hrs = hours % 12; if (!hrs) hrs = 12; } [imageAM[highlight] getSize:&size]; imageOrigin.x = 44; imageOrigin.y = 48 + imageAdjust; //(48) if (!militaryTime) { if (meridian) { imageOrigin.x = 45; [imagePM[highlight] composite:NX_COPY toPoint:&imageOrigin]; } else [imageAM[highlight] composite:NX_COPY toPoint:&imageOrigin]; } // Hours highlight = highlightSelection == 4 ? 1 : 0; imageOrigin = colonPosition; if (hrs / 10 || militaryTime) [DigitalNumbers[hrs / 10][highlight] getSize:&tensSize]; [DigitalNumbers[hrs % 10][highlight] getSize:&onesSize]; imageOrigin.x -= tensSize.width + onesSize.width; if (hrs / 10 || militaryTime) { [DigitalNumbers[hrs / 10][highlight] composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x += tensSize.width; } [DigitalNumbers[hrs % 10][highlight] composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x += onesSize.width; // Colon highlight = 0; [[imageColon[highlight] getSize:&size] composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x += size.width; // Minutes highlight = highlightSelection == 5 ? 1 : 0; [[DigitalNumbers[minutes / 10][highlight] getSize:&size] composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x += size.width; [DigitalNumbers[minutes % 10][highlight] composite:NX_COPY toPoint:&imageOrigin]; // Weekday highlight = 0; imageOrigin.x = 21; imageOrigin.y = 34 + imageAdjust; //(34) [DayNames[weekday][highlight] composite:NX_COPY toPoint:&imageOrigin]; // Month highlight = highlightSelection == 2 ? 1 : 0; imageOrigin.x = 19; imageOrigin.y = 9 + imageAdjust; //(9) [MonthNames[month][highlight] composite:NX_COPY toPoint:&imageOrigin]; tensSize.width = 0.0; tensSize.height = 0.0; // Day highlight = highlightSelection == 3 ? 1 : 0; imageOrigin.x = 30; imageOrigin.y = 15 + imageAdjust; //(15) if (date / 10) [DateNumbers[date / 10][highlight] getSize:&tensSize]; [DateNumbers[date % 10][highlight] getSize:&onesSize]; imageOrigin.x -= (tensSize.width + onesSize.width) / 2; if (date / 10) [DateNumbers[date / 10][highlight] composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x += tensSize.width + 1; [DateNumbers[date % 10][highlight] composite:NX_COPY toPoint:&imageOrigin]; //Draw the year if (showYear) { // Year highlight = highlightSelection == 1 ? 1 : 0; currentYear = [self year] + 1900; imageAyear = YearNumbers[currentYear / 1000][highlight]; currentYear = currentYear % 1000; imageByear = YearNumbers[currentYear / 100][highlight]; currentYear = currentYear % 100; imageCyear = YearNumbers[currentYear / 10][highlight]; currentYear = currentYear % 10; imageDyear = YearNumbers[currentYear][highlight]; [imageAyear getSize:&theSize]; widthA = theSize.width; [imageByear getSize:&theSize]; widthB = theSize.width; [imageCyear getSize:&theSize]; widthC = theSize.width; [imageDyear getSize:&theSize]; width = widthA + widthB + widthC + theSize.width; imageOrigin.x = 32 - (width / 2.0); imageOrigin.y = 0; [imageAyear composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x = imageOrigin.x + widthA; [imageByear composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x = imageOrigin.x + widthB; [imageCyear composite:NX_COPY toPoint:&imageOrigin]; imageOrigin.x = imageOrigin.x + widthC; [imageDyear composite:NX_COPY toPoint:&imageOrigin]; } return self; } - setSeconds:(int)theSeconds { seconds = theSeconds; return self; } - setMinutes:(int)theMinutes { minutes = theMinutes; return self; } - setHours:(int)theHours { hours = theHours; return self; } - setWeekday:(int)theWeekday { weekday = theWeekday; return self; } - setDate:(int)theDate { date = theDate; return self; } - setMonth:(int)theMonth { month = theMonth; return self; } - setYear:(int)theYear { year = theYear; return self; } - setMeridian:(int)theMeridian { meridian = theMeridian; return self; } - takeMinutesFrom:sender { [self setMinutes:[sender intValue]]; [self display]; return self; } - takeHoursFrom:sender { int localhours = [sender intValue]; localhours %= 24; if (localhours < 12) { [self setMeridian:0]; } else { [self setMeridian:1]; } [self setHours:localhours]; [self display]; return self; } - takeWeekdayFrom:sender { [self setWeekday:[sender intValue]]; [self display]; return self; } - takeDateFrom:sender { [self setDate:[sender intValue]]; [self display]; return self; } - takeMonthFrom:sender { [self setMonth:[sender intValue]]; [self display]; return self; } - setTime: (struct tm*)theTime { seconds = theTime->tm_sec; minutes = theTime->tm_min; hours = theTime->tm_hour; if (hours < 12) { meridian = 0; } else { meridian = 1; }; date = theTime->tm_mday; month = theTime->tm_mon; year = theTime->tm_year; weekday = theTime->tm_wday; return self; }; - (const char *)getInspectorClassName { return "MiscClockViewInspector"; } - (int)year { return year; } - (int)month { return month; } - (int)weekday { return weekday; } - (int)date { return date; } - (int)hours { return hours; } - (int)minutes { return minutes; } - (int)seconds { return seconds; } - (BOOL)militaryTime { return militaryTime; } - (BOOL)showYear { return showYear; } - setShowYear:(BOOL)state { showYear = state; return self; } - setMilitaryTime:(BOOL)state { militaryTime = state; return self; } - (BOOL)keepingTime { return keepingTime; } - setKeepingTime:(BOOL)yesno { keepingTime = yesno; return self; } - read:(NXTypedStream *) stream { int myVersion = NXTypedStreamClassVersion (stream,[self name]); [super read:stream]; if (myVersion < 2) { NXReadTypes (stream, "iiiiiiiiii", &seconds, &minutes, &hours, &date, &month, &year, &weekday, &meridian, &showYear, &militaryTime); } else { NXReadTypes (stream, "iiiiiiiicc", &seconds, &minutes, &hours, &date, &month, &year, &weekday, &meridian, &showYear, &militaryTime); } if (myVersion < 1) { keepingTime = NO; } else if (myVersion == 1) { NXReadType (stream, "i", &keepingTime); } else { NXReadType (stream, "c", &keepingTime); } if (myVersion > 2) { NXReadType (stream, "c", &hidden); } else { hidden = NO; } if (myVersion > 3) { delegate = NXReadObject (stream); } else { delegate = nil; } return self; } - write:(NXTypedStream *) stream { [super write:stream]; NXWriteTypes (stream, "iiiiiiiicc", &seconds, &minutes, &hours, &date, &month, &year, &weekday, &meridian, &showYear, &militaryTime); NXWriteType (stream, "c", &keepingTime); NXWriteType (stream, "c", &hidden); NXWriteObject (stream, delegate); return self; } - setHide:(BOOL)hide { hidden = hide; return self; } - (BOOL)isHidden { return hidden; } void Animate (timedEntry, now, self) DPSTimedEntry timedEntry; double now; id self; { [(id)self ticktock]; } - ticktock { struct timeval tp; struct timezone tzp; struct tm *tv; gettimeofday (&tp, &tzp); tv = localtime (&tp.tv_sec); [self setTime:tv]; [self display]; return self; } - startClock:sender { if (!keepingTime) { [self ticktock]; timedEntry = DPSAddTimedEntry (60, Animate, (void *)self, NX_MODALRESPTHRESHOLD); keepingTime = YES; NXPing (); } return self; } - stopClock:sender { if (timedEntry) { DPSRemoveTimedEntry (timedEntry); [self ticktock]; keepingTime = NO; timedEntry = 0; } return self; } - free { int i,j; for(j=0;j<2;j++) { [imageA[j] free]; [imageP[j] free]; for(i=0;i<10;i++) [DigitalNumbers[i][j] free]; [imageColon[j] free]; [imageAM[j] free]; [imagePM[j] free]; for(i=0;i<7;i++) [DayNames[i][j] free]; for(i=0;i<12;i++) [MonthNames[i][j] free]; for(i=0;i<10;i++) [DateNumbers[i][j] free]; for(i=0;i<10;i++) [YearNumbers[i][j] free]; [YearColon[j] free]; } [clockbase free]; [theImage free]; if (timedEntry != NULL) DPSRemoveTimedEntry (timedEntry); return[super free]; } - setToCurrentTime:sender { struct timeval tp; struct timezone tzp; struct tm *tv; gettimeofday (&tp, &tzp); tv = localtime (&tp.tv_sec); [self setTime:tv]; [self display]; return self; } // Action stuff - mouseDown:(NXEvent *)theEvent { NXPoint mouseLocation; NXRect minuteRect; NXRect hourRect; NXRect dayRect; NXRect monthRect; NXRect yearRect; BOOL flipped = [self isFlipped]; int oldSelection = highlightSelection; mouseLocation = theEvent->location; /* ... and convert them into our view coordinate system */ [self convertPoint:&mouseLocation fromView:nil]; NXSetRect(&hourRect,colonPosition.x-21.0,colonPosition.y,20.0,11.0); NXSetRect(&minuteRect,colonPosition.x+1.0,colonPosition.y,20.0,11.0); if(showYear) { NXSetRect(&dayRect,30.0,20.0,20.0,17.0); NXSetRect(&monthRect,19.0,14.0,22.0,5.0); NXSetRect(&yearRect,22.0,0.0,20.0,5.0); } else { NXSetRect(&dayRect,30.0,15.0,20.0,17.0); NXSetRect(&monthRect,19.0,9.0,22.0,5.0); } // Find out what we hit highlightSelection = 0; // 1. Year if(showYear) { if(NXMouseInRect(&mouseLocation, &yearRect, flipped)) { highlightSelection = 1; return oldSelection == highlightSelection ? self : [self display]; } } // 2. Month if(NXMouseInRect(&mouseLocation, &monthRect, flipped)) { highlightSelection = 2; } // 3. Day else if(NXMouseInRect(&mouseLocation, &dayRect, flipped)) { highlightSelection = 3; } // 4. Hour else if(NXMouseInRect(&mouseLocation, &hourRect, flipped)) { highlightSelection = 4; } // 5. Minutes else if(NXMouseInRect(&mouseLocation, &minuteRect, flipped)) { highlightSelection = 5; } return oldSelection == highlightSelection ? self : [self display]; } - increment:sender { return [self changeDate:1]; } - decrement:sender { return [self changeDate:-1]; } - changeDate:(int) change { static int monthDays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int daysInMonth; struct tm tmDate; time_t time; switch(highlightSelection) { case 1: // Year year += change; break; case 2: // Month month += change; break; case 3: // Day date += change; break; case 4: // Hours hours += change; break; case 5: // Minutes minutes += change; break; default: // Nothing selected return nil; } // Consistency checks if(minutes > 59) { ++hours; minutes = 0; } else if(minutes < 0) { --hours; minutes = 59; } if(hours > 23) { ++date; hours = 0; } else if(hours < 0) { --date; hours = 23; } meridian = hours > 12 ? 1 : 0; if(month != 1) { daysInMonth = monthDays[month]; } else { daysInMonth = (year % 4) ? 28 : 29; } if(date > daysInMonth) { ++month; date = 1; } else if(date < 1) { --month; if(month != 1) { daysInMonth = monthDays[month]; } else { daysInMonth = (year % 4) ? 28 : 29; } date = daysInMonth; } if(month > 11) { ++year; month = 0; } else if(month < 0) { --year; month = 11; } // We have to set the correct week day tmDate.tm_sec = 0; tmDate.tm_min = 0; tmDate.tm_hour = 0; tmDate.tm_mday = 1; tmDate.tm_mon = month; tmDate.tm_year = year - 1900; tmDate.tm_wday = 0; tmDate.tm_yday = 0; tmDate.tm_isdst = 0; tmDate.tm_gmtoff = 0; tmDate.tm_zone = ""; time = mktime(&tmDate); tmDate = *localtime(&time); time -= tmDate.tm_gmtoff; tmDate = *localtime(&time); weekday = tmDate.tm_wday; if(delegate && [delegate respondsTo:@selector(dateChanged:)]) { [delegate dateChanged:self]; } return [self display]; } - setDelegate:aDelegate { delegate = aDelegate; return self; } - delegate { return delegate; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.