0

I'm building an OS X cocoa application and I'm not using interface builder (for a variety of reasons). I've got the application to the point of loading a menu, title bar and main window, but I can't seem to figure out how to add the stoplight buttons to the title bar (programmatically).

My AppDelegate.m looks like this:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    MainViewController *mVC = [MainViewController new];
    [mVC showMainViewController];
}

Then code in the MainViewController then creates the menu, window, and loads the application, as follows:

//
//  MainViewController.m
//  TestApp
//

#import "MainViewController.h"

@implementation MainViewController

@synthesize menubar;
@synthesize appMenu;
@synthesize appMenuItem;
@synthesize quitMenuItem;
@synthesize appName;
@synthesize quitTitle;
@synthesize window;
@synthesize homeViewController;
@synthesize resolutionHeight;
@synthesize resolutionWidth;
@synthesize width;
@synthesize height;

- (id)init
{
    self = [super init];
    if (self) {
        appName = @"TestApp";
        [self setupMenubar];
        [self setupMainWindow];
    }
    return self;
}

- (void)setupMenubar
{
    // Set up the main menu
    menubar = [NSMenu new];
    appMenu = [NSMenu new];
    appMenuItem = [NSMenuItem new];
    quitTitle = [NSString stringWithFormat:@"Quit %@", appName];
    quitMenuItem = [[NSMenuItem alloc] initWithTitle:quitTitle
                                              action:@selector(terminate:)
                                       keyEquivalent:@"q"];

    [menubar addItem:appMenuItem];
    [appMenu addItem:quitMenuItem];
    [appMenuItem setSubmenu:appMenu];
    [NSApp setMainMenu:menubar];
}

- (void)setupMainWindow
{
    // set the dimensions of the application
    resolutionWidth = [[NSScreen mainScreen] frame].size.width;
    resolutionHeight = [[NSScreen mainScreen] frame].size.height;

    width = resolutionWidth * 0.75;
    height = resolutionHeight * 0.75;
    window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
                                         styleMask:NSTitledWindowMask
                                           backing:NSBackingStoreBuffered defer:NO];
    [window cascadeTopLeftFromPoint:NSMakePoint(10, 10)];

    // add window buttons
    closeButton = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:NSTitledWindowMask];


    // set metadata for the window
    [window setTitle:appName];
    [window makeKeyAndOrderFront:nil];
}

- (void)showMainViewController
{
    // Set app settings
    [NSApplication sharedApplication];
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    [NSApp activateIgnoringOtherApps:YES];
    [NSApp run];
}

@end

I've looked around and I'm kind of at a loss for how to proceed.

NSGod
  • 22,699
  • 3
  • 58
  • 66
marpaia
  • 39
  • 5

1 Answers1

2

You might try changing your NSWindow init method to the following:

window = [[NSWindow alloc]
             initWithContentRect:NSMakeRect(0, 0, width, height)
                       styleMask:NSTitledWindowMask | NSClosableWindowMask |
                        NSMiniaturizableWindowMask | NSResizableWindowMask

                         backing:NSBackingStoreBuffered defer:NO];

I believe that ORing in the additional masks automatically adds the corresponding buttons to the title bar for you: NSClosableWindowMask adds the close button, NSMiniaturizableWindowMask adds the minimize (center) button, and NSResizableWindowMask adds the zoom (rightmost) button.

NSGod
  • 22,699
  • 3
  • 58
  • 66
  • To expand a bit. The NSWindow method standardWindowButton: only returns a reference to the system supplied standard buttons. It doesn't create them and there is no public API in cocoa to create them beyond supplying the right NSWindowStyleMasks. If you were creating a custom window with custom buttons you would need to connect them to the right selectors and handle state changes of active, inactive, unavailable, key non key and mouseEntered mouseExited and mouseDown and possibly document dirty – uchuugaka Jan 16 '14 at 23:15
  • Technically you can use those methods to get the buttons but they won't be properly connected or responding to the above state changes visually. It's either an API bug or a documentation bug. – uchuugaka Jan 16 '14 at 23:17