NSButton avec une image en etat désactivé

ObiObi Membre
18:37 modifié dans API AppKit #1
J'ai beau chercher sur le net et bidouiller du code, je n'arrive pas à  afficher ma propre image dans un bouton qui est disabled (pas l'effet de transparence par défaut, qui est très moche dans mon cas). La question a été posée sur cocoadev mais sans réponse :'(
On peut uniquement spécifier les images des états normaux et pressés (icon et alt icon) mais dans Safari, par exemple, les boutons de navigation ont une image particulière quand ils sont désactivés (qui est dans les ressources).

J'ai essayé de faire une sous-classe de NSButton mais, lamentablement, je ne sais même pas :
- quelle méthode est appelée pendant l'init (le bouton est dans un NIB)
- si je dois empêcher le setEnabled pour proposer mon "propre" état désactivé
- si il faut une custom cell
- comment on peut empêcher le bouton de répondre à  un clic et ne pas envoyer l'action (dans le cas d'un faux état désactivé)
- si tout ça est la bonne piste !  ;D

Merci  :o

Réponses

  • Eddy58Eddy58 Membre
    mai 2005 modifié #2
    Personnellement, je ne m'embêterais pas pour si peu...;)
    Je mettrais tout d'abord une variable d'instance de type bool, du genre "isMonBoutonEnabled".
    Et ensuite, l'état de ce flag conditionnerait ou non une petite logique qui jouerait avec les images du bouton, via les méthodes setImage et setAlternateImage. Ainsi, quand isMonBoutonEnabled==NO, tu mets en image et alternate image ton image de bouton disabled à  toi, puis lorsque l'action du bouton est effectuée, si isMonBoutonEnabled==NO, alors tu avortes ta méthode des le début par un return. :)

    [tt]
    // Bouton dans son état normal
    isMonBoutonEnabled=YES;
    [monBouton setImage:image];
    [monBouton setAlternateImage:alternateImage];

    // Et puis à  un moment, lorsque les conditions sont réunies pour désactiver le bouton
    isMonBoutonEnabled=NO;
    [monBouton setImage:disabledImage];
    [monBouton setAlternateImage:disabledImage];

    // Le code de l'action
    -(IBAction)monBoutonClick:(id)sender
    {
         // Si le bouton est désactivé on quitte la méthode
         if (isMonBoutonEnabled==NO)
         {
              Return;
         }
         // Sinon suite du code...
    }
    [/tt]

    [EDIT] Tu peux aussi carrément désactiver l'action avec setAction, ce qui donne un résultat plus propre je pense (plus besoin de flag):
    [tt]
    // Bouton dans son état normal
    [monBouton setImage:image];
    [monBouton setAlternateImage:alternateImage];
    [monBouton setAction:@selector(monBoutonClick:)];

    // Et puis à  un moment, lorsque les conditions sont réunies pour désactiver le bouton
    [monBouton setImage:disabledImage];
    [monBouton setAlternateImage:disabledImage];
    [monBouton setAction:nil];
    [/tt]
  • ObiObi Membre
    18:37 modifié #3
    Merci pour ces conseils ! J'avais aussi réorienté mes tests vers quelque chose de plus simple ::)
    J'ai fais un mix avec ton idée et ce que j'avais déja fait et ca done ca :

    CustomDisabledImageButton.h

    <br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface CustomDisabledImageButton : NSButton {<br />	BOOL buttonIsEnabled;<br />	NSImage *normalStateImage;<br />	NSImage *disabledStateImage;<br />	NSImage *pressedStateImage;<br />}<br /><br />- (void)setButtonEnabled:(BOOL)flag;<br />- (void)setNormalStateImage:(NSImage *)lNormalStateImage;<br />- (void)setDisabledStateImage:(NSImage *)lDisabledStateImage;<br />- (void)setPressedStateImage:(NSImage *)lPressedStateImage;<br /><br />@end<br />
    


    CustomDisabledImageButton.m

    <br />#import &quot;CustomDisabledImageButton.h&quot;<br /><br />@implementation CustomDisabledImageButton<br /><br />-(void)awakeFromNib {<br />	buttonIsEnabled = YES;<br />	[self setEnabled:YES];<br />	[[self cell] setImageDimsWhenDisabled:FALSE];<br />}<br /><br />- (void)dealloc {<br />	[self setNormalStateImage:nil];<br />    [self setDisabledStateImage:nil];<br />	[self setPressedStateImage:nil];<br />    [super dealloc];<br />}<br /><br />-(void)setButtonEnabled:(BOOL)flag {<br />	buttonIsEnabled = flag;<br />	[self setImage:(buttonIsEnabled ? normalStateImage : disabledStateImage)];<br />	[self setAlternateImage:(buttonIsEnabled ? pressedStateImage : disabledStateImage)];<br />}<br /><br />-(BOOL)sendAction:(SEL)theAction to:(id)theTarget {<br />	if (buttonIsEnabled) {<br />		return [super sendAction:theAction to:theTarget];<br />	} else {<br />		return NO;<br />	}<br />}<br /><br />- (void)setNormalStateImage:(NSImage *)lNormalStateImage {<br />    if (normalStateImage != lNormalStateImage) {<br />        [normalStateImage release];<br />        normalStateImage = [lNormalStateImage retain];<br />    }<br />}<br /><br />- (void)setDisabledStateImage:(NSImage *)lDisabledStateImage {<br />    if (disabledStateImage != lDisabledStateImage) {<br />        [disabledStateImage release];<br />        disabledStateImage = [lDisabledStateImage retain];<br />    }<br />}<br /><br />- (void)setPressedStateImage:(NSImage *)lPressedStateImage {<br />    if (pressedStateImage != lPressedStateImage) {<br />        [pressedStateImage release];<br />        pressedStateImage = [lPressedStateImage retain];<br />    }<br />}<br /><br />@end<br />
    


    Pour lui passer les 3 images, j'utilise :
    <br />[button setNormalStateImage:&lt;NSImage&gt;];<br />[button setDisabledStateImage:&lt;NSImage&gt;];<br />[button setPressedStateImage:&lt;NSImage&gt;];<br />
    


    Et pour changer l'etat, j'utilise :
    [button setButtonEnabled:&lt;BOOL&gt;];
    

    au lieu de :
    [button setEnabled:&lt;BOOL&gt;];
    


    Voilà  !
Connectez-vous ou Inscrivez-vous pour répondre.