Adding support for menu providers to ITStatusItem using NSProxy subclass.
[ITKit.git] / ITStatusItem.m
index ea31d3a..d4e078a 100644 (file)
@@ -1,5 +1,51 @@
 #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)
@@ -51,4 +97,18 @@ static BOOL _ITStatusItemShouldKillShadow = NO;
        [(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