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;
90 // if ( _backgroundType == ITTransientStatusWindowRounded ) {
91 // _contentSubView = contentView;
93 // [self setContentView:contentView];
96 [self setIgnoresMouseEvents:YES];
97 [self setLevel:NSScreenSaverWindowLevel];
98 [self setContentView:contentView];
105 /*************************************************************************/
107 #pragma mark INSTANCE METHODS
108 /*************************************************************************/
110 - (BOOL)ignoresMouseEvents
112 return _reallyIgnoresEvents;
115 - (void)setIgnoresMouseEvents:(BOOL)flag
120 key = CGSCreateCString("IgnoreForEvents");
121 ignore = CGSCreateBoolean( (flag ? kCGSTrue : kCGSFalse) );
122 CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
124 CGSReleaseObj(ignore);
126 _reallyIgnoresEvents = flag;
133 if ( _backgroundType == ITTransientStatusWindowRounded ) {
134 return _contentSubView;
136 return [super contentView];
140 - (void)setContentView:(NSView *)aView
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];
149 [super setContentView:aView];
155 - (IBAction)appear:(id)sender
157 if ( _visibilityState == ITWindowHiddenState ) {
158 // Window is hidden. Appear as normal, and start the timer.
159 [_entryEffect performAppear];
160 } else if ( _visibilityState == ITWindowVisibleState ) {
161 // Window is completely visible. Simply reset the timer.
162 [self startVanishTimer];
163 } else if ( _visibilityState == ITWindowAppearingState ) {
164 // Window is on its way in. Do nothing.
165 } else if ( _visibilityState == ITWindowVanishingState ) {
166 // Window is on its way out. Cancel the vanish.
167 [_exitEffect cancelVanish];
171 - (IBAction)vanish:(id)sender
173 if ( _visibilityState == ITWindowVisibleState ) {
174 // Window is totally visible. Perform exit effect.
175 [_exitEffect performVanish];
176 } else if ( _visibilityState == ITWindowHiddenState ) {
177 // Window is hidden. Do nothing.
178 } else if ( _visibilityState == ITWindowAppearingState ) {
179 // Window is on its way in. Cancel appear.
180 [_entryEffect cancelAppear];
181 } else if ( _visibilityState == ITWindowVanishingState ) {
182 // Window is on its way out. Do nothing.
186 - (void)setSizing:(ITTransientStatusWindowSizing)newSizing
191 - (ITTransientStatusWindowSizing)sizing
196 - (ITWindowVisibilityState)visibilityState
198 return _visibilityState;
201 - (void)setVisibilityState:(ITWindowVisibilityState)newState
203 _visibilityState = newState;
205 if ( _visibilityState == ITWindowVisibleState ) {
206 [self startVanishTimer];
207 } else if ( (_visibilityState == ITWindowVanishingState) || (_visibilityState == ITWindowHiddenState) ) {
208 [self stopVanishTimer];
212 - (ITTransientStatusWindowExitMode)exitMode
217 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
221 if ( _visibilityState == ITWindowVisibleState ) {
222 if ( _exitMode == ITTransientStatusWindowExitOnCommand ) {
223 [self stopVanishTimer];
224 } else if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
225 [self startVanishTimer];
235 - (void)setExitDelay:(float)seconds
237 _exitDelay = seconds;
240 - (ITTransientStatusWindowBackgroundType)backgroundType
242 // return _backgroundType;
243 return ITTransientStatusWindowRounded;
246 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
248 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
249 // _backgroundType = newType;
250 _backgroundType = ITTransientStatusWindowRounded;
253 - (ITVerticalWindowPosition)verticalPosition;
255 return _verticalPosition;
258 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
260 _verticalPosition = newPosition;
263 - (ITHorizontalWindowPosition)horizontalPosition;
265 return _horizontalPosition;
268 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
270 _horizontalPosition = newPosition;
273 - (float)effectProgress
275 return _effectProgress;
278 - (void)setEffectProgress:(float)newProgress
280 _effectProgress = newProgress;
283 - (float)screenPadding
285 return _screenPadding;
288 - (void)setScreenPadding:(float)newPadding
290 _screenPadding = newPadding;
293 /*- (int)screenNumber
295 return _screenNumber;
298 - (void)setScreenNumber:(int)newNumber
300 _screenNumber = newNumber;
303 - (ITWindowEffect *)entryEffect
308 - (void)setEntryEffect:(ITWindowEffect *)newEffect
310 [_entryEffect releaseWhenIdle];
311 _entryEffect = [newEffect retain];
314 - (ITWindowEffect *)exitEffect
319 - (void)setExitEffect:(ITWindowEffect *)newEffect
321 [_exitEffect releaseWhenIdle];
322 _exitEffect = [newEffect retain];
326 /*************************************************************************/
328 #pragma mark PRIVATE METHODS
329 /*************************************************************************/
331 - (void)rebuildWindow;
333 if ( _backgroundType == ITTransientStatusWindowRounded ) {
334 ITTSWBackgroundView *roundedView = [[[ITTSWBackgroundView alloc] initWithFrame:[self frame]] autorelease];
336 [self setBackgroundColor:[NSColor clearColor]];
337 [self setHasShadow:NO];
340 [self setContentView:roundedView];
341 // [super setContentView:roundedView];
342 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
343 // [self setContentView:_contentSubView];
349 - (void)startVanishTimer
351 if ( _exitMode == ITTransientStatusWindowExitAfterDelay) {
352 [self stopVanishTimer];
353 _exitTimer = [NSTimer scheduledTimerWithTimeInterval:_exitDelay
355 selector:@selector(doDelayedExit)
361 - (void)doDelayedExit
367 - (void)stopVanishTimer
370 [_exitTimer invalidate];