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
}
}
精彩评论