2011-10-03 12 views
11

Nella mia app a cambiare la posizione delle standardWindowButtons vicino/miniturize/ampliare in questo modo:Cocoa/OSX - NSWindow standardWindowButton comporta in modo strano, una volta copiato e ha aggiunto di nuovo

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

Ora, quando viene visualizzata la finestra con i tasti lì è due problemi: 1. essi sono di colore grigio e non la loro corretta colore 2. quando il mouse è su di loro che non mostrano il + - o x segno

qualcuno può dirmi che cosa sto facendo male. Grazie.

risposta

-1

Chiama [button highlight:yes] per ciascun pulsante.

+7

Tristemente [pulsante di evidenziazione: SÌ] 'disegna solo lo stato" premuto "del pulsante della finestra ([riferimento] (http://www.cocoabuilder.com /archive/cocoa/76398-standardwindowbuttons.html)). Non conosco ancora un modo per disegnare lo stato "hover". – rentzsch

0

Non li stai aggiungendo di nuovo. Li stai spostando su contentView. I pulsanti sono originariamente in window.contentView.superview.

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

Si dovrebbe ottenere il comportamento corretto senza richiedere un trackingArea.

10

Ecco la meccanica di questa magia al passaggio del mouse: prima di disegnare il pulsante standard cerchiato (come NSWindowMiniaturizeButton) chiama il metodo superview non documentato _mouseInGroup:. Se questo metodo restituisce il pulsante cerchiato YES si disegna con l'icona all'interno. È tutto.

Se si posizionano questi pulsanti all'interno della propria vista, è possibile semplicemente implementare questo metodo e controllare questo aspetto del passaggio del mouse come si desidera. Se si spostano o si ritrasmettono questi pulsanti e sono ancoras di NSThemeFrame (o qualcosa di simile), è necessario attivare il metodo _mouseInGroup: per questa classe e probabilmente non ne vale la pena poiché abbiamo un metodo precedente perfettamente semplice.

Nel mio caso ho personalizzato NSView che contiene i miei pulsanti standard come subview s e questo codice rende tutti sopra descritti magia:

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

Sono pienamente consapevole del fatto che questa domanda è vecchio e Valentin Shergin's answer è corretto. Impedisce l'utilizzo di qualsiasi API privata , a differenza di Google did in Chrome. Volevo solo condividere un metodo per coloro che non si sentono come sottoclasse NSView solo per mettere quei pulsanti in una vista esistente (come ad esempio self.window.contentView).

Come Volevo solo riposizionare i NSWindowButton s via setFrame:, ho scoperto che una volta che la finestra era ridimensionata, le zone di monitoraggio sembra "fix" se stessi automagicamente, senza alcun utilizzo di API privato (almeno nel 10.11).

Così, si possono fare cose come il seguente per applicare "falso ridimensionare" alla finestra che si riposizionato i pulsanti:

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

(l'ho fatto nel mio finestra principale di NSWindowDelegatewindowDidBecomeMain:.Dovrebbe funzionare fino a quando la finestra è caricata e visibile.)