1 #import "ITTransientStatusWindow.h"
2 #import <CoreGraphics/CoreGraphics.h>
3 #import "ITCoreGraphicsHacks.h"
4 #import "ITTextField.h"
5 #import "ITGrayRoundedView.h"
8 @class ITGrayRoundedView;
10 /*************************************************************************/
12 #pragma mark EVIL HACKERY
13 /*************************************************************************/
15 @interface NSApplication (HACKHACKHACKHACK)
16 - (CGSConnectionID)contextID;
20 /*************************************************************************/
22 #pragma mark PRIVATE METHOD DECLARATIONS
23 /*************************************************************************/
25 @interface ITTransientStatusWindow (Private)
26 - (id)initWithContentView:(NSView *)contentView
27 exitMode:(ITTransientStatusWindowExitMode)exitMode
28 backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType;
29 - (void)rebuildWindow;
30 - (void)performEffect;
31 - (void)dissolveEffect:(BOOL)entering;
32 - (void)slideVerticalEffect:(BOOL)entering;
33 - (void)slideHorizontalEffect:(BOOL)entering;
37 /*************************************************************************/
39 #pragma mark IMPLEMENTATION
40 /*************************************************************************/
42 @implementation ITTransientStatusWindow
45 /*************************************************************************/
47 #pragma mark SHARED STATIC OBJECTS
48 /*************************************************************************/
50 static ITTransientStatusWindow *staticWindow = nil;
53 /*************************************************************************/
55 #pragma mark INITIALIZATION METHODS
56 /*************************************************************************/
58 + (ITTransientStatusWindow *)sharedWindow
60 if ( ! (staticWindow) ) {
61 staticWindow = [[self alloc] initWithContentView:nil
62 exitMode:ITTransientStatusWindowExitAfterDelay
63 backgroundType:ITTransientStatusWindowRounded];
68 - (id)initWithContentView:(NSView *)contentView
69 exitMode:(ITTransientStatusWindowExitMode)exitMode
70 backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
77 // If no Content View was provided, use a generic NSImageView with the app icon.
78 if ( ! (contentView) ) {
79 contentView = [[[NSView alloc] initWithFrame:
80 NSMakeRect(100.0, 100.0, 200.0, 200.0)] autorelease];
83 // Set the content rect to the frame of the content view, now guaranteed to exist.
84 contentRect = [contentView frame];
86 if ( ( self = [super initWithContentRect:contentRect
87 styleMask:NSBorderlessWindowMask
88 backing:NSBackingStoreBuffered
91 _visibilityState = ITTransientStatusWindowHiddenState;
93 _exitDelay = DEFAULT_EXIT_DELAY;
94 _backgroundType = backgroundType;
95 _verticalPosition = ITTransientStatusWindowPositionBottom;
96 _horizontalPosition = ITTransientStatusWindowPositionLeft;
97 _entryEffect = ITTransientStatusWindowEffectNone;
98 _exitEffect = ITTransientStatusWindowEffectDissolve;
103 // if ( _backgroundType == ITTransientStatusWindowRounded ) {
104 // _contentSubView = contentView;
106 // [self setContentView:contentView];
109 // [self setIgnoresMouseEvents:YES];
111 key = CGSCreateCString("IgnoreForEvents");
112 ignore = CGSCreateBoolean(kCGSTrue);
114 CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
117 CGSReleaseObj(ignore);
119 [self setLevel:NSScreenSaverWindowLevel];
120 [self setContentView:contentView];
121 [self rebuildWindow];
127 /*************************************************************************/
129 #pragma mark INSTANCE METHODS
130 /*************************************************************************/
132 - (void)orderFront:(id)sender
134 if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
135 // set the timer, and orderOut: when it lapses.
138 if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
139 [super orderFront:sender];
141 [self performEffect];
145 - (void)makeKeyAndOrderFront:(id)sender
147 if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
148 // set the timer, and orderOut: when it lapses.
151 if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
152 [super makeKeyAndOrderFront:sender];
154 [self performEffect];
155 [self makeKeyWindow];
159 - (void)orderOut:(id)sender
161 if ( _entryEffect == ITTransientStatusWindowEffectNone ) {
162 [super orderOut:sender];
164 [self performEffect];
172 if ( _backgroundType == ITTransientStatusWindowRounded ) {
173 return _contentSubView;
175 return [super contentView];
179 - (void)setContentView:(NSView *)aView
181 if ( _backgroundType == ITTransientStatusWindowRounded ) {
182 [_contentSubView removeFromSuperview];
183 _contentSubView = aView;
184 [_contentSubView setFrame:[[super contentView] frame]];
185 [[super contentView] addSubview:_contentSubView];
186 [_contentSubView setNextResponder:self];
188 [super setContentView:aView];
194 - (ITTransientStatusWindowVisibilityState)visibilityState
196 return _visibilityState;
199 - (ITTransientStatusWindowExitMode)exitMode
204 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
214 - (void)setExitDelay:(float)seconds
216 _exitDelay = seconds;
219 - (ITTransientStatusWindowBackgroundType)backgroundType
221 // return _backgroundType;
222 return ITTransientStatusWindowRounded;
225 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
227 // setBackgroundType: is currently ignored. Defaults to ITTransientStatusWindowRounded.
228 // _backgroundType = newType;
229 _backgroundType = ITTransientStatusWindowRounded;
232 - (ITTransientStatusWindowPosition)verticalPosition;
234 return _verticalPosition;
237 - (void)setVerticalPosition:(ITTransientStatusWindowPosition)newPosition;
239 _verticalPosition = newPosition;
242 - (ITTransientStatusWindowPosition)horizontalPosition;
244 return _horizontalPosition;
247 - (void)setHorizontalPosition:(ITTransientStatusWindowPosition)newPosition;
249 _horizontalPosition = newPosition;
252 - (ITTransientStatusWindowEffect)entryEffect
257 - (void)setEntryEffect:(ITTransientStatusWindowEffect)newEffect;
259 _entryEffect = newEffect;
262 - (ITTransientStatusWindowEffect)exitEffect;
267 - (void)setExitEffect:(ITTransientStatusWindowEffect)newEffect;
269 _exitEffect = newEffect;
273 /*************************************************************************/
275 #pragma mark PRIVATE METHODS
276 /*************************************************************************/
278 - (void)rebuildWindow;
280 if ( _backgroundType == ITTransientStatusWindowRounded ) {
281 ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
283 [self setBackgroundColor:[NSColor clearColor]];
284 [self setHasShadow:NO];
287 [self setContentView:roundedView];
288 // [super setContentView:roundedView];
289 // [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
290 // [self setContentView:_contentSubView];
296 - (void)performEffect
298 if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
299 if ( _entryEffect == ITTransientStatusWindowEffectDissolve ) {
300 [self dissolveEffect:YES];
301 } else if ( _entryEffect == ITTransientStatusWindowEffectSlideVertically ) {
302 [self slideVerticalEffect:YES];
303 } else if ( _entryEffect == ITTransientStatusWindowEffectSlideHorizontally ) {
304 [self slideHorizontalEffect:YES];
306 } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
307 if ( _exitEffect == ITTransientStatusWindowEffectDissolve ) {
308 [self dissolveEffect:NO];
309 } else if ( _exitEffect == ITTransientStatusWindowEffectSlideVertically ) {
310 [self slideVerticalEffect:NO];
311 } else if ( _exitEffect == ITTransientStatusWindowEffectSlideHorizontally ) {
312 [self slideHorizontalEffect:NO];
317 - (void)dissolveEffect:(BOOL)entering
320 [super orderFront:self];
322 [super orderOut:self];
326 - (void)slideVerticalEffect:(BOOL)entering
329 [super orderFront:self];
331 [super orderOut:self];
335 - (void)slideHorizontalEffect:(BOOL)entering
338 [super orderFront:self];
340 [super orderOut:self];