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 - (ITWindowVisibilityState)visibilityState
188 return _visibilityState;
191 - (void)setVisibilityState:(ITWindowVisibilityState)newState
193 _visibilityState = newState;
195 if ( _visibilityState == ITWindowVisibleState ) {
196 [self startVanishTimer];
197 } else if ( (_visibilityState == ITWindowVanishingState) || (_visibilityState == ITWindowHiddenState) ) {
198 [self stopVanishTimer];
202 - (ITTransientStatusWindowExitMode)exitMode
207 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
211 if ( _visibilityState == ITWindowVisibleState ) {
212 if ( _exitMode == ITTransientStatusWindowExitOnCommand ) {
213 [self stopVanishTimer];
214 } else if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
215 [self startVanishTimer];
225 - (void)setExitDelay:(float)seconds
227 _exitDelay = seconds;
230 - (ITTransientStatusWindowBackgroundType)backgroundType
232 // return _backgroundType;
233 return ITTransientStatusWindowRounded;
236 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
238 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
239 // _backgroundType = newType;
240 _backgroundType = ITTransientStatusWindowRounded;
243 - (ITVerticalWindowPosition)verticalPosition;
245 return _verticalPosition;
248 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
250 _verticalPosition = newPosition;
253 - (ITHorizontalWindowPosition)horizontalPosition;
255 return _horizontalPosition;
258 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
260 _horizontalPosition = newPosition;
263 - (float)effectProgress
265 return _effectProgress;
268 - (void)setEffectProgress:(float)newProgress
270 _effectProgress = newProgress;
273 - (float)screenPadding
275 return _screenPadding;
278 - (void)setScreenPadding:(float)newPadding
280 _screenPadding = newPadding;
283 /*- (int)screenNumber
285 return _screenNumber;
288 - (void)setScreenNumber:(int)newNumber
290 _screenNumber = newNumber;
293 - (ITWindowEffect *)entryEffect
298 - (void)setEntryEffect:(ITWindowEffect *)newEffect
300 [_entryEffect releaseWhenIdle];
301 _entryEffect = [newEffect retain];
304 - (ITWindowEffect *)exitEffect
309 - (void)setExitEffect:(ITWindowEffect *)newEffect
311 [_exitEffect releaseWhenIdle];
312 _exitEffect = [newEffect retain];
316 /*************************************************************************/
318 #pragma mark PRIVATE METHODS
319 /*************************************************************************/
321 - (void)rebuildWindow;
323 if ( _backgroundType == ITTransientStatusWindowRounded ) {
324 ITTSWBackgroundView *roundedView = [[[ITTSWBackgroundView alloc] initWithFrame:[self frame]] autorelease];
326 [self setBackgroundColor:[NSColor clearColor]];
327 [self setHasShadow:NO];
330 [self setContentView:roundedView];
331 // [super setContentView:roundedView];
332 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
333 // [self setContentView:_contentSubView];
339 - (void)startVanishTimer
341 if ( _exitMode == ITTransientStatusWindowExitAfterDelay) {
342 [self stopVanishTimer];
343 _exitTimer = [NSTimer scheduledTimerWithTimeInterval:_exitDelay
345 selector:@selector(doDelayedExit)
351 - (void)doDelayedExit
357 - (void)stopVanishTimer
360 [_exitTimer invalidate];