Question

I am making a simple application that uses a NSSlider, which can be put to it's max or min value with two buttons.The undo manager shall track all changes and allow to undo/redo all changes made using these two buttons.
Here is the interface:

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>
{
@private
    NSUndoManager* undoManager;
}

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSSlider *slider;


- (IBAction)putToMax:(id)sender;
- (IBAction)putToMin:(id)sender;
- (void) setSliderValue: (float) value;

@end

Implementation:

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize slider = _slider;

- (NSUndoManager*) windowWillReturnUndoManager: (NSWindow*) window
{
    return undoManager;
}

- (IBAction)putToMax:(id)sender 
{
    float value= [_slider floatValue];
    [ [undoManager prepareWithInvocationTarget: self] setSliderValue: value];
    if(![undoManager isUndoing])
        [undoManager setActionName: @"Put to Max"];
    NSLog(@"%f value added to the stack",value);
    [_slider setFloatValue: 100.0];
}

- (IBAction)putToMin:(id)sender 
{
    float value= [_slider floatValue];
    [ [undoManager prepareWithInvocationTarget: self] setSliderValue: value];
    if(![undoManager isUndoing])
        [undoManager setActionName: @"Put to Min"];
    NSLog(@"%f value added to the stack",value);
    [_slider setFloatValue: 0.0];
}

- (void) setSliderValue: (float) value
{
    [_slider setFloatValue: value];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
}

- (id) init
{
    self=[super init];
    if(self)
    {
        undoManager=[[NSUndoManager alloc]init];
    }
    return self;
}


@end

And a screenshot of the application:

enter image description here


The undo works fine, but I have problems with redo.

For example after launching the application:

  • I click on the put to max button.
  • Then menu Edit -> Undo put to max.

The slider goes back where it was.

But if I go to menu Edit -> Redo put to max, the slider doesn't go back to it's max position. And I don't understand why.

Was it helpful?

Solution

When the Undo system performs an undo action, it expects you to register the redo actions using the same code as for undo, (except that the NSUndoManager knows it's rewinding - but you should not care).

So add the proper NSUndoManager calls in -setSliderValue:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top