I have a NSView where I draw thousands of NSBezierPaths. I would like to highlight (change fill color) the a selected one on mousemoved event. At the moment I use in mouseMoved function the following command:
[self setsetNeedsDisplay:YES];
that force a call to drawRect to redraw every path. I would like to redraw only the selected one. I tried to use addClip in drawRect function:
NSBezierPath * path = ... //builds the path here
[path addClip];
[path fill];
but it seems that drawRect destroys all the other previously drawn paths and redraws only the one clipped.
Is it possible NOT to invalidate all the view when calling drawRect? I mean just to incrementally overwrite what was on the view before?
Thanks, Luca
You should use [self setNeedsDisplayInRect:…]
. Pass the NSRect you want invalidated, and that will be the area passed to the drawRect:
call.
Inside drawRect:
, check the area that was passed in and only perform the drawing necessary inside of that rectangle.
Also, you might want to look into using NSTrackingArea
instead of mouseMoved:
– these allow you to set up specific rectangles to trigger updates for.
I think I solved in a faster way, as I do not know a priori which paths are present in a rectangle I want to avoid a loop through all the paths. Fortunately my paths do not change often, so I can cache all the paths in a NSImage. On mouseMoved event I set:
RefreshAfterMouseMoved = YES;
and in drawRect function I put something like:
if (RefreshAfterMouseMoved) {
[cacheImage drawAtPoint:zero fromRect:viewRect operation:1
fraction:(CGFloat)1.0];
//redraw only the hilighted path
}
else{
if (cacheImage) [cacheImage release];
cacheImage = [[NSImage alloc] initWithSize: [self bounds].size ];
[cacheImage lockFocus];
// draw everything here
[cacheImage unlockFocus];
[cacheImage drawAtPoint:zero fromRect:viewRect operation:1
fraction:(CGFloat)1.0];
}
This method can be combined with the above setNeedsDisplayInRect method putting in mousedMoved function:
NSRect a, b, ab;
a = [oldpath bounds];
b = [newpath bounds];
ab = NSUnionRect(a,b);
RefreshAfterMouseMoved = YES;
[self setNeedsDisplayInRect:ab];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.