0

关于 NSRect 的问题...在 Hillegass 书中,我们正在创建一个 NSRect,我们在其中绘制一个椭圆(NSBezierPath *)。根据我们在视图中鼠标向下并随后拖动的位置,NSRect 的 size.width 和/或 size.height 可能是负数(即,如果我们从右上角开始,拖动左下角 - 两者都是负数)。实际绘制时,系统是否使用我们的负宽度和/或高度来仅定位我们拖动位置的 NSPoint?从而更新 NSRect?如果我们需要 NSRect 的大小,我们应该只使用绝对值吗?

在本章中,作者使用了 MIN() 和 MAX() 宏来创建一个 NSRect。但是,在挑战解决方案中,他们提供了这三种方法来响应鼠标事件:

- (void)mouseDown:(NSEvent *)theEvent
{
    NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    // Why do we offset by 0.5? Because lines drawn exactly on the .0 will end up spread over two pixels.
    workingOval = NSMakeRect(pointInView.x + 0.5, pointInView.y + 0.5, 0, 0);
    [self setNeedsDisplay:YES];
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    NSPoint pointInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    workingOval.size.width = pointInView.x - (workingOval.origin.x - 0.5);
    workingOval.size.height = pointInView.y - (workingOval.origin.y - 0.5);
    [self setNeedsDisplay:YES];
}

- (void)mouseUp:(NSEvent *)theEvent
{
    [[self document] addOvalWithRect:workingOval];
    workingOval = NSZeroRect; // zero rect indicates we are not presently drawing
    [self setNeedsDisplay:YES];
}

无论潜在的负值如何,此代码都会生成一个成功的矩形。我知道负值仅反映了相对于原点(我们“鼠标按下”的点)的左移。在正确计算我们拖到的 NSPoint 的幕后发生了什么?

4

1 回答 1

1

一个 NSRect 只是定义为一个 NSPoint 和一个 NSSize。NSSize 只是定义为一对 CGFloats,但文档说:

通常,宽度和高度的值是非负的。创建 NSSize 结构的函数不会阻止您为这些属性设置负值。但是,如果 width 或 height 的值为负数,则某些方法的行为可能是未定义的。

在上面显示的代码中,幕后绝对没有任何花哨的事情发生。您正在创建一个大小或宽度为负的矩形(workingOval),但实际上并没有在任何地方使用它。

根据您在其他地方使用 workingOval 所做的事情,幕后发生的事情会有所不同。但这将是三个非常简单的事情之一。一些方法将类似 (origin=(30, 40), size=(-10, -20)) 的矩形视为与 (origin=(20, 20), size=(10, 20)) 相同;其他人将其视为无效的矩形;有些人假设他们不测试,只会给你垃圾结果。例如,NSMinX 将返回 30,而不是 10。

于 2012-05-25T20:56:23.120 回答