|
DBOverlayWindow 1.0 Wednesday, November 22, 2006 Since I'm still new to Cocoa, I'm not very good yet at creating useful new classes. But I am getting really good at finding existing classes and modifying them to get what I want. After a day or so of messing with Matt Gemmell's RoundedFloatingPanel class, I've come up with a new class I'd like to share.
Matt's RoundedFloatingPanel class displays a semi-transparent floating window, similar to the one you see when typing Command-tab to switch applications on Mac OS X. It's a great class, and I'm thrilled that Matt has shared it. He's got a whole page full of great code that you should check out if you haven't already.
But in addition to displaying an icon, I also want to display text in the overlay window. Unfortunately, when a window's background is set to semi-transparent, the OS appears to dither the text, making it kinda ugly.
Through some testing with Matt's class, I discovered that if I made the window completely transparent and then displayed it over a gray rectangle, the text displayed clearly. So instead of displaying the window's contents over a semi-transparent rect, I created a new class that makes the window completely transparent, then opens another window behind it to display the semi-transparent background. This avoids the ugly text problem.
Now I'll grant you that this seems like a crazy way to display clear text over a semi-transparent window. There must be a better way, so please clue me in if you know a better way to do this.
The second window is created at runtime as a child window behind the window you create in Interface Builder. One advantage to this approach over Matt's implementation is that you don't need to add an NSView object behind your other window objects to display the semi-transparent background. This is now handled automatically for you. However, the drawing of this background is still handled by the same logic used in Matt's class.
I decided I also wanted the window to fade in and out like the overlay window you see when adjusting the display brightness or the volume. So while I was in there, I overrode NSWindow's orderFront: and orderOut: methods. I also added an accessor method to set the background color and transparency (as an NSColor value), so you can change the background without modifying the source.
And finally, I noticed that with a little extra tweak to the code, the transparent front window could support NSWindow's shadow feature, and cast shadows from the window's contents onto the background window. This makes the text a little easier to read if the window's transparency is high. It's not something you'd always want to use, but sometimes it's a better solution.
So here it is, my first source code contribution to the Cocoa community: DBOverlayWindow
Right now you need to add both the DBOverlayWindow class and the DBOverlayWindowBkgrnd class to your project. I'm thinking I might be able to move everything into a single class. I'd also like to provide methods to directly access the corner radius and fade rates. But I'll wait until I get some feedback on this first release before I spend any more time on it.
You'll notice in the demo that there's a short delay (1.5 seconds) built into quitting, just so you can see the window fade out before the application quits.
Here's some useful information for working with the class:
- (void)orderFront:(id)sender Send this message to your window to fade it in.
- (void)orderOut:(id)sender Send this message to your window to fade it out.
- (NSColor *)overlayColor Returns the window's background color and transparency.
- (void)setCanHide:(BOOL)flag By default this is set to NO. Set to YES to allow the window to be hidden when the application is hidden.
- (void)setHasShadow:(BOOL)hasShadow When displaying text, the text may be easier to read if the window has a shadow. Since no window is visible, the shadow is applied to its contents. So pass YES to this method to display a shadow around the objects in the window. This can also be done by selecting the Has shadow checkbox for the window in Interface Builder.
- (void)setIgnoresMouseEvents:(BOOL)flag Pass YES to prevent the user from dragging the window.
- (void)setOverlayColor:(NSColor *)aColor Set the overlay window's background color. If you want the window to be transparent, you must include the transparency as part of the color. For example:
Semi-transparent gray background:
[myOverlayWindow setOverlayColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.20]];
Opaque red background:
[theOverlayWindow setOverlayColor:[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:1.0]];
|