in my cocoa application, I need a custom NSCell for an NSTableView. This NSCell subclass contains a custom NSButtonCell for handling a click (and two or three NSTextFieldCells for textual contents). You’ll find a simplified example of my code below.
@implementation TheCustomCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
// various NSTextFieldCells
NSTextFieldCell *titleCell = [[NSTextFieldCell alloc] init];
....
// my custom NSButtonCell
MyButtonCell *warningCell = [[MyButtonCell alloc] init];
[warningCell setTarget:self];
[warningCell setAction:@selector(testButton:)];
[warningCell drawWithFrame:buttonRect inView:controlView];
}
The problem I’m stuck with is: what is the best/right way to get that Button (more precisely: the NSButtonCell) inside this NSCell to work properly? “work” means: trigger the assigned action message and show the alternate image when clicked. Out of the box, the button doesn’t do anything when clicked.
Information / readings on this topic is hard to find. The only posts I found on the net pointed me to implementing
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp;
Is this the correct way to do it??? Implement trackMouse: in my containing NSCell? And then forward the event to the NSButtonCell? I would have expected the NSButtonCell itself to know what to do when it’s being clicked (and I saw the trackMouse: methods more in cunjunction with really tracking mouse movements – not as a training wheel for ‘standard’ click behaviour). But it seems like it doesn’t do this when included in a cell itself…
It seems I haven’t grasped the big picture on custom cells, yet 😉
I’d be glad if someone could answer this (or point me to some tutorial or the like) out of his own experience – and tell me if I’m on the right track.
Thanks in advance,
Tobi
The minimal requirements are:
To make the button look pressed, you need to update the button cell’s
highlightedproperty as appropriate. Changing the state alone will not accomplish this, but what you want is for the button to be highlighted if, and only if, its states isNSOnState.To send the action message, you need to be aware of when the mouse is released, and then use
-[NSApplication sendAction:to:from:]to send the message.In order to be in position to send these messages, you will need to hook into the event tracking methods provided by
NSCell. Notice that all those tracking methods, except the final,-stopTracking:...method, return a Boolean to answer the question, “Do you want to keep receiving tracking messages?”The final twist is that, in order to be sent any tracking messages at all, you need to implement
-hitTestForEvent:inRect:ofView:and return an appropriate bitmask ofNSCellHit...values. Specifically, if the value returned doesn’t have theNSCellHitTrackableAreavalue in it, you won’t get any tracking messages!So, at a high level, your implementation will look something like: