Okay, here is the problem:
I have a NSTextView
and I add my custom NSButton
using:
[_textView addSubview:button];
Then, inside my NSButton
subclass, I have (along with the NSTrackingArea
stuff):
- (void)mouseEntered:(NSEvent *)event{
[[NSCursor arrowCursor] set];
}
- (void)mouseExited:(NSEvent *)theEvent{
[[NSCursor arrowCursor] set];
}
- (void)mouseDown:(NSEvent *)theEvent{
[[NSCursor arrowCursor] set];
}
- (void)mouseUp:(NSEvent *)theEvent{
[[NSCursor arrowCursor] set];
}
But when I hover it, the cursor remains the same IBeamCursor
(because it's a NSTextView
). Only when I press the button, the cursor gets updated. And then, when I move the mouse, still inside the button, the cursor goes back to the IBeamCursor
.
Any ideas on how to do this? Thank you!
Adding a tracking area that only tracks enter/exit events seems to be not enough for NSTextView
subviews. Somehow the textview always wins and sets it's IBeamCursor
.
You can try to always enable tracking for mouse move events (NSTrackingMouseMoved
) when adding the tracking area in your NSButton
subclass:
#import "SSWHoverButton.h"
@interface SSWHoverButton()
{
NSTrackingArea* trackingArea;
}
@end
@implementation SSWHoverButton
- (void)mouseMoved:(NSEvent*)theEvent
{
[[NSCursor arrowCursor] set];
}
- (void)updateTrackingAreas
{
if(trackingArea != nil)
{
[self removeTrackingArea:trackingArea];
}
NSTrackingAreaOptions opts = (NSTrackingMouseMoved|NSTrackingActiveAlways);
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)dealloc
{
[self removeTrackingArea:trackingArea];
}
@end
Swift 5 variant:
import Cocoa
class InsideTextButton: NSButton {
var trackingArea: NSTrackingArea?
override func mouseMoved(with event: NSEvent) {
NSCursor.arrow.set()
}
override func updateTrackingAreas() {
if let area = trackingArea {
removeTrackingArea(area)
}
trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseMoved, .activeAlways], owner: self, userInfo: nil)
if let area = trackingArea {
addTrackingArea(area)
}
}
deinit {
if let area = trackingArea {
removeTrackingArea(area)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With