Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Fold" an NSWindow using CoreAnimation

So I'm fairly new to AppKit and Cocoa (coming from UIKit with CocoaTouch) and I'm currently implementing an interface to fold an NSWindow. On iOS this would be fairly easy but seeing how there's lots of tiny differences to OS X I choose to ask.

How would you go about implementing the following transition?

Window Fold

Note: The bottom bar is part of my contentView and not the bottom bar OS X provides. I.e. my window (INAppStoreWindow by the way) consists of a titleBar and a contentView.

I guess I could just fold the contentView and resize the window synchronously but it'd be preferable if I was able to preserve the transparency while folding which happens due to the perspective transfomation. I.e. the sides that are bent inwards should (during the transition) be transparent. Or am I overthinking this?

like image 267
pkluz Avatar asked Nov 04 '22 22:11

pkluz


1 Answers

Bad news first: unlike UIKit, AppKit doesn't use Core Animation to render its controls. All CALayers inhabit their own world within special layer-hosting instances of NSView. So unless the content view of your window is layer-hosting, you can't apply a CAAnimations to the contents of your window as a whole without a fair degree of hackery (it might be possible to render the whole content view to a bitmap, set that as the contents of a layer, and perform the transformation on that. I'm not sure).

Hopefully your content view is Core Animation-based. If so, the approach you describe should work. You should also be able to host the layer in a transparent borderless, NSWindow and then any transformations you make to the content view will reveal the desktop behind it. Here's a snippet (from Matt Long) that ought to do what you want:

 - (id) initWithContentRect: (NSRect) contentRect
                 styleMask: (unsigned int) aStyle
                   backing: (NSBackingStoreType) bufferingType
                     defer: (BOOL) flag
{
    if (![super initWithContentRect: contentRect 
                             styleMask: NSBorderlessWindowMask 
                          backing: bufferingType 
                         defer: flag]) return nil;
    [self setBackgroundColor: [NSColor clearColor]];
    [self setOpaque:NO];

    return self;
}
like image 126
Chris Devereux Avatar answered Nov 15 '22 06:11

Chris Devereux