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 if ( _entryEffect == nil ) {
160 [self orderFront:self];
161 _visibilityState = ITTransientStatusWindowVisibleState;
163 [_entryEffect performAppear];
165 [self startVanishTimer];
166 } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
167 // Window is completely visible. Simply reset the timer.
168 [self startVanishTimer];
169 } else if ( _visibilityState == ITTransientStatusWindowAppearingState ) {
170 // Window is on its way in. Do nothing.
171 } else if ( _visibilityState == ITTransientStatusWindowVanishingState ) {
172 // Window is on its way out. Cancel the vanish.
173 if ( _exitEffect == nil ) {
174 [self orderFront:self];
175 _visibilityState = ITTransientStatusWindowVisibleState;
177 [_exitEffect cancelVanish];
179 [self startVanishTimer];
183 - (IBAction)vanish:(id)sender
185 if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
186 // Window is totally visible. Perform exit effect.
187 if ( _exitEffect == nil ) {
188 [self orderOut:self];
189 _visibilityState = ITTransientStatusWindowHiddenState;
191 [_exitEffect performVanish];
193 [self startVanishTimer];
194 } else if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
195 // Window is hidden. Do nothing.
196 } else if ( _visibilityState == ITTransientStatusWindowAppearingState ) {
197 // Window is on its way in. Cancel appear.
198 [_entryEffect cancelAppear];
199 } else if ( _visibilityState == ITTransientStatusWindowVanishingState ) {
200 // Window is on its way out. Do nothing.
204 - (ITWindowVisibilityState)visibilityState
206 return _visibilityState;
209 - (void)setVisibilityState:(ITWindowVisibilityState)newState
211 _visibilityState = newState;
214 - (ITTransientStatusWindowExitMode)exitMode
219 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
229 - (void)setExitDelay:(float)seconds
231 _exitDelay = seconds;
234 - (ITTransientStatusWindowBackgroundType)backgroundType
236 // return _backgroundType;
237 return ITTransientStatusWindowRounded;
240 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
242 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
243 // _backgroundType = newType;
244 _backgroundType = ITTransientStatusWindowRounded;
247 - (ITVerticalWindowPosition)verticalPosition;
249 return _verticalPosition;
252 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
254 _verticalPosition = newPosition;
257 - (ITHorizontalWindowPosition)horizontalPosition;
259 return _horizontalPosition;
262 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
264 _horizontalPosition = newPosition;
267 - (float)screenPadding
269 return _screenPadding;
272 - (void)setScreenPadding:(float)newPadding
274 _screenPadding = newPadding;
279 return _screenNumber;
282 - (void)setScreenNumber:(int)newNumber
284 _screenNumber = newNumber;
287 - (ITWindowEffect *)entryEffect
292 - (void)setEntryEffect:(ITWindowEffect *)newEffect
294 [_entryEffect autorelease];
295 _entryEffect = [newEffect retain];
298 - (ITWindowEffect *)exitEffect
303 - (void)setExitEffect:(ITWindowEffect *)newEffect
305 [_exitEffect autorelease];
306 _exitEffect = [newEffect retain];
310 /*************************************************************************/
312 #pragma mark PRIVATE METHODS
313 /*************************************************************************/
315 - (void)rebuildWindow;
317 if ( _backgroundType == ITTransientStatusWindowRounded ) {
318 ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
320 [self setBackgroundColor:[NSColor clearColor]];
321 [self setHasShadow:NO];
324 [self setContentView:roundedView];
325 // [super setContentView:roundedView];
326 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
327 // [self setContentView:_contentSubView];
333 - (void)startVanishTimer