2009-04-19 14 views
8

Ho un'applicazione Cocoa che visualizza un avviso modale dell'applicazione utilizzando la classe NSAlert. Mi piacerebbe che la finestra di avviso galleggi sopra tutte le finestre di altre applicazioni. Questo può essere fatto con NSAlert o devo implementare la mia finestra?È possibile utilizzare NSAlert per creare una finestra mobile?

Non so se ciò sia importante, ma l'applicazione è un'applicazione agente (LSUIElement è vera) implementata come NSStatusItem. (Per maggiori informazioni sulla app, incluso il codice sorgente, guarda <here>.)

Qui è il codice che consente di visualizzare l'avviso:

- (void)showTimerExpiredAlert { 
    [NSApp activateIgnoringOtherApps:YES]; 

    NSAlert *alert = [[NSAlert alloc] init]; 
    [alert setAlertStyle:NSInformationalAlertStyle]; 
    [alert setMessageText:NSLocalizedString(@"Menubar Countdown Complete", @"Expiration message")]; 
    [alert setInformativeText:NSLocalizedString(@"The countdown timer has reached 00:00:00.", 
               @"Expiration information")]; 
    [alert addButtonWithTitle:NSLocalizedString(@"OK", @"OK button title")]; 
    [alert addButtonWithTitle:NSLocalizedString(@"Restart Countdown...", @"Restart button title")]; 

    NSInteger clickedButton = [alert runModal]; 
    [alert release]; 

    if (clickedButton == NSAlertSecondButtonReturn) { 
     // ... 
    } 
} 

Ho provato a mettere questo prima della runModal chiamata:

[[alert window] setFloatingPanel:YES]; 

ho anche provato questo:

[[alert window] setLevel:NSFloatingWindowLevel]; 

Ma neit lei di quelli fa rimanere la finestra sopra gli altri se faccio clic sulla finestra di un'altra applicazione. Sospetto che l'runModal non rispetti queste impostazioni.

+1

ogni volta che runModal viene chiamato reimposta il livello della finestra, non è sicuro se questo aiuti ... – cobbal

risposta

5

Ho rovinato il mio cervello proprio su questa cosa un attimo fa.

L'unico modo in cui è possibile ottenere che questo funzioni (sorta), era di sottoclasse NSApplication e override -sendEvent. In -sendEvent, devi prima di chiamare l'implementazione di super, poi fare qualcosa di simile:

id *modalWindow = [self modalWindow]; 
if (modalWindow && [modalWindow level] != MY_DESIRED_MODAL_WINDOW_LEVEL) 
    [modalWindow setLevel: MY_DESIRED_MODAL_WINDOW_LEVEL]; 

A parte che anche questo non ha funzionato del tutto perfettamente - quando si cambia apps - che non avevo mai vuole fare questo in ogni caso perché è un hack spudorato e grossolano.

Quindi sì, purtroppo stai meglio scrivendo la tua versione di NSAlert. Se ti interessa davvero di questa possibilità, inserirò un bug su di esso. È piuttosto strano che [[alert window] setLevel: someLevel] non sia onorato da NSApplication ed è uno spreco dover ricostruire NSAlert con tutte le sue semplici funzionalità di impaginazione automatica solo per poterlo fare.

2

Quello che ho finito è stato abbandonare NSAlert e invece carico un allarmante NSWindow da un NIB.

Qui è il codice che visualizza la finestra:

- (void)showAlert { 
    NSWindow *w = [self window]; 
    [w makeFirstResponder:nil]; 
    [w setLevel:NSFloatingWindowLevel]; 
    [w center]; 
    [w makeKeyAndOrderFront:self]; 
} 

Questo ha lo scopo di rendere più agire come un allarme, se non che galleggia anche, e non è modale, quindi le voci di menu possono essere selezionati, mentre è finito.

C'è altro che avrei dovuto fare?

Problemi correlati