2011-07-25 256 views
4

我正在使用左右兩側的狀態欄應用程序。我已經從其他帖子的提示開始工作,但我不知道如何去右鍵單擊顯示菜單。NSStatusItem右鍵單擊菜單

我用一個子類的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菜單左鍵單擊?

回答

19

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 
+2

你答案的好處是它解決了我完全不相關的問題:)謝謝。 如果NSStatusItem具有菜單集,則不會在目標上調用該操作。因此,我無法設置NSMenu,然後使用popUpStatusItemMenu方法顯示菜單:) – Mazyod

3

一種選擇是隻假鼠標左鍵向下:

- (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]; 
} 
+0

非常棘手,但我不認爲這會對我有用,因爲我的左鍵單擊運行交流並沒有顯示菜單。 – keegan3d

+0

是的,我的代碼和描述有點困惑 - 你現在怎麼顯示菜單? –

+0

對不起,我經過了更多的挖掘和試驗後纔開始工作。感謝您的摘錄,我確信這會在一天內有用:) – keegan3d

0

增加了一點東西,因爲當你需要的標題在你看來

- (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]; 

} 
+0

您是否想要回答不同的問題?這個問題是關於當狀態項被右鍵單擊時顯示一個彈出菜單。 –

+0

也許它應該作爲評論(深夜coindg)。這是被接受的答案的一點補充。認爲它可能有助於某個人,有一天。 –