Уволить пользовательское окно для NSStatusItem - PullRequest
1 голос
/ 22 июля 2011

При нажатии NSStatusItem появляется пользовательское окно. Код основан на MAAtachedwindow . Все работает отлично, но я не могу найти способ закрыть окно, когда пользователь нажимает на что-то еще, например на другой элемент строки состояния или другое приложение.

Вот мой код для создания окна:

    statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:width] retain];

    //setup custom status menu view
    CGFloat height = [[NSStatusBar systemStatusBar] thickness];
    NSRect viewFrame = NSMakeRect(0.0f, 0.0f, width, height);
    statusMenuView = [[[_ISStatusMenuView alloc] initWithFrame:viewFrame] retain];
    statusMenuView.offset = aOffset;
    statusItem.view = statusMenuView;

    //setup the window to show when clicked
    NSRect contentRect = NSZeroRect;
    contentRect.size = aView.frame.size;
    statusMenuWindow = [[[NSWindow alloc] initWithContentRect:contentRect
                                   styleMask:NSBorderlessWindowMask
                                     backing:NSBackingStoreBuffered 
                                       defer:NO] retain];

    [statusMenuWindow setLevel:NSPopUpMenuWindowLevel];
    [statusMenuWindow setBackgroundColor:[NSColor clearColor]];
    [statusMenuWindow setMovableByWindowBackground:NO];
    [statusMenuWindow setExcludedFromWindowsMenu:YES];
    [statusMenuWindow setOpaque:NO];
    [statusMenuWindow setHasShadow:NO];
    [statusMenuWindow useOptimizedDrawing:YES];
    [[statusMenuWindow contentView] addSubview:aView];
    [statusMenuWindow setDelegate:self];

    statusMenuView.statusMenuWindow = statusMenuWindow;

А вот как я показываю окно:

- (void)centerView{
    NSRect menuFrame = self.window.frame;
    NSRect windowFrame = self.statusMenuWindow.frame;
    NSPoint menuPoint = NSMakePoint(NSMidX(menuFrame), NSMinY(menuFrame));
    menuPoint.x -= windowFrame.size.width*0.5f;
    menuPoint.y -= windowFrame.size.height+self.offset;
    [self.statusMenuWindow setFrameOrigin:menuPoint];
    [self.statusMenuWindow makeKeyAndOrderFront:self];
}

Я надеялся, что метод делегата windowDidResignKey справится, но с этой конфигурацией он не сработает. Делегат работает, потому что windowDidMove работает.

- (void)windowDidResignKey:(NSNotification *)notification{
    NSLog(@"windowDidResignKey");
    [statusMenuView hideView];
}

- (void)windowDidResignMain:(NSNotification *)notification{
    NSLog(@"windowDidResignMain");
}

- (void)windowDidMove:(NSNotification *)notification{
    NSLog(@"windowDidMove");
}

Итак, напомним, как я могу скрыть свое пользовательское окно, когда пользователь нажимает на что-нибудь еще, как работают стандартные меню строки состояния?

Редактировать После просмотра примера Popup мне не хватало только одного: я должен был создать подкласс NSPanel и сделать его таким, чтобы он мог стать ключевым окном.

@interface Panel : NSPanel
@end

@implementation Panel

- (BOOL)canBecomeKeyWindow{
    return YES;
}

@end

1 Ответ

4 голосов
/ 22 июля 2011

Вы должны убедиться, что ваше окно может стать ключевым, и вызывать метод orderOut: вашего окна, когда он уходит в отставку.Вы должны использовать пользовательский NSWindowController, если вы этого еще не сделали, и в этом случае вы просто вызвали бы его метод "close", чтобы закрыть свое окно.

Вместо публикации группы кода, я бы предложил вам простопосмотрите на этот превосходный, недавно опубликованный пример присоединения окна к элементу состояния: Пример всплывающего окна Шпаковского

...