Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iTunes-style NSWindow subclass?

Is there an open-source library for Cocoa to create a window following iTunes' style? That is the window controls are laid out vertically instead of horizontally:

sample iTunes window

I find it space-saving and good for utility-type applications that doesn't need a window title.

like image 916
adib Avatar asked Nov 29 '10 13:11

adib


3 Answers

This quickly hacked away NSWindow delegate should get you started:

//VerticalTrafficLightsWindowDelegate.h

#import <Cocoa/Cocoa.h>

@interface VerticalTrafficLightsWindowDelegate : NSObject <NSWindowDelegate> {
    NSWindow *window;
}

@property (assign) IBOutlet NSWindow *window;

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow;

@end

//VerticalTrafficLightsWindowDelegate.m

#import "VerticalTrafficLightsWindowDelegate.h"

@implementation VerticalTrafficLightsWindowDelegate

@synthesize window;

- (void)awakeFromNib {
    [self verticalizeButtonsForWindow:window];
}

- (void)windowDidResize:(NSNotification *)notification {
    [self verticalizeButtonsForWindow:window];
}

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow {
    NSArray *contentSuperViews = [[[aWindow contentView] superview] subviews];

    NSView *closeButton = [contentSuperViews objectAtIndex:0];
    NSRect closeButtonFrame = [closeButton frame];

    NSView *minimizeButton = [contentSuperViews objectAtIndex:2];
    NSRect minimizeButtonFrame = [minimizeButton frame];

    NSView *zoomButton = [contentSuperViews objectAtIndex:1];
    NSRect zoomButtonFrame = [zoomButton frame];

    [minimizeButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y - 20.0, minimizeButtonFrame.size.width, minimizeButtonFrame.size.height)];
    [zoomButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y - 40.0, zoomButtonFrame.size.width, zoomButtonFrame.size.height)];
}

@end

However I got to say that just like JeremyP I can only hope Apple's not going to spread this any wider in OS X.

like image 86
Regexident Avatar answered Nov 01 '22 12:11

Regexident


Just a modified version based on @Regexident 's for new macOS. The view hierarchy changed for new macOS UI, so the original version does not work. The modified code is as follows (works on macOS 10.13):

- (void)verticalizeButtonsForWindow:(NSWindow *)aWindow {
    // New view hierarchy.
    NSView *titleBarContainerView = aWindow.contentView.superview.subviews[1];
    titleBarContainerView.frame = NSMakeRect(titleBarContainerView.frame.origin.x, titleBarContainerView.frame.origin.y - 60.0 + titleBarContainerView.frame.size.height, titleBarContainerView.frame.size.width, 60.0);
    NSView *titleBarView = titleBarContainerView.subviews[0];
    titleBarView.frame = NSMakeRect(0.0, 0.0, titleBarView.frame.size.width, 60.0);
    NSArray *titleBarSubviews = titleBarView.subviews;

    NSView *closeButton = [titleBarSubviews objectAtIndex:0];
    NSRect closeButtonFrame = [closeButton frame];

    NSView *minimizeButton = [titleBarSubviews objectAtIndex:2];
    NSRect minimizeButtonFrame = [minimizeButton frame];

    NSView *zoomButton = [titleBarSubviews objectAtIndex:1];
    NSRect zoomButtonFrame = [zoomButton frame];

    // Coordinate changed: add instead of minus.
    [minimizeButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y + 20.0, minimizeButtonFrame.size.width, minimizeButtonFrame.size.height)];
    [zoomButton setFrame:NSMakeRect(closeButtonFrame.origin.x, closeButtonFrame.origin.y + 40.0, zoomButtonFrame.size.width, zoomButtonFrame.size.height)];
}

Result screenshot: enter image description here

like image 2
Zhigang An Avatar answered Nov 01 '22 13:11

Zhigang An


You'll probably have to subclass NSWindow, NSView and do the window and buttons drawing yourself.

Oh and just wanted to add that you lose some quite important details doing custom drawing. Since the drawing is done in the main thread and your main thread might get busy doing some heavy important task blocking the main thread execution for a while, user won't be able to move the window and they button mouse over animation won't work.

Unless of course you implement mouse listening events in another thread, do the drawing there, lock focus... What I meant was - don't bother unless you really think this will make your app much better :)

like image 1
Aidynskas Avatar answered Nov 01 '22 12:11

Aidynskas