[NSButton Subclass] Gérer le mouvement de la souris
Salut à tous,
Pour ceux qui s'aventurent un jour dans la réalisation de NSButton personnalisés (HUD par exemple), voici un code bien pratique qui permet de surveiller la position de la souris afin de changer l'état (Appuyé ou non) du bouton.
Par exemple, si vous appuyez sur un NSButton basique et qu'en restant appuyé vous sortez de sa zone, vous pouvez relâcher votre souris sans que le click soit effectué.
Pourquoi la conversion ?
- Si votre bouton se trouve directement dans votre fenêtre, le "NSPoint location = [theEvent locationInWindow];" suffit.
Sauf que si votre bouton se trouve dans une vue, qui est elle même implantée dans votre fenêtre, ça change complètement l'origine de votre bouton qui est calculé en fonction de sa position dans la vue et non pas dans la fenêtre.
Le BOOL "performClick" permet simplement à la méthode "mouseUp" (que j'utilise habituellement pour envoyer l'action du bouton avec [self performClick:self]; ) de savoir oui ou non si l'action du bouton doit être réalisée ou non.
Voili voilu
Pour ceux qui s'aventurent un jour dans la réalisation de NSButton personnalisés (HUD par exemple), voici un code bien pratique qui permet de surveiller la position de la souris afin de changer l'état (Appuyé ou non) du bouton.
Par exemple, si vous appuyez sur un NSButton basique et qu'en restant appuyé vous sortez de sa zone, vous pouvez relâcher votre souris sans que le click soit effectué.
<br />- (void)mouseDragged:(NSEvent*)theEvent<br />{<br /> if(![self isEnabled])<br /> return;<br /> <br /> NSPoint location = [theEvent locationInWindow];<br /> <br /> location = [[[self window] contentView] convertPoint:location toView:[self superview]]; <br /> <br /> if(location.x<[self frame].origin.x){<br /> performClick = NO;<br /> [self mouseUp:nil];<br /> }else if(location.x>[self frame].origin.x+[self frame].size.width){<br /> performClick = NO;<br /> [self mouseUp:nil];<br /> }else if(location.y<[self frame].origin.y){<br /> performClick = NO;<br /> [self mouseUp:nil];<br /> }else if(location.y>[self frame].origin.y+[self frame].size.height){<br /> performClick = NO;<br /> [self mouseUp:nil];<br /> }<br /><br />}<br />
Pourquoi la conversion ?
- Si votre bouton se trouve directement dans votre fenêtre, le "NSPoint location = [theEvent locationInWindow];" suffit.
Sauf que si votre bouton se trouve dans une vue, qui est elle même implantée dans votre fenêtre, ça change complètement l'origine de votre bouton qui est calculé en fonction de sa position dans la vue et non pas dans la fenêtre.
Le BOOL "performClick" permet simplement à la méthode "mouseUp" (que j'utilise habituellement pour envoyer l'action du bouton avec [self performClick:self]; ) de savoir oui ou non si l'action du bouton doit être réalisée ou non.
Voili voilu
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Je veux dire moi si je voulais faire un bouton au look personnalisé, pour pas perdre les fonctionnalités propres au bouton, avec la gestion des target/actions, et tout, j'aurais juste sous-classé NSButtonCell, non ? et demandé à mes boutons d'utiliser cette cellClass à la place de celle par défaut ? Et le NSControl qu'est NSButton, lui, gérant juste les interactions et pas le drawing, garderait sa fonction première, dont la gestion des mouseDown:, mouseDragged: et mouseUp: ?
Ou j'ai loupé un épisode ?
About Cells and Controls
Après comme j'ai jamais fait y'a sans doute des subtilités que je n'ai pas vues, mais bon, quand même ça reste à tester et ça vaut le coup de relire cette partie de la doc pour s'assurer qu'on a bien fait les choses proprement et avec la méthode la plus adaptée
De plus NSButtonCell (et donc ses potentielles sous-classes) a tout ce qu'il faut pour gérer la souris.
- on peut détecter les survols de la souris sur le bouton (méthodes mouseEntered: et mouseExited:),
- on peut détecter les évènements souris dans le bouton (startTrackingAt:inView:),
- on peut suivre les mouvements de la souris pendant un clic (continueTracking:at:inView: , pratique par exemple pour déplacer un bouton sous forme de curseur),
Et en fin, last but not least, toute la mécanique target/action/delegate reste utilisable.
Effectivement, tu t'es pris la tête pour rien... Tout ça est déjà géré par NSButton / NSButtonCell.
M'en fiche au moins ça m'aurait entraà®né à me faire chier pour rien ;D j'suis un champion dans ce domaine