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)performEffect;
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;
130 - (void)orderFront:(id)sender
132 if ( _entryEffect == nil ) {
133 [super orderFront:sender];
134 _visibilityState = ITTransientStatusWindowVisibleState;
136 [self performEffect];
138 if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
139 // set the timer, and orderOut: when it lapses.
143 - (void)makeKeyAndOrderFront:(id)sender
145 if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
146 // set the timer, and orderOut: when it lapses.
149 if ( _entryEffect == nil ) {
150 [super makeKeyAndOrderFront:sender];
151 _visibilityState = ITTransientStatusWindowVisibleState;
153 [self performEffect];
154 [self makeKeyWindow];
158 - (void)orderOut:(id)sender
160 if ( _entryEffect == nil ) {
161 [super orderOut:sender];
162 _visibilityState = ITTransientStatusWindowHiddenState;
164 [self performEffect];
168 - (NSTimeInterval)animationResizeTime:(NSRect)newFrame
175 if ( _backgroundType == ITTransientStatusWindowRounded ) {
176 return _contentSubView;
178 return [super contentView];
182 - (void)setContentView:(NSView *)aView
184 if ( _backgroundType == ITTransientStatusWindowRounded ) {
185 [_contentSubView removeFromSuperview];
186 _contentSubView = aView;
187 [_contentSubView setFrame:[[super contentView] frame]];
188 [[super contentView] addSubview:_contentSubView];
189 [_contentSubView setNextResponder:self];
191 [super setContentView:aView];
199 if ( _entryEffect == nil ) {
200 [self orderFront:self];
201 _visibilityState = ITTransientStatusWindowVisibleState;
203 _visibilityState = ITTransientStatusWindowAppearingState;
204 [_entryEffect performAppear];
205 _visibilityState = ITTransientStatusWindowVisibleState;
207 if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
208 // set the timer, and vanish when it lapses.
214 if ( _entryEffect == nil ) {
215 [self orderOut:self];
216 _visibilityState = ITTransientStatusWindowHiddenState;
218 [_exitEffect performVanish];
219 _visibilityState = ITTransientStatusWindowHiddenState;
223 - (ITTransientStatusWindowVisibilityState)visibilityState
225 return _visibilityState;
228 - (ITTransientStatusWindowExitMode)exitMode
233 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
243 - (void)setExitDelay:(float)seconds
245 _exitDelay = seconds;
248 - (ITTransientStatusWindowBackgroundType)backgroundType
250 // return _backgroundType;
251 return ITTransientStatusWindowRounded;
254 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
256 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
257 // _backgroundType = newType;
258 _backgroundType = ITTransientStatusWindowRounded;
261 - (ITVerticalWindowPosition)verticalPosition;
263 return _verticalPosition;
266 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
268 _verticalPosition = newPosition;
271 - (ITHorizontalWindowPosition)horizontalPosition;
273 return _horizontalPosition;
276 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
278 _horizontalPosition = newPosition;
281 - (float)screenPadding
283 return _screenPadding;
286 - (void)setScreenPadding:(float)newPadding
288 _screenPadding = newPadding;
293 return _screenNumber;
296 - (void)setScreenNumber:(int)newNumber
298 _screenNumber = newNumber;
301 - (ITWindowEffect *)entryEffect
306 - (void)setEntryEffect:(ITWindowEffect *)newEffect
308 [_entryEffect autorelease];
309 _entryEffect = [newEffect retain];
312 - (ITWindowEffect *)exitEffect
317 - (void)setExitEffect:(ITWindowEffect *)newEffect
319 [_exitEffect autorelease];
320 _exitEffect = [newEffect retain];
324 /*************************************************************************/
326 #pragma mark PRIVATE METHODS
327 /*************************************************************************/
329 - (void)rebuildWindow;
331 if ( _backgroundType == ITTransientStatusWindowRounded ) {
332 ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
334 [self setBackgroundColor:[NSColor clearColor]];
335 [self setHasShadow:NO];
338 [self setContentView:roundedView];
339 // [super setContentView:roundedView];
340 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
341 // [self setContentView:_contentSubView];
349 - (void)performEffect
351 if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
352 _visibilityState = ITTransientStatusWindowEnteringState;
353 } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
354 _visibilityState = ITTransientStatusWindowExitingState;
359 if ( _entryEffect == ITTransientStatusWindowEffectDissolve ) {
360 [self dissolveEffect];
361 } else if ( _entryEffect == ITTransientStatusWindowEffectSlideVertically ) {
362 [self slideVerticalEffect];
363 } else if ( _entryEffect == ITTransientStatusWindowEffectSlideHorizontally ) {
364 [self slideHorizontalEffect];
365 } else if ( _entryEffect == ITTransientStatusWindowEffectPivot ) {