Какао / OSX - NSWindow standardWindowButton ведет себя странно, когда копируется и добавляется снова - PullRequest
11 голосов
/ 03 октября 2011

В моем приложении я меняю положение стандартных оконных кнопок закрытия / миниатюризации / расширения следующим образом:

 //Create the buttons
    NSButton *minitButton = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:window.styleMask];
NSButton *closeButton = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:window.styleMask];
NSButton *fullScreenButton = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:window.styleMask];


//set their location
[closeButton setFrame:CGRectMake(7+70, window.frame.size.height - 22 - 52, closeButton.frame.size.width, closeButton.frame.size.height)];
[fullScreenButton setFrame:CGRectMake(47+70, window.frame.size.height - 22 -52, fullScreenButton.frame.size.width, fullScreenButton.frame.size.height)];
[minitButton setFrame:CGRectMake(27+70, window.frame.size.height - 22 - 52, minitButton.frame.size.width, minitButton.frame.size.height)];

//add them to the window
[window.contentView addSubview:closeButton];
[window.contentView addSubview:fullScreenButton];
[window.contentView addSubview:minitButton];

Теперь, когда появляется окно с кнопками, возникает две проблемы: 1. они серые и не правильного цвета 2. когда мышь находится над ними, они не показывают знак + - или x

Может кто-нибудь сказать мне, что я делаю не так. Спасибо.

Ответы [ 4 ]

10 голосов
/ 23 мая 2015

Вот механизм этой парящей магии: перед тем, как нарисовать саму стандартную кнопку в кружке (например, NSWindowMiniaturizeButton), вызывается их superview недокументированный метод _mouseInGroup:.Если этот метод возвращает YES кнопка обведена в кружок со значком внутри.Вот и все.

Если вы разместите эти кнопки внутри своего собственного представления, вы можете просто реализовать этот метод и управлять этим появлением при наведении курсора мыши, как вы хотите.Если вы просто перемещаете или ретранслируете эти кнопки, и они по-прежнему имеют значение subview с NSThemeFrame (или что-то подобное), вам придется воспользоваться методом _mouseInGroup: для этого класса, и, вероятно, оно того не стоит, потому что у нас отличнопростой предыдущий метод.

В моем случае у меня есть пользовательский NSView, который содержит мои стандартные кнопки как subview s, и этот код превращает все описанное выше в магию:

- (void)updateTrackingAreas
{
    NSTrackingArea *const trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:self userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void)mouseEntered:(NSEvent *)event
{
    [super mouseEntered:event];
    self.mouseInside = YES;
    [self setNeedsDisplayForStandardWindowButtons];
}

- (void)mouseExited:(NSEvent *)event
{
    [super mouseExited:event];
    self.mouseInside = NO;
    [self setNeedsDisplayForStandardWindowButtons];
}

- (BOOL)_mouseInGroup:(NSButton *)button
{
    return self.mouseInside;
}

- (void)setNeedsDisplayForStandardWindowButtons
{
    [self.closeButtonView setNeedsDisplay];
    [self.miniaturizeButtonView setNeedsDisplay];
    [self.zoomButtonView setNeedsDisplay];
}
1 голос
/ 29 марта 2016

Я полностью осознаю, что этот вопрос старый и Валентин Шергин ответ - правильный .Он предотвращает использование любого частного API , в отличие от , который Google сделал в Chrome .Просто хотел поделиться методом для тех, кто не чувствует себя подклассом NSView, просто поместить эти кнопки в существующее представление (например, self.window.contentView).

Как я только хотел изменить положение NSWindowButton s через setFrame:, я обнаружил, что как только окно было изменено в размере , области отслеживания, кажется, " fix " сами автоматически , безлюбое использование частного API (по крайней мере, в 10.11).

Таким образом, вы можете сделать что-то вроде следующего, чтобы применить " fake resize " к окну, в котором вы переместили свои кнопки:

NSRect frame = [self.window frame];
frame.size = NSMakeSize(frame.size.width, frame.size.height+1.f);
[self.window setFrame:frame display:NO animate:NO];
frame.size = NSMakeSize(frame.size.width, frame.size.height-1.f);
[self.window setFrame:frame display:NO animate:YES];

(я сделал это в главном окне NSWindowDelegate windowDidBecomeMain:. Должно работать, пока окно загружено и видно .)

0 голосов
/ 02 июля 2013

Вы не добавите их снова.Вы перемещаете их в contentView.Кнопки изначально находятся в window.contentView.superview.

[window.contentView.superview addSubview:closeButton];
[window.contentView.superview addSubview:fullScreenButton];
[window.contentView.superview addSubview:minitButton];

Должны получить правильное поведение без отслеживания области.

0 голосов
/ 24 декабря 2011

Звоните [button highlight:yes] для каждой кнопки.

...