Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

History (Undo/Redo) API

by BlackBerry Development Advisor on ‎02-04-2011 03:36 PM (1,509 Views)

I wrote a small History API (History.as and HistoryEvent.as) that I'd like to share on this forum with anyone that might find it useful for their BlackBerry® PlayBook™ applications.  Fill your boots!

 

Basically, it allows you to record property values of objects to a history stack which can be undone and redone.  I've attached a "HistoryTest" example project that demonstrates the use of QNX LabelButtons ("Undo" and "Redo") to undo and redo changes of a draggable sprite and/or a QNX Slider object.

 

I'm also very open to receive some suggestions, thoughts on if / how the code (History.as and HistoryEvent.as) can be refactored, optimized or broadened.  I'm all ears.

 

 

package developer.mattie.desktop
{
//Imports
import developer.mattie.events.HistoryEvent;
import flash.events.EventDispatcher;

//Class
public class History extends EventDispatcher
{
//Properties
public var maximumStates:uint;

//Variables
private var states:Array = new Array();
private var index:int = -1;
private var firstUndo:Boolean = true;

//Constructor
public function History(maximumStates:uint)
{
this.maximumStates = maximumStates;
}

//Record History State
public function record(name:String, object:Object = null, properties:Array = null, values:Array = null):void
{
states.splice(index + 1);
states.push(state(name, object, properties, values));

if (states.length > maximumStates)
states.splice(0, 1);

index = states.length - 1;
firstUndo = true;
}

//History State Object
private function state(name:String, object:Object, properties:Array, values:Array, redoValues:Array = null):Object
{
var result:Object = new Object();
result.name = name;
result.object = object;
result.properties = properties;
result.values = values;
result.redoValues = redoValues;
return result;
}

//Undo History State
public function undo():void
{
if (undoable)
{
var undoItem:Object = states[index--];
var currentValues:Array = new Array();

for each (var element:Object in undoItem.properties)
currentValues.push(undoItem.object[element]);

if (firstUndo)
{
firstUndo = false;
states.splice(index + 1);
states.push(state(undoItem.name, undoItem.object, undoItem.properties, undoItem.values));
}

var redoItem:Object = states[index + 1];
redoItem.redoValues = currentValues;

dispatchEvent(new HistoryEvent(HistoryEvent.CHANGE, undoItem.name, undoItem.object, undoItem.properties, undoItem.values));
}
}

//Redo History State
public function redo():void
{
if (redoable)
{
index++;
var redoItem:Object = states[index];

dispatchEvent(new HistoryEvent(HistoryEvent.CHANGE, redoItem.name, redoItem.object, redoItem.properties, redoItem.redoValues));
}
}

//Undoable Getter
public function get undoable():Boolean
{
return index >= 0;
}

//Redoable Getter
public function get redoable():Boolean
{
return index < states.length - 1;
}
}
}

 

 

package developer.mattie.events
{
//Imports
import flash.events.Event;

//Class
public class HistoryEvent extends Event
{
//Constants
public static const CHANGE:String = "change";

//Variables
public var name:String;
public var object:Object;
public var properties:Array;
public var values:Array;

//Constructor
public function HistoryEvent(type:String, name:String = null, object:Object = null, properties:Array = null, values:Array = null)
{
super(type);

this.name = name;
this.object = object;
this.properties = properties;
this.values = values;
}

//Clone Override
override public function clone():Event
{
return new HistoryEvent(type, name, object, properties, values);
}
}
}
Users Online
Currently online: 4 members 2,116 guests
Please welcome our newest community members: