source: trunk/Cocoa/Pester/Source/PSApplication.m@ 28

Last change on this file since 28 was 28, checked in by Nicholas Riley, 20 years ago

Pester 1.0

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