1 #import "ITTransientStatusWindow.h"
2 #import "ITWindowEffect.h"
3 #import <ApplicationServices/ApplicationServices.h>
4 #import "ITCoreGraphicsHacks.h"
5 #import "ITTextField.h"
6 #import "ITTSWBackgroundView.h"
8 #define EFFECT_FPS 30.0
11 /*************************************************************************/
13 #pragma mark PRIVATE METHOD DECLARATIONS
14 /*************************************************************************/
16 @interface ITTransientStatusWindow (Private)
17 - (id)initWithContentView:(NSView *)contentView
18 exitMode:(ITTransientStatusWindowExitMode)exitMode
19 backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType;
20 - (void)rebuildWindow;
21 - (void)startVanishTimer;
22 - (void)stopVanishTimer;
26 /*************************************************************************/
28 #pragma mark IMPLEMENTATION
29 /*************************************************************************/
31 @implementation ITTransientStatusWindow
34 /*************************************************************************/
36 #pragma mark SHARED STATIC OBJECTS
37 /*************************************************************************/
39 static ITTransientStatusWindow *staticWindow = nil;
42 /*************************************************************************/
44 #pragma mark INITIALIZATION METHODS
45 /*************************************************************************/
47 + (ITTransientStatusWindow *)sharedWindow
49 if ( ! (staticWindow) ) {
50 staticWindow = [[self alloc] initWithContentView:nil
51 exitMode:ITTransientStatusWindowExitAfterDelay
52 backgroundType:ITTransientStatusWindowRounded];
57 - (id)initWithContentView:(NSView *)contentView
58 exitMode:(ITTransientStatusWindowExitMode)exitMode
59 backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
63 // If no Content View was provided, use a generic view.
64 if ( ! (contentView) ) {
65 contentView = [[[NSView alloc] initWithFrame:
66 NSMakeRect(100.0, 100.0, 200.0, 200.0)] autorelease];
69 // Set the content rect to the frame of the content view, now guaranteed to exist.
70 contentRect = [contentView frame];
72 if ( ( self = [super initWithContentRect:contentRect
73 styleMask:NSBorderlessWindowMask
74 backing:NSBackingStoreBuffered
77 _visibilityState = ITWindowHiddenState;
79 _exitDelay = DEFAULT_EXIT_DELAY;
80 _backgroundType = backgroundType;
81 _verticalPosition = ITWindowPositionBottom;
82 _horizontalPosition = ITWindowPositionLeft;
83 _screenPadding = 32.0;
87 _reallyIgnoresEvents = YES;
89 [self setScreen:[NSScreen mainScreen]];
91 // if ( _backgroundType == ITTransientStatusWindowRounded ) {
92 // _contentSubView = contentView;
94 // [self setContentView:contentView];
97 [self setIgnoresMouseEvents:YES];
98 [self setLevel:NSScreenSaverWindowLevel];
99 [self setContentView:contentView];
100 [self rebuildWindow];
111 /*************************************************************************/
113 #pragma mark INSTANCE METHODS
114 /*************************************************************************/
116 - (BOOL)ignoresMouseEvents
118 return _reallyIgnoresEvents;
121 - (void)setIgnoresMouseEvents:(BOOL)flag
124 //CGSValueObj ignore;
127 /*key = CGSCreateCString("IgnoreForEvents");
128 ignore = CGSCreateBoolean( (flag ? kCGSTrue : kCGSFalse) );
129 CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
131 CGSReleaseObj(ignore);*/
133 CGSGetWindowTags([NSApp contextID], (CGSWindowID)[self windowNumber], &tags, 32);
136 tags = tags | CGSTagTransparent;
138 tags = tags & CGSTagTransparent;
141 CGSSetWindowTags([NSApp contextID], (CGSWindowID)[self windowNumber], &tags, 32);
143 _reallyIgnoresEvents = flag;
150 if ( _backgroundType == ITTransientStatusWindowRounded ) {
151 return _contentSubView;
153 return [super contentView];
157 - (void)setContentView:(NSView *)aView
159 if ( _backgroundType == ITTransientStatusWindowRounded ) {
160 [_contentSubView removeFromSuperview];
161 _contentSubView = aView;
162 [_contentSubView setFrame:[[super contentView] frame]];
163 [[super contentView] addSubview:_contentSubView];
164 [_contentSubView setNextResponder:self];
166 [super setContentView:aView];
172 - (IBAction)appear:(id)sender
174 if ( _visibilityState == ITWindowHiddenState ) {
175 // Window is hidden. Appear as normal, and start the timer.
176 [_entryEffect performAppear];
177 } else if ( _visibilityState == ITWindowVisibleState ) {
178 // Window is completely visible. Simply reset the timer.
179 [self startVanishTimer];
180 } else if ( _visibilityState == ITWindowAppearingState ) {
181 // Window is on its way in. Do nothing.
182 } else if ( _visibilityState == ITWindowVanishingState ) {
183 // Window is on its way out. Cancel the vanish.
184 [_exitEffect cancelVanish];
188 - (IBAction)vanish:(id)sender
190 if ( _visibilityState == ITWindowVisibleState ) {
191 // Window is totally visible. Perform exit effect.
192 [_exitEffect performVanish];
193 } else if ( _visibilityState == ITWindowHiddenState ) {
194 // Window is hidden. Do nothing.
195 } else if ( _visibilityState == ITWindowAppearingState ) {
196 // Window is on its way in. Cancel appear.
197 [_entryEffect cancelAppear];
198 } else if ( _visibilityState == ITWindowVanishingState ) {
199 // Window is on its way out. Do nothing.
203 - (void)setScreen:(NSScreen *)newScreen
206 _screen = [newScreen retain];
214 - (void)setSizing:(ITTransientStatusWindowSizing)newSizing
219 - (ITTransientStatusWindowSizing)sizing
224 - (ITWindowVisibilityState)visibilityState
226 return _visibilityState;
229 - (void)setVisibilityState:(ITWindowVisibilityState)newState
231 _visibilityState = newState;
233 if ( _visibilityState == ITWindowVisibleState ) {
234 [self startVanishTimer];
235 } else if ( (_visibilityState == ITWindowVanishingState) || (_visibilityState == ITWindowHiddenState) ) {
236 [self stopVanishTimer];
240 - (ITTransientStatusWindowExitMode)exitMode
245 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
249 if ( _visibilityState == ITWindowVisibleState ) {
250 if ( _exitMode == ITTransientStatusWindowExitOnCommand ) {
251 [self stopVanishTimer];
252 } else if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
253 [self startVanishTimer];
263 - (void)setExitDelay:(float)seconds
265 _exitDelay = seconds;
268 - (ITTransientStatusWindowBackgroundType)backgroundType
270 // return _backgroundType;
271 return ITTransientStatusWindowRounded;
274 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
276 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
277 // _backgroundType = newType;
278 _backgroundType = ITTransientStatusWindowRounded;
281 - (ITVerticalWindowPosition)verticalPosition;
283 return _verticalPosition;
286 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
288 _verticalPosition = newPosition;
291 - (ITHorizontalWindowPosition)horizontalPosition;
293 return _horizontalPosition;
296 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
298 _horizontalPosition = newPosition;
301 - (float)effectProgress
303 return _effectProgress;
306 - (void)setEffectProgress:(float)newProgress
308 _effectProgress = newProgress;
311 - (float)screenPadding
313 return _screenPadding;
316 - (void)setScreenPadding:(float)newPadding
318 _screenPadding = newPadding;
321 /*- (int)screenNumber
323 return _screenNumber;
326 - (void)setScreenNumber:(int)newNumber
328 _screenNumber = newNumber;
331 - (ITWindowEffect *)entryEffect
336 - (void)setEntryEffect:(ITWindowEffect *)newEffect
338 [_entryEffect releaseWhenIdle];
339 _entryEffect = [newEffect retain];
342 - (ITWindowEffect *)exitEffect
347 - (void)setExitEffect:(ITWindowEffect *)newEffect
349 [_exitEffect releaseWhenIdle];
350 _exitEffect = [newEffect retain];
354 /*************************************************************************/
356 #pragma mark PRIVATE METHODS
357 /*************************************************************************/
359 - (void)rebuildWindow;
361 if ( _backgroundType == ITTransientStatusWindowRounded ) {
362 ITTSWBackgroundView *roundedView = [[[ITTSWBackgroundView alloc] initWithFrame:[self frame]] autorelease];
364 [self setBackgroundColor:[NSColor clearColor]];
365 [self setHasShadow:NO];
368 [self setContentView:roundedView];
369 // [super setContentView:roundedView];
370 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
371 // [self setContentView:_contentSubView];
377 - (void)startVanishTimer
379 if ( _exitMode == ITTransientStatusWindowExitAfterDelay) {
380 [self stopVanishTimer];
381 _exitTimer = [NSTimer scheduledTimerWithTimeInterval:_exitDelay
383 selector:@selector(doDelayedExit)
389 - (void)doDelayedExit
395 - (void)stopVanishTimer
398 [_exitTimer invalidate];