I need a NSButton that gives me 2 events, one when the button is pressed down (NSOnState) and one when the button is released (NSOffState) and so far i've got it working with the mouse (intercepting the mouseDown: event). But using a keyboard shortcut doesn't work, it fires a NSOnState once and then after a delay really often. Is there any way to get a button that fires NSOnState when pressed and NSOffState when released?
My current subclass of NSButton looks like this and unfortunately works using a delegate:
-(void)awakeFromNib {
[self setTarget:self];
[self setAction:@selector(buttonAction:)];
}
-(void)mouseDown:(NSEvent *)theEvent {
[_delegate button:self isPressed:YES];
[super mouseDown:theEvent];
}
-(void)buttonAction:(id)sender {
[_delegate button:self isPressed:NO];
}
The button can be set to send mouse events at both times by using -sendActionOn:
:
[self.button sendActionOn: NSLeftMouseDownMask | NSLeftMouseUpMask];
Handling keyboard events similarly seems more difficult. If you don't need the event exactly at the same time the highlight is removed from the button, you could override NSButton's -performKeyEquivalent:
so that it will e.g. send the action twice.
- (BOOL) performKeyEquivalent: (NSEvent *) anEvent
{
if ([super performKeyEquivalent: anEvent])
{
[self sendAction: self.action to: self.target];
return YES;
}
return NO;
}
If you do need the event at the same time, I think you need to use a custom button cell (by creating a subclass of NSButtonCell and setting the button's cell in the initializer) and override its -highlight:withFrame:inView:
:
- (void)highlight:(BOOL)flag
withFrame:(NSRect)cellFrame
inView:(NSView *)controlView
{
[super highlight: flag withFrame:cellFrame inView:controlView];
if (flag)
{
// Action hasn't been sent yet.
}
else
{
// Action has been sent.
}
}