Re: How can we draw a NSWindow in a custom NSView?
Re: How can we draw a NSWindow in a custom NSView?
- Subject: Re: How can we draw a NSWindow in a custom NSView?
- From: Ricky Sharp <email@hidden>
- Date: Mon, 1 Oct 2007 19:42:04 -0500
On Oct 1, 2007, at 6:27 PM, Stéphane Sudre wrote:
On lundi, octobre 1, 2007, at 10:02 PM, Eric Schlegel wrote:
On Oct 1, 2007, at 12:58 PM, Stéphane Sudre wrote:
My issue with HIThemes APIs is that they are probably not
resolution independent compatible.
Actually, they are.
I'm not sure I can say they are. My point being that if the drawing
is already incorrect at resolution = 1.0f, I don't think it can be
said that they correctly deal with higher resolution.
I've just spent some times testing the HITheme API to draw a window
frame and while I'm getting close to a not too bad result, I've
found the method to draw Window frame to be buggy:
(1) it doesn't draw the window frame, it draws the inner part of a
window frame.
(2) it doesn't draw the window growbox the Cocoa way
(3) it doesn't draw the Window buttons correctly (they are
vertically offseted by at least 2 pixels).
While it's possible to work around (2) pretty easily, (1) and (3)
are more problematic.
(1) could be solved by computing the frame line but there are no
guarantees the frame would be the same on different OS versions.
(3) might be solved by using the NSWindow API to get access to real
NSWindow buttons. But again, it's not a nice move toward
compatibility.
One thing you could try (I just tried an experiment and it mostly
works) is to do this:
Create a subclass of NSWindow (your fake window):
- (id)initWithParentWindow:(NSWindow*)aWindow;
{
NSRect theParentWindowRect = [aWindow frame];
NSRect theFakeWindowRect = NSInsetRect (theParentWindowRect, 50.0f,
50.0f);
if ((self = [super initWithContentRect:theFakeWindowRect
styleMask:(NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask)
backing:NSBackingStoreBuffered
defer:NO]) != nil)
{
[self setHidesOnDeactivate:NO];
[self setReleasedWhenClosed:NO];
[self setMovableByWindowBackground:NO];
[self setHasShadow:YES];
[self useOptimizedDrawing:YES];
[self setOpaque:YES];
[aWindow addChildWindow:self ordered:NSWindowAbove];
}
return self;
}
In my test nib, I created an outlet to the default window supplied by
a Cocoa nib. Created a controller subclass and in
applicationDidFinishLaunching, I create an instance of the fakeWindow
with a parent of the default window.
Then at least override the following as well in your NSWindow subclass:
- (BOOL)canBecomeKeyWindow (return NO)
- (BOOL)canBecomeMainWindow (return NO)
- (BOOL)accessibilityIsIgnored (return YES)
This will at least draw a window with frame, title bar and shadow.
However, my limited test app will not do the following:
- resizing main window will not dynamically resize the fake window
- you're able to resize the fake window. Not sure how to do it, but
you may be able to disable that control.
- The three title button widgets always appear disabled (unless you
mouse-over). They are also clickable and will take the appropriate
action. You'd have to figure out how to trap for those as well.
- while dragging the window by its background isn't allowed, you can
drag it from its title bar.
One cool thing about this approach is that it appears to be Expose-
savvy (at least in 10.4.x). The fake window's position will always
be in sync with its parent window. And, since the fake window can
never become key/main, expose keeps it out of its list of windows you
can directly select. When you mouseover the fake window, expose
gives you the name of its parent window instead.
___________________________________________________________
Ricky A. Sharp mailto:email@hidden
Instant Interactive(tm) http://www.instantinteractive.com
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden