[awake app] 自定义StatusItemView
源码已经放在github上
左击切换状态,右击显示菜单;但是NSStatusItem没有提供右键菜单,所以要定义自己的View;若果需要直接方便使用的话,有开源框架RHStatusItemView,引入项目中就可以用了。下面是我自己实现的:
//
// StatusItemView.h
// awake
//
// Created by xiaozi on 14-2-21.
// Copyright (c) 2014年 xiaozi. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface StatusItemView : NSControl <NSMenuDelegate>{
NSImage *_image;
NSImage *_alternateImage;
NSStatusItem *_statusItem;
BOOL _isHighlighted;
SEL _action;
SEL _rightAction;
id __unsafe_unretained _target;
}
@property (nonatomic, readonly) NSStatusItem *statusItem;
@property (nonatomic, strong) NSImage *image;
@property (nonatomic, strong) NSImage *alternateImage;
@property (nonatomic, setter = setHighlighted:) BOOL isHighlighted;
@property (nonatomic) SEL action;
@property (nonatomic) SEL rightAction;
@property (nonatomic, unsafe_unretained) id target;
- (id) initWithStatusItem: (NSStatusItem *) statusItem;
@end
//
// StatusItemView.m
// awake
//
// Created by xiaozi on 14-2-21.
// Copyright (c) 2014年 xiaozi. All rights reserved.
//
#import "StatusItemView.h"
@implementation StatusItemView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void) drawRect:(NSRect)dirtyRect
{
[_statusItem drawStatusBarBackgroundInRect:dirtyRect withHighlight:_isHighlighted];
NSImage *icon = _isHighlighted ? _alternateImage : _image;
NSSize iconSize = [icon size];
NSRect bounds = [self bounds];
CGFloat iconX = roundf((NSWidth(bounds) - iconSize.width) / 2);
CGFloat iconY = roundf((NSHeight(bounds) - iconSize.height) / 2);
NSPoint iconPoint = NSMakePoint(iconX, iconY);
[icon drawAtPoint:iconPoint fromRect:bounds operation:NSCompositeSourceOver fraction:1.0];
}
- (id) initWithStatusItem: (NSStatusItem *) statusItem {
CGFloat itemWidth = [statusItem length];
CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
self = [self initWithFrame:itemRect];
if (self != nil)
{
_statusItem = statusItem;
[_statusItem setView: self];
}
return self;
}
- (void)setMenu:(NSMenu *) menu {
[menu setDelegate: self];
[super setMenu: menu];
}
- (void)setHighlighted:(BOOL)newFlag
{
if (_isHighlighted == newFlag) return;
_isHighlighted = newFlag;
[self setNeedsDisplay:YES];
}
- (void)mouseDown:(NSEvent *)theEvent
{
[NSApp sendAction:_action to:_target from:self];
}
- (void)rightMouseDown:(NSEvent *)theEvent
{
NSMenu *menu = [super menu];
[_statusItem popUpStatusItemMenu:menu];
[NSApp sendAction:_rightAction to:_target from:self];
}
- (void)menuWillOpen:(NSMenu *)menu {
[self setHighlighted:YES];
[self setNeedsDisplay:YES];
}
- (void)menuDidClose:(NSMenu *)menu {
[self setHighlighted:NO];
[self setNeedsDisplay:YES];
}
- (void)setImage:(NSImage *)newImage
{
_image = newImage;
[self setNeedsDisplay: YES];
}
- (void)setAlternateImage:(NSImage *)newImage
{
_alternateImage = newImage;
if (_isHighlighted)
[self setNeedsDisplay:YES];
}
- (BOOL)isOpaque
{
return YES;
}
@end
具体使用方法:
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength: 22.0];
[statusItem setHighlightMode:YES];
statusView = [[StatusItemView alloc] initWithStatusItem: statusItem];
[statusView setMenu: statusMenu];
// [statusItem setView: statusView];
[statusView setImage: [NSImage imageNamed:@"MenuIcon"]];
[statusView setAlternateImage: [NSImage imageNamed:@"MenuIconSelected"]];
[statusView setAction: @selector(clickStatusItem:)];