Cleaning up a bit, and testing SyncMail. PLEASE DO NOT CHANGE THE ITKIT TARGET SETTI...
[ITKit.git] / ITTransientStatusWindow.m
1 #import "ITTransientStatusWindow.h"
2 #import <CoreGraphics/CoreGraphics.h>
3 #import "ITCoreGraphicsHacks.h"
4 #import "ITTextField.h"
5 #import "ITGrayRoundedView.h"
6
7 @class ITTextField;
8 @class ITGrayRoundedView;
9
10 /*************************************************************************/
11 #pragma mark -
12 #pragma mark EVIL HACKERY
13 /*************************************************************************/
14
15 @interface NSApplication (HACKHACKHACKHACK)
16 - (CGSConnectionID)contextID;
17 @end
18
19
20 /*************************************************************************/
21 #pragma mark -
22 #pragma mark PRIVATE METHOD DECLARATIONS
23 /*************************************************************************/
24
25 @interface ITTransientStatusWindow (Private)
26 - (id)initWithContentView:(NSView *)contentView
27                  exitMode:(ITTransientStatusWindowExitMode)exitMode
28            backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType;
29 - (void)rebuildWindow;
30 - (void)performEffect;
31 - (void)dissolveEffect:(BOOL)entering;
32 - (void)slideVerticalEffect:(BOOL)entering;
33 - (void)slideHorizontalEffect:(BOOL)entering;
34 @end
35
36
37 /*************************************************************************/
38 #pragma mark -
39 #pragma mark IMPLEMENTATION
40 /*************************************************************************/
41
42 @implementation ITTransientStatusWindow
43
44
45 /*************************************************************************/
46 #pragma mark -
47 #pragma mark SHARED STATIC OBJECTS
48 /*************************************************************************/
49
50 static ITTransientStatusWindow *staticWindow = nil;
51
52
53 /*************************************************************************/
54 #pragma mark -
55 #pragma mark INITIALIZATION METHODS
56 /*************************************************************************/
57
58 + (ITTransientStatusWindow *)sharedWindow
59 {
60     if ( ! (staticWindow) ) {
61         staticWindow = [[self alloc] initWithContentView:nil
62                                                 exitMode:ITTransientStatusWindowExitAfterDelay
63                                           backgroundType:ITTransientStatusWindowRounded];
64     }
65     return staticWindow;
66 }
67
68 - (id)initWithContentView:(NSView *)contentView
69                  exitMode:(ITTransientStatusWindowExitMode)exitMode
70            backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
71 {
72     NSRect contentRect;
73     
74     CGSValueObj          key;
75     CGSValueObj          ignore;
76
77     // If no Content View was provided, use a generic NSImageView with the app icon.
78     if ( ! (contentView) ) {
79         contentView = [[[NSView alloc] initWithFrame:
80             NSMakeRect(100.0, 100.0, 200.0, 200.0)] autorelease];
81     }
82     
83     // Set the content rect to the frame of the content view, now guaranteed to exist.
84     contentRect = [contentView frame];
85     
86     if ( ( self = [super initWithContentRect:contentRect
87                                    styleMask:NSBorderlessWindowMask
88                                      backing:NSBackingStoreBuffered
89                                        defer:NO] ) ) {
90                                     
91         _visibilityState    = ITTransientStatusWindowHiddenState;
92         _exitMode           = exitMode;
93         _exitDelay          = DEFAULT_EXIT_DELAY;
94         _backgroundType     = backgroundType;
95         _verticalPosition   = ITTransientStatusWindowPositionBottom;
96         _horizontalPosition = ITTransientStatusWindowPositionLeft;
97         _entryEffect        = ITTransientStatusWindowEffectNone;
98         _exitEffect         = ITTransientStatusWindowEffectDissolve;
99         
100         _delayTimer = nil;
101         _fadeTimer  = nil;
102
103 //        if ( _backgroundType == ITTransientStatusWindowRounded ) {
104 //            _contentSubView = contentView;
105 //        } else {
106 //            [self setContentView:contentView];
107 //        }
108
109 //      [self setIgnoresMouseEvents:YES];
110
111         key = CGSCreateCString("IgnoreForEvents");
112         ignore = CGSCreateBoolean(kCGSTrue);
113         
114         CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
115
116         CGSReleaseObj(key);
117         CGSReleaseObj(ignore);
118         
119         [self setLevel:NSScreenSaverWindowLevel];
120         [self setContentView:contentView];
121         [self rebuildWindow];
122     }
123     return self;
124 }
125
126
127 /*************************************************************************/
128 #pragma mark -
129 #pragma mark INSTANCE METHODS
130 /*************************************************************************/
131
132 - (void)orderFront:(id)sender
133 {
134     if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
135         // set the timer, and orderOut: when it lapses.
136     }
137
138     if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
139         [super orderFront:sender];
140     } else {
141         [self performEffect];
142     }
143 }
144
145 - (void)makeKeyAndOrderFront:(id)sender
146 {
147     if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
148         // set the timer, and orderOut: when it lapses.
149     }
150
151     if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
152         [super makeKeyAndOrderFront:sender];
153     } else {
154         [self performEffect];
155         [self makeKeyWindow];
156     }
157 }
158
159 - (void)orderOut:(id)sender
160 {
161     if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
162         [super orderOut:sender];
163     } else {
164         [self performEffect];
165     }
166 }
167
168 /*
169
170 - (id)contentView
171 {
172     if ( _backgroundType == ITTransientStatusWindowRounded ) {
173         return _contentSubView;
174     } else {
175         return [super contentView];
176     }
177 }
178
179 - (void)setContentView:(NSView *)aView
180 {
181     if ( _backgroundType == ITTransientStatusWindowRounded ) {
182        [_contentSubView removeFromSuperview];
183         _contentSubView = aView;
184         [_contentSubView setFrame:[[super contentView] frame]];
185         [[super contentView] addSubview:_contentSubView];
186         [_contentSubView setNextResponder:self];
187     } else {
188         [super setContentView:aView];
189     }
190 }
191
192 */
193
194 - (ITTransientStatusWindowVisibilityState)visibilityState
195 {
196     return _visibilityState;
197 }
198
199 - (ITTransientStatusWindowExitMode)exitMode
200 {
201     return _exitMode;
202 }
203
204 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
205 {
206     _exitMode = newMode;
207 }
208
209 - (float)exitDelay
210 {
211     return _exitDelay;
212 }
213
214 - (void)setExitDelay:(float)seconds
215 {
216     _exitDelay = seconds;
217 }
218
219 - (ITTransientStatusWindowBackgroundType)backgroundType
220 {
221 //  return _backgroundType;
222     return ITTransientStatusWindowRounded;
223 }
224
225 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
226 {
227 //  setBackgroundType: is currently ignored.  Defaults to ITTransientStatusWindowRounded.
228 //  _backgroundType = newType;
229     _backgroundType = ITTransientStatusWindowRounded;
230 }
231
232 - (ITTransientStatusWindowPosition)verticalPosition;
233 {
234     return _verticalPosition;
235 }
236
237 - (void)setVerticalPosition:(ITTransientStatusWindowPosition)newPosition;
238 {
239     _verticalPosition = newPosition;
240 }
241
242 - (ITTransientStatusWindowPosition)horizontalPosition;
243 {
244     return _horizontalPosition;
245 }
246
247 - (void)setHorizontalPosition:(ITTransientStatusWindowPosition)newPosition;
248 {
249     _horizontalPosition = newPosition;
250 }
251
252 - (ITTransientStatusWindowEffect)entryEffect
253 {
254     return _entryEffect;
255 }
256
257 - (void)setEntryEffect:(ITTransientStatusWindowEffect)newEffect;
258 {
259     _entryEffect = newEffect;
260 }
261
262 - (ITTransientStatusWindowEffect)exitEffect;
263 {
264     return _exitEffect;
265 }
266
267 - (void)setExitEffect:(ITTransientStatusWindowEffect)newEffect;
268 {
269     _exitEffect = newEffect;
270 }
271
272
273 /*************************************************************************/
274 #pragma mark -
275 #pragma mark PRIVATE METHODS
276 /*************************************************************************/
277
278 - (void)rebuildWindow;
279 {
280     if ( _backgroundType == ITTransientStatusWindowRounded ) {
281         ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
282
283         [self setBackgroundColor:[NSColor clearColor]];
284         [self setHasShadow:NO];
285         [self setOpaque:NO];
286         
287         [self setContentView:roundedView];
288 //      [super setContentView:roundedView];
289 //      [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
290 //      [self setContentView:_contentSubView];
291     } else {
292         // YUO == CLWONBAOT
293     }
294 }
295
296 - (void)performEffect
297 {
298     if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
299         if ( _entryEffect == ITTransientStatusWindowEffectDissolve ) {
300             [self dissolveEffect:YES];
301         } else if ( _entryEffect == ITTransientStatusWindowEffectSlideVertically ) {
302             [self slideVerticalEffect:YES];
303         } else if ( _entryEffect == ITTransientStatusWindowEffectSlideHorizontally ) {
304             [self slideHorizontalEffect:YES];
305         }
306     } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
307         if ( _exitEffect == ITTransientStatusWindowEffectDissolve ) {
308             [self dissolveEffect:NO];
309         } else if ( _exitEffect == ITTransientStatusWindowEffectSlideVertically ) {
310             [self slideVerticalEffect:NO];
311         } else if ( _exitEffect == ITTransientStatusWindowEffectSlideHorizontally ) {
312             [self slideHorizontalEffect:NO];
313         }
314     }
315 }
316
317 - (void)dissolveEffect:(BOOL)entering
318 {
319     if ( entering ) {
320         [super orderFront:self];
321     } else {
322         [super orderOut:self];
323     }
324 }
325
326 - (void)slideVerticalEffect:(BOOL)entering
327 {
328     if ( entering ) {
329         [super orderFront:self];
330     } else {
331         [super orderOut:self];
332     }
333 }
334
335 - (void)slideHorizontalEffect:(BOOL)entering
336 {
337     if ( entering ) {
338         [super orderFront:self];
339     } else {
340         [super orderOut:self];
341     }
342 }
343
344
345 @end