2009-01-12 19 views
12

Tengo una pregunta acerca de NSView:¿Hay alguna manera de obtener coordenadas relativas al NSView más interno cuando el padre no es la ventana?

Imagine una Vista personalizada donde los métodos mouseDown, mouseDrag y mouseUp son anulados para que el usuario pueda arrastrar un punto (NSRect) en la pantalla. Para arrastrarlo, necesito las coordenadas del mouse relativas a la vista actual. Esto no es un problema cuando el padre de la vista es la ventana, pero ¿cómo los obtengo cuando la vista está dentro de otra vista?

@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]; 
    } 
} 

Respuesta

23

No necesita convertir manualmente al sistema de coordenadas local. Puede convertir el punto al sistema de coordenadas local enviando el mensaje convertPoint:fromView: a su vista. Enviar nil como el parámetro a fromView convertirá el punto de la ventana principal de la vista (donde sea). También puede enviar cualquier otra vista para obtener las coordenadas convertidas desde ese espacio también:

// 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]; 
Cuestiones relacionadas