NSStatusItem右键菜单

发布于 2024-11-26 05:37:14 字数 739 浏览 4 评论 0原文

我正在开发一个具有左键和右键单击功能的状态栏应用程序。我已经按照其他帖子的提示开始了这项工作,但我不确定如何在右键单击时显示菜单。

我使用子类 NSView 作为 NSStatusItem 的自定义视图,并通过右键单击和左键单击执行不同的功能:

- (void)mouseDown:(NSEvent *)theEvent{
    [super mouseDown:theEvent];
    if ([theEvent modifierFlags] & NSCommandKeyMask){
        [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
    }else{
        [self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
    }
}

- (void)rightMouseDown:(NSEvent *)theEvent{
    [super rightMouseDown:theEvent];
    [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}

如何在右键单击时显示菜单,就像标准 NSStatusItem 在左键单击时显示菜单一样?

I'm working on a status bar app that has a left and right click. I've got the start of this working by following the tips from other posts but I'm not sure how to go about showing a menu on right click.

I use a subclassed NSView as the custom view of my NSStatusItem and have the right and left clicks executing different functions:

- (void)mouseDown:(NSEvent *)theEvent{
    [super mouseDown:theEvent];
    if ([theEvent modifierFlags] & NSCommandKeyMask){
        [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
    }else{
        [self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
    }
}

- (void)rightMouseDown:(NSEvent *)theEvent{
    [super rightMouseDown:theEvent];
    [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}

How can I show a menu on right click, the same way the standard NSStatusItem does on left click?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

卖梦商人 2024-12-03 05:37:14

NSStatusItem popUpStatusItemMenu: 成功了。我通过右键单击操作调用它并传递我想要显示的菜单,它正在显示它!这不是我所期望的这个功能,但它正在工作。

这是我的代码的重要部分:

- (void)showMenu{
    // check if we are showing the highlighted state of the custom status item view
    if(self.statusItemView.clicked){
        // show the right click menu
        [self.statusItem popUpStatusItemMenu:self.rightClickMenu];
    }
}

// menu delegate method to unhighlight the custom status bar item view
- (void)menuDidClose:(NSMenu *)menu{ 
    [self.statusItemView setHighlightState:NO];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    // setup custom view that implements mouseDown: and rightMouseDown:
    self.statusItemView = [[ISStatusItemView alloc] init];
    self.statusItemView.image = [NSImage imageNamed:@"menu.png"];
    self.statusItemView.alternateImage = [NSImage imageNamed:@"menu_alt.png"];    
    self.statusItemView.target = self;
    self.statusItemView.action = @selector(mainAction);
    self.statusItemView.rightAction = @selector(showMenu);

    // set menu delegate
    [self.rightClickMenu setDelegate:self];

    // use the custom view in the status bar item
    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
    [self.statusItem setView:self.statusItemView];
}

这是自定义视图的实现:

@implementation ISStatusItemView

@synthesize image = _image;
@synthesize alternateImage = _alternateImage;
@synthesize clicked = _clicked;
@synthesize action = _action;
@synthesize rightAction = _rightAction;
@synthesize target = _target;

- (void)setHighlightState:(BOOL)state{
    if(self.clicked != state){
        self.clicked = state;
        [self setNeedsDisplay:YES];
    }
}

- (void)drawImage:(NSImage *)aImage centeredInRect:(NSRect)aRect{
    NSRect imageRect = NSMakeRect((CGFloat)round(aRect.size.width*0.5f-aImage.size.width*0.5f),
                                  (CGFloat)round(aRect.size.height*0.5f-aImage.size.height*0.5f),
                                  aImage.size.width, 
                                  aImage.size.height);
    [aImage drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}

- (void)drawRect:(NSRect)rect{
    if(self.clicked){
        [[NSColor selectedMenuItemColor] set];
        NSRectFill(rect);        
        if(self.alternateImage){
            [self drawImage:self.alternateImage centeredInRect:rect];
        }else if(self.image){
            [self drawImage:self.image centeredInRect:rect];
        }
    }else if(self.image){
        [self drawImage:self.image centeredInRect:rect];
    }
}

- (void)mouseDown:(NSEvent *)theEvent{
    [super mouseDown:theEvent];
    [self setHighlightState:!self.clicked];
    if ([theEvent modifierFlags] & NSCommandKeyMask){
        [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
    }else{
        [self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
    }
}

- (void)rightMouseDown:(NSEvent *)theEvent{
    [super rightMouseDown:theEvent];
    [self setHighlightState:!self.clicked];
    [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}

- (void)dealloc{
    self.target = nil;
    self.action = nil;
    self.rightAction = nil;
    [super dealloc];
}

@end

NSStatusItem popUpStatusItemMenu: did the trick. I am calling it from my right click action and passing in the menu I want to show and it's showing it! This is not what I would have expected this function to do, but it's working.

Here's the important parts of what my code looks like:

- (void)showMenu{
    // check if we are showing the highlighted state of the custom status item view
    if(self.statusItemView.clicked){
        // show the right click menu
        [self.statusItem popUpStatusItemMenu:self.rightClickMenu];
    }
}

// menu delegate method to unhighlight the custom status bar item view
- (void)menuDidClose:(NSMenu *)menu{ 
    [self.statusItemView setHighlightState:NO];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    // setup custom view that implements mouseDown: and rightMouseDown:
    self.statusItemView = [[ISStatusItemView alloc] init];
    self.statusItemView.image = [NSImage imageNamed:@"menu.png"];
    self.statusItemView.alternateImage = [NSImage imageNamed:@"menu_alt.png"];    
    self.statusItemView.target = self;
    self.statusItemView.action = @selector(mainAction);
    self.statusItemView.rightAction = @selector(showMenu);

    // set menu delegate
    [self.rightClickMenu setDelegate:self];

    // use the custom view in the status bar item
    self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
    [self.statusItem setView:self.statusItemView];
}

Here is the implementation for the custom view:

@implementation ISStatusItemView

@synthesize image = _image;
@synthesize alternateImage = _alternateImage;
@synthesize clicked = _clicked;
@synthesize action = _action;
@synthesize rightAction = _rightAction;
@synthesize target = _target;

- (void)setHighlightState:(BOOL)state{
    if(self.clicked != state){
        self.clicked = state;
        [self setNeedsDisplay:YES];
    }
}

- (void)drawImage:(NSImage *)aImage centeredInRect:(NSRect)aRect{
    NSRect imageRect = NSMakeRect((CGFloat)round(aRect.size.width*0.5f-aImage.size.width*0.5f),
                                  (CGFloat)round(aRect.size.height*0.5f-aImage.size.height*0.5f),
                                  aImage.size.width, 
                                  aImage.size.height);
    [aImage drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
}

- (void)drawRect:(NSRect)rect{
    if(self.clicked){
        [[NSColor selectedMenuItemColor] set];
        NSRectFill(rect);        
        if(self.alternateImage){
            [self drawImage:self.alternateImage centeredInRect:rect];
        }else if(self.image){
            [self drawImage:self.image centeredInRect:rect];
        }
    }else if(self.image){
        [self drawImage:self.image centeredInRect:rect];
    }
}

- (void)mouseDown:(NSEvent *)theEvent{
    [super mouseDown:theEvent];
    [self setHighlightState:!self.clicked];
    if ([theEvent modifierFlags] & NSCommandKeyMask){
        [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
    }else{
        [self.target performSelectorOnMainThread:self.action withObject:nil waitUntilDone:NO];
    }
}

- (void)rightMouseDown:(NSEvent *)theEvent{
    [super rightMouseDown:theEvent];
    [self setHighlightState:!self.clicked];
    [self.target performSelectorOnMainThread:self.rightAction withObject:nil waitUntilDone:NO];
}

- (void)dealloc{
    self.target = nil;
    self.action = nil;
    self.rightAction = nil;
    [super dealloc];
}

@end
美人如玉 2024-12-03 05:37:14

一种选择是假装鼠标左键按下:

- (void)rightMouseDown: (NSEvent *)event {
    NSEvent * newEvent;
    newEvent = [NSEvent mouseEventWithType:NSLeftMouseDown
                                  location:[event locationInWindow]
                             modifierFlags:[event modifierFlags]
                                 timestamp:CFAbsoluteTimeGetCurrent()
                              windowNumber:[event windowNumber]
                                   context:[event context]
                               eventNumber:[event eventNumber]
                                clickCount:[event clickCount]
                                  pressure:[event pressure]];
    [self mouseDown:newEvent];
}

One option is to just fake the left mouse down:

- (void)rightMouseDown: (NSEvent *)event {
    NSEvent * newEvent;
    newEvent = [NSEvent mouseEventWithType:NSLeftMouseDown
                                  location:[event locationInWindow]
                             modifierFlags:[event modifierFlags]
                                 timestamp:CFAbsoluteTimeGetCurrent()
                              windowNumber:[event windowNumber]
                                   context:[event context]
                               eventNumber:[event eventNumber]
                                clickCount:[event clickCount]
                                  pressure:[event pressure]];
    [self mouseDown:newEvent];
}
惯饮孤独 2024-12-03 05:37:14

当您在视图中需要标题时添加一些小东西

- (void)drawRect:(NSRect)rect{
    if(self.clicked){
        [[NSColor selectedMenuItemColor] set];
        NSRectFill(rect);
        if(self.alternateImage){
            [self drawImage:self.alternateImage centeredInRect:rect];
        }else if(self.image){
            [self drawImage:self.image centeredInRect:rect];
        } else {
            [self drawTitleInRect:rect];
        }
    } else if(self.image){
        [self drawImage:self.image centeredInRect:rect];
    } else {
        [self drawTitleInRect:rect];
    }

}

-(void)drawTitleInRect:(CGRect)rect
{
    CGSize size = [_title sizeWithAttributes:nil];

    CGRect newRect = CGRectMake(MAX((rect.size.width - size.width)/2.f,0.f),
                                MAX((rect.size.height - size.height)/2.f,0.f),
                                size.width,
                                size.height);

    NSDictionary *attributes = @{NSForegroundColorAttributeName : self.clicked?[NSColor highlightColor]:[NSColor textColor]
                                 };
    [_title drawInRect:newRect withAttributes:attributes];

}

Added little something for when you need title in your view

- (void)drawRect:(NSRect)rect{
    if(self.clicked){
        [[NSColor selectedMenuItemColor] set];
        NSRectFill(rect);
        if(self.alternateImage){
            [self drawImage:self.alternateImage centeredInRect:rect];
        }else if(self.image){
            [self drawImage:self.image centeredInRect:rect];
        } else {
            [self drawTitleInRect:rect];
        }
    } else if(self.image){
        [self drawImage:self.image centeredInRect:rect];
    } else {
        [self drawTitleInRect:rect];
    }

}

-(void)drawTitleInRect:(CGRect)rect
{
    CGSize size = [_title sizeWithAttributes:nil];

    CGRect newRect = CGRectMake(MAX((rect.size.width - size.width)/2.f,0.f),
                                MAX((rect.size.height - size.height)/2.f,0.f),
                                size.width,
                                size.height);

    NSDictionary *attributes = @{NSForegroundColorAttributeName : self.clicked?[NSColor highlightColor]:[NSColor textColor]
                                 };
    [_title drawInRect:newRect withAttributes:attributes];

}
人间☆小暴躁 2024-12-03 05:37:14
- (void)statusItemAction {
    NSEvent *event = NSApp.currentEvent;
    
    if (event.type == NSEventTypeRightMouseDown || (event.modifierFlags & NSEventModifierFlagControl)) {
        [self toggleMenu];
    } else {
        [self togglePopOver];
    }
}
- (void)statusItemAction {
    NSEvent *event = NSApp.currentEvent;
    
    if (event.type == NSEventTypeRightMouseDown || (event.modifierFlags & NSEventModifierFlagControl)) {
        [self toggleMenu];
    } else {
        [self togglePopOver];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文