X-Git-Url: http://git.ithinksw.org/ITKit.git/blobdiff_plain/0fc44e732f98ed55cdd0d0914c4031ad9c005edc..810a7d925af4a7aea741e8319d9dddce5947710a:/ITStatusItem.m?ds=inline diff --git a/ITStatusItem.m b/ITStatusItem.m index ea31d3a..0978705 100644 --- a/ITStatusItem.m +++ b/ITStatusItem.m @@ -1,4 +1,59 @@ #import "ITStatusItem.h" +#import + +@interface ITStatusItemMenuProxy : NSProxy { + id menuProvider; + ITStatusItem *statusItem; + AbsoluteTime cachedTime; + NSMenu *menu; +} + +- (id)initWithMenuProvider:(id )provider statusItem:(ITStatusItem *)item; + +@end + +@implementation ITStatusItemMenuProxy + ++ (BOOL)respondsToSelector:(SEL)aSelector { + if (![super respondsToSelector:aSelector]) { + return [NSMenu respondsToSelector:aSelector]; + } + return YES; +} + +- (id)initWithMenuProvider:(id )provider statusItem:(ITStatusItem *)item { + menuProvider = [provider retain]; + statusItem = [item retain]; + cachedTime = UpTime(); + menu = nil; + return self; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation { + AbsoluteTime diff = SubAbsoluteFromAbsolute(UpTime(),cachedTime); + + if (!menu || diff.lo > 1000000) { + [menu release]; + menu = [[menuProvider menuForStatusItem:statusItem] retain]; + cachedTime = UpTime(); + } + + [anInvocation setTarget:menu]; + [anInvocation invoke]; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { + return [NSMenu instanceMethodSignatureForSelector:aSelector]; +} + +- (void)dealloc { + [menu release]; + [statusItem release]; + [menuProvider release]; + [super dealloc]; +} + +@end @class NSStatusBarButton; @@ -7,6 +62,11 @@ - (NSStatusBarButton *)_button; @end +@protocol _ITStatusItemNSStatusBarButtonMethods +- (NSMenu *)statusMenu; +- (void)setStatusMenu:(NSMenu *)menu; +@end + @protocol _ITStatusItemNSStatusItemPantherCompatability - (void)setAlternateImage:(NSImage *)image; - (NSImage *)alternateImage; @@ -28,6 +88,8 @@ static BOOL _ITStatusItemShouldKillShadow = NO; - (id)_initInStatusBar:(NSStatusBar *)statusBar withLength:(float)length withPriority:(int)priority { if ((self = [super _initInStatusBar:statusBar withLength:length withPriority:priority])) { + _menuProvider = nil; + _menuProxy = nil; if (_ITStatusItemShouldKillShadow) { [[(NSButton *)[self _button] cell] setType:NSNullCellType]; } @@ -51,4 +113,25 @@ static BOOL _ITStatusItemShouldKillShadow = NO; [(NSButton *)[self _button] setAlternateImage:image]; } +- (id )menuProvider { + return _menuProvider; +} + +- (void)setMenuProvider:(id )provider { + [_menuProxy autorelease]; + _menuProxy = nil; + _menuProvider = provider; + if (_menuProvider) { + _menuProxy = [[ITStatusItemMenuProxy alloc] initWithMenuProvider:_menuProvider statusItem:self]; + [(id <_ITStatusItemNSStatusBarButtonMethods>)[self _button] setStatusMenu:_menuProxy]; + } else { + [self setMenu:[self menu]]; + } +} + +- (void)dealloc { + [_menuProxy release]; + [super dealloc]; +} + @end \ No newline at end of file