Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a GUI and react to Cocoa events programmatically?

I found out how to create a window in Cocoa programmatically but can't figure out how to react to events. The window is not reacting to a Quit request or button click.

I tried adding the following controller and used setDelegate/setTarget without luck:

    @interface AppController : NSObject {
    }
    - (IBAction)doSomething:(id)sender;
    @end

    @implementation AppController
    - (IBAction)doSomething:(id)sender;
    {
        printf("Button clicked!\n");
    }
    @end

    int main(int argc, char **args){
        NSRect frame = NSMakeRect(0, 0, 200, 200);

        AppController *controller = [[AppController alloc] init];

>       [[NSApplication sharedApplication] setDelegate:controller];
        NSWindow* window  = [[NSWindow alloc] initWithContentRect:frame
                                            styleMask:NSBorderlessWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask
                                            backing:NSBackingStoreBuffered
                                            defer:NO];
        [window setBackgroundColor:[NSColor blueColor]];

        NSButton *button = [ [ NSButton alloc ] initWithFrame: NSMakeRect( 30.0, 20.0, 80.0, 50.0 ) ];
        [ button setBezelStyle:NSRoundedBezelStyle];
        [ button setTitle: @"Click" ];
>       [ button setAction:@selector(doSomething:)];
>       [ button setTarget:controller];
        [ [ window contentView ] addSubview: button ];

        [window makeKeyAndOrderFront:NSApp];

        [[NSRunLoop currentRunLoop] run];
        return 0;
    }
like image 281
Daniel Furrer Avatar asked Mar 17 '09 21:03

Daniel Furrer


Video Answer


2 Answers

You need to invoke -[NSApplication run] instead of -[[NSRunLoop currentRunLoop] run]. The reason should be clear if you look at the basic structure of the method:

- (void)run
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self finishLaunching];

    shouldKeepRunning = YES;
    do
    {
        [pool release];
        pool = [[NSAutoreleasePool alloc] init];

        NSEvent *event =
            [self
                nextEventMatchingMask:NSAnyEventMask
                untilDate:[NSDate distantFuture]
                inMode:NSDefaultRunLoopMode
                dequeue:YES];

        [self sendEvent:event];
        [self updateWindows];
    } while (shouldKeepRunning);

    [pool release];
}

NSApplication encapsulates a lot about how to get an event, how to dispatch them and how to update windows.

like image 94
Matt Gallagher Avatar answered Oct 09 '22 01:10

Matt Gallagher


I found out how to create a window in Cocoa programmatically …

Why? Why not just make a nib?

The window is not reacting to a Quit request or button click.

How would you quit a window? This isn't Windows 3; applications can have multiple windows on Mac OS X. As such, closing a window and quitting an application are separate actions.

[[NSRunLoop currentRunLoop] run];

Except in rare circumstances, running the run loop is NSApplication's job, and you should leave that to it. Use NSApplicationMain or -[NSApplication run] to tell the application to run.

like image 28
Peter Hosey Avatar answered Oct 09 '22 01:10

Peter Hosey