NSButton With Hover and Active States

如果我想要一个按钮有三种不同的状态:普通状态,鼠标移上去的状态,以及鼠标按下去的状态

首先这是一个功能按钮,按下去会触发相应的动作,比如弹出一个新的窗口。
NSButton 支持设置图片,且可以分别位普通状态和alternate状态(按下去的状态)设置图片,如果你没有设置alternate状态的图片,则按下的时候则显示的比之前的暗些。

1
2
– setImage:
– setAlternateImage:

为了实现既定的效果,大体的思路是这样的:
1.当鼠标不在按钮上的时候 按钮设置成普通按钮图片
2.当鼠标移到按钮上的时候 按钮设置成hover状态的图片
3.按钮被按下的时候,就使用默认的变暗效果(在hover的基础上变暗)

所以这个时候关键问题变成如何去”订阅”鼠标移到按钮内部以及移出按钮内部的事件消息!
并在相应的响应函数中作出相应的图片设置显示操作。

Mouse Event

NSButton使用的使用的鼠标事件处理方式为 “The Mouse-Tracking Loop Approach”
就是只有NSButton的

1
- (void)mouseDown:(NSEvent *)theEvent;

会被调用,所有的鼠标左键事情比如mouseDragged,mouseUp等都会被放到一个队列中,可以通过

1
- (NSEvent *)nextEventMatchingMask:(NSUInteger)mask untilDate:(NSDate *)expiration inMode:(NSString *)mode dequeue:(BOOL)flag

指定mask(比如NSLeftMouseUpMask,NSLeftMouseDraggedMask)获得事情队列中的指定事件.然后对事情做相应的处理。
不过貌似对于hover的效果无需考虑mouseUp和mouseDrag的事件.

TrackingArea

我们要找的是鼠标移到按钮区域内和移出按钮区域内的事件.
所以找到了“Using Tracking-Area Objects”
这个的方式也蛮简单,

1
- (void)updateTrackingAreas;

继承上面的方法,为当前按钮添加一个Tracking-Area,其实就是设置一个控件内的矩形区域以及设置如何跟踪(比如设置跟踪的event NSTrackingMouseEnteredAndExited,NSTrackingMouseMoved,NSTrackingCursorUpdate,设置跟踪的时机 NSTrackingActiveWhenFirstResponder ….).
设置好了之后相应的函数便可以在相应的事件触发后得到响应了。

实现的关键代码片段,继承NSButton

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (void)setNormalImage:(NSImage *)image{
    if (normalImage) {
        [normalImage release];
    }
    normalImage = [image retain];
    [self setImage:normalImage];
}

- (void)updateTrackingAreas
{
    [super updateTrackingAreas];
   
    if (trackingArea)
    {
        [self removeTrackingArea:trackingArea];
        [trackingArea release];
    }
   
    NSTrackingAreaOptions options = NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp;
    trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:options owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void)mouseEntered:(NSEvent *)event
{
    [self setImage:hoverImage];
}

- (void)mouseExited:(NSEvent *)event
{
    [self setImage:normalImage];
}

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>