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"
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;
25 /*************************************************************************/
27 #pragma mark IMPLEMENTATION
28 /*************************************************************************/
30 @implementation ITTransientStatusWindow
33 /*************************************************************************/
35 #pragma mark SHARED STATIC OBJECTS
36 /*************************************************************************/
38 static ITTransientStatusWindow *staticWindow = nil;
41 /*************************************************************************/
43 #pragma mark INITIALIZATION METHODS
44 /*************************************************************************/
46 + (ITTransientStatusWindow *)sharedWindow
48 if ( ! (staticWindow) ) {
49 staticWindow = [[self alloc] initWithContentView:nil
50 exitMode:ITTransientStatusWindowExitAfterDelay
51 backgroundType:ITTransientStatusWindowRounded];
56 - (id)initWithContentView:(NSView *)contentView
57 exitMode:(ITTransientStatusWindowExitMode)exitMode
58 backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
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];
68 // Set the content rect to the frame of the content view, now guaranteed to exist.
69 contentRect = [contentView frame];
71 if ( ( self = [super initWithContentRect:contentRect
72 styleMask:NSBorderlessWindowMask
73 backing:NSBackingStoreBuffered
76 _visibilityState = ITTransientStatusWindowHiddenState;
78 _exitDelay = DEFAULT_EXIT_DELAY;
79 _backgroundType = backgroundType;
80 _verticalPosition = ITWindowPositionBottom;
81 _horizontalPosition = ITWindowPositionLeft;
82 _screenPadding = 32.0;
86 _reallyIgnoresEvents = YES;
89 // if ( _backgroundType == ITTransientStatusWindowRounded ) {
90 // _contentSubView = contentView;
92 // [self setContentView:contentView];
95 [self setIgnoresMouseEvents:YES];
96 [self setLevel:NSScreenSaverWindowLevel];
97 [self setContentView:contentView];
104 /*************************************************************************/
106 #pragma mark INSTANCE METHODS
107 /*************************************************************************/
109 - (BOOL)ignoresMouseEvents
111 return _reallyIgnoresEvents;
114 - (void)setIgnoresMouseEvents:(BOOL)flag
119 key = CGSCreateCString("IgnoreForEvents");
120 ignore = CGSCreateBoolean( (flag ? kCGSTrue : kCGSFalse) );
121 CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
123 CGSReleaseObj(ignore);
125 _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 == ITTransientStatusWindowHiddenState ) {
158 // Window is hidden. Appear as normal, and start the timer.
159 [_entryEffect performAppear];
160 } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
161 // Window is completely visible. Simply reset the timer.
162 [self startVanishTimer];
163 } else if ( _visibilityState == ITTransientStatusWindowAppearingState ) {
164 // Window is on its way in. Do nothing.
165 } else if ( _visibilityState == ITTransientStatusWindowVanishingState ) {
166 // Window is on its way out. Cancel the vanish.
167 [_exitEffect cancelVanish];
171 - (IBAction)vanish:(id)sender
173 if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
174 // Window is totally visible. Perform exit effect.
175 [_exitEffect performVanish];
176 } else if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
177 // Window is hidden. Do nothing.
178 } else if ( _visibilityState == ITTransientStatusWindowAppearingState ) {
179 // Window is on its way in. Cancel appear.
180 [_entryEffect cancelAppear];
181 } else if ( _visibilityState == ITTransientStatusWindowVanishingState ) {
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 == ITTransientStatusWindowVisibleState ) {
196 [self startVanishTimer];
200 - (ITTransientStatusWindowExitMode)exitMode
205 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
215 - (void)setExitDelay:(float)seconds
217 _exitDelay = seconds;
220 - (ITTransientStatusWindowBackgroundType)backgroundType
222 // return _backgroundType;
223 return ITTransientStatusWindowRounded;
226 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
228 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
229 // _backgroundType = newType;
230 _backgroundType = ITTransientStatusWindowRounded;
233 - (ITVerticalWindowPosition)verticalPosition;
235 return _verticalPosition;
238 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
240 _verticalPosition = newPosition;
243 - (ITHorizontalWindowPosition)horizontalPosition;
245 return _horizontalPosition;
248 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
250 _horizontalPosition = newPosition;
253 - (float)effectProgress
255 return _effectProgress;
258 - (void)setEffectProgress:(float)newProgress
260 _effectProgress = newProgress;
263 - (float)screenPadding
265 return _screenPadding;
268 - (void)setScreenPadding:(float)newPadding
270 _screenPadding = newPadding;
275 return _screenNumber;
278 - (void)setScreenNumber:(int)newNumber
280 _screenNumber = newNumber;
283 - (ITWindowEffect *)entryEffect
288 - (void)setEntryEffect:(ITWindowEffect *)newEffect
290 [_entryEffect autorelease];
291 _entryEffect = [newEffect retain];
294 - (ITWindowEffect *)exitEffect
299 - (void)setExitEffect:(ITWindowEffect *)newEffect
301 [_exitEffect autorelease];
302 _exitEffect = [newEffect retain];
306 /*************************************************************************/
308 #pragma mark PRIVATE METHODS
309 /*************************************************************************/
311 - (void)rebuildWindow;
313 if ( _backgroundType == ITTransientStatusWindowRounded ) {
314 ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
316 [self setBackgroundColor:[NSColor clearColor]];
317 [self setHasShadow:NO];
320 [self setContentView:roundedView];
321 // [super setContentView:roundedView];
322 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
323 // [self setContentView:_contentSubView];
329 - (void)startVanishTimer
331 // start timer, if appropriate
332 // if timer already exists, restart it.