OK I'm really stumped on this one. I want to make a checkbox with a
NSTextFieldCell combined together. It's important that the checkbox
goes ON if the mouse hits the box, NOT the text. I've accomplished
this, more or less, but the issue is receiving the mouse event because
I click one checkbox in a row, but ALL of them turn to NSOnState. I
will show what I've done and my various failed attempts in order to
get this to work.
So this is how I've done it so far:
header:
@interface MyCheckboxCellToo : NSTextFieldCell {
NSButtonCell *_checkboxCell;
}
implementation:
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
NSLog(@"%@", NSStringFromPoint(point));
NSRect checkFrame;
NSDivideRect(cellFrame, &checkFrame, &cellFrame, cellFrame.size.height/*3 + [[_checkboxCell image] size].width*/, NSMinXEdge);
if (NSMouseInRect(point, checkFrame, [controlView isFlipped])) {
// the checkbox, or the small region around it, was hit. so let's flip the state
NSCellStateValue checkState = ([_checkboxCell state] == NSOnState) ? NSOffState:NSOnState;
[self setState:checkState];
[_checkboxCell setState:checkState];
[controlView setNeedsDisplay:YES];
return NSCellHitTrackableArea;
}
return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];
}
I know I probably shouldn't be doing:
[self setState:checkState];
[_checkboxCell setState:checkState];
[controlView setNeedsDisplay:YES];
in there... because the result is that EVERY checkbox in every goes to
NSOnState. Is this because cells are re-used? How come the ImageAndTextCell can have different images in the same tableview? How do I handle the mouse event?
I have tried:
- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame
ofView:(NSView *)controlView untilMouseUp:(BOOL)untilMouseUp {
NSLog(@"%s %@", _cmd, theEvent);
return [_checkboxCell trackMouse:theEvent inRect:cellFrame
ofView:controlView untilMouseUp:untilMouseUp];
// return YES;
// return [super trackMouse:theEvent inRect:cellFrame
ofView:controlView untilMouseUp:untilMouseUp];
}
- (BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView {
NSLog(@"%s %@", _cmd, NSStringFromPoint(startPoint));
return [super startTrackingAt:startPoint inView:controlView];
}
- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint
inView:(NSView *)controlView {
NSLog(@"%s %@", _cmd, NSStringFromPoint(currentPoint));
return [super continueTracking:lastPoint at:currentPoint
inView:controlView];
}
- (void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint
inView:(NSView *)controlView mouseIsUp:(BOOL)flag {
NSLog(@"%s %d %@", _cmd, flag, NSStringFromPoint(stopPoint));
}
trackMouse: ... DOES gets called
but
startTrackingAt:..., continueTracking:..., and stopTracking:.... DO
NOT get called when I click on the checkbox "hit area"
in trackMouse:... I have tried
return [_checkboxCell trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
and
return [super trackMouse:theEvent inRect:cellFrame ofView:controlView untilMouseUp:untilMouseUp];
and neither seems to result in the mouse event being handled by the checkbox.
How do I get that single checkbox to go NSOnState? I know I'm pretty
close but after a lot of doc reading and google searching I haven't
been successful at solving this.
suggestions and comments welcome..
OK here is a bit more to show creation and destruction of the object..
- (id)init {
if ((self = [super init])) {
_checkboxCell = [[NSButtonCell alloc] init];
[_checkboxCell setButtonType:NSSwitchButton];
[_checkboxCell setTitle:@""];
[_checkboxCell setTarget:self];
[_checkboxCell setImagePosition:NSImageLeft];
[_checkboxCell setControlSize:NSRegularControlSize];
}
return self;
}
- copyWithZone:(NSZone *)zone {
MyCheckboxCellToo *cell = (MyCheckboxCellToo *)[super copyWithZone:zone];
cell->_checkboxCell = [_checkboxCell copyWithZone:zone];
return cell;
}
- (void)dealloc {
[_checkboxCell release];
[super dealloc];
}