événements souris sur plusieurs vues

arnolix

Membre confirmé
15 Juillet 2003
80
3
Bonjour

Voici ma colle du jour.

Le code suivant est celui d'une vue personnalisée myView qui vire au rouge quand on clique Down dessus, et vire au bleu quand on clique Up dessus.

@interface myView : NSView {
float red, green, blue ;
}

@end

@implementation myView

- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}

- (void)drawRect:(NSRect)rect {
[[NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1] set];
NSRectFill(rect);
}

- (void)mouseDown:(NSEvent*)theEvent
{
red = 1 ; blue = 0 ; green = 0 ;
[self setNeedsDisplay:YES];
}

- (void)mouseUp:(NSEvent*)theEvent
{
red = 0 ; blue = 1 ; green = 0 ;
[self setNeedsDisplay:YES];
}

@end


Voila.

Maintenant sous IB je crée deux vues juxtaposées dans la même fenêtre qui sont des instances de cette classe myView.

Quand je clique Down et Up dans chacune d'elles, elles alternent du rouge au bleu.

Normal jusque la.

Maintenant, je clique down sur la première, je glisse, sans relâcher la souris sur la seconde et je clique Up sur cette dernière. J'avais cru alors que la chose suivante se serait passée : la première devient rouge puis que la seconde devient bleue. Or c'est la première qui redevient bleue.

Le message mouseUp s'adresse donc à la première et non à la seconde, bien que la souris se trouve au dessus de la seconde.

Et là je sèche : comment modifier ce code pour que le message mouseUp s'adresse à la vue dans laquelle se trouve la souris au moment du relâchement, après avoir changé de vue en glissant ?

J'ai potassé les histoires de first responder mais pour l'instant je ne vois pas du tout comment aboutir selon cette voie.

Merci pour vos conseils avisés ?
 
En principe chaque vue est autonome. La seule manière de faire collaborer des vues est en utilisant le Drag&Drop. Dans ton cas, peut-être que la solution est de faire une seule vue, divisée en plusieurs zones, comme ça tous les événements seront envoyés à la même vue.
Sinon, le comportement que tu attends n'est pas forcément celui que les utilisateurs attendent... ;)
 
  • J’aime
Réactions: molgow
Si tu pouvais éclaicir si j'ai bien compris ce que tu essayes de faire

je pense que tu devrais avoir une seule nsview

interface myNSView

interface myNSViewReflectionObject

interface myNSViewEventsRegister
 
Merci pour vos contributions.


Mais à y réfléchir je crois que ce que je veux est impossible. Le message MouseUp s'adrresse uniquement à la vue qui a été désignée par la fenêtre, choix qui se fait sur celle qui a reçu le message mouseDown.

Donc laissez tomber ! ;)
 
arnolix a dit:
Merci pour vos contributions.


Mais à y réfléchir je crois que ce que je veux est impossible. Le message MouseUp s'adrresse uniquement à la vue qui a été désignée par la fenêtre, choix qui se fait sur celle qui a reçu le message mouseDown.

Donc laissez tomber ! ;)
Oui d'accord mais rien ne t'interdit de passez par le Notification Center pour obliger l'autre View de changer d'aspect.
 
Manu a dit:
Oui d'accord mais rien ne t'interdit de passez par le Notification Center pour obliger l'autre View de changer d'aspect.

une seule nsview --------> reflectingobject ----------------------> register id object ----------------------> register event on this object
 
pas vraiment compris tattouille.

L'idée d'utiliser des notifications je l'ai pas retenu car au final il y aura beaucoup de vues (peut être des centaines !) et ca devrait dans ce cas saturer rapidement le système.

En fait le code que j'ai cité c'est pour l'exemple. Dans mon soft, l'idée est de pouvoir construire une vue à partir de deux (ou plusieurs) autres vues déjà construites. Je voulais sélectionner la première par un mouseDown, puis dragger la souris pour enfin sélectionner la seconde par un mouseUp. Mais cette manière de faire n'est pas en accord avec le système de messages souris des vues.

Je croyais au départ qu'il y avait une solution connue à mon pb. Mais maintenant j'ai décidé d'opter pour un click normal sur chacune des vues à sélectionner. Ca marche mais je trouve ça moins élégant.

Mais bon tant pis.
 
Comme ce que tu veux faire n'est pas le comportement standard, tu es obligé de le gérer toi même, une solution consisterait à avoir un customView recouvrant toutes tes vues et à rechercher celles qui se trouvent sous la souris avec hitTest de NSView. J'ai déjà utilisé ce principe quand effectivement le model standard ne me convenait pas.
 
oui, ca voudrait dire que la customview globale se charge du boulot à la place de la fenêtre. Du coup on utilise plus le framework cocoa et on réinvente la roue.
C'est ce que je voulais savoir en fait : savoir si n'il y avait pas d'autre solution que de tout reprendre pour obtenir le comportement que j'attendais.
 
arnolix a dit:
oui, ca voudrait dire que la customview globale se charge du boulot à la place de la fenêtre. Du coup on utilise plus le framework cocoa et on réinvente la roue.
.

Une autre solution consiste à mettre cette customView sous tes vues (au niveau du contentView) et comme ça tu peux faire une sélection multiple à la manière du finder en utilisant les routines standard :)
 
arnolix a dit:
oui, ca voudrait dire que la customview globale se charge du boulot à la place de la fenêtre. Du coup on utilise plus le framework cocoa et on réinvente la roue.
C'est ce que je voulais savoir en fait : savoir si n'il y avait pas d'autre solution que de tout reprendre pour obtenir le comportement que j'attendais.
Non, tu ne réinventes pas la roue. :affraid:
Car tu implémentes uniquement ce dont tu as besoin pour ton application.
C'est un parti-pris logique: les vues sont des entitées indépendantes au niveau de la distribution des événements. :zen:
De plus, les vues sont des objets assez lourds. Il est préférable d'avoir une seule vue affichant 1000 objets plutôt que 1000 vues affichant chacune un seul objet. :casse:

A+ ;)
 
->mpergand
c'est déjà ce que j'ai fait, mais la sélection d'objets type finder ne convient pas, car il faut sélectionner qu'une toute petite partie de mes vues. En fait chacune de mes vues contient une figure géométrique et avec la souris je désigne une partie de ces figures pour en construire d'autres. Cependant à l'avenir le mode de sélection que tu proposes sera implémenter pour effectuer des copier-coller. C'est une fonctionnalité de cocoa qui s'obtient avec peu de code certainement.

->la tortue
en fait les vues ont des comportements communicants. Si j'inclus des objets dans une seule vue, ces objets devront communiquer et je serais donc amener à refaire ce que les vues savent déjà faire. Peut être que le code sera moins vorace en temps et volume mais cela relève de l'optimisation, ce qui n'est pas mon objectif immédiat.
D'autre part les vues permettront activer par la suite la couleur, les tooltips, le masquer/afficher, etc. (enfin j'espère?)

Merci pour vos interventions, mais ce que je posais comme problème ne se résout pas facilement certainement. Par contre comme je l'ai dit les cliques successifs fonctionnent bien. J'aurais voulu retirer mon post mais c'est pas possible.