Add Operation classes for undoing

This commit is contained in:
Anuken
2017-12-20 19:29:30 -05:00
parent db79d59701
commit a8b6ebacca
4 changed files with 131 additions and 58 deletions

View File

@@ -0,0 +1,14 @@
package io.anuke.mindustry.mapeditor;
import com.badlogic.gdx.graphics.Pixmap;
public abstract class DrawOperation{
protected Pixmap pixmap;
public DrawOperation(Pixmap pixmap){
this.pixmap = pixmap;
}
public abstract void undo();
public abstract void redo();
}

View File

@@ -22,6 +22,7 @@ import io.anuke.ucore.graphics.Pixmaps;
import io.anuke.ucore.scene.builders.*; import io.anuke.ucore.scene.builders.*;
import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Strings;
public class MapEditorDialog extends Dialog{ public class MapEditorDialog extends Dialog{
private MapEditor editor; private MapEditor editor;
@@ -52,7 +53,7 @@ public class MapEditorDialog extends Dialog{
Vars.ui.showError("[orange]Invalid image dimensions![]\nValid map dimensions: " + Arrays.toString(MapEditor.validMapSizes)); Vars.ui.showError("[orange]Invalid image dimensions![]\nValid map dimensions: " + Arrays.toString(MapEditor.validMapSizes));
} }
}catch (Exception e){ }catch (Exception e){
Vars.ui.showError("Error loading image file!"); Vars.ui.showError("Error loading image file:\n" + Strings.parseException((Exception)e.getCause()));
e.printStackTrace(); e.printStackTrace();
} }
Vars.ui.hideLoading(); Vars.ui.hideLoading();
@@ -67,10 +68,9 @@ public class MapEditorDialog extends Dialog{
Vars.ui.showLoading(); Vars.ui.showLoading();
Timers.run(3f, () -> { Timers.run(3f, () -> {
try{ try{
Gdx.app.error("MINDUSTRYAAAAAAAAAA", "Saving to file: " + result.toString() + " " + result.type());
Pixmaps.write(editor.pixmap(), result); Pixmaps.write(editor.pixmap(), result);
}catch (Exception e){ }catch (Exception e){
Vars.ui.showError("Error saving image file!"); Vars.ui.showError("Error saving image file:\n " + Strings.parseException((Exception)e.getCause()));
e.printStackTrace(); e.printStackTrace();
} }
Vars.ui.hideLoading(); Vars.ui.hideLoading();
@@ -110,6 +110,7 @@ public class MapEditorDialog extends Dialog{
editor.getMap().name = name; editor.getMap().name = name;
Timers.run(10f, () -> { Timers.run(10f, () -> {
Vars.world.maps().saveAndReload(editor.getMap(), editor.pixmap()); Vars.world.maps().saveAndReload(editor.getMap(), editor.pixmap());
loadDialog.rebuild();
Vars.ui.hideLoading(); Vars.ui.hideLoading();
}); });
}else{ }else{
@@ -159,45 +160,46 @@ public class MapEditorDialog extends Dialog{
defaults().growY().width(130f).padBottom(-6); defaults().growY().width(130f).padBottom(-6);
new imagebutton("icon-terrain", isize, () -> { new imagebutton("icon-terrain", isize, () ->
dialog.show(); dialog.show()
}).text("generate"); ).text("generate");
row(); row();
new imagebutton("icon-resize", isize, () -> { new imagebutton("icon-resize", isize, () ->
resizeDialog.show(); resizeDialog.show()
}).text("resize").padTop(4f); ).text("resize").padTop(4f);
row(); row();
new imagebutton("icon-load-map", isize, () -> { new imagebutton("icon-load-map", isize, () ->
loadDialog.show(); loadDialog.show()
}).text("load map"); ).text("load map");
row(); row();
new imagebutton("icon-save-map", isize, ()->{ new imagebutton("icon-save-map", isize, ()->
saveDialog.show(); saveDialog.show()
}).text("save map"); ).text("save map");
row(); row();
new imagebutton("icon-load-image", isize, () -> { new imagebutton("icon-load-image", isize, () ->
openFile.show(); openFile.show()
}).text("load image"); ).text("load image");
row(); row();
new imagebutton("icon-save-image", isize, () -> { new imagebutton("icon-save-image", isize, () ->
saveFile.show(); saveFile.show()
}).text("save image"); ).text("save image");
row(); row();
new imagebutton("icon-back", isize, () -> { new imagebutton("icon-back", isize, () -> {
if(!saved){ if(!saved){
Vars.ui.showConfirm("Confirm Exit", "[scarlet]You have unsaved changes![]\nAre you sure you want to exit?", () -> hide()); Vars.ui.showConfirm("Confirm Exit", "[scarlet]You have unsaved changes![]\nAre you sure you want to exit?",
MapEditorDialog.this::hide);
}else{ }else{
hide(); hide();
} }
@@ -234,9 +236,7 @@ public class MapEditorDialog extends Dialog{
new table("button"){{ new table("button"){{
margin(10f); margin(10f);
Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false); Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false);
slider.moved(f -> { slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]));
editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]);
});
new label(() -> "Brush size: " + MapEditor.brushSizes[(int)slider.getValue()]).left(); new label(() -> "Brush size: " + MapEditor.brushSizes[(int)slider.getValue()]).left();
row(); row();
add(slider).growX().padTop(4f); add(slider).growX().padTop(4f);

View File

@@ -11,10 +11,32 @@ import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
public class MapLoadDialog extends FloatingDialog{ public class MapLoadDialog extends FloatingDialog{
Map selected = Vars.world.maps().getMap(0); private Map selected = Vars.world.maps().getMap(0);
public MapLoadDialog(Consumer<Map> loader) { public MapLoadDialog(Consumer<Map> loader) {
super("load map"); super("load map");
rebuild();
TextButton button = new TextButton("Load");
button.setDisabled(() -> selected == null);
button.clicked(() -> {
if (selected != null) {
loader.accept(selected);
hide();
}
});
buttons().defaults().size(200f, 50f);
buttons().addButton("Cancel", this::hide);
buttons().add(button);
}
public void rebuild(){
content().clear();
selected = Vars.world.maps().getMap(0);
ButtonGroup<TextButton> group = new ButtonGroup<>(); ButtonGroup<TextButton> group = new ButtonGroup<>();
int maxcol = 3; int maxcol = 3;
@@ -28,35 +50,22 @@ public class MapLoadDialog extends FloatingDialog{
ScrollPane pane = new ScrollPane(table, "horizontal"); ScrollPane pane = new ScrollPane(table, "horizontal");
pane.setFadeScrollBars(false); pane.setFadeScrollBars(false);
for(Map map : Vars.world.maps().list()){ for (Map map : Vars.world.maps().list()) {
if(!map.visible) continue; if (!map.visible) continue;
TextButton button = new TextButton(map.name, "toggle"); TextButton button = new TextButton(map.name, "toggle");
button.add(new BorderImage(map.texture, 2f)).size(16*4f); button.add(new BorderImage(map.texture, 2f)).size(16 * 4f);
button.getCells().reverse(); button.getCells().reverse();
button.clicked(() -> selected = map); button.clicked(() -> selected = map);
button.getLabelCell().grow().left().padLeft(5f); button.getLabelCell().grow().left().padLeft(5f);
group.add(button); group.add(button);
table.add(button); table.add(button);
if(++i % maxcol == 0) table.row(); if (++i % maxcol == 0) table.row();
} }
content().add("Select a map to load:"); content().add("Select a map to load:");
content().row(); content().row();
content().add(pane); content().add(pane);
TextButton button = new TextButton("Load");
button.setDisabled(() -> selected == null);
button.clicked(() -> {
if(selected != null){
loader.accept(selected);
hide();
}
});
buttons().defaults().size(200f, 50f);
buttons().addButton("Cancel", this::hide);
buttons().add(button);
} }
} }

View File

@@ -0,0 +1,50 @@
package io.anuke.mindustry.mapeditor;
import com.badlogic.gdx.utils.Array;
public class OperationStack{
private Array<DrawOperation> stack = new Array<>();
private int index = 0;
public OperationStack(){
}
public void clear(){
stack.clear();
index = 0;
}
public void add(DrawOperation action){
stack.truncate(stack.size + index);
index = 0;
stack.add(action);
}
public boolean canUndo(){
return !(stack.size - 1 + index < 0);
}
public boolean canRedo(){
return !(index > -1 || stack.size + index < 0);
}
public void undo(){
if(!canUndo()) return;
stack.get(stack.size - 1 + index).undo();
index --;
}
public void redo(){
if(!canRedo()) return;
index ++;
stack.get(stack.size - 1 + index).redo();
}
public void dispose(){
//TODO
}
}