Finish all editor features

This commit is contained in:
Anuken
2017-12-19 18:01:16 -05:00
parent a6e72c93f0
commit ed59e7c7cb
42 changed files with 1097 additions and 270 deletions

View File

@@ -0,0 +1,337 @@
package io.anuke.mindustry.ui;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Comparator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.Mindustry;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.function.Consumer;
import io.anuke.ucore.function.Predicate;
import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
public class FileChooser extends FloatingDialog{
private Table files;
private FileHandle homeDirectory = Gdx.files.local(Gdx.files.getExternalStoragePath());
private FileHandle directory = homeDirectory;
private ScrollPane pane;
private TextField navigation, filefield;
private TextButton ok;
private FileHistory stack = new FileHistory();
private Predicate<FileHandle> filter;
private Consumer<FileHandle> selectListener;
private boolean open;
public FileChooser(String title, boolean open, Consumer<FileHandle> result){
this(title, defaultFilter, open, result);
}
public FileChooser(String title, Predicate<FileHandle> filter, boolean open, Consumer<FileHandle> result){
super(title);
this.open = open;
this.filter = filter;
this.selectListener = result;
setupWidgets();
}
private void setupWidgets(){
getCell(content()).maxWidth(Gdx.graphics.getWidth()/2);
content().pad(-Unit.dp.inPixels(10));
Table content = new Table();
filefield = new TextField();
if(!open) Mindustry.platforms.addDialog(filefield);
filefield.setDisabled(open);
ok = new TextButton(open ? "Open" : "Save");
ok.clicked(() -> {
if(ok.isDisabled()) return;
if(selectListener != null)
selectListener.accept(directory.child(filefield.getText()));
hide();
});
filefield.changed(() -> {
ok.setDisabled(filefield.getText().replace(" ", "").isEmpty());
});
filefield.change();
TextButton cancel = new TextButton("Cancel");
cancel.clicked(() -> hide());
navigation = new TextField("");
navigation.setTouchable(Touchable.disabled);
files = new Table();
pane = new ScrollPane(files){
public float getPrefHeight(){
return Gdx.graphics.getHeight();
}
};
pane.setOverscroll(false, false);
pane.setFadeScrollBars(false);
updateFiles(true);
Table icontable = new Table();
float isize = Unit.dp.inPixels(14*2);
ImageButton up = new ImageButton("icon-folder-parent");
up.resizeImage(isize);
up.clicked(()->{
directory = directory.parent();
updateFiles(true);
});
ImageButton back = new ImageButton("icon-arrow-left");
back.resizeImage(isize);
ImageButton forward = new ImageButton("icon-arrow-right");
forward.resizeImage(isize);
forward.clicked(()-> stack.forward());
back.clicked(()-> stack.back());
ImageButton home = new ImageButton("icon-home");
home.resizeImage(isize);
home.clicked(()->{
directory = homeDirectory;
updateFiles(true);
});
icontable.defaults().height(50).growX().uniform();
icontable.add(home);
icontable.add(back);
icontable.add(forward);
icontable.add(up);
Table fieldcontent = new Table();
fieldcontent.bottom().left().add(new Label("File Name:"));
fieldcontent.add(filefield).height(40f).fillX().expandX().padLeft(10f);
Table buttons = new Table();
buttons.defaults().growX().height(50);
buttons.add(cancel);
buttons.add(ok);
content.top().left();
content.add(icontable).expandX().fillX();
content.row();
//content.add(navigation).colspan(3).left().padBottom(10f).expandX().fillX().height(40f);
//content.row();
content.center().add(pane).width(Gdx.graphics.getWidth()/2).colspan(3).units(Unit.px).grow();
content.row();
if(!open){
content.bottom().left().add(fieldcontent).colspan(3).grow().padTop(-2).padBottom(2);
content.row();
}
content.add(buttons).growX();
content().add(content);
//content().add(icontable).expandY().top();
}
private void updateFileFieldStatus(){
if(!open){
ok.setDisabled(filefield.getText().replace(" ", "").isEmpty());
}else{
ok.setDisabled(!directory.child(filefield.getText()).exists() || directory.child(filefield.getText()).isDirectory());
}
}
private FileHandle[] getFileNames(){
FileHandle[] handles = directory.list(new FileFilter(){
@Override
public boolean accept(File file){
return !file.getName().startsWith(".");
}
});
Arrays.sort(handles, new Comparator<FileHandle>(){
@Override
public int compare(FileHandle a, FileHandle b){
if(a.isDirectory() && !b.isDirectory()) return -1;
if( !a.isDirectory() && b.isDirectory()) return 1;
return a.name().compareTo(b.name());
}
});
return handles;
}
private void updateFiles(boolean push){
if(push) stack.push(directory);
navigation.setText(directory.toString());
GlyphLayout layout = Pools.obtain(GlyphLayout.class);
layout.setText(Core.font, navigation.getText());
if(layout.width < navigation.getWidth()){
navigation.setCursorPosition(0);
}else{
navigation.setCursorPosition(navigation.getText().length());
}
Pools.free(layout);
files.clearChildren();
FileHandle[] names = getFileNames();
Image upimage = new Image("icon-folder-parent");
TextButton upbutton = new TextButton(".." + directory.toString());
upbutton.clicked(()->{
directory = directory.parent();
updateFiles(true);
});
upbutton.left().add(upimage).padRight(4f).size(14*2);
upbutton.getCells().reverse();
files.top().left().add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2);
upbutton.getLabel().setAlignment(Align.left);
files.row();
ButtonGroup<TextButton> group = new ButtonGroup<TextButton>();
group.setMinCheckCount(0);
for(FileHandle file : names){
if( !file.isDirectory() && !filter.test(file)) continue; //skip non-filtered files
String filename = file.name();
TextButton button = new TextButton(shorten(filename), "toggle");
group.add(button);
button.clicked(()->{
if( !file.isDirectory()){
filefield.setText(filename);
updateFileFieldStatus();
}else{
directory = directory.child(filename);
updateFiles(true);
}
});
filefield.changed(()->{
button.setChecked(filename.equals(filefield.getText()));
});
Image image = new Image(file.isDirectory() ? "icon-folder" : "icon-file-text");
button.add(image).padRight(4f).size(14*2f);
button.getCells().reverse();
files.top().left().add(button).align(Align.topLeft).fillX().expandX()
.height(50).pad(2).padTop(0).padBottom(0).colspan(2);
button.getLabel().setAlignment(Align.left);
files.row();
}
pane.setScrollY(0f);
updateFileFieldStatus();
if(open) filefield.clearText();
}
private String shorten(String string){
int max = 30;
if(string.length() <= max){
return string;
}else{
return string.substring(0, max - 3).concat("...");
}
}
@Override
public Dialog show(){
super.show();
Core.scene.setScrollFocus(pane);
return this;
}
public void fileSelected(Consumer<FileHandle> listener){
this.selectListener = listener;
}
public class FileHistory{
private Array<FileHandle> history = new Array<FileHandle>();
private int index;
public FileHistory(){
}
public void push(FileHandle file){
if(index != history.size) history.truncate(index);
history.add(file);
index ++;
}
public void back(){
if( !canBack()) return;
index --;
directory = history.get(index - 1);
updateFiles(false);
}
public void forward(){
if( !canForward()) return;
directory = history.get(index);
index ++;
updateFiles(false);
}
public boolean canForward(){
return !(index >= history.size);
}
public boolean canBack(){
return !(index == 1) && index > 0;
}
void print(){
System.out.println("\n\n\n\n\n\n");
int i = 0;
for(FileHandle file : history){
i ++;
if(index == i){
System.out.println("[[" + file.toString() + "]]");
}else{
System.out.println("--" + file.toString() + "--");
}
}
}
}
public static interface FileHandleFilter{
public boolean accept(FileHandle file);
}
public static Predicate<FileHandle> pngFilter = file -> file.extension().equalsIgnoreCase("png");
public static Predicate<FileHandle> jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg");
public static Predicate<FileHandle> defaultFilter = file -> true;
}

View File

@@ -8,7 +8,6 @@ import io.anuke.mindustry.world.Map;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.function.StringSupplier;
import io.anuke.ucore.scene.ui.*;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
@@ -18,6 +17,7 @@ import io.anuke.ucore.scene.utils.Elements;
public class LevelDialog extends FloatingDialog{
private Map selectedMap = Vars.world.maps().getMap(0);
private TextureRegion region = new TextureRegion();
private ScrollPane pane;
public LevelDialog(){
super("Level Select");
@@ -34,7 +34,7 @@ public class LevelDialog extends FloatingDialog{
void setup(){
Table maps = new Table();
ScrollPane pane = new ScrollPane(maps);
pane = new ScrollPane(maps);
pane.setFadeScrollBars(false);
int maxwidth = 4;
@@ -66,7 +66,7 @@ public class LevelDialog extends FloatingDialog{
Table inset = new Table("pane-button");
inset.add("[accent]"+map.name).pad(3f).units(Unit.dp);
inset.row();
inset.add((StringSupplier)(()->"High Score: [accent]" + Settings.getInt("hiscore" + map.name)))
inset.label((() -> "High Score: [accent]" + Settings.getInt("hiscore" + map.name)))
.pad(3f).units(Unit.dp);
inset.pack();
@@ -80,7 +80,21 @@ public class LevelDialog extends FloatingDialog{
ImageButton image = new ImageButton(new TextureRegion(map.texture), "togglemap");
image.row();
image.add(inset).width(images+6).units(Unit.dp);
TextButton[] delete = new TextButton[1];
if(map.custom){
image.row();
delete[0] = image.addButton("Delete", () -> {
Vars.ui.showConfirm("Confirm Delete", "Are you sure you want to delete\nthe map \"[orange]" + map.name + "[]\"?", () -> {
Vars.world.maps().removeMap(map);
reload();
Core.scene.setScrollFocus(pane);
});
}).width(images+16).units(Unit.dp).padBottom(-10f).grow().get();
}
image.clicked(()->{
if(delete[0] != null && delete[0].getClickListener().isOver()){
return;
}
selectedMap = map;
hide();
Vars.control.playMap(selectedMap);
@@ -90,7 +104,7 @@ public class LevelDialog extends FloatingDialog{
stack.add(back);
stack.add(image);
maps.add(stack).width(170).pad(4f).units(Unit.dp);
maps.add(stack).width(170).top().pad(4f).units(Unit.dp);
maps.padRight(Unit.dp.inPixels(26));