2009-01-12 4 views
12

J'ai une question à propos de NSView:Existe-t-il un moyen d'obtenir des coordonnées par rapport au NSView le plus interne lorsque le parent n'est pas la fenêtre?

Imaginez une vue personnalisée où les méthodes mouseDown, mouseDrag et mouseUp sont remplacées afin que l'utilisateur puisse faire glisser un point (NSRect) sur l'écran. Pour le faire glisser, j'ai besoin des coordonnées de la souris par rapport à la vue actuelle. Ce n'est pas un problème quand le parent de la vue est la fenêtre, mais comment les obtenir quand la vue est dans une autre vue?

@implementation MyView 

- (id)initWithFrame:(NSRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     pointXPosition = 200.0f; 
     pointYPosition = 200.0f; 

     locked = NO; 
    } 
    return self; 
} 

- (void) drawRect:(NSRect)rect { 

    NSRect point = NSMakeRect(pointXPosition, pointYPosition, 6.0f, 6.0f); 
    [[NSColor redColor] set]; 
    NSRectFill(point); 

} 

- (void)mouseDown:(NSEvent *)theEvent { 
    NSPoint mousePos = [theEvent locationInWindow]; 
    NSRect frame = [super frame]; 
    CGFloat deltaX = mousePos.x - frame.origin.x - pointXPosition; 
    CGFloat deltaY = mousePos.y - frame.origin.y - pointYPosition; 
    if(sqrtf(deltaX * deltaX + deltaY * deltaY) < 100.0f) 
     locked = YES; 
} 

- (void)mouseUp:(NSEvent *)theEvent { 
    locked = NO; 
} 

- (void)mouseDragged:(NSEvent *)theEvent { 

    if(locked) { 
     NSPoint mousePos = [theEvent locationInWindow]; 

     NSRect frame = [super frame]; 

     CGFloat oldXPos = pointXPosition; 
     CGFloat oldYPos = pointYPosition; 

     pointXPosition = mousePos.x - frame.origin.x; 
     pointYPosition = mousePos.y - frame.origin.y; 

     CGFloat rectToDisplayXMin = MIN(oldXPos, pointXPosition); 
     CGFloat rectToDisplayYMin = MIN(oldYPos, pointYPosition); 

     CGFloat rectWidthToDisplay = MAX(oldXPos, pointXPosition) - rectToDisplayXMin; 
     CGFloat rectHeigthToDisplay = MAX(oldYPos, pointYPosition) - rectToDisplayYMin; 

     NSRect dirtyRect = NSMakeRect(rectToDisplayXMin, 
             rectToDisplayYMin, 
             rectWidthToDisplay + 6.0f, 
             rectHeigthToDisplay + 6.0f); 

     [self setNeedsDisplayInRect:dirtyRect]; 
    } 
} 

Répondre

23

Vous n'avez pas besoin de convertir manuellement le système de coordonnées local. Vous pouvez convertir le point en système de coordonnées local en envoyant le message à votre affichage. L'envoi de nil en tant que paramètre à fromView convertit le point à partir de la fenêtre parente de la vue (où que ce soit). Vous pouvez également envoyer toute autre vue pour obtenir les coordonnées converties à partir de cet espace:

// convert from the window's coordinate system to the local coordinate system 
NSPoint clickPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 

// convert from some other view's cooridinate system 
NSPoint otherPoint = [self convertPoint:somePoint fromView:someSuperview]; 
Questions connexes