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:
@@ -72,7 +72,7 @@ public class EditorFrame extends ManagedJFrame
|
|||||||
{
|
{
|
||||||
_writer = writer;
|
_writer = writer;
|
||||||
// treat a closing window as a request to quit
|
// treat a closing window as a request to quit
|
||||||
addWindowListener(new WindowAdapter () {
|
addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void windowClosing (WindowEvent e) {
|
public void windowClosing (WindowEvent e) {
|
||||||
handleQuit(null);
|
handleQuit(null);
|
||||||
@@ -96,7 +96,7 @@ public class EditorFrame extends ManagedJFrame
|
|||||||
System.getProperty("user.dir"));
|
System.getProperty("user.dir"));
|
||||||
}
|
}
|
||||||
_chooser = (target == null) ? new JFileChooser() : new JFileChooser(target);
|
_chooser = (target == null) ? new JFileChooser() : new JFileChooser(target);
|
||||||
_chooser.setFileFilter(new FileFilter () {
|
_chooser.setFileFilter(new FileFilter() {
|
||||||
@Override public boolean accept (File f) {
|
@Override public boolean accept (File f) {
|
||||||
return (f.isDirectory() || f.getName().endsWith(".xml"));
|
return (f.isDirectory() || f.getName().endsWith(".xml"));
|
||||||
}
|
}
|
||||||
@@ -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) {
|
||||||
@@ -939,7 +950,7 @@ public class EditorScenePanel extends StageScenePanel
|
|||||||
/**
|
/**
|
||||||
* Paint the specified StageLocation
|
* Paint the specified StageLocation
|
||||||
*/
|
*/
|
||||||
protected void paintLocation(Graphics2D gfx, StageLocation loc, Color color, boolean highlight)
|
protected void paintLocation (Graphics2D gfx, StageLocation loc, Color color, boolean highlight)
|
||||||
{
|
{
|
||||||
// get the portal's center coordinate
|
// get the portal's center coordinate
|
||||||
Point spos = new Point();
|
Point spos = new Point();
|
||||||
@@ -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