Подтвердить что ты не робот

Есть ли способ получить координаты относительно самого внутреннего NSView, когда родительский элемент не является окном?

У меня вопрос о NSView:

Представьте себе пользовательский вид, в котором методы mouseDown, mouseDrag и mouseUp переопределяются, чтобы пользователь мог перетащить точку (NSRect) на экран. Чтобы перетащить его, мне нужны координаты мыши относительно текущего вида. Это не проблема, когда родителем представления является окно, но как его получить, когда представление находится внутри другого представления?

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

Ответ 1

Вам не нужно вручную преобразовывать в локальную систему координат. Вы можете преобразовать точку в локальную систему координат, отправив сообщение convertPoint:fromView: в ваше представление. Отправка nil, поскольку параметр fromView преобразует точку из родительского окна представления (где бы это ни было). Вы также можете отправить любое другое представление для получения координат, преобразованных из этого пространства:

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

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