Рисование какао, «блокировка» мыши на специальных мероприятиях - PullRequest
3 голосов
/ 30 апреля 2011

С небольшой помощью из последнего вопроса, касающегося рисунков в Какао, я реализовал некоторые основные формы, а также перетаскивание / изменение размера.

Итак, сейчас я пытаюсь выяснить, как создать эффект, подобный Keynote, когда размер фигуры изменяется, и он автоматически соответствует размеру другой фигуры рядом с ней, а затем немного «блокирует» мышь времени.

Первая попытка - использовать функцию задержки, например

NSDate *future = [NSDate dateWithTimeIntervalSinceNow: 0.5 ];
[NSThread sleepUntilDate:future];

реагирование на желаемое событие (например, ширина фигуры == высота). Но это приводит не к желаемому эффекту, так как все приложение зависает на указанное время. В дополнение к этому, я думаю, что пользователь не распознает это как что-то, говорящее «вы достигли специального размера». Показ указаний только на мероприятии не является решением, так как указание отображается, как только выбрана форма.

1 Ответ

4 голосов
/ 01 мая 2011

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

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

Если вы сопоставляете края прямоугольников, вы, вероятно, найдете Foundation Rect Functions , например NSMaxX и NSMaxY, полезными.

- (void)mouseDragged:(NSEvent *)event {
    if( !currMovingDot ) return;
    NSPoint spot = [self convertPoint:[event locationInWindow] 
                             fromView:nil];
    spot.x = MAX(0, MIN(spot.x, self.bounds.size.width));
    spot.y = MAX(0, MIN(spot.y, self.bounds.size.height));

    // Look for Dots whose centerlines are close to
    // the current mouse position
    for( Dot * dot in dots ){
        if (dot == currMovingDot) {
            // Don't snap to myself! Leaving this out causes
            // "snap to grid" effect.
            continue;
        }
        // Where SNAP_DIST is #define'd somewhere
        // something under 10 seems to be a good value
        if( abs(spot.x - dot.position.x) <= SNAP_DIST ){
            spot.x = dot.position.x;
        }
        if( abs(spot.y - dot.position.y) <= SNAP_DIST ){
            spot.y = dot.position.y;
        }
    } 


    currMovingDot.position = spot;
    [self setNeedsDisplay:YES];
}
...