JUCE Components into an NSView

I recently had to add some JUCE UI stuff to a legacy Cocoa app.  I thought I'd add some of my findings in case they're useful for someone else. 

 

In IB I dropped in an NSView(lets call it juceContentView) object and wired up its outlet to the Controller.mm

On awakeFromNib I instantiate the JUCE Component and add it to the NSView(Not sure why I had the ComponentPeer flags, but anyway...)

juceView->addToDesktop(ComponentPeer::windowHasTitleBar | ComponentPeer::windowHasDropShadow,juceContentView);

juceView->setVisible(true);

Then I had to manually monitor whenever the view bounds changed and manually tell the component.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewResized:) name:NSViewFrameDidChangeNotification object:nil];

 

- (void) viewResized:(NSNotification *)aNotification

{

    if ([aNotification object]==juceContentView)

    {

        NSRect newBounds=[[aNotification object]bounds];

        juceView->setBounds(Rectangle<int>(0,0,newBounds.size.width,newBounds.size.height));

    }

}

 

There was one other little hurdle, that took me a while to figure out.  I didn't want the components to grab focus from the Cocoa views, but I did want mouseEnter and mouseExit calls so I could do things like highlight rollovers, and have tooltips work.  I tried mucking about with the NSResponder chain manually, but because of Jules' cunning code it didn't quite work.  I then tried Cocoa's trackingRects, but that was flaky at best.(And tons of code to do right... and very finicky about when added).  After countless hours experimenting...  The magic sauce was this...

 

NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:NSTrackingMouseMoved|NSTrackingInVisibleRect|NSTrackingActiveInKeyWindow owner:(NSView*)juceView->getWindowHandle() userInfo:nil];

        [(NSView*)juceView->getWindowHandle() addTrackingArea:trackingArea];

        [trackingArea release];

Thank you so much. This works great!