Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a custom title bar on a standard NSWindow

I've been trying to build a specific look for my menubar app.

enter image description here

I've been using a NSWindow with a NSBorderlessWindowMask style mask and setting [window setOpaque:NO] and [window setBackgroundColor:[NSColor clearColor]]. That gives me a blank canvas which works great for the title bar.

Now I'm having problems with the view-based NSTableView I'm using for the listing. How can I clip the NSTableCellViews to the window's rounded corners?

I started out just having a custom view wrapping the NSTableView, drawing the background with rounded corners. Using [view addClip:path] doesn't clip child views though.

I've also tried using a [view setWantsLayer:YES] with a mask. That worked great, but the table view cells would sporadically glitch out. It seems that having a NSScrollView be a child of a layer is a known problem:

http://i.stack.imgur.com/JmhjD.png

My current view structure looks something like:

NSWindow
- MyTitleBarView
- MyBackgroundView
  - NSScrollView
    - NSTableView
like image 924
Joseph North Avatar asked Jul 25 '12 20:07

Joseph North


1 Answers

I found one way to do it:

The trick is to keep the window style as the default and not set NSBorderlessWindowMask. Then you can add your custom title bar view to the window's theme frame like so:

NSView *themeFrame = [[window contentView] superview];
NSView *firstSubview = [[themeFrame subviews] objectAtIndex:0];
[titleBarView setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
[themeFrame addSubview:titleBarView positioned:NSWindowBelow relativeTo:firstSubview];

This basically just puts your custom title bar view on top of the standard title bar. You'll probably have to do some rejiggering to the view frames and window buttons. See INAppStoreWindow for some code examples of this.

The INAppStoreWindow project says that this method doesn't use any private APIs, and thus is able to be used on the App Store.

If you require the window to be transparent, you can just set the following on the window:

[window setOpaque:NO];
[window setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:0.5]];
like image 193
Joseph North Avatar answered Sep 19 '22 16:09

Joseph North