Re: How to make NSWindow redraw vacated rects "ifNeeded"?
Re: How to make NSWindow redraw vacated rects "ifNeeded"?
- Subject: Re: How to make NSWindow redraw vacated rects "ifNeeded"?
- From: Darkshadow <email@hidden>
- Date: Mon, 9 Apr 2007 00:06:06 -0400
On Apr 8, 2007, at 6:37 PM, Jerry Krinock wrote:
P.S. There is also a Really Weird way to solve the problem: If I -
orderFront: the window before adding the NSBox subview, then the
vacated rect gets redrawn by -displayIfNeeded as expected. A
possibly related mystery is that I find -orderFront: is needed to
get an NSProgressIndicator to start animating (with threaded
animation).
It's not working because you're going the wrong way with this.
You're telling *only* the box to display itself, and it's doing that,
but as far as the window is concerned it doesn't have any dirty rects
that need display so calling -displayIfNeeded on the window doesn't
do anything. What you really need to do is tell the box's superview
to display in the old and new rects. Calling -orderFront: on the
window is working because (most likely) that in turn tells the
window's subviews to display as well (I don't know for sure - I don't
know the internals of how a window displays - but that seems likely
from what you are seeing).
Something like this should do what you want:
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)noti {
// Create window
NSWindow* window = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0,0,300,100)
styleMask:NSTitledWindowMask
backing:NSBackingStoreBuffered
defer:NO] ;
[window center] ;
// Create a box and add to window
NSBox* box ;
box = [[NSBox alloc]
initWithFrame:NSMakeRect(20,10,260,40)] ;
[[window contentView] addSubview:box] ;
/* You had a memory leak here, fixed by releasing the box */
[box release];
[window orderFront:self] ;
// Move box origin from y=10 up to y=50
// (a) First, mark the current rect for redrawing
[[box superview] setNeedsDisplayInRect:[box frame]] ;
// (b) Move it
[box setFrame:NSMakeRect(20,50,260,40)] ;
// (c) Mark the new rect as needing redrawing
[[box superview] setNeedsDisplayInRect:[box frame]];
}
@end
Also, if the old and new frames of the view you want to move are
close to each other, or overlap, you can optimize the redrawing a bit
by using NSUnionRect() with the old and new frame to call -
setNeedsDisplayInRect: once rather than twice. You'd need to save
the old frame to do it, but it'd be something like this:
NSRect oldFrame = [box frame];
[box setFrame:NSMakeRect(20,50,260,40)];
[[box superview] setNeedsDisplayInRect:NSUnionRect(oldFrame, [box
frame])];
If you're in a tight loop or handling mouse events yourself or
something of the like, where you need the display updated *now*
rather than through the next event loop, you can change the -
setNeedsDisplayInRect: messages to -displayRect: i.e. [[box
superview] displayRect:[box frame]].
------------------------------------------------
Darkshadow
(aka Michael Nickerson)
http://www.nightproductions.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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