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