Сделать MAAttachedWindow изменяемого размера без отказов? - PullRequest
0 голосов
/ 01 мая 2011

Чтобы сделать MAAttachedWindow изменяемым размером, я использую код из здесь :

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

}

Когда я перетаскиваю окно, я могу изменить его размер.Но есть небольшой скачок время от времени.Вы можете скачать проект demo .Запустите проект и щелкните значок в меню состояния, чтобы открыть окно.Попробуйте растянуть назад и вперед, чтобы вы могли легко воспроизвести его.Надеюсь, кто-нибудь может помочь мне исправить это.

1 Ответ

1 голос
/ 01 мая 2011

Я проверил ваш код, и, похоже, ошибка заключалась в том, что иногда NSPoint newMouseLocation = [window convertBaseToScreen:[newEvent locationInWindow]]; возвращал исходное местоположение мыши вместо нового.

Я не уверен, почему это не получится, но, несмотря на этоне оптимальный способ сделать это.Вместо того, чтобы вычислять новый кадр из исходного местоположения мыши, вы должны постоянно обновлять это местоположение и просто перемещать окно на величину, на которую мышь переместилась в текущей итерации отслеживания

Вотисправлена ​​укороченная версия, которая, похоже, устраняет ошибку.

- (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

}

}

...