Search code examples
objective-cmacoscocoanstokenfieldnspopover

Show NSPopover from NSTokenField Token on Click


I am attempting to show an NSPopover from an NSTokenField token when the token is clicked.

These tokens have a built in way to show a menu, so from a design standpoint, it's not unlike that action.

However, there does not appear to be any (good) way to execute arbitrary code when a token is clicked.

I have managed to slip some code into - tokenField:menuForRepresentedObject:, but it's far from elegant.

Assuming that - tokenField:menuForRepresentedObject: is the only way to execute code when a token is clicked, I still have another problem: getting the NSRect that represents the token, so that the NSPopover can maintain a visual relationship with said token. I've tried to do some string juggling, figure out how tokens come first, etc., but it is far from reliable, and even requires an undocumented method.

Bottom Line: How do I show an NSPopover from the selected token in an NSTokenField?


Solution

  • This is what I ended up doing. I'm working on an open-source NSTokenField alternative with this capability built in.

    // in an NSWindowController
    - (NSMenu *)tokenField:(NSTokenField *)tokenField menuForRepresentedObject:(id)representedObject
    {
        NSRect displayRect = NSMakeRect(([NSEvent mouseLocation].x - 2.5),
                                        ([NSEvent mouseLocation].y - 2.5),
                                        5, 5);
        displayRect = [self.window convertRectFromScreen: displayRect];
    
    
        // establish popover from displayRect ...
    }
    

    It looks pretty great, despite feeling very hacked (and being ocasionally 1px off).