开发者

Creating a continuously updating custom control with proper undo management

开发者 https://www.devze.com 2023-03-03 23:57 出处:网络
I am putting together a custom NSView that handles two values through bindings. I am propagating the values upon updates as outlined by Tom Dalling in the question Can you manually implement Cocoa bin

I am putting together a custom NSView that handles two values through bindings. I am propagating the values upon updates as outlined by Tom Dalling in the question Can you manually implement Cocoa bindings?. This all works fine.

In order to make the control update continuously, I update and propagate the values in the -mouseDragged method. Again, this works fine, but it registers the intermediate steps to the NSUndoManager, which I don't want. So, I tried issuing disableUndoRegistration in -mouseDown and then enableUndoRegistration in mouseUp. Naturally I upd开发者_开发问答ate and propagate the results again.

No undo at all was registered, and I realized it's because my set function doesn't register an undo if the value is unchanged:

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

Since the -mouseDragged had already propagated the value, it didn't change when it was sent again in -mouseUp, so the undo was never recorded. I of course want it to undo to the place it was before the initial -mouseDown, so let's say I do this by storing that value in the control and then sending that one again in -mouseUp, before I send the new value. This of course still has the problem that I can see a flash of it going back to its old value.

I could fix this in the -setX: method, by checking if the undo manager is enabled and keeping a track of the old value. However, I should be able to accomplish this from within the control, since there are controls with this exact behaviour (like an NSSlider set to continuous).

Thanks!


Can't you just use beginUndoGrouping and endUndoGrouping?


P.S. If you're curious how Cocoa classes work internally, it can sometimes be helpful to check out the GNUstep implementions (NSUndoManager is in GNUstep Base, AppKit classes like NSSliderCell are in GNUstep GUI):

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

0

精彩评论

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

关注公众号