开发者

Make MAAttachedWindow resizable without bounce?

To make the MAAttachedWindow resizable, I use code from here:

- (void)mouseDown:(NSEvent *)event {
NSPoint pointInView = [event locationInWindow];

BOOL resize = YES;
if (NSPointInRect(pointInView, [self resizeRect]))
{
    resize = YES;
}

NSWindow *window = self;
NSPoint originalMouseLocation = [window convertBaseToScreen:[event locationInWindow]];
NSRect originalFrame = [window frame];

while (YES)
{
    //
    // Lock focus and take all the dragged and mouse up events until we
    // receive a mouse up.
    //
    NSEvent *newEvent = [window
                         nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];

    if ([newEvent type] == NSLeftMouseUp)
    {
        break;
    }

    //
    // Work out how much the mouse has moved
    //
    NSPoint newMouseLocation = [window convertBaseToScreen:[newEvent locationInWindow]];
    NSPoint delta = NSMakePoint(
                                newMouseLocation.x - originalMouseLocation.x,
                                newMouseLocation.y - originalMouseLocation.y);

    NSRect newFrame = originalFrame;

    if (!resize)
    {
        //
        // Alter the frame for a drag
        //
        newFrame.origin.x += delta.x;
        newFrame.origin.y += delta.y;
    }
    else
    {
        //
        // Alter the frame for a resize
        //
        //          newFrame.size.width += delta.x;
        newFrame.size.width += delta.x*2; // customize
        newFrame.size.height -= delta.y;
        newFrame.origin.y += delta.y;

        //
        // Constrain to the window's min and max size
        //
        NSRect newContentRect = [window contentRectForFrameRect:newFrame];
        NSSize maxSize = [window maxSize];
        NSSize minSize = [window minSize];
        if (newContentRect.size.width > maxSize.width)
        {
            newFrame.size.width -= newContentRect.size.width - maxSize.width;
        }
        else if (newContentRect.size.width < minSize.width)
        {
            newFrame.size.width += minSize.width - newContentRect.size.width;
        }
        if (newContentRect.size.height > maxSize.height)
        {
            newFrame.size.height -= newContentRect.size.height - maxSize.height;
            newFrame.origin.y += newContentRect.size.height - maxSize.height;
        }
        else if (newContentRect.size.height < minSize.height)
        {
            newFrame.size.height += minSize.height - newContentRect.size.height;
            newFrame.origin.y -= minSize.height - newContentRect.size.height;
        }
    }




    [window setFrame:newFrame display:NO animate:NO];
    }

}

When I drag the window, I can resize it. But there is a little bounc开发者_运维知识库e every now and then. You can download the demo project. Run the project and click the icon on the status menu to open the window. Try to stretch back and forward so you can reproduce it easily. Hope someone can help me fixed this.


I checked out you code and it seemed like the bug was that occasionally NSPoint newMouseLocation = [window convertBaseToScreen:[newEvent locationInWindow]]; would return the original mouse location instead of the new one.

I'm not sure why that would fail but regardless that's not the optimal way to do it. Instead of calculating the new frame from the original mouse location, you should continually update that location and just move the window by the amount that the mouse has moved in the current tracking iteration

Here's a cleaned up, shortened version that seems to eliminate the bug.

- (void) mouseDown:(NSEvent *)event
{
    NSWindow *window = self;
    NSPoint originalMouseLocation = [window convertBaseToScreen:[event locationInWindow]];


while (YES)
{

    NSEvent *newEvent = [window
                         nextEventMatchingMask:(NSLeftMouseDraggedMask | NSLeftMouseUpMask)];

    if ([newEvent type] == NSLeftMouseUp)
    {
        break;
    }

    NSPoint newMouseLocation = [window convertBaseToScreen:[newEvent locationInWindow]];

    NSPoint delta = NSMakePoint(
                                roundf(newMouseLocation.x - originalMouseLocation.x),
                                roundf(newMouseLocation.y - originalMouseLocation.y));

    NSRect newFrame = [window frame];
    newFrame.size.width += delta.x*2; // customize
    newFrame.size.height -= delta.y;
    newFrame.origin.y += delta.y;

    [window setFrame:newFrame display:YES animate:NO];
    originalMouseLocation = newMouseLocation; // <-- added this

}

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜