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 |
会被调用,所有的鼠标左键事情比如mouseDragged,mouseUp等都会被放到一个队列中,可以通过
1 |
指定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]; } |