2010-10-12 48 views
2

我想在Objective-C中制作一个服务器监视器,其行为类似于OS X中的停靠栏。我希望让它从屏幕的侧面滑动当鼠标移动到屏幕的一侧时,有点像自动隐藏时打开的底座。我不知道从哪里开始虽然..重新实现Mac OS X Dock的自动隐藏

我猜我需要有一个NSBorderlessWindowMask面具的窗口,但之后,我不知所措。我是否只有1个像素的窗口显示,并等待mouseOver事件,或者这只是一个可以合理完成的事情的黑客解决方案?如果这是实现它的最佳方式,我将如何检查鼠标悬停事件?

回答

5

你有正确的想法,我想。请记住,尽管如此,取决于你想要做什么,无边界窗口并不是最容易处理的事情(它们可能会非常棘手,特别是空间和Exposé可能会增加的复杂性)。

如果这只是一个个人项目,那么您可能会失去显示窗口的一个像素边缘。如果这是一个专业项目,我会建议寻找使用事件点击(稍后更多)。

如果你走“个人项目”的方式,你可以离开窗口的1px边缘显示,使用一个自定义的NSView子类,它将自己绘制成透明的,并设置一个NSTrackingArea来通知你mouseEntered:events。

要绘制的透明区域,你可以做这样的事情在的drawRect:

- (void)drawRect:(NSRect)frame { 
    [[NSColor clearColor] set]; 
    NSRectFill(frame); 
} 

要建立一个跟踪区域,在您的视图子类做到这一点的awakeFromNib:

- (void)awakeFromNib { 
NSTrackingArea *tracker = [[[NSTrackingArea alloc] initWithRect:[self frame] 
    options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) 
    owner:self 
    userInfo:nil] autorelease]; 

[self addTrackingArea:tracker]; 
} 

- (void)mouseEntered:(NSEvent *)theEvent { 
[[[self window] windowController] showWindow:self]; 
} 

- (void)mouseExited:(NSEvent *)theEvent { 
[[[self window] windowController] myHideMethodName:self]; 
} 

这假定你重写了窗口控制器的showWindow:方法来做一个动画或其他)。顺便说一句,无论你做什么,都不要寻找鼠标移动的事件。 (对于您的情况,这不是什么大问题,因为您的区域可能会非常小,但一般来说,寻找鼠标移动的事件是错误的方法,因为它们可以快速填充事件队列。 Quartz Debug来查看大多数软件是如何实现的)。请记住,尽管视图可能会使其本身变得透明,但它仍然会阻止鼠标事件进入它下面的任何内容(可能是另一个窗口或桌面等)。

如果你想要去“专业”路线,你应该能够设置事件点击以基本完成跟踪区域代码所做的相同的事情。有了这条路线,您可以将窗口完全隐藏起来,以免干扰任何事情。为了了解事件丝锥是如何工作的,你可能需要下载以下两个应用程序:

http://brockerhoff.net/quay/

http://pfiddlesoft.com/eventtapstestbench/

首先是你如何使用事件阴凉例如水龙头来完成一些很酷的东西(阅读帮助以查看更多高级功能)。 Rainer使用事件点击来轻敲Dock以确定何时将鼠标移动到Dock左侧的项目上方。然后他可以显示他的自定义菜单,而不是Dock的内置菜单。

第二个应用程序将在检查Quay(或QuayMenu,真的)如何以及如何对其事件点击进行操作时不可或缺。

BTW,事件水龙头API是石英(以下是你用来建立一个事件自来水什么为例):

CFMachPortRef CGEventTapCreate (
    CGEventTapLocation tap, 
    CGEventTapPlacement place, 
    CGEventTapOptions options, 
    CGEventMask eventsOfInterest, 
    CGEventTapCallBack callback, 
    void *refcon 
); 

我不知道有足够的了解事件的水龙头自己举一个如何设置它的例子,但至少应该让你指向正确的方向。

希望这会有所帮助....