将鼠标光标更改为不活动的NSWindow

时间:2014-02-08 21:42:42

标签: macos cocoa mouse mouseover nswindow

我已经将NSWindow子类化了,我有一个MYWindow类实现了以下方法:

-(void)resetCursorRects {
    NSImage *image = [NSImage imageNamed:@"cursor.png"];
    [image setSize:NSMakeSize(32, 32)];
    NSCursor *cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(1, 1)];
    [super resetCursorRects];    
    [self addCursorRect:[self bounds] cursor:cursor];
}

这会改变整个窗口的光标,我会看到cursor.png而不是默认的鼠标指针。问题是,这只有在MYWindow设置为关键窗口时才有效,这当然是非常重要的。

在我的项目开始时我只有一个主窗口,但现在我需要有两个不同的MYWindow。两个窗口的问题是不能将它们都设置为关键窗口,因此自定义鼠标指针仅显示在活动窗口上。我需要单击另一个窗口才能显示光标。

这有什么办法吗?所以我在两个窗口上都有一个自定义光标?

编辑:尝试NSTrackingArea

我将此添加到我的内容视图的init方法:

self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame] options: (NSTrackingCursorUpdate | NSTrackingActiveAlways | NSTrackingMouseMoved) owner:self userInfo:nil];
[self addTrackingArea:self.trackingArea];

然后我重写了cursorUpdate:像这样:

-(void)cursorUpdate:(NSEvent *)event {
    NSLog(@"event : %@", event);
    [[NSCursor crosshairCursor] set];
}

这使得crosshairCursor在包含NSImageView派生类的NSWindow是关键窗口时显示。但是如果我在应用程序的关键窗口中创建另一个NSWindow,则光标会再次返回标准光标。我做错了吗?

2 个答案:

答案 0 :(得分:4)

您应该能够添加一个更改光标的NSTrackingArea,只要您不希望它在应用程序处于非活动状态时也发生变化(这基本上是不可能的)。


编辑:

我能够使用以下代码实现此目的:

- (vod)someSetup;
{
    NSTrackingArea *const trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:self userInfo:nil];
    [self.view addTrackingArea:trackingArea];
}

- (void)mouseEntered:(NSEvent *)theEvent;
{
    [[NSCursor IBeamCursor] push];
}

- (void)mouseExited:(NSEvent *)theEvent;
{
    [[NSCursor IBeamCursor] pop];
}

答案 1 :(得分:2)

现在我终于找到了一个有效的解决方案。我不知道将来是否会让我陷入困境,但至少在测试时这似乎有用。

感谢Wil的例子,它让我走了一半。但只有当我最终将它与resetCursorRects结合起来并且还在每个视图中使用特定光标定义了一个游标rect时。这花了我很长时间才弄清楚,我不知道解决方案是否是最优的(欢迎提出改进建议)

以下是最终使它适用于我的完整示例(self.cursor是游标的一个实例)

- (void)viewWillMoveToWindow:(NSWindow *)newWindow {
    NSTrackingArea *const trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
    [self.window invalidateCursorRectsForView:self];
}

- (void)resetCursorRects {
    [super resetCursorRects];
    [self addCursorRect:self.bounds cursor:self.cursor];
}

- (void)mouseEntered:(NSEvent *)theEvent {
    [super mouseEntered:theEvent];
    [self.cursor push];
}

- (void)mouseExited:(NSEvent *)theEvent {
    [super mouseExited:theEvent];
    [self.cursor pop];
}