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;
134 if ( _backgroundType == ITTransientStatusWindowRounded ) {
135 return _contentSubView;
137 return [super contentView];
141 - (void)setContentView:(NSView *)aView
143 if ( _backgroundType == ITTransientStatusWindowRounded ) {
144 [_contentSubView removeFromSuperview];
145 _contentSubView = aView;
146 [_contentSubView setFrame:[[super contentView] frame]];
147 [[super contentView] addSubview:_contentSubView];
148 [_contentSubView setNextResponder:self];
150 [super setContentView:aView];
156 - (IBAction)appear:(id)sender
158 if ( _visibilityState == ITWindowHiddenState ) {
159 // Window is hidden. Appear as normal, and start the timer.
160 [_entryEffect performAppear];
161 } else if ( _visibilityState == ITWindowVisibleState ) {
162 // Window is completely visible. Simply reset the timer.
163 [self startVanishTimer];
164 } else if ( _visibilityState == ITWindowAppearingState ) {
165 // Window is on its way in. Do nothing.
166 } else if ( _visibilityState == ITWindowVanishingState ) {
167 // Window is on its way out. Cancel the vanish.
168 [_exitEffect cancelVanish];
172 - (IBAction)vanish:(id)sender
174 if ( _visibilityState == ITWindowVisibleState ) {
175 // Window is totally visible. Perform exit effect.
176 [_exitEffect performVanish];
177 } else if ( _visibilityState == ITWindowHiddenState ) {
178 // Window is hidden. Do nothing.
179 } else if ( _visibilityState == ITWindowAppearingState ) {
180 // Window is on its way in. Cancel appear.
181 [_entryEffect cancelAppear];
182 } else if ( _visibilityState == ITWindowVanishingState ) {
183 // Window is on its way out. Do nothing.
187 - (ITWindowVisibilityState)visibilityState
189 return _visibilityState;
192 - (void)setVisibilityState:(ITWindowVisibilityState)newState
194 _visibilityState = newState;
196 if ( _visibilityState == ITWindowVisibleState ) {
197 [self startVanishTimer];
198 } else if ( (_visibilityState == ITWindowVanishingState) || (_visibilityState == ITWindowHiddenState) ) {
199 [self stopVanishTimer];
203 - (ITTransientStatusWindowExitMode)exitMode
208 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
212 if ( _visibilityState == ITWindowVisibleState ) {
213 if ( _exitMode == ITTransientStatusWindowExitOnCommand ) {
214 [self stopVanishTimer];
215 } else if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
216 [self startVanishTimer];
226 - (void)setExitDelay:(float)seconds
228 _exitDelay = seconds;
231 - (ITTransientStatusWindowBackgroundType)backgroundType
233 // return _backgroundType;
234 return ITTransientStatusWindowRounded;
237 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
239 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
240 // _backgroundType = newType;
241 _backgroundType = ITTransientStatusWindowRounded;
244 - (ITVerticalWindowPosition)verticalPosition;
246 return _verticalPosition;
249 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
251 _verticalPosition = newPosition;
254 - (ITHorizontalWindowPosition)horizontalPosition;
256 return _horizontalPosition;
259 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
261 _horizontalPosition = newPosition;
264 - (float)effectProgress
266 return _effectProgress;
269 - (void)setEffectProgress:(float)newProgress
271 _effectProgress = newProgress;
274 - (float)screenPadding
276 return _screenPadding;
279 - (void)setScreenPadding:(float)newPadding
281 _screenPadding = newPadding;
284 /*- (int)screenNumber
286 return _screenNumber;
289 - (void)setScreenNumber:(int)newNumber
291 _screenNumber = newNumber;
294 - (ITWindowEffect *)entryEffect
299 - (void)setEntryEffect:(ITWindowEffect *)newEffect
301 [_entryEffect releaseWhenIdle];
302 _entryEffect = [newEffect retain];
305 - (ITWindowEffect *)exitEffect
310 - (void)setExitEffect:(ITWindowEffect *)newEffect
312 [_exitEffect releaseWhenIdle];
313 _exitEffect = [newEffect retain];
317 /*************************************************************************/
319 #pragma mark PRIVATE METHODS
320 /*************************************************************************/
322 - (void)rebuildWindow;
324 if ( _backgroundType == ITTransientStatusWindowRounded ) {
325 ITTSWBackgroundView *roundedView = [[[ITTSWBackgroundView alloc] initWithFrame:[self frame]] autorelease];
327 [self setBackgroundColor:[NSColor clearColor]];
328 [self setHasShadow:NO];
331 [self setContentView:roundedView];
332 // [super setContentView:roundedView];
333 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
334 // [self setContentView:_contentSubView];
340 - (void)startVanishTimer
342 if ( _exitMode == ITTransientStatusWindowExitAfterDelay) {
343 [self stopVanishTimer];
344 _exitTimer = [NSTimer scheduledTimerWithTimeInterval:_exitDelay
346 selector:@selector(doDelayedExit)
352 - (void)doDelayedExit
358 - (void)stopVanishTimer
361 [_exitTimer invalidate];