Programmatically handle Cocoa events?

495 views Asked by At

I am attempting to hook up cocoa events to a minimal objective-c++ cocoa message proxy that will call my c++ functions to handle the event.

For a button, OnClick, its simple, I go:

@interface cocoa_proxy : NSObject
    - (void)action:(id)sender;
@end

@implementation cocoa_proxy
    - (void)action:(id)sender
    {
        exit(0);
    }
@end

cocoa_proxy* proxy = [[cocoa_proxy alloc] init];
[button setTarget:proxy];
[button setAction:@selector(action:)];

However I am unsure about how I could capture other events for the button (such as OnPress, OnRelease, OnEnter, OnExit, etc...) nor can I seem to capture events for a Window or View. Any attempt trying a similar route, with slightly differently formatted methods (from various, not quite the same, but similar questions on the web) results in an error like:

reason: '-[NSWindow setTarget:]: unrecognized selector sent to instance xxxxx

I already have a large codebase that I want to reuse, so it is paramount that I have a proxy, rather than just "do everything in objective-c++".

For completeness, here is how I create the Window

window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(x, y, w, h)
    styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
        autorelease];

To be clear, I do not use XCode, or Interface Builder, or any GUI creation software or Cocoa aware software, or utilize concepts such as NIBs, everything is done procedurally and with minimal interaction with objective-c++.

So my question is, how do I handle different events for a Button, and how do I handle events (at all), in a similar manner for Windows and Views.

1

There are 1 answers

5
Ken Thomases On

The action method fired by a button when it is clicked (complete press and release sequence), is not an event as such. It's the consequence of a series of events.

It's not entirely clear at what level you need to operate, but you may need to use a custom subclass of NSApplication and override -sendEvent:. There you will get the low-level events like left-mouse-button-down, left-mouse-button-up, key-down, key-up, etc.

If you are only interested in a single window, you could instead use a custom subclass of NSWindow and override -sendEvent: there.

If you don't allow events to be processed through Cocoa in the normal way (by calling through to super in either override), then you are responsible for all application responses to events. You can rely on clicks in the window controls to close, minimize, or full-screen/zoom the window. Clicks on Cocoa buttons won't work. Etc. So, you have to choose carefully what you do or don't do with the events.

To just get additional control over a button, you would subclass NSButton, NSButtonCell, or both and override a bunch of methods. For example, you would probable want to override -startTrackingAt:inView:, -continueTracking:at:inView:, and -stopTracking:at:inView:mouseIsUp: in your button cell class.