source: releases/Pester/1.1a1/Source/PSApplication.m@ 338

Last change on this file since 338 was 34, checked in by Nicholas Riley, 21 years ago

Changes for Pester 1.1d1.

File size: 7.0 KB
Line 
1//
2// PSApplication.m
3// Pester
4//
5// Created by Nicholas Riley on Fri Oct 11 2002.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSApplication.h"
10#import "PSAlarmSetController.h"
11#import "PSAlarmAlertController.h"
12#import "PSAlarmsController.h"
13#import "PSAlarm.h"
14#import "PSAlarms.h"
15
16@implementation PSApplication
17
18- (void)finishLaunching;
19{
20 appIconImage = [[NSImage imageNamed: @"NSApplicationIcon"] retain];
21 [[NSNotificationCenter defaultCenter] addObserver: [PSAlarmAlertController class] selector: @selector(controllerWithTimerExpiredNotification:) name: PSAlarmTimerExpiredNotification object: nil];
22 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(nextAlarmDidChange:) name: PSAlarmsNextAlarmDidChangeNotification object: nil];
23 [PSAlarms setUp];
24 [self setDelegate: self];
25 [super finishLaunching];
26}
27
28- (IBAction)showHelp:(id)sender;
29{
30 [[NSWorkspace sharedWorkspace] openFile: [[NSBundle mainBundle] pathForResource: @"Read Me" ofType: @"rtfd"]];
31}
32
33- (IBAction)stopAlerts:(id)sender;
34{
35 [PSAlarmAlertController stopAlerts: sender];
36}
37
38- (IBAction)orderFrontSetAlarmPanel:(id)sender;
39{
40 [NSApp activateIgnoringOtherApps: YES];
41 [alarmSetController showWindow: self];
42}
43
44- (IBAction)orderFrontAlarmsPanel:(id)sender;
45{
46 [NSApp activateIgnoringOtherApps: YES];
47 if (alarmsController == nil) {
48 alarmsController = [[PSAlarmsController alloc] init];
49 }
50 [alarmsController showWindow: self];
51}
52
53- (void)_resetUpdateTimer;
54{
55 if (dockUpdateTimer != nil) {
56 [dockUpdateTimer invalidate];
57 [dockUpdateTimer release];
58 dockUpdateInterval = 0;
59 dockUpdateTimer = nil;
60 }
61}
62
63- (void)_setUpdateTimerForInterval:(NSTimeInterval)interval alarm:(PSAlarm *)alarm repeats:(BOOL)repeats;
64{
65 dockUpdateTimer = [NSTimer scheduledTimerWithTimeInterval: interval target: self selector: @selector(_updateDockTile:) userInfo: alarm repeats: repeats];
66 [dockUpdateTimer retain];
67 dockUpdateInterval = interval; // because [timer timeInterval] always returns 0 once set
68}
69
70- (void)_updateDockTile:(NSTimer *)timer;
71{
72 PSAlarm *alarm = [timer userInfo];
73 NSTimeInterval alarmInterval;
74 NSString *tileString;
75 if (timer == nil) alarm = [[PSAlarms allAlarms] nextAlarm];
76 if (alarm == nil) return;
77 tileString = [alarm timeRemainingString];
78 {
79 NSMutableDictionary *atts = [NSMutableDictionary dictionary];
80 NSSize imageSize = [appIconImage size];
81 NSImage *tile = [[NSImage alloc] initWithSize: imageSize];
82 NSSize textSize;
83 NSPoint textOrigin;
84 NSRect frameRect;
85 float fontSize = 37;
86
87 do {
88 fontSize -= 1;
89 [atts setObject: [NSFont boldSystemFontOfSize: fontSize] forKey: NSFontAttributeName];
90 textSize = [tileString sizeWithAttributes: atts];
91 } while (textSize.width > imageSize.width - 8);
92
93 textOrigin = NSMakePoint(imageSize.width / 2 - textSize.width / 2,
94 imageSize.height / 2 - textSize.height / 2);
95 frameRect = NSInsetRect(NSMakeRect(textOrigin.x, textOrigin.y, textSize.width, textSize.height),
96 -4, -2);
97
98 [tile lockFocus];
99 // draw the grayed-out app icon
100 [appIconImage dissolveToPoint: NSZeroPoint fraction: 0.5];
101 // draw the frame
102 [[NSColor colorWithCalibratedWhite: 0.1 alpha: 0.5] set];
103 NSRectFill(frameRect);
104 // draw a gray two-pixel text shadow
105 [atts setObject: [NSColor grayColor] forKey: NSForegroundColorAttributeName];
106 textOrigin.x++; textOrigin.y--;
107 [tileString drawAtPoint: textOrigin withAttributes: atts];
108 textOrigin.x++; textOrigin.y--;
109 [tileString drawAtPoint: textOrigin withAttributes: atts];
110 // draw white text
111 textOrigin.x -= 2; textOrigin.y += 2;
112 [atts setObject: [NSColor whiteColor] forKey: NSForegroundColorAttributeName];
113 [tileString drawAtPoint: textOrigin withAttributes: atts];
114
115 [tile unlockFocus];
116 [NSApp setApplicationIconImage: tile];
117 [tile release];
118 }
119 alarmInterval = [alarm interval];
120 // NSLog(@"_updateDockTile > time remaining %@ (%.0lf), last time interval %.0lf", tileString, alarmInterval, dockUpdateInterval);
121 if (alarmInterval > 61) {
122 NSTimeInterval nextUpdate = ((unsigned long long)alarmInterval) % 60;
123 if (nextUpdate <= 1) nextUpdate = 60;
124 [self _resetUpdateTimer];
125 [self _setUpdateTimerForInterval: nextUpdate alarm: alarm repeats: NO];
126 // NSLog(@"_updateDockTile > set timer for %.0lf seconds", nextUpdate);
127 } else if (timer == nil || dockUpdateInterval > 1) {
128 [self _resetUpdateTimer];
129 [self _setUpdateTimerForInterval: 1 alarm: alarm repeats: YES];
130 // NSLog(@"_updateDockTile > set timer for 1 second");
131 } else if (alarmInterval < 2) {
132 [self _resetUpdateTimer];
133 }
134}
135
136- (void)nextAlarmDidChange:(NSNotification *)notification;
137{
138 PSAlarm *nextAlarm = [notification object];
139 // NSLog(@"nextAlarmDidChange: %@", nextAlarm);
140 [self _resetUpdateTimer];
141 if (nextAlarm == nil) {
142 [NSApp setApplicationIconImage: appIconImage];
143 } else {
144 [self _updateDockTile: nil];
145 }
146}
147
148@end
149
150@implementation PSApplication (NSApplicationDelegate)
151
152- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag;
153{
154 if (!flag) [alarmSetController showWindow: self];
155 return YES;
156}
157
158- (NSMenu *)applicationDockMenu:(NSApplication *)sender;
159{
160 NSMenu *dockMenu = [[NSMenu alloc] initWithTitle: @""];
161 PSAlarms *alarms = [PSAlarms allAlarms];
162 PSAlarm *nextAlarm = [alarms nextAlarm];
163 NSMenuItem *item;
164 if (nextAlarm == nil) {
165 [dockMenu addItemWithTitle: @"No Pending Alarms" action: nil keyEquivalent: @""];
166 } else {
167 [dockMenu addItemWithTitle: @"Next Alarm" action: nil keyEquivalent: @""];
168 [dockMenu addItemWithTitle: [NSString stringWithFormat: @" %@", [nextAlarm message]] action: nil keyEquivalent: @""];
169 [dockMenu addItemWithTitle: [NSString stringWithFormat: @" %@ %@", [nextAlarm shortDateString], [nextAlarm timeString]] action: nil keyEquivalent: @""];
170 [dockMenu addItemWithTitle: [NSString stringWithFormat: @" Remaining: %@", [nextAlarm timeRemainingString]] action: nil keyEquivalent: @""];
171 }
172 [dockMenu addItem: [NSMenuItem separatorItem]];
173 item = [dockMenu addItemWithTitle: @"Set AlarmÉ" action: @selector(orderFrontSetAlarmPanel:) keyEquivalent: @""];
174 [item setTarget: self];
175 item = [dockMenu addItemWithTitle: [NSString stringWithFormat: @"All Alarms (%d)É", [alarms alarmCount]] action: @selector(orderFrontAlarmsPanel:) keyEquivalent: @""];
176 [item setTarget: self];
177 return [dockMenu autorelease];
178}
179
180@end
181
182@implementation PSApplication (NSApplicationNotifications)
183
184- (void)applicationWillTerminate:(NSNotification *)notification;
185{
186 [NSApp setApplicationIconImage: appIconImage];
187}
188
189@end
Note: See TracBrowser for help on using the repository browser.