views:

552

answers:

2

I have a custom NSCell with various elements inside of it (images, various text pieces) and one of those text blocks may have various clickable links inside of it. I have my NSAttributedString correctly identifying the links and coloring them blue however I can't figure out how to get the cursor to turn into a hand and allow a user to actually click on them.

Right now I have my attributed string drawn right to the cell which obviously isn't clickable, but I'm not sure how to add it any other way since NSCell doesn't inherit from NSView. Normally I'd just add an NSTextField as a subview but I can't do it like that in this case.

Any thoughts?

+2  A: 

The only solution I can think of is via manual hit testing and mouse tracking within your NSCell. The hardest part (which I don't have the answer to) is how to determine the rect of the link text ... hopefully someone can answer that?

Once you know the rect of the url text it's possible to implement the clicking action by implementing hitTestForEvent. I think you'd do it something like this;

// If the event is a mouse down event and the point is inside the rect trigger the url 
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)frame ofView:(NSView *)controlView {
   NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
// Check that the point is over the url region
   if (NSPointInRect(point, urlFrame)) {
       // If event is mousedown activate url
       // Insert code here to activate url
       return NSCellHitTrackableArea;
   } else {
    return [super hitTestForEvent:event inRect:frame ofView:controlView];
   }
}
Ira Cooke
A: 

Based on talks with Ira Cooke and other folks I've decided to go for the following solution:

  • Draw directly to the NSCell
  • When the mouse enters an NSCell, I will immediately add a custom NSView subview to the NSTableView at the same position as the NSCell that was hovered over.
  • Their designs match pixel for pixel so there's no discernible difference
  • This NSView will have an NSTextView (or Field, haven't decided) that will display the attributed string with links in it allowing it to be clickable.
  • When you hover out of the NSCell its mirror NSView is destroyed

If all goes according to plan then I should only have 1 NSView attached to the NSTableView at a time and most of the time none at all. I'll come back and report my results once I get it working.

Mike Rundle
This is 100% implemented and works like a charm. The key is to add an NSTrackingArea to the visible portion of the scrollview, then you translate the mouse point and call rowAtPoint: on the NSTableView. Then, get the rect for the returned row and put your NSView there. Perfect.
Mike Rundle
Hi Mike, Would you mind sharing the code you wrote to implement this?