How can I clip an image to a custom NSView?

chrisBchrisB USMember
edited August 2015 in Xamarin.Mac

I have a custom NSVIew subclass to display a popup window. Now I want to set a background image of this view, similar to flickr uploadr (see attached image) that clips to the custom drawn shape of the NSView.
How can I achieve this?

Currently the NSImageView is overlapping its parent NSView (see second attached image).

Thnx, Chris

Tagged:

Answers

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    I've never done this, but some searching suggests (http://www.cocoabuilder.com/archive/cocoa/197356-setting-clip-mask-on-nsview.html) that you can parent your view in an NSClipView.

  • chrisBchrisB USMember

    [...] but the next paragraph makes me think
    that a rectangular mask may be enough. If that's the case, you could
    stick your NSView inside an NSClipView, [...]

    Hence, my masks isn't rectangular, I don't think that's going to work for me. But I tried it anyways, without the expected outcome (all I did was putting my custom drawn NSView inside a NSClipView).
    Do you have any other ideas on how to accomplish that? Or is there a way to custom draw a NSImageView so it fits my parent view?

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    If your masks aren't rectangular, I think you are going to have to do the heavy lifting by hand.

    See technique 5 here:

    http://www.cocoawithlove.com/2010/05/5-ways-to-draw-2d-shape-with-hole-in.html

  • cblaettlcblaettl USMember

    I ended up reusing a lot of my drawing code from the parent view to get the same shape and drew the image in code:

    base.DrawRect(dirtyRect);
    
    NSBezierPath bezierPath = new NSBezierPath();
    // custom drawing code magic happens here
    
    // General Declarations
    var context = NSGraphicsContext.CurrentContext;
    
    // Image Declarations
    var background = NSImage.ImageNamed("background.jpg");
    
    // Rectangle Drawing
    context.SaveGraphicsState();
    bezierPath.AddClip();
    background.Draw(bezierPath.Bounds);
    context.RestoreGraphicsState();
    
Sign In or Register to comment.