X-Git-Url: http://git.ithinksw.org/ITKit.git/blobdiff_plain/32440a12defde03dcc52e42cff4aa6300d7d96fb..11c398c047d4e737a59c70f13de3cde3a788810a:/ITStatusItem.m?ds=sidebyside diff --git a/ITStatusItem.m b/ITStatusItem.m old mode 100755 new mode 100644 index 5e517a0..fade99c --- a/ITStatusItem.m +++ b/ITStatusItem.m @@ -1,99 +1,137 @@ #import "ITStatusItem.h" +#import -/*************************************************************************/ -#pragma mark - -#pragma mark EVIL HACKERY -/*************************************************************************/ +@interface ITStatusItemMenuProxy : NSProxy { + id menuProvider; + ITStatusItem *statusItem; + AbsoluteTime cachedTime; + NSMenu *menu; +} -// This stuff is actually implemented by the AppKit. -// We declare it here to cancel out warnings. +- (id)initWithMenuProvider:(id )provider statusItem:(ITStatusItem *)item; -@interface NSStatusBarButton : NSButton @end -@interface NSStatusItem (HACKHACKHACKHACK) -- (id) _initInStatusBar:(NSStatusBar*)statusBar - withLength:(float)length - withPriority:(int)priority; -- (NSStatusBarButton*) _button; +@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 -/*************************************************************************/ -#pragma mark - -#pragma mark PRIVATE METHOD DECLARATIONS -/*************************************************************************/ +@class NSStatusBarButton; -@interface ITStatusItem (Private) -- (void) setSmallTitle:(NSString*)title; +@interface NSStatusItem (ITStatusItemHacks) +- (id)_initInStatusBar:(NSStatusBar *)statusBar withLength:(float)length withPriority:(int)priority; +- (NSStatusBarButton *)_button; @end -@implementation ITStatusItem +@protocol _ITStatusItemNSStatusBarButtonMethods +- (NSMenu *)statusMenu; +- (void)setStatusMenu:(NSMenu *)menu; +@end -/*************************************************************************/ -#pragma mark - -#pragma mark INITIALIZATION METHODS -/*************************************************************************/ - -- (id)initWithStatusBar:(NSStatusBar*)statusBar withLength:(float)length -{ - if ( ( self = [super _initInStatusBar:statusBar - withLength:length - withPriority:1000] ) ) { - - //Eliminate the fucking shadow... - [[[self _button] cell] setType:NSNullCellType]; - - //Be something other than a dumbshit about highlighting... - [self setHighlightMode:YES]; - } - return self; -} +@protocol _ITStatusItemNSStatusItemPantherCompatability +- (void)setAlternateImage:(NSImage *)image; +- (NSImage *)alternateImage; +@end +@implementation ITStatusItem -/*************************************************************************/ -#pragma mark - -#pragma mark ACCESSOR METHODS -/*************************************************************************/ +static BOOL _ITStatusItemShouldKillShadow = NO; -- (NSImage*) alternateImage { - return [[self _button] alternateImage]; ++ (void)initialize { + if ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_1) && (floor(NSAppKitVersionNumber) <= 663.6)) { + _ITStatusItemShouldKillShadow = YES; + } } -- (void) setAlternateImage:(NSImage*)image { - [[self _button] setAlternateImage:image]; +- (id)initWithStatusBar:(NSStatusBar *)statusBar withLength:(float)length { + return [self _initInStatusBar:statusBar withLength:length withPriority:1000]; } -- (void) setImage:(NSImage*)image { - [super setImage:image]; - if ([self title]) { - [self setSmallTitle:[self title]]; - } +- (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]; + } + [self setHighlightMode:YES]; + } + return self; } -- (NSString*) title { - if ([self image]) { - return [[self attributedTitle] string]; - } else { - [super title]; - } +- (NSImage *)alternateImage { + if ([super respondsToSelector:@selector(alternateImage)]) { + return [super alternateImage]; + } + return [(NSButton *)[self _button] alternateImage]; } -- (void) setTitle:(NSString*)title { - [super setTitle:title]; - if ([self image]) { - [self setSmallTitle:[self title]]; - } +- (void)setAlternateImage:(NSImage*)image { + if ([super respondsToSelector:@selector(setAlternateImage:)]) { + [super setAlternateImage:image]; + return; + } + [(NSButton *)[self _button] setAlternateImage:image]; } -/*************************************************************************/ -#pragma mark - -#pragma mark PRIVATE METHODS -/*************************************************************************/ +- (id )menuProvider { + return _menuProvider; +} -- (void) setSmallTitle:(NSString*)title { - NSAttributedString *attrTitle = [[NSAttributedString alloc] initWithString:title attributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Lucida Grande" size:12.0] forKey:NSFontAttributeName]]; - [self setAttributedTitle:attrTitle]; - [attrTitle release]; +- (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]]; + } } -@end +- (void)dealloc { + [_menuProxy release]; + [super dealloc]; +} + +@end \ No newline at end of file