Adding support for menu providers to ITStatusItem using NSProxy subclass.
[ITKit.git] / ITStatusItem.m
index b758d5c..d4e078a 100644 (file)
@@ -1,5 +1,51 @@
 #import "ITStatusItem.h"
 
 #import "ITStatusItem.h"
 
+@interface ITStatusItemMenuProxy : NSProxy {
+       id <ITStatusItemMenuProvider> menuProvider;
+       ITStatusItem *statusItem;
+}
+
+- (id)initWithMenuProvider:(id <ITStatusItemMenuProvider>)provider statusItem:(ITStatusItem *)item;
+
+@end
+
+@implementation ITStatusItemMenuProxy
+
++ (BOOL)respondsToSelector:(SEL)aSelector {
+       if (![super respondsToSelector:aSelector]) {
+               return [NSMenu respondsToSelector:aSelector];
+       }
+       return YES;
+}
+
+- (id)initWithMenuProvider:(id <ITStatusItemMenuProvider>)provider statusItem:(ITStatusItem *)item {
+       menuProvider = [provider retain];
+       statusItem = [item retain];
+       return self;
+}
+
+- (void)forwardInvocation:(NSInvocation *)anInvocation {
+       NSMenu *temporaryMenu = [[menuProvider menuForStatusItem:statusItem] retain];
+       [anInvocation setTarget:temporaryMenu];
+       [anInvocation invoke];
+       [temporaryMenu release];
+}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
+       NSMenu *temporaryMenu = [[menuProvider menuForStatusItem:statusItem] retain];
+       NSMethodSignature *signature = [temporaryMenu methodSignatureForSelector:aSelector];
+       [temporaryMenu release];
+       return signature;
+}
+
+- (void)dealloc {
+       [statusItem release];
+       [menuProvider release];
+       [super dealloc];
+}
+
+@end
+
 @class NSStatusBarButton;
 
 @interface NSStatusItem (ITStatusItemHacks)
 @class NSStatusBarButton;
 
 @interface NSStatusItem (ITStatusItemHacks)
@@ -27,13 +73,13 @@ static BOOL _ITStatusItemShouldKillShadow = NO;
 }
 
 - (id)_initInStatusBar:(NSStatusBar *)statusBar withLength:(float)length withPriority:(int)priority {
 }
 
 - (id)_initInStatusBar:(NSStatusBar *)statusBar withLength:(float)length withPriority:(int)priority {
-    if ((self = [super _initInStatusBar:statusBar withLength:length withPriority:priority])) {
+       if ((self = [super _initInStatusBar:statusBar withLength:length withPriority:priority])) {
                if (_ITStatusItemShouldKillShadow) {
                        [[(NSButton *)[self _button] cell] setType:NSNullCellType];
                }
                if (_ITStatusItemShouldKillShadow) {
                        [[(NSButton *)[self _button] cell] setType:NSNullCellType];
                }
-        [self setHighlightMode:YES];
-    }
-    return self;
+           [self setHighlightMode:YES];
+       }
+       return self;
 }
 
 - (NSImage *)alternateImage {
 }
 
 - (NSImage *)alternateImage {
@@ -48,7 +94,21 @@ static BOOL _ITStatusItemShouldKillShadow = NO;
                [(id <_ITStatusItemNSStatusItemPantherCompatability>)super setAlternateImage:image];
                return;
        }
                [(id <_ITStatusItemNSStatusItemPantherCompatability>)super setAlternateImage:image];
                return;
        }
-    [(NSButton *)[self _button] setAlternateImage:image];
+       [(NSButton *)[self _button] setAlternateImage:image];
+}
+
+- (id <ITStatusItemMenuProvider>)menuProvider {
+       return _menuProvider;
+}
+
+- (void)setMenuProvider:(id <ITStatusItemMenuProvider>)provider {
+       [_menuProvider autorelease];
+       _menuProvider = [provider retain];
+       if (provider) {
+               [self setMenu:[[ITStatusItemMenuProxy alloc] initWithMenuProvider:_menuProvider statusItem:self]];
+       } else {
+               [self setMenu:nil];
+       }
 }
 
 @end
\ No newline at end of file
 }
 
 @end
\ No newline at end of file