Add Operation classes for undoing
This commit is contained in:
14
core/src/io/anuke/mindustry/mapeditor/DrawOperation.java
Executable file
14
core/src/io/anuke/mindustry/mapeditor/DrawOperation.java
Executable 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();
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
50
core/src/io/anuke/mindustry/mapeditor/OperationStack.java
Executable file
50
core/src/io/anuke/mindustry/mapeditor/OperationStack.java
Executable 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user