This is Calendar.m in view mode; [Download] [Up]
//---------------------------------------------------------------------------------------------------- // // Calendar // // Inherits From: Control // // Declared In: Calendar.h // // Disclaimer // // You may freely copy, distribute and reuse this software and its // associated documentation. I disclaim any warranty of any kind, // expressed or implied, as to its fitness for any particular use. // //---------------------------------------------------------------------------------------------------- #import "Calendar.h" static const char* DAYS [7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static const char* MONTHS [12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static int LAST_DAY_OF_MONTH [13] = { 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; char dateString [25]; @implementation Calendar //---------------------------------------------------------------------------------------------------- // Private Methods //---------------------------------------------------------------------------------------------------- - _initMonthTextField { // Create the monthTextField instance and add it as a subview. Font* font = [Font newFont:"Helvetica-Bold" size:12 style:0 matrix:NX_FLIPPEDMATRIX]; NXRect frameRect = {5.0, 114.0, 94.0, 15.0}; monthTextField = [[TextField allocFromZone:[self zone]] initFrame: &frameRect]; [monthTextField setEditable: NO]; [monthTextField setBezeled: NO]; [monthTextField setBackgroundColor: NX_COLORLTGRAY]; [monthTextField setFont: font]; [self addSubview: monthTextField]; return self; } - _initYearTextField { // Create the yearTextField instance and add it as a subview. Font* font = [Font newFont:"Helvetica-Bold" size:12 style:0 matrix:NX_FLIPPEDMATRIX]; NXRect frameRect = {133.0, 114.0, 33.0, 15.0}; yearTextField = [[TextField allocFromZone:[self zone]] initFrame: &frameRect]; [yearTextField setEditable: NO]; [yearTextField setBezeled: NO]; [yearTextField setAlignment: NX_RIGHTALIGNED]; [yearTextField setBackgroundColor: NX_COLORLTGRAY]; [yearTextField setFont: font]; [self addSubview: yearTextField]; return self; } - _initWeekdayTextField { // Create the weekdayTextField instance and add it as a subview. Font* font = [Font newFont:"Helvetica-Bold" size:10 style:0 matrix:NX_FLIPPEDMATRIX]; NXRect frameRect = {7.0, 96.0, 157.0, 13.0}; weekdayTextField = [[TextField allocFromZone:[self zone]] initFrame: &frameRect]; [weekdayTextField setEditable: NO]; [weekdayTextField setBezeled: NO]; [weekdayTextField setAlignment: NX_CENTERED]; [weekdayTextField setBackgroundColor: NX_COLORDKGRAY]; [weekdayTextField setTextColor: NX_COLORWHITE]; [weekdayTextField setFont: font]; [weekdayTextField setStringValue: " S M T W T F S"]; [self addSubview: weekdayTextField]; return self; } - _initDayMatrix { // Create the dayMatrix ButtonCell Matrix and add it as a subview. id buttonCell; int cellTag = 0; int row; int column; Font* font = [Font newFont:"Helvetica" size:10 style:0 matrix:NX_FLIPPEDMATRIX]; NXRect matrixRect = {7.0, 3.0, 161.0, 90.0}; NXRect cellRect = {0.0, 0.0, 23.0, 15.0}; NXSize cellSize = {0.0, 0.0}; buttonCell = [[ButtonCell allocFromZone:[self zone]] initTextCell: ""]; [buttonCell setHighlightsBy: NX_CHANGEGRAY]; [buttonCell setType: NX_ONOFF]; [buttonCell setEditable: NO]; [buttonCell setBordered: NO]; [buttonCell setFont: font]; dayMatrix = [[Matrix allocFromZone:[self zone]] initFrame:&matrixRect mode:NX_RADIOMODE prototype:buttonCell numRows:6 numCols:7]; for (row = 0; row < 6; row++) for (column = 0; column < 7; column++) [[dayMatrix cellAt:row :column] setTag: cellTag++]; [dayMatrix setIntercell:&cellSize]; [dayMatrix setCellSize:&cellRect.size]; [dayMatrix sizeToCells]; [dayMatrix setAutodisplay:YES]; [[dayMatrix setTarget: self] setAction: @selector (_daySelected:)]; [dayMatrix setEmptySelectionEnabled: YES]; [self addSubview: dayMatrix]; return self; } - _initWithSystemDate { struct timeval greenwich; struct tm* today; gettimeofday (&greenwich, NULL); today = (localtime (&(greenwich.tv_sec))); day = today->tm_mday; month = 1 + today->tm_mon; year = 1900 + today->tm_year; return self; } - (int) _lastDayOfMonth { if (month == 0) [self _initWithSystemDate]; if (month == 2) LAST_DAY_OF_MONTH[1] = (year % 4 ? 28 : 29); return LAST_DAY_OF_MONTH [month - 1]; } - (int) _firstWeekdayOfMonth { int theMonth = month; int theYear = year; int weekDay; int offset; long julian; if (theMonth <= 2) { theYear--; theMonth += 12; } offset = 0; if ((theYear * 10000.0) + (theMonth * 100.0) + 1 >= 15821015.0) offset = (2 - (theYear / 100)) + ((theYear / 100) / 4); julian = (365.25 * theYear); julian += (long) (30.6001 * (theMonth +1)); julian += (long) 1; julian += 1720994L; julian += (long) offset; weekDay = (int) ((julian + 2) % 7); return (weekDay < 0 || weekDay > 6 ? 0 : weekDay); } - _highlightCurrentDay { // Called by _updateCalendar and day: methods to select current day. int firstWeekday; id selectedCell; [dayMatrix selectCellAt: -1 :-1]; if (day == 0) return self; firstWeekday = [self _firstWeekdayOfMonth]; selectedCell = [dayMatrix findCellWithTag: day + firstWeekday - 1]; if ([selectedCell title]) if (strcmp ([selectedCell title], "")) [dayMatrix selectCellWithTag: day + firstWeekday - 1]; return self; } - _sendActionToTarget { if ([self target] && [self isEnabled]) if ([[self target] respondsTo: [self action]]) [[self target] perform:[self action] with:self]; return self; } - _daySelected: sender { // Private action method for dayMatrix. Send user's action to target. day = ([sender selectedCell] ? atoi ([[sender selectedCell] title]) : 0); [self _sendActionToTarget]; return self; } - _updateCalendar { // Handles display update of subviews. int date; int cellTag; int firstWeekday = [self _firstWeekdayOfMonth]; int lastDayOfMonth = [self _lastDayOfMonth]; char dateString[3]; [[dayMatrix window] disableDisplay]; for (cellTag = 0; cellTag < firstWeekday; cellTag++) [[[dayMatrix findCellWithTag: cellTag] setTitle: ""] setEnabled: NO]; for (cellTag = lastDayOfMonth; cellTag < [dayMatrix cellCount]; cellTag++) [[[dayMatrix findCellWithTag: cellTag] setTitle: ""] setEnabled: NO]; for (cellTag = firstWeekday, date = 1; date <= lastDayOfMonth; cellTag++, date++) { sprintf (dateString, "%d", date); [[[dayMatrix findCellWithTag: cellTag] setTitle: dateString] setEnabled: isEnabled]; } [self _highlightCurrentDay]; [monthTextField setStringValue: MONTHS [month - 1]]; [yearTextField setIntValue: year]; [[dayMatrix window] reenableDisplay]; [self display]; return self; } - _nextText: sender { // Called by 'takeFrom' methods to assist UI flow. if ([sender isKindOf: [TextField class]]) if ([[sender nextText] respondsTo: @selector(selectText:)]) [[sender nextText] selectText:nil]; return self; } //---------------------------------------------------------------------------------------------------- // Initializing and Freeing //---------------------------------------------------------------------------------------------------- - initFrame: (const NXRect*) frameRect { // Init and display current date. Create an ActionCell instance to // hold our target/action values. Enable day selection. [super initFrame: frameRect]; [self setCell: [[ActionCell allocFromZone:[self zone]] init]]; [self setEnabled: YES]; [self _initMonthTextField]; [self _initYearTextField]; [self _initWeekdayTextField]; [self _initDayMatrix]; [self _initWithSystemDate]; [self _updateCalendar]; return self; } - free { if (dayMatrix) [dayMatrix free]; if (monthTextField) [monthTextField free]; if (yearTextField) [yearTextField free]; if (weekdayTextField) [weekdayTextField free]; return [super free]; } //---------------------------------------------------------------------------------------------------- // Accessors //---------------------------------------------------------------------------------------------------- - month: (int) aMonth { month = (aMonth < 1 || aMonth > 12 ? 1 : aMonth); [self _updateCalendar]; return self; } - day: (int) aDay { day = (aDay < 1 || aDay > [self _lastDayOfMonth] ? 0 : aDay); [self _highlightCurrentDay]; return self; } - year: (int) aYear { year = (aYear < 1 || aYear > 9999 ? 1 : aYear); [self _updateCalendar]; return self; } - (const char*) monthStringValue { return [monthTextField stringValue]; } - (const char*) dayStringValue { return ([[dayMatrix selectedCell] title]); } - (const char*) yearStringValue { return [yearTextField stringValue]; } - (const char*) dayOfWeekStringValue { return DAYS [([[dayMatrix selectedCell] tag] % 7)]; } - (const char*) dateStringValue { if (day) sprintf (dateString, "%s %d, %.4d", [self monthStringValue], day, [self yearIntValue]); else sprintf (dateString, "%s %.4d", [self monthStringValue], [self yearIntValue]); return dateString; } - (int) monthIntValue { return month; } - (int) dayIntValue { return day; } - (int) yearIntValue { return year; } - (int) dayOfWeekIntValue { return ([[dayMatrix selectedCell] tag] % 7); } - (const char*) stringValue { return [self dateStringValue]; } - (int) intValue { return day; } - (float) floatValue { return (float) day; } - (double) doubleValue { return (double) day; } //---------------------------------------------------------------------------------------------------- // Enabling Day Selection //---------------------------------------------------------------------------------------------------- - setEnabled: (BOOL) aFlag { // Set enabling of day selection to aFlag and redisplay calendar (this will // force update of dayMatrix buttonCells which are what actually gets // enabled or disabled). Since the subview dayMatrix handles the mouse // events we're interested in, we (the superview) will always remain disabled. isEnabled = aFlag; [self _updateCalendar]; [super setEnabled: NO]; return self; } - (BOOL) isEnabled { return isEnabled; } //---------------------------------------------------------------------------------------------------- // Action Methods //---------------------------------------------------------------------------------------------------- - incrementMonth: sender { if (++month > 12) month = 1; [self _updateCalendar]; return self; } - decrementMonth: sender { if (--month < 1) month = 12; [self _updateCalendar]; return self; } - incrementYear: sender { if (++year > 9999) year = 1; [self _updateCalendar]; return self; } - decrementYear: sender { if (--year < 1) year = 9999; [self _updateCalendar]; return self; } - takeMonthIntValueFrom: sender { if ([sender isKindOf: [Matrix class]]) sender = [sender selectedCell]; if ([sender respondsTo: @selector (intValue)]) [self month: [sender intValue]]; [self _nextText: sender]; return self; } - takeDayIntValueFrom: sender { if ([sender isKindOf: [Matrix class]]) sender = [sender selectedCell]; if ([sender respondsTo: @selector (intValue)]) [self day: [sender intValue]]; [self _nextText: sender]; return self; } - takeYearIntValueFrom: sender { if ([sender isKindOf: [Matrix class]]) sender = [sender selectedCell]; if ([sender respondsTo: @selector (intValue)]) [self year: [sender intValue]]; [self _nextText: sender]; return self; } - showSystemDate: sender { [self _initWithSystemDate]; [self _updateCalendar]; return self; } //---------------------------------------------------------------------------------------------------- // Archiving //---------------------------------------------------------------------------------------------------- - read: (NXTypedStream*) stream { [super read: stream]; NXReadTypes (stream, "iii@@@c", &month, &day, &year, &monthTextField, &dayMatrix, &yearTextField, &isEnabled); return self; } - write: (NXTypedStream*) stream { [super write: stream]; NXWriteTypes (stream, "iii@@@c", &month, &day, &year, &monthTextField, &dayMatrix, &yearTextField, &isEnabled); return self; } //---------------------------------------------------------------------------------------------------- // IB Methods //---------------------------------------------------------------------------------------------------- - (const char*) getInspectorClassName { // Returns the name of the class responsible for managing custom // IB Attributes inspection. return "CalendarInspector"; } - getMinSize:(NXSize *)minSize maxSize:(NXSize *)maxSize from:(int)where { // Constrains resize within IB. minSize->width = maxSize->width = 175.0; minSize->height = maxSize->height = 137.0; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.