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.