2011-10-03 15 views
11

añadido en mi aplicación puedo cambiar la posición de los standardWindowButtons cerrar/miniturize/ampliar de este modo:Cacao/OSX - NSWindow standardWindowButton comporta de forma extraña, una vez copiado y otra vez

//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]; 

Ahora, cuando la ventana aparece con los botones allí hay dos problemas: 1. Son de color gris y no su color correcto 2. cuando el mouse está sobre ellos no muestran el signo + - o x

alguien me puede decir lo que estoy haciendo mal. Gracias.

Respuesta

-1

Llame [button highlight:yes] para cada botón.

+7

Tristemente '[botón resaltado: YES]' solo dibuja el estado "presionado" del botón de la ventana ([referencia] (http://www.cocoabuilder.com) /archive/cocoa/76398-standardwindowbuttons.html)). No sé de una manera aún de dibujar el estado "hover". – rentzsch

0

No las va a agregar de nuevo. Los está moviendo a contentView. Los botones están originalmente en window.contentView.superview.

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

usted debe conseguir el comportamiento correcto sin necesidad de un trackingArea.

10

Aquí está la mecánica de esta magia de vuelo estacionario: Antes de dibujarse un botón con un círculo estándar (como NSWindowMiniaturizeButton) llama a su superview método no documentado _mouseInGroup:. Si este método devuelve YES, el botón con un círculo se dibuja con un icono dentro. Eso es todo.

Si coloca estos botones dentro de su propia vista, simplemente puede implementar este método y controlar este mouse-hover-appearance como lo desee. Si solo mueve o retransmite estos botones y todavía son subview s de NSThemeFrame (o algo similar), tiene que cambiar el método _mouseInGroup: para esta clase, y probablemente no valga la pena porque tenemos el método anterior perfectamente simple.

En mi caso tengo la costumbre NSView que contiene mis botones estándar como subview s y este código hace toda la magia se ha descrito anteriormente:

- (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

Soy plenamente consciente de que esta pregunta es de edad y es Valentin Shergin's answercorrecto. Impide el uso de Private API, a diferencia de Google did in Chrome. Solo quería compartir un método para aquellos que no se sienten como la subclase NSView solo para poner esos botones en una vista existente (como self.window.contentView).

Como sólo quería cambiar la posición de los NSWindowButton s a través de setFrame:, descubrí que una vez que la ventana estaba redimensionada, las áreas de seguimiento parece "solución" a sí mismos automagicamente, sin ningún tipo de uso de la API privada (al menos en 10.11).

De este modo, se pueden hacer cosas como las que siguen para aplicar "falsa cambiar el tamaño" de la ventana que lo cambie de posición de los botones:

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]; 

(lo hice dentro de mi ventana principal de NSWindowDelegatewindowDidBecomeMain:.Debe funcionar siempre que la ventana esté cargada y visible.)

Cuestiones relacionadas