Add Undo/Redo to the Scene Editor - Rollback visibility is limited to 20 steps since it's ocpying the entire model at each step.
git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@900 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -272,6 +272,14 @@ public class EditorFrame extends ManagedJFrame
|
|||||||
accel = KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.CTRL_MASK);
|
accel = KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.CTRL_MASK);
|
||||||
MenuUtil.addMenuItem(menuActions, "Update mini view",
|
MenuUtil.addMenuItem(menuActions, "Update mini view",
|
||||||
KeyEvent.VK_M, accel, this, "updateMiniView");
|
KeyEvent.VK_M, accel, this, "updateMiniView");
|
||||||
|
|
||||||
|
accel = KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK);
|
||||||
|
MenuUtil.addMenuItem(menuActions, "Undo",
|
||||||
|
KeyEvent.VK_Z, accel, this, "undo");
|
||||||
|
|
||||||
|
accel = KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK);
|
||||||
|
MenuUtil.addMenuItem(menuActions, "Redo",
|
||||||
|
KeyEvent.VK_Y, accel, this, "redo");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setScene (StageScene scene)
|
protected void setScene (StageScene scene)
|
||||||
@@ -494,6 +502,16 @@ public class EditorFrame extends ManagedJFrame
|
|||||||
_scrollBox.updateView();
|
_scrollBox.updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void undo (ActionEvent evt)
|
||||||
|
{
|
||||||
|
_svpanel.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void redo (ActionEvent evt)
|
||||||
|
{
|
||||||
|
_svpanel.redo();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a request to open the preferences dialog.
|
* Handles a request to open the preferences dialog.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ package com.threerings.stage.tools.editor;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import java.awt.AlphaComposite;
|
import java.awt.AlphaComposite;
|
||||||
@@ -220,6 +221,8 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
*/
|
*/
|
||||||
protected void placeTile (int x, int y)
|
protected void placeTile (int x, int y)
|
||||||
{
|
{
|
||||||
|
markCheckpoint();
|
||||||
|
|
||||||
Rectangle drag = clearTileSelectRegion(x, y);
|
Rectangle drag = clearTileSelectRegion(x, y);
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
@@ -250,6 +253,8 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
*/
|
*/
|
||||||
protected void deleteTile (int x, int y)
|
protected void deleteTile (int x, int y)
|
||||||
{
|
{
|
||||||
|
markCheckpoint();
|
||||||
|
|
||||||
Rectangle drag = clearTileSelectRegion(x, y);
|
Rectangle drag = clearTileSelectRegion(x, y);
|
||||||
log.info("Deleting " + drag);
|
log.info("Deleting " + drag);
|
||||||
|
|
||||||
@@ -301,6 +306,8 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
*/
|
*/
|
||||||
protected void editTile (int x, int y)
|
protected void editTile (int x, int y)
|
||||||
{
|
{
|
||||||
|
markCheckpoint();
|
||||||
|
|
||||||
// bail if we're not hovering over a scene object
|
// bail if we're not hovering over a scene object
|
||||||
if (_hobject == null || !(_hobject instanceof SceneObject)) {
|
if (_hobject == null || !(_hobject instanceof SceneObject)) {
|
||||||
return;
|
return;
|
||||||
@@ -332,6 +339,8 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
*/
|
*/
|
||||||
protected void editPortal (EditablePortal portal)
|
protected void editPortal (EditablePortal portal)
|
||||||
{
|
{
|
||||||
|
markCheckpoint();
|
||||||
|
|
||||||
// create our portal dialog if we haven't yet
|
// create our portal dialog if we haven't yet
|
||||||
if (_dialogPortal == null) {
|
if (_dialogPortal == null) {
|
||||||
_dialogPortal = new PortalDialog(_ctx, this);
|
_dialogPortal = new PortalDialog(_ctx, this);
|
||||||
@@ -397,6 +406,8 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EditorModel.ACTION_PLACE_PORTAL:
|
case EditorModel.ACTION_PLACE_PORTAL:
|
||||||
|
markCheckpoint();
|
||||||
|
|
||||||
Point fcoords = getFullCoords(mx, my);
|
Point fcoords = getFullCoords(mx, my);
|
||||||
// mouse button three is delete
|
// mouse button three is delete
|
||||||
if (event.getButton() == MouseEvent.BUTTON3) {
|
if (event.getButton() == MouseEvent.BUTTON3) {
|
||||||
@@ -1118,6 +1129,49 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void markCheckpoint ()
|
||||||
|
{
|
||||||
|
_undo.preserve();
|
||||||
|
_redo.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void undo ()
|
||||||
|
{
|
||||||
|
if (_undo.size() > 0) {
|
||||||
|
_redo.preserve();
|
||||||
|
_undo.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void redo ()
|
||||||
|
{
|
||||||
|
if (_redo.size() > 0) {
|
||||||
|
_undo.preserve();
|
||||||
|
_redo.rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class UndoStack extends LinkedList<MisoSceneModel>
|
||||||
|
{
|
||||||
|
public void preserve () {
|
||||||
|
addFirst(_model.clone());
|
||||||
|
|
||||||
|
if (size() > MAX_UNDO_SIZE) {
|
||||||
|
removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rollback () {
|
||||||
|
if (size() > 0) {
|
||||||
|
_model = removeFirst();
|
||||||
|
_blocks.clear();
|
||||||
|
refreshScene();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final int MAX_UNDO_SIZE = 20;
|
||||||
|
|
||||||
/** Provides access to stuff. */
|
/** Provides access to stuff. */
|
||||||
protected EditorContext _ctx;
|
protected EditorContext _ctx;
|
||||||
|
|
||||||
@@ -1177,6 +1231,9 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
/** The object currently being edited by the object editor dialog. */
|
/** The object currently being edited by the object editor dialog. */
|
||||||
protected SceneObject _eobject;
|
protected SceneObject _eobject;
|
||||||
|
|
||||||
|
protected UndoStack _undo = new UndoStack();
|
||||||
|
protected UndoStack _redo = new UndoStack();
|
||||||
|
|
||||||
/** The triangle used to render a portal on-screen. */
|
/** The triangle used to render a portal on-screen. */
|
||||||
protected static Polygon _locTri;
|
protected static Polygon _locTri;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user