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.ui.*;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.util.Strings;
public class MapEditorDialog extends Dialog{
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));
}
}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();
}
Vars.ui.hideLoading();
@@ -67,10 +68,9 @@ public class MapEditorDialog extends Dialog{
Vars.ui.showLoading();
Timers.run(3f, () -> {
try{
Gdx.app.error("MINDUSTRYAAAAAAAAAA", "Saving to file: " + result.toString() + " " + result.type());
Pixmaps.write(editor.pixmap(), result);
}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();
}
Vars.ui.hideLoading();
@@ -110,6 +110,7 @@ public class MapEditorDialog extends Dialog{
editor.getMap().name = name;
Timers.run(10f, () -> {
Vars.world.maps().saveAndReload(editor.getMap(), editor.pixmap());
loadDialog.rebuild();
Vars.ui.hideLoading();
});
}else{
@@ -159,45 +160,46 @@ public class MapEditorDialog extends Dialog{
defaults().growY().width(130f).padBottom(-6);
new imagebutton("icon-terrain", isize, () -> {
dialog.show();
}).text("generate");
new imagebutton("icon-terrain", isize, () ->
dialog.show()
).text("generate");
row();
new imagebutton("icon-resize", isize, () -> {
resizeDialog.show();
}).text("resize").padTop(4f);
new imagebutton("icon-resize", isize, () ->
resizeDialog.show()
).text("resize").padTop(4f);
row();
new imagebutton("icon-load-map", isize, () -> {
loadDialog.show();
}).text("load map");
new imagebutton("icon-load-map", isize, () ->
loadDialog.show()
).text("load map");
row();
new imagebutton("icon-save-map", isize, ()->{
saveDialog.show();
}).text("save map");
new imagebutton("icon-save-map", isize, ()->
saveDialog.show()
).text("save map");
row();
new imagebutton("icon-load-image", isize, () -> {
openFile.show();
}).text("load image");
new imagebutton("icon-load-image", isize, () ->
openFile.show()
).text("load image");
row();
new imagebutton("icon-save-image", isize, () -> {
saveFile.show();
}).text("save image");
new imagebutton("icon-save-image", isize, () ->
saveFile.show()
).text("save image");
row();
new imagebutton("icon-back", isize, () -> {
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{
hide();
}
@@ -234,9 +236,7 @@ public class MapEditorDialog extends Dialog{
new table("button"){{
margin(10f);
Slider slider = new Slider(0, MapEditor.brushSizes.length-1, 1, false);
slider.moved(f -> {
editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]);
});
slider.moved(f -> editor.setBrushSize(MapEditor.brushSizes[(int)(float)f]));
new label(() -> "Brush size: " + MapEditor.brushSizes[(int)slider.getValue()]).left();
row();
add(slider).growX().padTop(4f);

View File

@@ -11,52 +11,61 @@ import io.anuke.ucore.scene.ui.TextButton;
import io.anuke.ucore.scene.ui.layout.Table;
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) {
super("load map");
ButtonGroup<TextButton> group = new ButtonGroup<>();
int maxcol = 3;
int i = 0;
Table table = new Table();
table.defaults().size(200f, 90f).pad(4f);
table.pad(10f);
ScrollPane pane = new ScrollPane(table, "horizontal");
pane.setFadeScrollBars(false);
for(Map map : Vars.world.maps().list()){
if(!map.visible) continue;
TextButton button = new TextButton(map.name, "toggle");
button.add(new BorderImage(map.texture, 2f)).size(16*4f);
button.getCells().reverse();
button.clicked(() -> selected = map);
button.getLabelCell().grow().left().padLeft(5f);
group.add(button);
table.add(button);
if(++i % maxcol == 0) table.row();
}
content().add("Select a map to load:");
content().row();
content().add(pane);
rebuild();
TextButton button = new TextButton("Load");
button.setDisabled(() -> selected == null);
button.clicked(() -> {
if(selected != null){
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<>();
int maxcol = 3;
int i = 0;
Table table = new Table();
table.defaults().size(200f, 90f).pad(4f);
table.pad(10f);
ScrollPane pane = new ScrollPane(table, "horizontal");
pane.setFadeScrollBars(false);
for (Map map : Vars.world.maps().list()) {
if (!map.visible) continue;
TextButton button = new TextButton(map.name, "toggle");
button.add(new BorderImage(map.texture, 2f)).size(16 * 4f);
button.getCells().reverse();
button.clicked(() -> selected = map);
button.getLabelCell().grow().left().padLeft(5f);
group.add(button);
table.add(button);
if (++i % maxcol == 0) table.row();
}
content().add("Select a map to load:");
content().row();
content().add(pane);
}
}

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
}
}