NSWindow

chaps31chaps31 Membre
23:16 modifié dans API AppKit #1
2 petites bricoles :

1) Je cherche désespérement un moyen simple de fermer d'un coup toutes les fenêtres de l'application active.

2) Je me heurte à  un petit problème,
-orderFront:self
  amène bien la fenêtre au premier plan mais par contre ne la rend pas "active" il faut cliquer dessus, pas très grave mais j'aimerais bien savoir comment faire pour la rendre active immédiatement.

Merci de vos lumières, je sens bien que je pose encore des questions de base... ::)
«1

Réponses

  • NoNo Membre
    23:16 modifié #2
    dans 1230654529:

    2) Je me heurte à  un petit problème,
    -orderFront:self
    
      amène bien la fenêtre au premier plan mais par contre ne la rend pas "active" il faut cliquer dessus, pas très grave mais j'aimerais bien savoir comment faire pour la rendre active immédiatement.


    Fais un makeKeyWindow après pour rendre ta fenêtre "active", ou, mieux, remplace orderFront: par makeKeyAndOrderFront: qui fait les 2 à  la fois.
  • chaps31chaps31 Membre
    23:16 modifié #3
    Merci, merci, merci...objective-cocoa c'est quelque chose quand même....  o:)
  • NoNo Membre
    23:16 modifié #4
    dans 1230654529:

    1) Je cherche désespérement un moyen simple de fermer d'un coup toutes les fenêtres de l'application active.


    Ca n'existe pas.
    Si c'est pour masquer ton appli, tu peux utiliser hide: de NSApplication.

    Si tu veux garder ton appli active, alors faut parcourir chaque fenêtre pour la masquer.
    Je ne connais pas l'architecture de ton appli, sinon tu peux essayer windows de NSApplication. Ca retourne un NSArray de toutes les fenêtres de l'appli. Il faut ensuite tester si chaque fenêtre est visible, et dans l'affirmative la masquer.
  • chaps31chaps31 Membre
    23:16 modifié #5
    C'est bien ce que je craignais...
  • NoNo Membre
    23:16 modifié #6
    dans 1230662046:

    C'est bien ce que je craignais...


    Pourquoi ça craint ?
    Ca se fait en quelques lignes :
    <br />id fenetre;<br />NSEnumerator *enumerator=[[NSApp windows] objectEnumerator];<br />while (fenetre=[enumerator nextObject]) if ([fenetre isVisible]) [fenetre orderOut:nil];<br />
    

  • chaps31chaps31 Membre
    23:16 modifié #7
    Merci  ;)
  • GreensourceGreensource Membre
    23:16 modifié #8
    Oulà là  il est temps de ré-ouvrir ce sujet, ya un gros warning rouge qui fait peur!!!
    Bon bref j'ai une petit question en lien.
    Moi aussi j'ai voulu porter ma fenêtre au premier plan mais ça ne marche pas.
    J'ai commencer par l'ouvrir puis la sortir de ses gonds...hum désoler c'est vendredi  :P

    DONC, pour vous expliquer le contexte, j'ai un xib qui contient ma fenêtre et le File's Owner est mon NSWindowController.
    Dans ce controller j'ai voulu mettre makeKeyAndOrderFront dans la méthode awakeFromNib.
    Sauf que manque de bol, ça ne fait rien! J'ai même essayer de la fermé (close) mais rien...
    Or quand je le fait "plus tard", c'est à  dire via un bouton par exemple, et bien là  ça marche.

    Du coup je suppose que awakeFromNib est une méthode appelé un peu trop tôt pour ce que je veux faire. Mais je trouve ça étrange car je n'ai rien vu d'autres dans la doc...

    Quelques chose qui pourrait peut-être aider aussi, je fait:
    [login setStringValue:NSFullUserName()];
    

    dans awakeFromNib et ça ça marche bien par contre.

    Les connections sont faites correctement dans IB, comme le montre le screenshot.

    Merci
  • zoczoc Membre
    23:16 modifié #9
    Et en mettant le code dans windowDidLoad du NSWindowController ?
  • GreensourceGreensource Membre
    23:16 modifié #10
    Pas plus malheureusement :(
    J'avoue ne vraiment pas comprendre.
    orderToFront ça met bien la fenêtre au premier plan?
  • CéroceCéroce Membre, Modérateur
    23:16 modifié #11
    windowDidLoad est bien appelée ?

    Quand tu charges le nib, si la case "Visible at Launch" est cochée, la fenêtre s'affiche, mais ton window controller n'a pas forcément de référence vers elle.  Le système n'est pas trop bien conçu et à  chaque fois, je me pose la question. Il te faut tout vérifier.
  • GreensourceGreensource Membre
    23:16 modifié #12
    Non en effet elle n'est pas appelé, du coup forcément ça ne marche pas.
    A priori le contrôleur à  bien une référence, au moins dans le awakeFromNib puisque j'envoie des message à  self.window.

    Mais comment ce fait-ce qu'elle ne soit pas appelé non didiou! J'ai bien déclarer mon objet comme NSWindowController, j'ai bien fait le lien dans IB de l'attribut window de mon NSWindowController vers la NSWindow.

    Sinon il y a quelques choses qui me chiffonne dans la Doc. NSWindow à  un delegate mais il n'existe pas de classe NSWindowDelegate? C'est pas un peu étrange?
  • zoczoc Membre
    23:16 modifié #13
    dans 1246264658:
    Sinon il y a quelques choses qui me chiffonne dans la Doc. NSWindow à  un delegate mais il n'existe pas de classe NSWindowDelegate? C'est pas un peu étrange?


    Non, ce n'est pas étrange, c'est une conséquence de l'absence des méthodes optionnelles dans les protocoles formels (@protocol) d'objective-C "pré" 2.0...

    Dans ce cas là , les méthodes delegates sont déclarés comme des catégories de NSObject, et par conséquent le delegate a pour type "id".
  • GreensourceGreensource Membre
    23:16 modifié #14
    Attend je comprend pas très bien là . Pourquoi ne pas avoir de @optional dans le protocole formel empêche d'avoir un NSWindowDelegate?

    Et sinon tu penses que tout ça à  avoir avec mon souci? Je vois pas trop comment mais bon...
    J'ai pas besoin d'avoir un delegate dans mon cas, si?
  • AliGatorAliGator Membre, Modérateur
    23:16 modifié #15
    En fait, avant que la version 2.0 d'Objective-C existe, il n'y avait pas de possibilité de rendre optionnelles certaines méthodes des @protocols. Ce qui veut dire que si Apple avait mis [tt]id<NSWindowDelegate> delegate[/tt] il aurait absolument fallu que l'objet que tu mettes en delegate de ta NSWindow implémente TOUTES les méthodes de ce protocole NSWindowDelegate. Ce qui n'est pas franchement toujours très pratique.

    Maintenant avec Objective-C 2.0 on peut quand on définit un @protocol (comme ça pourrait être le cas avec NSWindowDelegate), indiquer que certaines méthodes sont requises (@required) et d'autres sont optionelles (@optional). Du coup cette contrainte n'existe plus.

    Mais avant cette contrainte qui faisait que toutes les méthodes devaient être implémentées était souvent gênantes, donc Apple avait trouvé une "parade" en utilisant les catégories de NSObject, c'est à  dire en déclarant les delegate methods à  implémenter en tant qu'extension (catégorie) de la classe NSObject dont descendent toutes les autres classes. Avec une implémentation par défaut. Ce qui fait que si tu ne la redéclarais pas et ne la réimplémentais pas dans ton delegate, ça faisait le code par défaut. Du coup en plus ça évitait les warnings "machin may not respond to 'uneMethodeDeNSWindowDelegate'" qu'on aurait eu sinon si on implémentait pas la méthode.


    Donc maintenant tout ça est dépassé, tu le vois dans le SDK de l'iPhone où maintenant Apple utilise des @protocol partout, ce qui est bien plus propre et plus "orienté objet", mais historiquement il reste encore quelques "delegate" qui ne sont déclarés que sous forme"id" et pas "id<MachinDelegate>" de par ce passif pré-Objective-C-2.0
  • CéroceCéroce Membre, Modérateur
    23:16 modifié #16
    dans 1246264658:

    A priori le contrôleur à  bien une référence, au moins dans le awakeFromNib puisque j'envoie des message à  self.window.


    Non, en ObjC on peut tout à  fait envoyer un message à  nil. Donc ça ne prouve rien.
    Il faut que tu vérifies que window != nil.

    D'expérience, il est nécessaire d'appeler -[NSWindowController show:] pour effectivement déclencher le chargement du NIB.
  • FloFlo Membre
    23:16 modifié #17

    D'expérience, il est nécessaire d'appeler -[NSWindowController show:] pour effectivement déclencher le chargement du NIB.


    Il me semble que c'est plutôt [NSWindowController showWindow:] non ?

    J'ai eu un soucis similaire une fois, j'ai délocalisé le xib et ça a remarché...
  • GreensourceGreensource Membre
    23:16 modifié #18
    dans 1246286225:

    ... j'ai délocalisé le xib ...

    En Inde?  ::)

    Bon, jeu de mot facile à  part, je suis sur que window != nil car la fenêtre réagissait. C'était close il me semble).

    Sinon votre méthode showWindow: c'est une IBAction donc en principe ça c'est à  l'utilisateur final de le déclencher? Moi je veux que ma fenêtre se mettre au premier plan à  la sortir du xib.

    Et ce que je trouve bizarre c'est que le awakeFromNib est correctement appelé mais pas le windowDidLoad, ça viens sûrement de là , non?
  • CéroceCéroce Membre, Modérateur
    23:16 modifié #19
    dans 1246286225:

    Il me semble que c'est plutôt [NSWindowController showWindow:] non ?
    J'ai eu un soucis similaire une fois, j'ai délocalisé le xib et ça a remarché...


    Ton problème était certainement que l'outlet window du NSWindowController était relié dans l'un des XIB et pas dans l'autre.

    Il semble que ce soit un autre problème ici. Je voulais dire qu'il fallait essayer d'appeler [self window] pour forcer le chargement de la fenêtre. Ensuite, je ne peux pas en dire plus sans avoir le code.
  • GreensourceGreensource Membre
    23:16 modifié #20
    Ouais j'ai essayer de l'appeler mais ça n'y fait rien.
    Ce que je ne comprend pas c'est comme je peux voir ma fenêtre à  l'écran alors que la méthode windowDidLoad n'est pas appelé? Pour moi c'est forcément que le controller n'est pas relié? Pourtant il reçoit bien le awakeFromNib et de celui quand j'appelle [self.window close] par exemple ça ferme bien la fenêtre.

    Bon je vous joint le projet dès fois que quelqu'un y verrais mieux que moi.
  • FloFlo Membre
    juin 2009 modifié #21
    Pour moi vu que ton PassWordController hérite de NSWindowController il ne faut pas utiliser la méthode loadNibNamed:owner: de NSBundle mais bien initWithWindowNibName: de NSWindowController

    Je pense que ton problème vient de là ...

    Pas ça : [NSBundle loadNibNamed:@Password owner:PasswordController alloc] init;

    Mais ça: [[PasswordController alloc] initWithWindowNibName: @Password];
  • CéroceCéroce Membre, Modérateur
    23:16 modifié #22
    Effectivement, c'est la bonne façon de faire. Et là , windowDidLoad devrait être  appelée.

    J'ai tout de même fait un essai:
    <br />- (void)awakeFromNib<br />{<br />	[login setStringValue:NSFullUserName()];<br />	NSWindow* fen = [self window];<br />	[fen makeKeyAndOrderFront:self];<br />}<br />
    


    Et la fenêtre s'affiche (j'ai décoché Visible at Launch).
  • GreensourceGreensource Membre
    23:16 modifié #23
    Ah ouais ok!!! Oh bas merci dit donc parce que ça j'aurais eu du mal à  trouver!

    Mais alors à  quoi ça sert le truc de NSBundle pour ouvrir les Nib?
    Je me pencherais sur la Doc demain pour éluder ce mystère  :P

    Merci beaucoup en tout cas!
  • FloFlo Membre
    23:16 modifié #24
    Perso moi je me sers des méthodes de NSBundle dédiées au chargement de nib quand je souhaite qu'une instance ne dérivant pas de NSWindowController soit le file owner d'un nib (genre une sheet par exemple, pas besoin d'instancier un NSWindowController juste pour ça  ;) ).

    Je pense qu'il vaut mieux passer par un NSWindowController quand on désire gérer plusieurs "top level objects" dans un même nib ou alors quand on est sur un projet document based. ça a également du sens quand l'application souhaite charger plusieurs instances d'un même nib.
  • GreensourceGreensource Membre
    23:16 modifié #25
    Re!
    Alors j'en suis arrivée à  une autre solution mais toujours le même souci à  propos de la mise au premier plan d'une fenêtre.
    Désormais j'ai besoin que ce soit un NSAlertPanel qui soit au premier plan.
    A priori pas de souci puisqu'il se met de lui même au premier plan. Mais non il reste caché derrière d'autres fenêtre d'autres appli.

    Alors je fait la supposition suivante: peut-être que les makeMainAndOrderToFront et Cie ne concerne que l'appli courante? Or moi mon appli est juste un menu dans la StatusBar de MacOSX. J'ai activé "Application is Agent" dans la info.plist.
    Du coup est t'il possible de faire passer son application comme celle principale puis de mettre une fenêtre au premier plan?
    Est-ce que je n'ai pas un problème de conception, dans le sens ou ce n'est peut-être pas une "Application Agent" que je devrais faire?
  • CéroceCéroce Membre, Modérateur
    23:16 modifié #26
    dans 1246435420:

    Alors je fait la supposition suivante: peut-être que les makeMainAndOrderToFront et Cie ne concerne que l'appli courante?


    Oui.

    Pour le reste, je ne sais pas trop, mais jette un oe“il à  la méthode -[NSWindow - setLevel:].
  • GreensourceGreensource Membre
    23:16 modifié #27
    Malheureusement c'est toujours le même souci, setLevel permet de choisir le niveau auquel ta fenêtre va se trouver mais en gros c'est comme orderFront.

    Je vais aller fouiner plus en profondeur au niveau de NSApplication.
  • GreensourceGreensource Membre
    23:16 modifié #28
    Bon ça commence à  bien m'amuser ce truc! Je suis donc aller voir la Doc de NSApplication, ya tout ce qui faut pour agencer ses propres fenêtres au sein de son Application mais rien pour en passer une au dessus de toute les autres application.

    J'en arrive à  deux question qui pourrais m'aider:
    • Existe t-il un moyen de passer son application entière au premier plan même si c'est un agent?
    • Existe t-il un framework pour gérer le serveur de fenêtre de tout le système?
  • mpergandmpergand Membre
    23:16 modifié #29
    Tu as essayé:
    - (void)activateIgnoringOtherApps:(BOOL)flag (NSApp)
  • GreensourceGreensource Membre
    23:16 modifié #30
    :) Je viens de tombé dessus de suite. Mais non toujours rien, je ne comprend pas.
    Pour ta méthode je l'envoyer à  [NSApplication sharedApplication] et j'ai mis le booléen à  YES.

    Elle est déjà  active en fait, j'ai fait le test isActive.
  • 23:16 modifié #31
    les NSAlertPanel avec une application LSUIElement 1 c'est toujours  un problème :p
    Tu est sûr que si tu fais :
    <br />[NSApp activateIgnoringOtherApps:YES];<br />NSRunAlertPanel(@&quot;lol&quot;,@&quot;lol&quot;,nil,nil,nil);<br />
    
    ;

    ?
Connectez-vous ou Inscrivez-vous pour répondre.