gpt4 book ai didi

Swift:10.10 中的 NSStatusItem 菜单行为(例如,仅在鼠标右键单击时显示)

转载 作者:IT王子 更新时间:2023-10-29 05:43:59 24 4
gpt4 key购买 nike

我正在用 Swift 编写一个简单的状态栏应用程序,并尝试使用 OS X 10.10 中引入的新 NSStatusItem API。

我想要的界面是用鼠标左键单击 statusItem 来打开和关闭核心功能,用鼠标右键单击(或按住 control 单击)选项显示设置菜单。对于此功能,我不需要自定义 View 或弹出窗口。

默认情况下,如果将 NSMenu 分配给 NSStatusItem,它将在左键和右键单击时显示菜单。我想将行为更改为仅在右键单击时显示菜单,或者作为解决方法,防止在左键单击时弹出菜单

以前,似乎要控制 NSStatusItem 上的鼠标事件,必须设置一个具有覆盖鼠标事件的自定义 View (参见 this related question)。

在新的 NSStatusItem API在 10.10 中引入,设置自定义 View 的方法已被弃用,看起来不鼓励这种行为。根据@Taylor 在this answer应通过 statusItemObject.button() 返回的 NSStatusBarButton 对象使用一些已弃用的行为,但在撰写本文时,没有 NSStatusBarButton 的文档,并且返回的对象是只读的,不能用覆盖鼠标的自定义按钮替换事件处理程序。

有没有办法在一定程度上控制附加到 NSStatusItem(或 NSStatusBarButton)的 NSMenu 是否针对鼠标事件显示?

最佳答案

这是我想出的解决方案。它工作得相当好,尽管有一件事我不满意:在右键单击菜单中选择一个选项后,状态项保持突出显示。一旦您与其他事物互动,突出显示就会消失。

另请注意,自 OS X 10.10 (Yosemite) 起,popUpStatusItemMenu: 已“温和弃用”,并将在未来的版本中正式弃用。现在,它可以工作并且不会给你任何警告。希望我们在正式弃用之前有一个完全支持的方法来做到这一点——我建议 filing a bug report如果你同意。

首先您需要一些属性和一个枚举:

typedef NS_ENUM(NSUInteger,JUNStatusItemActionType) {
JUNStatusItemActionNone,
JUNStatusItemActionPrimary,
JUNStatusItemActionSecondary
};

@property (nonatomic, strong) NSStatusItem *statusItem;
@property (nonatomic, strong) NSMenu *statusItemMenu;
@property (nonatomic) JUNStatusItemActionType statusItemAction;

然后在某些时候你会想要设置状态项:

NSStatusItem *item = [[NSStatusBar systemStatusBar] statusItemWithLength:29.0];
NSStatusBarButton *button = item.button;
button.image = [NSImage imageNamed:@"Menu-Icon"];
button.target = self;
button.action = @selector(handleStatusItemAction:);
[button sendActionOn:(NSLeftMouseDownMask|NSRightMouseDownMask|NSLeftMouseUpMask|NSRightMouseUpMask)];
self.statusItem = item;

然后你只需要处理状态项按钮发送的 Action :

- (void)handleStatusItemAction:(id)sender {

const NSUInteger buttonMask = [NSEvent pressedMouseButtons];
BOOL primaryDown = ((buttonMask & (1 << 0)) != 0);
BOOL secondaryDown = ((buttonMask & (1 << 1)) != 0);
// Treat a control-click as a secondary click
if (primaryDown && ([NSEvent modifierFlags] & NSControlKeyMask)) {
primaryDown = NO;
secondaryDown = YES;
}

if (primaryDown) {
self.statusItemAction = JUNStatusItemActionPrimary;
} else if (secondaryDown) {
self.statusItemAction = JUNStatusItemActionSecondary;
if (self.statusItemMenu == nil) {
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
[menu addItemWithTitle:NSLocalizedString(@"Quit",nil) action:@selector(terminate:) keyEquivalent:@""];
self.statusItemMenu = menu;
}
[self.statusItem popUpStatusItemMenu:self.statusItemMenu];
} else {
self.statusItemAction = JUNStatusItemActionNone;
if (self.statusItemAction == JUNStatusItemActionPrimary) {
// TODO: add whatever you like for the primary action here
}
}

}

所以基本上,handleStatusItemAction: 在鼠标按下和鼠标弹起时为两个鼠标按钮调用。当按钮按下时,它会跟踪它是应该执行主要操作还是次要操作。如果它是次要操作,则会立即处理,因为菜单通常出现在鼠标按下时。如果它是主要操作,则在鼠标松开时处理。

关于Swift:10.10 中的 NSStatusItem 菜单行为(例如,仅在鼠标右键单击时显示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26924454/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com