使用 NSMenu 上的箭头控制 NSStatusItem-Objective-C/Cocoa 的 NSSlider
我想创建一个状态项,其中有一个垂直滑块,很像苹果提供的声音控制。我的问题是:如何让它对向上/向下箭头键做出反应,就像声音菜单中的滑块一样?
我尝试创建一个 NSSlider 子类,当按下按键时,该子类会增加/减少其值(见下文),但我需要使其成为第一响应者。为了使其成为第一响应者,我将主类作为该菜单的委托,并添加了以下方法:
- (void)menuWillOpen: (NSMenu*)menu
{
if (menu == statusBarMenu) {
[THE_WINDOW_THAT_CONTAINS_THE_SLIDER makeFirstResponder: slider];
}
我应该调用哪个窗口?我应该以其他方式这样做吗?你会怎么做?
滑块子类:
#import <AppKit/AppKit.h>
@interface KeyRespondingSlider : NSSlider
@end
@implementation KeyRespondingSlider
- (BOOL)canBecomeKeyView
{
return YES;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)keyDown: (NSEvent*)theEvent
{
unsigned short keyCode = [theEvent keyCode];
if (keyCode == 126) { // up-arrow
[self setDoubleValue: [self doubleValue] + kChange];
}
else if (keyCode == 125) { // down-arrow
[self setDoubleValue: [self doubleValue] - kChange];
}
}
@end
我已经测试过它,当它是具有普通 NSWindow 的第一响应者时它可以工作。我只是无法使用状态栏项目中的菜单来做到这一点。
I would like to create a status item with a vertical slider in it, much like the sound control provided by Apple. My question is: how do I make it react to the up/down arrow keys, just like the slider in the sound menu?
I have tried to create a NSSlider subclass that would increase/decrease its value when the keys are pressed (see below), but I need to make it the first responder. To make it the first responder I made the main class the delegate of this menu and added this method:
- (void)menuWillOpen: (NSMenu*)menu
{
if (menu == statusBarMenu) {
[THE_WINDOW_THAT_CONTAINS_THE_SLIDER makeFirstResponder: slider];
}
Which window should I call? Should I do this any other way? How would you do this?
The slider subclass:
#import <AppKit/AppKit.h>
@interface KeyRespondingSlider : NSSlider
@end
@implementation KeyRespondingSlider
- (BOOL)canBecomeKeyView
{
return YES;
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)keyDown: (NSEvent*)theEvent
{
unsigned short keyCode = [theEvent keyCode];
if (keyCode == 126) { // up-arrow
[self setDoubleValue: [self doubleValue] + kChange];
}
else if (keyCode == 125) { // down-arrow
[self setDoubleValue: [self doubleValue] - kChange];
}
}
@end
I have tested it and it works when it is the first responder with a normal NSWindow. I just can't do it with a menu in a status bar item.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已经想通了。 Apple 使用名为 NSCarbonMenuWindow 的 NSWindow 子类来实现菜单。所以我收到了 menuWillOpen: 消息,我等待了一会儿菜单打开,我得到了最后一个窗口(刚刚创建的窗口 - 菜单窗口),并将滑块设置为第一个响应者。现在一切正常了!
I have figured it out. Apple uses a NSWindow subclass called
NSCarbonMenuWindow
for implementing menus. So I get the menuWillOpen: message, I wait a bit for the menu to open, I get the last window (the one created just now - menu window) and I make the slider the firstResponder. It all works now!