> On 16 Jan 2016, at 4:10 PM, Ken Thomases <k...@codeweavers.com> wrote:
> 
> NSView* view1 = /* ... */;
> NSRect rect = /* some rect in view1's internal coordinate space (relative to 
> its bounds, not its frame) */;
> NSView* view2 = /* some view in another window */;
> 
> rect = [view1 convertRect:rect toView:nil];
> rect = [view1.window convertRectToScreen:rect];
> rect = [view2.window convertRectFromScreen:rect];
> rect = [view2 convertRect:rect fromView:nil];
> 
> rect is now in view2's internal coordinate space.
> 
> Regards,
> Ken
> 



Thanks Ken, this is exactly what I have - I changed to use 
-convertRect:toView:nil as Roland suggested rather than worrying about the 
backing.

The rect I convert is the bounds of view1. When I’m done converting, I set up 
an NSAffineTransform that translates to the resulting rect’s origin, (and also 
scales to match the original view, but I’m ignoring scaling until I get the 
basics working), then concat’s that transform with the current CTM.

So my -drawRect: looks something like this:


-(void) drawRect:(NSRect) dirty
{
        NSRect localRect = [self convertBoundsFromAnotherView:view1];   // just 
the above code, using view1.bounds as the rect

        NSAffineTransform* xfm = [NSAffineTransform transform];
        [xfm translateXBy:localRect.origin.x yBy:localRect.origin.y];           
        // ignore scale for now

        [NSGraphicsContext saveGraphicsState];
        
        [xfm concat];
        
        /* draw content using coordinate system of original view1 */

        [NSGraphicsContext restoreGraphicsState];
}


Turns out, this is actually working - when I draw using the coordinates of 
view1, it does draw at the correct location.

What isn’t working is correctly setting the dirty rects when part of the view 
needs to be refreshed. This is what has been leading me astray - because the 
dirty region is misaligned, the drawing I’m doing is clipped, so it doesn’t 
appear unless by chance the dirty region does overlap where I’m trying to draw. 
I discovered this just now, after I posted originally. If I dirty the ENTIRE 
overlay view, it draws OK, because the whole view is dirty and so there’s no 
clipping. This *might* be acceptable because the overlay view only draws a few 
transitory elements, and doesn’t need to worry too much about limiting drawing 
for performance. But it would be nicer to be able to let 
-setNeedsDisplayInRect: work as it should.

So the question is how to keep the view aligned to the original view at all 
necessary times, not just when drawing.

I factored out the transform setting, and tried to do the same in an override 
of -setNeedsDisplayInRect, but that doesn’t seem to do it - it works slightly 
better, but there’s still clipping preventing correct drawing.

Is there a better place or better method to set up the overlay’s coordinate 
system so it is valid at all necessary times? There are the methods 
-translateOriginToPoint:, -setBoundsOrigin:, -scaleUnitSquareToSize: and so on 
- these seem likely candidates, but I’m no sure quite where to set these up. 
I’ll experiment…


—Graham



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to