Создание постоянно обновляемого пользовательского элемента управления с надлежащим управлением отмены - PullRequest
3 голосов
/ 06 мая 2011

Я собираю собственный NSView, который обрабатывает два значения через привязки.Я распространяю значения после обновлений, описанные Томом Даллингом в вопросе Можете ли вы вручную реализовать привязки Какао? .Все это прекрасно работает.

Чтобы постоянно обновлять элементы управления, я обновляю и распространяю значения в методе -mouseDragged.Опять же, это работает нормально, но регистрирует промежуточные шаги в NSUndoManager, который я не хочу.Итак, я попытался выдать disableUndoRegistration в -mouseDown, а затем enableUndoRegistration в mouseUp.Естественно, я обновляю и распространяю результаты снова.

Отмена вообще не была зарегистрирована, и я понял, что это потому, что моя функция set не регистрирует отмену, если значение не изменилось:

- (void)setX:(double)newX {
    if (newX != x) {
        [[undoManager prepareWithInvocationTarget:self] setX:x];
        [self willChangeValueForKey:@"x"];
        x = newX;
        [self didChangeValueForKey:@"x"];
    }
}

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

Я мог бы исправить это в методе -setX:, проверив, включен ли менеджер отмены и сохранивтрек старого значения.Тем не менее, я должен быть в состоянии выполнить это изнутри элемента управления, поскольку есть элементы управления с таким точным поведением (например, NSSlider, установленный на непрерывный).

Спасибо!

1 Ответ

2 голосов
/ 09 мая 2011

Разве вы не можете просто использовать beginUndoGrouping и endUndoGrouping?


P.S. Если вам интересно, как классы Какао работают внутри, иногда полезно проверить реализации GNUstep (NSUndoManager находится в GNUstep Base, классы AppKit, такие как NSSliderCell, находятся в графическом интерфейсе GNUstep):

http://wwwmain.gnustep.org/resources/downloads.php?site=http%3A%2F%2Fftpmain.gnustep.org%2Fpub%2Fgnustep%2F#core

...