Reputation: 721
In hopes of creating a rollover effect on a button, I created a subclass of NSButton called Button.
Button.h:
#import <AppKit/AppKit.h>
@interface Button : NSButton {
}
- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
- (void)mouseDown:(NSEvent *)ev;
- (void)mouseUp:(NSEvent *)theEvent;
@end
Button.m: #import "Button.h"
@implementation Button
- (id)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if(self != nil) {
NSLog(@"btn init");
}
return self;
}
- (void)mouseEntered:(NSEvent *)theEvent{
NSLog(@"mouseEntered");
[self setImage:[NSImage imageNamed:@"lockIcon_2.png"]];
[self setNeedsDisplay];
}
- (void)mouseExited:(NSEvent *)theEvent{
[self setImage:[NSImage imageNamed:@"lockIcon_1.png"]];
NSLog(@"mouseExited");
[self setNeedsDisplay];
}
- (void)mouseDown:(NSEvent *)ev {
NSLog(@"mouseDown!");
}
- (void)mouseUp:(NSEvent *)ev {
NSLog(@"mouseUp!");
}
@end
With the code above, every time I click on a button I see "mouseDown" in the logs, but I don't see "mouseEntered" nor "mouseExited" (and of course don't see the image change)?? Sadly, I know I'm missing something obvious, but I'm just not seeing it... ???
Upvotes: 11
Views: 4361
Reputation: 3028
While setting up a tracking area is definitely a way to do this, NSButton
/NSButtonCell
already have this functionality built in.
Check out NSButton's showsBorderOnlyWhileMouseInside
, and the corresponding NSButtonCell's mouseEntered
and mouseExited
. It is documented here:
Depending on your use-case, this may or may not work. For me, I was subclassing NSButtonCell anyways, so it was perfect. One thing to be aware of is it also affects calls to drawBezel
.
Upvotes: 1
Reputation: 1682
The problem is that NSButton can handle some mouse events only if you add your custom NSTrackingArea to button.
Try to add this code in your button class. It helped me. Also you can play with options if they not satisfied you.
- (void)createTrackingArea
{
NSTrackingAreaOptions focusTrackingAreaOptions = NSTrackingActiveInActiveApp;
focusTrackingAreaOptions |= NSTrackingMouseEnteredAndExited;
focusTrackingAreaOptions |= NSTrackingAssumeInside;
focusTrackingAreaOptions |= NSTrackingInVisibleRect;
NSTrackingArea *focusTrackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
options:focusTrackingAreaOptions owner:self userInfo:nil];
[self addTrackingArea:focusTrackingArea];
}
- (void)awakeFromNib
{
[self createTrackingArea];
}
Hope it helps.
Upvotes: 24