[Résolu] Une sous-classe de NSView capable de recevoir un échantillon de couleur du NSColorPanel?

berfisberfis Membre
mars 2015 modifié dans API AppKit #1

Bonsoir,


 


Je n'ai pas trouvé la doc qui permet de savoir comment certaines NSView peuvent recevoir un message de "colorisation". Par exemple, si on sélectionne du texte, qu'on ouvre le NSColorPanel et que l'on glisse-dépose l'échantillon de couleur sur le texte, celui-ci prend la couleur voulue.


 


De quoi s'agit-il? d'une notification? d'un protocole? d'une méthode commune aux NSView?


 


Est-il possible de concevoir une sous-classe de NSView qui accepte ce genre d'événement?


 


Si l'un de vous a une indication sur la façon de procéder, je lui serai reconnaissant de me l'indiquer. Pour le moment, je travaille avec des ColorWell, c'est moche et peu agréable à  utiliser.


Mots clés:

Réponses

  • AliGatorAliGator Membre, Modérateur
    Je chercherais du côté de l'implémentation du Drag & Drop dans les vues (via NSPasteboard & co).

    C'est à  mon avis un cas particulier de Drag & Drop où tu acceptes les objets de type NSColor à  être drag & dropés.

    Ca fait un bail que j'ai pas mis le Drag & Drop en pratique (vu que ça fait un bail que je fais plus d'OSX à  la base) mais en cherchant dans la doc je suis tombé sur ce Guide Apple qui devrait te mettre sur la piste.

    Bon après si ça se trouve c'est pas du tout ça, car j'ai jamais essayé, mais quand même vu que tu décris que tu fais un Drag & Drop d'une couleur depuis la palette vers ta vue, ça me semble être du côté de cette implémentation et de ces docs qu'il faut creuser
  • berfisberfis Membre
    mars 2015 modifié #3

    Merci Ali,


     


    J'avais cherché entre-temps (comme quoi...) et je suis tombé sur la même doc, j'ai même fait des essais, et effectivement ça marche. On a même le gros signe "+" qui s'ajoute au curseur si le récepteur accepte le drop... Le "tuyau" était donc le bon.


     


    Finalement j'ai implémenté autrement: le firstResponder envoie un message au [NSColorPanel sharedColorPanel] pour lui dire "je suis ton prochain target, voici la couleur que j'ai actuellement et en cas de changement j'appellerai ma méthode changeMyColor"... Parce que finalement je me suis dit que dragger/dropper une couleur c'était un peu moins HIG.


     


    Bon, autant mettre le code:



    // - (void)willAcceptColor
    // {
    [[NSColorPanel sharedColorPanel]setTarget:self];
    [[NSColorPanel sharedColorPanel]setContinuous:YES];
    [[NSColorPanel sharedColorPanel]setColor:self.classroom.deskColor];
    [[NSColorPanel sharedColorPanel]setAction:@selector(colorChanged:)];
    }
    // - (void)colorChanged:(id)sender
    // { // Verify if color has changed !
    if (![self.classroom.deskColor isEqualTo:[[NSColorPanel sharedColorPanel]color]]) [self.classroom setDeskColor:[[NSColorPanel sharedColorPanel]color]];
    [self.view display];
    }

    Il ne reste plus qu'à  documenter tout ça...  <_<



  •  


    Responding to a Color Change

        


changeColor:






    Sent to the first responder when the user selects a color in an NSColorPanel object. 




    Declaration
OBJECTIVE-C


    
- (void)changeColor:(id)sender 





    Discussion



    When the user selects a color in an NSColorPanel object, the panel sends a changeColor: action message to the first responder. You can override this method in any responder that needs to respond to a color change. 





     


    A priori, changeColor est la méthode définie par défaut.


  • Oui, j'ai essayé, mais ça n'avait pas marché.


     


    J'ai finalement centralisé les accès au NSColorPanel dans le contrôleur qui gère une vue et ses sous-vues. Elles adoptent toutes un protocole: elles indiquent au contrôleur "j'ai reçu un mouseDown" et elles l'interrogent ensuite "Suis-je sélectionnée?" ce qui permet au contrôleur de gérer les vues sélectionnées (dans un NSMutableSet). Ce mouseDown indique aussi au NSColorPanel que la vue sera la prochaine à  recevoir un message "couleur".


     


    C'est là  qu'après avoir essuyé un certain nombre d'erreurs et rajouté des NSLog un peu partout, j'ai vu où était le problème: quand une vue est sélectionnée, sa couleur actuelle doit s'afficher dans le NSColorPanel. Du coup, celui-ci envoie un message "la couleur a changé" et il faut faire attention que ce ne soit pas la vue précédemment sélectionnée qui le reçoive. Si la méthode est une unique "changeColor", ça va foirer.


     


    J'ai donc découplé les méthodes dans ce genre-là :



    switch (destination) {
    case DMChangeBackColor:
    [[NSColorPanel sharedColorPanel]setAction:@selector(backColorChanged:)];
    [[NSColorPanel sharedColorPanel]setColor:self.classroom.backColor];
    break;
    case DMChangeDeskColor:
    [[NSColorPanel sharedColorPanel]setAction:@selector(deskColorChanged:)];
    [[NSColorPanel sharedColorPanel]setColor:self.classroom.deskColor];
    break;
    ...

    Chaque méthode vérifie ensuite que la couleur a effectivement changé par rapport à  la précédente avant de mettre backColor ou deskColor à  jour (sinon le mécanisme du undo va stocker une modification pour rien).


     


    Mais finalement ça marche (et c'est 100% MVC pour ceux qui veillent au grain...).


     


    Merci de ta réponse en tout cas!


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