Builds now. Also some moderate effect architecture changes.
[ITKit.git] / ITTransientStatusWindow.m
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"
7
8 #define EFFECT_FPS 30.0
9
10
11 /*************************************************************************/
12 #pragma mark -
13 #pragma mark PRIVATE METHOD DECLARATIONS
14 /*************************************************************************/
15
16 @interface ITTransientStatusWindow (Private)
17 - (id)initWithContentView:(NSView *)contentView
18                  exitMode:(ITTransientStatusWindowExitMode)exitMode
19            backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType;
20 - (void)rebuildWindow;
21 // - (void)performEffect;
22 @end
23
24
25 /*************************************************************************/
26 #pragma mark -
27 #pragma mark IMPLEMENTATION
28 /*************************************************************************/
29
30 @implementation ITTransientStatusWindow
31
32
33 /*************************************************************************/
34 #pragma mark -
35 #pragma mark SHARED STATIC OBJECTS
36 /*************************************************************************/
37
38 static ITTransientStatusWindow *staticWindow = nil;
39
40
41 /*************************************************************************/
42 #pragma mark -
43 #pragma mark INITIALIZATION METHODS
44 /*************************************************************************/
45
46 + (ITTransientStatusWindow *)sharedWindow
47 {
48     if ( ! (staticWindow) ) {
49         staticWindow = [[self alloc] initWithContentView:nil
50                                                 exitMode:ITTransientStatusWindowExitAfterDelay
51                                           backgroundType:ITTransientStatusWindowRounded];
52     }
53     return staticWindow;
54 }
55
56 - (id)initWithContentView:(NSView *)contentView
57                  exitMode:(ITTransientStatusWindowExitMode)exitMode
58            backgroundType:(ITTransientStatusWindowBackgroundType)backgroundType
59 {
60     NSRect contentRect;
61     
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];
66     }
67     
68     // Set the content rect to the frame of the content view, now guaranteed to exist.
69     contentRect = [contentView frame];
70     
71     if ( ( self = [super initWithContentRect:contentRect
72                                    styleMask:NSBorderlessWindowMask
73                                      backing:NSBackingStoreBuffered
74                                        defer:NO] ) ) {
75                                     
76         _visibilityState     = ITTransientStatusWindowHiddenState;
77         _exitMode            = exitMode;
78         _exitDelay           = DEFAULT_EXIT_DELAY;
79         _backgroundType      = backgroundType;
80         _verticalPosition    = ITWindowPositionBottom;
81         _horizontalPosition  = ITWindowPositionLeft;
82         _screenPadding       = 32.0;
83         _screenNumber        = 0;
84         _entryEffect         = nil;
85         _exitEffect          = nil;
86         _reallyIgnoresEvents = YES;
87         _delayTimer          = nil;
88
89 //      if ( _backgroundType == ITTransientStatusWindowRounded ) {
90 //          _contentSubView = contentView;
91 //      } else {
92 //          [self setContentView:contentView];
93 //      }
94
95         [self setIgnoresMouseEvents:YES];
96         [self setLevel:NSScreenSaverWindowLevel];
97         [self setContentView:contentView];
98         [self rebuildWindow];
99     }
100     return self;
101 }
102
103
104 /*************************************************************************/
105 #pragma mark -
106 #pragma mark INSTANCE METHODS
107 /*************************************************************************/
108
109 - (BOOL)ignoresMouseEvents
110 {
111     return _reallyIgnoresEvents;
112 }
113
114 - (void)setIgnoresMouseEvents:(BOOL)flag
115 {
116     CGSValueObj          key;
117     CGSValueObj          ignore;
118
119     key = CGSCreateCString("IgnoreForEvents");
120     ignore = CGSCreateBoolean( (flag ? kCGSTrue : kCGSFalse) );
121     CGSSetWindowProperty([NSApp contextID], (CGSWindowID)[self windowNumber], key, ignore);
122     CGSReleaseObj(key);
123     CGSReleaseObj(ignore);
124
125     _reallyIgnoresEvents = flag;
126 }
127
128 /*
129
130 - (void)orderFront:(id)sender
131 {
132     if ( _entryEffect == nil ) {
133         [super orderFront:sender];
134         _visibilityState = ITTransientStatusWindowVisibleState;
135     } else {
136         [self performEffect];
137     }
138     if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
139         // set the timer, and orderOut: when it lapses.
140     }
141 }
142
143 - (void)makeKeyAndOrderFront:(id)sender
144 {
145     if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
146         // set the timer, and orderOut: when it lapses.
147     }
148
149     if ( _entryEffect == nil ) {
150         [super makeKeyAndOrderFront:sender];
151         _visibilityState = ITTransientStatusWindowVisibleState;
152     } else {
153         [self performEffect];
154         [self makeKeyWindow];
155     }
156 }
157
158 - (void)orderOut:(id)sender
159 {
160     if ( _entryEffect == nil ) {
161         [super orderOut:sender];
162         _visibilityState = ITTransientStatusWindowHiddenState;
163     } else {
164         [self performEffect];
165     }
166 }
167
168 - (NSTimeInterval)animationResizeTime:(NSRect)newFrame
169 {
170     return _resizeTime;
171 }
172
173 - (id)contentView
174 {
175     if ( _backgroundType == ITTransientStatusWindowRounded ) {
176         return _contentSubView;
177     } else {
178         return [super contentView];
179     }
180 }
181
182 - (void)setContentView:(NSView *)aView
183 {
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];
190     } else {
191         [super setContentView:aView];
192     }
193 }
194
195 */
196
197 - (void)appear
198 {
199     if ( _entryEffect == nil ) {
200         [self orderFront:self];
201         _visibilityState = ITTransientStatusWindowVisibleState;
202     } else {
203         _visibilityState = ITTransientStatusWindowAppearingState;
204         [_entryEffect performAppear];
205         _visibilityState = ITTransientStatusWindowVisibleState;
206     }
207     if ( _exitMode == ITTransientStatusWindowExitAfterDelay ) {
208         // set the timer, and vanish when it lapses.
209     }
210 }
211
212 - (void)vanish
213 {
214     if ( _entryEffect == nil ) {
215         [self orderOut:self];
216         _visibilityState = ITTransientStatusWindowHiddenState;
217     } else {
218         [_exitEffect performVanish];
219         _visibilityState = ITTransientStatusWindowHiddenState;
220     }
221 }
222
223 - (ITTransientStatusWindowVisibilityState)visibilityState
224 {
225     return _visibilityState;
226 }
227
228 - (ITTransientStatusWindowExitMode)exitMode
229 {
230     return _exitMode;
231 }
232
233 - (void)setExitMode:(ITTransientStatusWindowExitMode)newMode
234 {
235     _exitMode = newMode;
236 }
237
238 - (float)exitDelay
239 {
240     return _exitDelay;
241 }
242
243 - (void)setExitDelay:(float)seconds
244 {
245     _exitDelay = seconds;
246 }
247
248 - (ITTransientStatusWindowBackgroundType)backgroundType
249 {
250 //  return _backgroundType;
251     return ITTransientStatusWindowRounded;
252 }
253
254 - (void)setBackgroundType:(ITTransientStatusWindowBackgroundType)newType
255 {
256 //  setBackgroundType: is currently ignored.  Defaults to ITTransientStatusWindowRounded.
257 //  _backgroundType = newType;
258     _backgroundType = ITTransientStatusWindowRounded;
259 }
260
261 - (ITVerticalWindowPosition)verticalPosition;
262 {
263     return _verticalPosition;
264 }
265
266 - (void)setVerticalPosition:(ITVerticalWindowPosition)newPosition;
267 {
268     _verticalPosition = newPosition;
269 }
270
271 - (ITHorizontalWindowPosition)horizontalPosition;
272 {
273     return _horizontalPosition;
274 }
275
276 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
277 {
278     _horizontalPosition = newPosition;
279 }
280
281 - (float)screenPadding
282 {
283     return _screenPadding;
284 }
285
286 - (void)setScreenPadding:(float)newPadding
287 {
288     _screenPadding = newPadding;
289 }
290
291 - (int)screenNumber
292 {
293     return _screenNumber;
294 }
295
296 - (void)setScreenNumber:(int)newNumber
297 {
298     _screenNumber = newNumber;
299 }
300
301 - (ITWindowEffect *)entryEffect
302 {
303     return _entryEffect;
304 }
305
306 - (void)setEntryEffect:(ITWindowEffect *)newEffect
307 {
308     [_entryEffect autorelease];
309     _entryEffect = [newEffect retain];
310 }
311
312 - (ITWindowEffect *)exitEffect
313 {
314     return _exitEffect;
315 }
316
317 - (void)setExitEffect:(ITWindowEffect *)newEffect
318 {
319     [_exitEffect autorelease];
320     _exitEffect = [newEffect retain];
321 }
322
323
324 /*************************************************************************/
325 #pragma mark -
326 #pragma mark PRIVATE METHODS
327 /*************************************************************************/
328
329 - (void)rebuildWindow;
330 {
331     if ( _backgroundType == ITTransientStatusWindowRounded ) {
332         ITGrayRoundedView *roundedView = [[[ITGrayRoundedView alloc] initWithFrame:[self frame]] autorelease];
333
334         [self setBackgroundColor:[NSColor clearColor]];
335         [self setHasShadow:NO];
336         [self setOpaque:NO];
337         
338         [self setContentView:roundedView];
339 //      [super setContentView:roundedView];
340 //      [_contentSubView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
341 //      [self setContentView:_contentSubView];
342     } else {
343         // YUO == CLWONBAOT
344     }
345 }
346
347 /*
348
349 - (void)performEffect
350 {
351     if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
352         _visibilityState = ITTransientStatusWindowEnteringState;
353     } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
354         _visibilityState = ITTransientStatusWindowExitingState;
355     } else {
356         return;
357     }
358         
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 ) {
366         [self pivotEffect];
367     }
368 }
369
370 */
371
372
373 @end