This is AlarmClock.m in view mode; [Download] [Up]
#import "AlarmClock.h" #import "Animator.h" // Some notes: there are three alarms. You can set any or // all of the three alarms any way you like. The alarm only looks at // minutes and hours; it ignores seconds...and only has an accuracy // of +/- 5 sec. with respect to the system clock, since I only check // every ten seconds to see if it's time to go off. A better way to // do this might be to have three timed entries, each set to go off // at the right time and call the proper alarm trigger function, but // this way works just fine for me. I really need to implement prefs // especially for the "x minutes after launch" alarm: that would be // nice to suggest that you to log off after a certain amount of time. // Also, the interface is a bit confusing and very ugly... @implementation AlarmClock - appDidInit:sender { int i; launchTime = [[DAYTime alloc] initWithCurrentTime]; fromSet = [[DAYTime alloc] init]; absolute = [[DAYTime alloc] init]; fromLaunch = [[DAYTime alloc] init]; for (i=0; i<3; i++) { alarms[i] = [[DAYTime alloc] initWithCurrentTime]; } // set up a timer to call us once every so often. animator = [[Animator alloc] initChronon:ALARM_FREQUENCY adaptation:0.0 target:self action:@selector(tick:) autoStart:YES eventMask:0]; [self doAtSetTime:self]; return self; } - setAlarm:sender { if (alarmType[num] < 0) { NXRunAlertPanel(NULL, [strings valueForStringKey:"setTfirst"], [strings valueForStringKey:"OK"], NULL, NULL); return nil; } if (alarms[num]) [alarms[num] free]; switch (num) { case 0 : { [absolute setMinute:[[timeMatrix findCellWithTag:1] intValue]]; [absolute setHour:[[timeMatrix findCellWithTag:0] intValue]]; alarms[0] = [absolute copy]; break; } case 1 : { [fromSet setMinute:[[timeMatrix findCellWithTag:1] intValue]]; [fromSet setHour:[[timeMatrix findCellWithTag:0] intValue]]; alarms[1] = [[DAYTime alloc] initWithCurrentTime]; // the addTime: method isn't done yet, so I'm using these. [alarms[1] addMinutes:[fromSet minute]]; [alarms[1] addHours:[fromSet hour]]; break; } case 2 : { [fromLaunch setMinute:[[timeMatrix findCellWithTag:1] intValue]]; [fromLaunch setHour:[[timeMatrix findCellWithTag:0] intValue]]; alarms[2] = [launchTime copy]; [alarms[2] addMinutes:[fromLaunch minute]]; [alarms[2] addHours:[fromLaunch hour]]; break; } default: break; // should never get here } alarmOn[num] = YES; return self; } - tick:sender { int i; DAYTime *currentTime = [[DAYTime alloc] initWithCurrentTime]; for (i=0; i<3; i++) { if (alarmOn[i] && ([currentTime minute] == [alarms[i] minute]) && ([currentTime hour] == [alarms[i] hour])) { // time to fire off the alarm if (((alarmType[i] == ALARM_SOUND_AND_GRAPHIC) || (alarmType[i] == ALARM_GRAPHIC)) && images[i]) { // put up a graphic NXRect theFrame; NXSize theSize; NXPoint aPoint = {0, 0}; Window *aWindow; [images[i] getSize:&theSize]; // really, I should grab the actual screen size here // but for now I'm using the standard NeXT screen size // (1120x832) since I don't have time to do it right NXSetRect(&theFrame, (1120-theSize.width-2)/2, (832-theSize.height-21)/2, theSize.width, theSize.height); aWindow = [[Window alloc] initContent:&theFrame style:NX_TITLEDSTYLE backing:NX_RETAINED buttonMask:NX_CLOSEBUTTONMASK defer:NO]; [aWindow setTitle: [strings valueForStringKey:"ImageWindowTitle"]]; [aWindow display]; [[aWindow contentView] lockFocus]; [images[i] composite:NX_COPY toPoint:&aPoint]; [[aWindow contentView] unlockFocus]; [aWindow makeKeyAndOrderFront:self]; [NXApp activateSelf:YES]; } if ((alarmType[i] == ALARM_SOUND_AND_GRAPHIC) || (alarmType[i] == ALARM_SOUND)) [sounds[i] play]; if (alarmType[i] == ALARM_UNIX_COMMAND) { // do a UNIX command system([commands[i] stringValue]); } // make sure the alarm doesn't go off more than once alarmOn[i] = NO; } } return self; } - free { int i; for (i=0; i<3; i++) { [alarms[i] free]; [images[i] free]; [sounds[i] free]; [commands[i] free]; } [fromSet free]; [absolute free]; [fromLaunch free]; [launchTime free]; [super free]; return self; } - getSound:sender { const char *const types[] = {"snd", NULL}; if ([[OpenPanel new] runModalForTypes:types]) { [soundText setStringValue:[[OpenPanel new] filename]]; } return self; } - getImage:sender { const char *const types[] = {"tiff", "eps", NULL}; if ([[OpenPanel new] runModalForTypes:types]) { [imageText setStringValue:[[OpenPanel new] filename]]; } return self; } - setSound:sender { if (sounds[num]) [sounds[num] free]; sounds[num] = [[Sound alloc] initFromSoundfile:[soundText stringValue]]; if (!sounds[num]) { NXRunAlertPanel(NULL, [strings valueForStringKey:"setSfirst"], [strings valueForStringKey:"OK"], NULL, NULL); return nil; } alarmType[num] = ALARM_SOUND; return self; } - setGraphic:sender { if (images[num]) [images[num] free]; images[num] = [[NXImage alloc] initFromFile:[imageText stringValue]]; if (!images[num]) { NXRunAlertPanel(NULL, [strings valueForStringKey:"setGfirst"], [strings valueForStringKey:"OK"], NULL, NULL); return nil; } alarmType[num] = ALARM_GRAPHIC; return self; } - setSoundAndGraphic:sender { if (!sounds[num]) sounds[num] = [[Sound alloc] initFromSoundfile:[soundText stringValue]]; if (!images[num]) images[num] = [[NXImage alloc] initFromFile:[imageText stringValue]]; if (!sounds[num] && !images[num]) { NXRunAlertPanel(NULL, [strings valueForStringKey:"setSandGfirst"], [strings valueForStringKey:"OK"], NULL, NULL); return nil; } alarmType[num] = ALARM_SOUND_AND_GRAPHIC; return self; } - setUnixCommand:sender { [NXApp runModalFor:unixWindow]; // get the command alarmType[num] = ALARM_UNIX_COMMAND; return self; } - gotUnixCommand:sender { if (commands[num]) [commands[num] free]; commands[num] = [[DAYString alloc] initString:[unixText stringValue]]; [unixWindow orderOut:self]; [NXApp stopModal]; return self; } - doAtSetTime:sender { num = 0; [typeList setTitle:[strings valueForStringKey:"Sound"]]; alarmType[num] = -1; [[timeMatrix findCellWithTag:1] setIntValue:[absolute minute]]; [[timeMatrix findCellWithTag:0] setIntValue:[absolute hour]]; return self; } - doFromNow:sender { num = 1; [typeList setTitle:[strings valueForStringKey:"Sound"]]; alarmType[num] = -1; [[timeMatrix findCellWithTag:1] setIntValue:[fromSet minute]]; [[timeMatrix findCellWithTag:0] setIntValue:[fromSet hour]]; return self; } - doFromLaunch:sender { num = 2; [typeList setTitle:[strings valueForStringKey:"Sound"]]; alarmType[num] = -1; [[timeMatrix findCellWithTag:1] setIntValue:[fromLaunch minute]]; [[timeMatrix findCellWithTag:0] setIntValue:[fromLaunch hour]]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.