2011-09-29 2 views
4

J'ai une sous-classe de NSView qui réimplémente un certain nombre de fonctions d'événement de la souris. Par exemple, dans mouseDown pour obtenir le point de la NSEvent J'utilise:Coordonnées de souris NSView inversées

NSEvent *theEvent; // <- argument to function 

NSPoint p = [theEvent locationInWindow]; 
p = [self convertPoint:p fromView:nil]; 

Cependant, les coordonnées semblent être pivotés, (0, 0) est en bas à gauche de la fenêtre?

EDIT: Je l'ai déjà substituée la méthode isFlipped retourner TRUE, mais il a seulement affecté le dessin. Désolé, je ne peux pas croire que j'ai oublié de le mettre tout de suite.

Répondre

5

Qu'entendez-vous par retourné? Mac utilise un système de coordonnées LLO (origine inférieure gauche) pour tout.

EDIT Je ne peux pas reproduire cela avec un projet simple. J'ai créé un NSView unique mis en œuvre comme ceci:

@implementation FlipView 
- (BOOL)isFlipped { 
    return YES; 
} 

- (void)mouseDown:(NSEvent *)theEvent { 
    NSPoint p = [theEvent locationInWindow]; 
    p = [self convertPoint:p fromView:nil]; 
    NSLog(@"%@", NSStringFromPoint(p)); 
} 
@end 

J'ai reçu les coordonnées j'attendre. La suppression du isFlipped a changé l'orientation comme prévu. Avez-vous un projet simple qui démontre votre problème?

+0

que je voulais dire, je l'avais déjà substituée la méthode isFlipped. Ma faute, je n'ai pas été assez clair. – CD1212

+0

Le remplacement de la méthode '-isFlipped' n'a pas fonctionné pour moi aussi. –

+2

Dans mes tests, 'isFlipped {YES}' * va * convertir le point en une origine en haut à gauche si vous utilisez convertPoint: ** fromView: **. Mais * not * si vous utilisez convertPoint: ** toView: ** - ceci est attendu, puisque toView: suppose que le point est déjà dans le système de coordonnées de la vue self. –

2

Ce n'est pas « renversé », nécessairement, c'est à quel point Quartz ne coordonnées. Un extrait de la documentation sur Quartz 2D:

un point dans l'espace de l'utilisateur est représenté par une paire de coordonnées (x, y), où x représente l'emplacement le long de l'axe horizontal (gauche et droite) et y représente le axe vertical (haut et bas). L'origine de l'espace de coordonnées utilisateur est le point (0,0). L'origine est située dans le coin inférieur gauche de la page, comme illustré dans la Figure 1-4. Dans le système de coordonnées par défaut pour Quartz, l'axe des abscisses augmente à mesure qu'il se déplace de la gauche vers la droite de la page. L'axe des y augmente en valeur lorsqu'il se déplace du bas vers le haut de la page.

Je ne sais pas exactement quelle est votre question. Cherchez-vous un moyen d'obtenir les coordonnées "retournées"? Si c'est le cas, vous pouvez sous-classer votre NSView, en remplaçant la méthode -(BOOL)isFlipped pour retourner YES.

2

J'ai trouvé ce si odieux - jusqu'au jour où je me suis assise et a refusé de se lever jusqu'à ce que j'avais quelque chose qui fonctionnait parfaitement. Ici, il est appelé via .. ...

-(void) mouseDown:(NSEvent *)click{ 
    NSPoint mD = [NSScreen wtfIsTheMouse:click 
         relativeToView:self]; 
} 

invoque une catégorie sur NSScreen ....

@implementation NSScreen (FlippingOut) 
+ (NSPoint)wtfIsTheMouse:(NSEvent*)anyEevent 
      relativeToView:(NSView *)view { 
    NSScreen *now = [NSScreen currentScreenForMouseLocation]; 
    return [now flipPoint:[now convertToScreenFromLocalPoint:event.locationInWindow relativeToView:view]]; 
} 
- (NSPoint)flipPoint:(NSPoint)aPoint { 
     return (NSPoint) { aPoint.x, 
    self.frame.size.height - aPoint.y }; 
} 
- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point 
     relativeToView:(NSView *)view { 
    NSPoint winP, scrnP, flipScrnP; 
    if(self) { 
     winP = [view convertPoint:point toView:nil]; 
     scrnP = [[view window] convertBaseToScreen:winP]; 
     flipScrnP = [self flipPoint:scrnP]; 
     flipScrnP.y += [self frame].origin.y; 
     return flipScrnP; 
     } return NSZeroPoint; 
} 
@end 

Espérons que cela peut empêcher qu'un mineur Freakout .. quelque part, un jour . Pour les enfants, damnit. Je vous en prie .. pour les enfants.

2

Ce code a fonctionné pour moi:

NSPoint location = [self convertPoint:theEvent.locationInWindow fromView:nil]; 
location.y = self.frame.size.height - location.y; 
Questions connexes