Posts Tagged undo

Undo/Redo in MacRuby

As I’m working on my upcoming O’Reilly MacRuby book, I’m writing quite a lot of example code. I have spent the last few weeks digging through most of the Foundation framework classes to hopefully make Cocoa more accessible to Ruby developers.

In some instances things might look quite weird to someone new to Cocoa in some cases, things seem almost too easy. Here is an example implementing a undo/redo functionality using Foundations’ NSUndoManager.

framework 'Foundation'
class Player
  attr_accessor :x, :y
 
  def initialize
    @x = @y = 0
  end
 
  def undo_manager
    @manager ||= NSUndoManager.alloc.init
  end
 
  def left
    undo_manager.prepareWithInvocationTarget(self).right
    @x -= 1
  end
 
  def right
    undo_manager.prepareWithInvocationTarget(self).left
    @x += 1
  end
end

Which you can use as such:

 
>> lara = Player.new
=> <Player:0x200267c80 @y=0 @x=0>
>> lara.undo_manager.canUndo
=> false # normal since we did not do anything yet
>> lara.left
=> -1
>> lara.x # -1
=> -1
>> lara.undo_manager.canUndo
=> true # now we can undo, so let's try
>> lara.undo_manager.undo # undo back to initial position
=> #<NSUndoManager:0x200257560>
>> lara.x
=> 0
>> lara.undo_manager.canUndo
=> false # we can't anymore which makes sense 
>> lara.undo_manager.canRedo
=> true # however we can redo what we just undone
>> lara.undo_manager.redo # redo to before we called undo
=> #<NSUndoManager:0x200257560>
>> lara.x
=> -1

The above example was tested in macirb but as you can see, actions can be undone and redone very very easily. This is just a quick preview of what you can do using Ruby + Cocoa and hopefully it will give you some cool ideas to implement.

, , , ,

9 Comments