Echange d'info entre objets

tommyaltaïr

Membre confirmé
5 Mars 2008
25
0
Bonjour,
J'ai écrit un application qui affiche une image dans une fenêtre ainsi que les coordonnées d'un clic sur cette image.
J'aimerai afficher une portion de cette image dans une autre fenêtre en utilisant le clic de la souris, définissant un rectangle centré sur le point du clic.

La structure du programme est ainsi :
Bloc de code:
@implementation GUIControl

- (void) awakeFromNib
{							
}

- (IBAction)preView:(id)sender
{
}

- (void) myShow
{
}
@end

@implementation MainImageView

- (void) mouseDown:(NSEvent *) theEvent
	{
	NSPoint where = [self convertPoint:[theEvent locationInWindow] fromView:nil];  				
	}
	
@end

GUIControl est une class que j'ai créé.
MainImageView est une class de type NSImageView.

J'aimerai utiliser "where" dans GUIControl.

Comment faire ?

Merci pour vos réponses.
 
Un contrôleur connaît la vue qu'il contrôle (fonction "view"). Donc deux solutions :

1/ dans "awakeFromNib" tu peux créer le lien inverse pour que la vue connaisse son contrôleur et quand "where" est calculé, la vue envoie l'info à son contrôleur. Le pattern "observateur" sera le bien venu pour que le contrôleur soit notifié sur une mise à jour de "where".

2/ ou tu stockes "where" quand il est calculé et le contrôleur interroge sa vue quand il a en besoin

Je pencherais pour la première solution est le DP qui va bien.
 
" 1/ dans "awakeFromNib" tu peux créer le lien inverse pour que la vue connaisse son contrôleur et quand "where" est calculé, la vue envoie l'info à son contrôleur. Le pattern "observateur" sera le bien venu pour que le contrôleur soit notifié sur une mise à jour de "where"".

Cela correspond t'il à une connexion inverse dans InterfaceBuilder ?
Est il possible d'avoir un exemple ?


"2/ ou tu stockes "where" quand il est calculé et le contrôleur interroge sa vue quand il a en besoin"

La variable "where" n'est visible que dans l'implémentation de MainImageView. Je suppose qu'il faut que je définisse une variable Global. Comment fait on cela ?
 
Cela correspond t'il à une connexion inverse dans InterfaceBuilder ?
Est il possible d'avoir un exemple ?
Non, pas forcement. Tu peux implémenter une mécanique observateur/observable.
La variable "where" n'est visible que dans l'implémentation de MainImageView. Je suppose qu'il faut que je définisse une variable Global. Comment fait on cela ?
Là je pense que tu ne maîtrises pas de tout la programmation objet. :siffle: Pour accéder en lecture/écriture à une variable interne, il suffit d'ajouter des fonctions accesseur get/set.
La variable globale est à bannir d'une programmation objet propre. :zen:
 
Slt NTX,
J'ai fait quelques recherches et j'ai trouvé ce code :

Model.h
Bloc de code:
#import <Foundation/Foundation.h>

@interface Model: NSObject
{
	double acc;
}

-(void) setAcc: (double) value;
-(void) clear;
-(double) acc;
-(void) add: (double) value;
-(void) mul: (double) value;
-(void) sub: (double) value;
-(void) div: (double) value;
@end

Model.m
Bloc de code:
#import "Model.h"

@implementation Model

-(void) setAcc: (double) value {acc = value;}

-(void) clear {acc = 0;}

-(double) acc {return acc;}

-(void) add: (double) value {
[self setAcc: ([self acc] + value)];   // style pur objet
}

-(void) mul: (double) value{
	acc *= value;                         // style plus classique
}

-(void) sub: (double) value {acc -= value;}

-(void) div: (double) value {acc /= value;}

@end

Calc.m
Bloc de code:
#import "Model.h"

int main (int argc, const char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	
	Model *calc = [[Model alloc] init];
	[calc setAcc: 100];
	[calc add: 200];
	[calc div: 2];
	[calc mul: 5];
	NSLog(@"acc = %f", [calc acc]);
	[calc release];
	
    [pool drain];
    return 0;
}

Ce code introduit il une autre façon d'échange entre objet ?
Récupérer les coordonnées d'un clic sur une image ?
je me questionne sur la façon de le faire :
- awakeFromNib (jai cru comprendre que cette méthode s'exécutait qu'une fois)
- tu stockes "where" quand il est calculé et le contrôleur interroge sa vue quand il a en besoin"
- ou l'utilisation du code fourni en exemple
 
Ce code introduit il une autre façon d'échange entre objet ?
Je ne vois où ce code introduit une discussion entre deux objets vu qu'il y en un seul d'instancié, calc.

Franchement, avant de te lancer dans Cocoa et les IHM, commence déjà par apprendre à programmer. :siffle: La programmation d'interfaces graphiques ne peut se faire sans les bases. Cela fait appel à des notions très avancées de programmation objet, et toi tu ne possèdes même pas la base de la base. :zen: As-tu seulement la moindre idée de la façon d'utiliser un pointeur pour référencer un objet ? :confused:
 
C'est pour cela que je fait appel aux forums.
Je souhaite vraiment parfaire mes connaissances dans ce domaine.
J'ai lu quelques documents sur le site developer d'Apple
As tu un lien à me proposer ?

Pour les pointeurs, j'utiliserai NomduPointeur.ChampsduPointeur
 
As tu un lien à me proposer ?
Les liens pour apprendre le C, l'Obj-C et Cocoa ont déjà été donnés mille fois. Fais une recherche :zen:
Pour les pointeurs, j'utiliserai NomduPointeur.ChampsduPointeur
Tu n'as même pas compris la question ... Connais-tu la différence entre valeur et adresse ? Sais-tu ce qu'es un pointeur ? As-tu seulement appris le C avant de te lancer dans Cocoa ? :confused:
 
Le constat est partagé, j'ai à apprendre encore et encore.
Sans trop vouloir la ramener, j'ai modifié un driver PCI et son UserClient
afin d'afficher des images couleurs de 20000 par 12000 pixels d'un scanner de document que
j'ai réalisé de mes petites mains, alors les pointeurs...C'est pas ce truc qui contient l'adresse d'un autre truc ?
Merci pour ton aide.
 
As-tu seulement appris le C avant de te lancer dans Cocoa ?

J'étais confronté a un problème, je me suis donc initié au C.
Mon approche est celle d'un autodidacte.

Et quels sont ils ces patterns plus élégants ?
Des exemples, des mots clef...
 
Et quels sont ils ces patterns plus élégants, mis à part observateur/observable ?

En utilisant les fonctions accesseur get/set, je n'ai pas réussi à récupérer les coordonnées d'un clic sourie dans mon contrôleur. En traçant mon programme, j'ai pu m'apercevoir que la méthode getMouse de ma vue me revoyait le point de valeur 0,0 en permanence alors que les coordonnées de celui-ci étaient correctes dans la méthode mouseDown.
Par contre, le contrôleur récupère les bonnes valeurs du point si je les fixe dans getMouse.

Je suis donc passé à NSNotificationCenter bien que les fonctions accesseur get/set me plaisent plus.
 
Et quels sont ils ces patterns plus élégants, mis à part observateur/observable ?
C'est très élégant comme pattern :D Une grand partie des discussions entre objets dans les IHM Java fonctionne comme cela. Mais le NSNotificationCenter n'est en gros qu'une généralisation de sce pattern. Mais tu as un seul observateur qui reçoit toutes les notifications et les redistribue à ses abonnés. Il ne faut pas craindre les engorgements :D La voie directe entre deux objets doit être plus rapide.
 
Bonjour ntx,
j'ai fait un nouvel essai avec la mécanique observateur/observable.
le programme ne fonctionne pas comme je souhaite: Quand je clic sur la NSImageView les différentes méthodes de MainImageView s'exécutent correctement avec les bonne values. Lors après, j'active un NSButton, la méthode "preView" de GUIControl s'exécute mais là, je récupère un NSPoint à 0. Si je regarde la variable "test" lorsque le programme est stoppé dans GUIControl, tous les champs sont à 0 alors qu'ils sont correctement renseignés lorsque le programme est stoppé dans MainImageView. Si je set la variable storeWhere dans awakeFromNib sans faire de clic dans la vue, les coordonnées du point sont correctes dans GUIControl. I need help.

voilà le code:

Preview.h
Bloc de code:
@interface MainImageView : NSImageView
{
	NSPoint				where;
	NSPoint				storeWhere;
}
 
- (void) awakeFromNib;
- (void) mouseDown:(NSEvent *) theEvent;
- (NSPoint) mousePosition;
- (void) setPosition:(NSPoint)clic;
@end

Preview.m
Bloc de code:
@implementation MainImageView

- (void) awakeFromNib
 {
//	storeWhere.x=235;
//	storeWhere.y=238;
}

- (void) mouseDown:(NSEvent *) theEvent
	{
	where = [theEvent locationInWindow];
	[self setPosition:where];
	}
	
- (NSPoint) mousePosition
	{
	return  storeWhere;
	}

- (void) setPosition:(NSPoint)clic
	{
	storeWhere=clic;
	}

@end

GUIControl.h
Bloc de code:
@interface GUIControl : NSObject
{
	MainImageView * test;
}

- (IBAction)preView:(id)sender;

@end


GUIControl.m
Bloc de code:
@implementation GUIControl

- (void) awakeFromNib
{
	test = [[MainImageView alloc] init];						
}

- (IBAction)preView:(id)sender
{
    NSPoint crop;
    crop =[test mousePosition];
}

@end
 
Ton code n'est pas tout à fait un pattern observateur/observé.
Pour ce pattern, l'observateur doit s'enregistrer auprès de son observé qui gère donc une liste de ses observateurs. Ensuite à chaque fois qu'une action est faite, l'observé doit notifier ses observateurs.

Bon, tu n'as pas tout implémenté mais ton code doit aussi marcher ... à une nuance près. Comment est créée ton instance de la classe MainImageView ? Par IB ? Car dans ce cas je pense que cette instance créée par IB et celle créée dans ta classe GUIControl ne sont pas les mêmes. Pour en être sûr, affiche les adresses de ces objets dans les différentes méthodes ou regarde au debugueur.

Dans IB, il faut définir ta vue comme étant une classe MainImageView.
Ensuite toujours dans IB tu déclares une instance de la classe GUIControl.
Dans ta classe GUIControl, tu définis un IBOutlet de type MainImageView et tu fais un lien dans IB entre tes deux instances, ta vue et son contrôleur. Et là ton contrôleur connaît la vue qu'il contrôle et il peut l'interroger.
Ensuite tu peux faire en sorte que ta vue connaisse son contrôleur : tu ajoutes dans les membres de ta classe MainImageView un pointeur du type GUIControl avec son setter, et dans la fonction GUIControl::awakeFromNib tu positionnes self sur la valeur de ce pointeur.
 
Dernière édition: