diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 8c14141445..7ff5d633b3 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -6,6 +6,8 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/res/layout/gdxdialogs_inputtext.xml b/android/res/layout/gdxdialogs_inputtext.xml new file mode 100755 index 0000000000..656600a753 --- /dev/null +++ b/android/res/layout/gdxdialogs_inputtext.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index 698b5697f9..18b98c3c97 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -15,6 +15,7 @@ import android.os.Bundle; import android.telephony.TelephonyManager; import io.anuke.mindustry.io.PlatformFunction; import io.anuke.ucore.function.Callable; +import io.anuke.ucore.scene.ui.TextField; import io.anuke.ucore.scene.ui.layout.Unit; public class AndroidLauncher extends AndroidApplication{ @@ -47,6 +48,11 @@ public class AndroidLauncher extends AndroidApplication{ Intent intent = new Intent( Intent.ACTION_VIEW, marketUri ); startActivity(intent); } + + @Override + public void addDialog(TextField field){ + TextFieldDialogListener.add(field); + } }; Mindustry.donationsCallable = new Callable(){ @Override public void run(){ showDonations(); } }; diff --git a/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java b/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java new file mode 100644 index 0000000000..6d1a2a83a4 --- /dev/null +++ b/android/src/io/anuke/mindustry/AndroidTextFieldDialog.java @@ -0,0 +1,135 @@ +package io.anuke.mindustry; + + +import com.badlogic.gdx.Gdx; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.text.InputFilter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager.LayoutParams; +import android.widget.EditText; + +public class AndroidTextFieldDialog{ + private Activity activity; + private EditText userInput; + private AlertDialog.Builder builder; + private TextPromptListener listener; + private boolean isBuild; + + public AndroidTextFieldDialog() { + this.activity = (Activity)Gdx.app; + load(); + } + + public AndroidTextFieldDialog show() { + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown."); + AlertDialog dialog = builder.create(); + + dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); + + dialog.show(); + + } + }); + + return this; + } + + private AndroidTextFieldDialog load() { + + activity.runOnUiThread(new Runnable() { + + @Override + public void run() { + + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity); + LayoutInflater li = LayoutInflater.from(activity); + + View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null); + + alertDialogBuilder.setView(promptsView); + + userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id")); + + alertDialogBuilder.setCancelable(false); + builder = alertDialogBuilder; + + isBuild = true; + } + }); + + // Wait till TextPrompt is built. + while (!isBuild) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + } + } + + return this; + } + + public int getResourceId(String pVariableName, String pVariableType) { + try { + return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName()); + } catch (Exception e) { + Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName + + " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?"); + e.printStackTrace(); + return -1; + } + } + + public AndroidTextFieldDialog setText(CharSequence value) { + userInput.append(value); + return this; + } + + public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) { + builder.setNegativeButton(label, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + return this; + } + + public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) { + builder.setPositiveButton(label, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + if (listener != null && !userInput.getText().toString().isEmpty()) { + listener.confirm(userInput.getText().toString()); + } + + } + }); + return this; + } + + public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener) { + this.listener = listener; + return this; + } + + public AndroidTextFieldDialog setInputType(int type) { + userInput.setInputType(type); + return this; + } + + public AndroidTextFieldDialog setMaxLength(int length) { + userInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(length) }); + return this; + } + + public static interface TextPromptListener{ + public void confirm(String text); + } + +} diff --git a/android/src/io/anuke/mindustry/TextFieldDialogListener.java b/android/src/io/anuke/mindustry/TextFieldDialogListener.java new file mode 100644 index 0000000000..bb2e935d59 --- /dev/null +++ b/android/src/io/anuke/mindustry/TextFieldDialogListener.java @@ -0,0 +1,71 @@ +package io.anuke.mindustry; + + +import com.badlogic.gdx.Application.ApplicationType; +import com.badlogic.gdx.Gdx; + +import android.text.InputType; +import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener; +import io.anuke.ucore.scene.event.InputEvent; +import io.anuke.ucore.scene.event.InputListener; +import io.anuke.ucore.scene.ui.TextField; +import io.anuke.ucore.scene.utils.ChangeListener; +import io.anuke.ucore.scene.utils.ClickListener; + +public class TextFieldDialogListener extends ClickListener{ + private TextField field; + private int type; + private int max; + + public static void add(TextField field, int type, int max){ + field.addListener(new TextFieldDialogListener(field, type, max)); + field.addListener(new InputListener(){ + public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { + Gdx.input.setOnscreenKeyboardVisible(false); + return false; + } + }); + } + + public static void add(TextField field){ + add(field, 0, 15); + } + + //type - 0 is text, 1 is numbers, 2 is decimals + public TextFieldDialogListener(TextField field, int type, int max){ + this.field = field; + this.type = type; + this.max = max; + } + + public void clicked(final InputEvent event, float x, float y){ + + if(Gdx.app.getType() == ApplicationType.Desktop) return; + + AndroidTextFieldDialog dialog = new AndroidTextFieldDialog(); + + dialog.setTextPromptListener(new TextPromptListener(){ + public void confirm(String text){ + field.clearText(); + field.appendText(text); + field.fire(new ChangeListener.ChangeEvent()); + Gdx.graphics.requestRendering(); + } + }); + + if(type == 0){ + dialog.setInputType(InputType.TYPE_CLASS_TEXT); + }else if(type == 1){ + dialog.setInputType(InputType.TYPE_CLASS_NUMBER); + }else if(type == 2){ + dialog.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); + } + + dialog.setConfirmButtonLabel("OK").setText(field.getText()); + dialog.setCancelButtonLabel("Cancel"); + dialog.setMaxLength(max); + dialog.show(); + event.cancel(); + + } +} diff --git a/build.gradle b/build.gradle index 41c2c5e07b..b9a26c5ee0 100644 --- a/build.gradle +++ b/build.gradle @@ -79,7 +79,7 @@ project(":core") { apply plugin: "java" dependencies { - compile 'com.github.anuken:ucore:9c523c4' + compile 'com.github.anuken:ucore:a525ad2043' compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx-ai:1.8.1" } diff --git a/core/assets-raw/sprites/ui/icon-file-text.png b/core/assets-raw/sprites/ui/icon-file-text.png new file mode 100755 index 0000000000..3aea932bbb Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-file-text.png differ diff --git a/core/assets-raw/sprites/ui/icon-file.png b/core/assets-raw/sprites/ui/icon-file.png new file mode 100644 index 0000000000..8ebd7eba64 Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-file.png differ diff --git a/core/assets-raw/sprites/ui/icon-folder-parent.png b/core/assets-raw/sprites/ui/icon-folder-parent.png new file mode 100755 index 0000000000..82b70ca831 Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-folder-parent.png differ diff --git a/core/assets-raw/sprites/ui/icon-folder.png b/core/assets-raw/sprites/ui/icon-folder.png new file mode 100755 index 0000000000..6d9471196b Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-folder.png differ diff --git a/core/assets-raw/sprites/ui/icon-home.png b/core/assets-raw/sprites/ui/icon-home.png new file mode 100755 index 0000000000..087443880f Binary files /dev/null and b/core/assets-raw/sprites/ui/icon-home.png differ diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 5d792246a9..84e0e16d12 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -34,56 +34,56 @@ blocks/blackrockshadow1 index: -1 blocks/blackstone1 rotate: false - xy: 635, 222 + xy: 716, 267 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone2 rotate: false - xy: 625, 174 + xy: 716, 257 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstone3 rotate: false - xy: 733, 264 + xy: 726, 269 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock1 rotate: false - xy: 728, 254 + xy: 726, 259 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock2 rotate: false - xy: 728, 244 + xy: 736, 264 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneblock3 rotate: false - xy: 728, 234 + xy: 716, 247 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/blackstoneedge rotate: false - xy: 519, 201 + xy: 521, 153 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/block rotate: false - xy: 738, 244 + xy: 736, 254 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -118,112 +118,112 @@ blocks/chainturret-icon index: -1 blocks/coal1 rotate: false - xy: 743, 264 + xy: 726, 239 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal2 rotate: false - xy: 748, 254 + xy: 736, 234 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coal3 rotate: false - xy: 748, 244 + xy: 333, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coaldrill rotate: false - xy: 748, 234 + xy: 343, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator rotate: false - xy: 801, 454 + xy: 353, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalgenerator-top rotate: false - xy: 801, 444 + xy: 363, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/coalpurifier rotate: false - xy: 801, 434 + xy: 373, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/combustiongenerator rotate: false - xy: 801, 424 + xy: 383, 91 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/compositewall rotate: false - xy: 797, 410 + xy: 393, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduit rotate: false - xy: 797, 400 + xy: 403, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitbottom rotate: false - xy: 333, 91 + xy: 413, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduitliquid rotate: false - xy: 343, 91 + xy: 423, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conduittop rotate: false - xy: 353, 91 + xy: 433, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyor rotate: false - xy: 363, 91 + xy: 443, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyormove rotate: false - xy: 373, 91 + xy: 453, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/conveyortunnel rotate: false - xy: 383, 91 + xy: 463, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -237,56 +237,56 @@ blocks/core index: -1 blocks/cross rotate: false - xy: 393, 95 + xy: 473, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/crucible rotate: false - xy: 403, 95 + xy: 483, 95 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/deepwater rotate: false - xy: 413, 95 + xy: 813, 449 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt1 rotate: false - xy: 423, 95 + xy: 813, 439 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt2 rotate: false - xy: 433, 95 + xy: 813, 429 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirt3 rotate: false - xy: 443, 95 + xy: 813, 419 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/dirtedge rotate: false - xy: 519, 187 + xy: 537, 169 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/door rotate: false - xy: 453, 95 + xy: 592, 219 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -300,7 +300,7 @@ blocks/door-large index: -1 blocks/door-large-icon rotate: false - xy: 463, 95 + xy: 602, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -314,21 +314,21 @@ blocks/door-large-open index: -1 blocks/door-open rotate: false - xy: 473, 95 + xy: 612, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/doubleturret rotate: false - xy: 709, 279 + xy: 833, 487 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/duriumwall rotate: false - xy: 483, 95 + xy: 622, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -342,266 +342,266 @@ blocks/duriumwall-large index: -1 blocks/duriumwall-large-icon rotate: false - xy: 656, 222 + xy: 632, 222 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/enemyspawn rotate: false - xy: 666, 222 + xy: 269, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/flameturret rotate: false - xy: 721, 281 + xy: 845, 487 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/fluxpump rotate: false - xy: 649, 202 + xy: 289, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass1 rotate: false - xy: 659, 212 + xy: 299, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass2 rotate: false - xy: 649, 192 + xy: 309, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grass3 rotate: false - xy: 659, 202 + xy: 319, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock1 rotate: false - xy: 659, 192 + xy: 393, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassblock2 rotate: false - xy: 669, 212 + xy: 403, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/grassedge rotate: false - xy: 547, 201 + xy: 709, 277 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/ice1 rotate: false - xy: 669, 202 + xy: 413, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice2 rotate: false - xy: 669, 192 + xy: 423, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ice3 rotate: false - xy: 676, 222 + xy: 433, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iceedge rotate: false - xy: 547, 187 + xy: 656, 230 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/icerock1 rotate: false - xy: 679, 212 + xy: 443, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerock2 rotate: false - xy: 679, 202 + xy: 453, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow1 rotate: false - xy: 679, 192 + xy: 463, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow1 rotate: false - xy: 679, 192 + xy: 463, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/icerockshadow2 rotate: false - xy: 649, 182 + xy: 473, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rockshadow2 rotate: false - xy: 649, 182 + xy: 473, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron1 rotate: false - xy: 309, 87 + xy: 531, 129 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron2 rotate: false - xy: 319, 87 + xy: 529, 119 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/iron3 rotate: false - xy: 393, 85 + xy: 527, 109 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/irondrill rotate: false - xy: 403, 85 + xy: 881, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/ironwall rotate: false - xy: 413, 85 + xy: 891, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/junction rotate: false - xy: 423, 85 + xy: 901, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/laserturret rotate: false - xy: 613, 184 + xy: 749, 277 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/lava rotate: false - xy: 433, 85 + xy: 911, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/lavaedge rotate: false - xy: 568, 213 + xy: 670, 230 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/lavasmelter rotate: false - xy: 443, 85 + xy: 921, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquiditemjunction rotate: false - xy: 453, 85 + xy: 931, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidjunction rotate: false - xy: 463, 85 + xy: 941, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/liquidrouter rotate: false - xy: 473, 85 + xy: 951, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/machineturret rotate: false - xy: 625, 184 + xy: 575, 203 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/megarepairturret rotate: false - xy: 637, 210 + xy: 575, 191 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mortarturret rotate: false - xy: 637, 198 + xy: 575, 179 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/mossblock rotate: false - xy: 493, 88 + xy: 971, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/mossstone rotate: false - xy: 493, 88 + xy: 971, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -622,7 +622,7 @@ blocks/nuclearreactor-center index: -1 blocks/nuclearreactor-icon rotate: false - xy: 513, 90 + xy: 991, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -643,329 +643,329 @@ blocks/nuclearreactor-small index: -1 blocks/oil rotate: false - xy: 523, 90 + xy: 1001, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/oiledge rotate: false - xy: 561, 199 + xy: 723, 279 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/oilrefinery rotate: false - xy: 747, 291 + xy: 749, 267 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/omnidrill rotate: false - xy: 745, 281 + xy: 801, 413 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/plasmaturret rotate: false - xy: 637, 186 + xy: 575, 167 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/playerspawn rotate: false - xy: 757, 291 + xy: 800, 403 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerbooster rotate: false - xy: 755, 281 + xy: 811, 409 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyor rotate: false - xy: 493, 78 + xy: 810, 399 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/poweredconveyormove rotate: false - xy: 503, 78 + xy: 602, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaser rotate: false - xy: 513, 80 + xy: 612, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlasercorner rotate: false - xy: 523, 80 + xy: 622, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/powerlaserrouter rotate: false - xy: 753, 271 + xy: 632, 212 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduit rotate: false - xy: 683, 233 + xy: 599, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduitbottom rotate: false - xy: 693, 233 + xy: 599, 192 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pulseconduittop rotate: false - xy: 686, 223 + xy: 609, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/pump rotate: false - xy: 696, 223 + xy: 599, 182 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/repairturret rotate: false - xy: 733, 274 + xy: 580, 215 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/rock1 rotate: false - xy: 689, 213 + xy: 619, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rock2 rotate: false - xy: 689, 203 + xy: 599, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/router rotate: false - xy: 689, 193 + xy: 609, 182 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator rotate: false - xy: 689, 183 + xy: 619, 192 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/rtgenerator-top rotate: false - xy: 699, 213 + xy: 629, 202 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand1 rotate: false - xy: 699, 203 + xy: 609, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand2 rotate: false - xy: 699, 193 + xy: 619, 182 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sand3 rotate: false - xy: 699, 183 + xy: 629, 192 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock1 rotate: false - xy: 716, 223 + xy: 619, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock2 rotate: false - xy: 709, 213 + xy: 629, 182 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandblock3 rotate: false - xy: 709, 203 + xy: 629, 172 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sandedge rotate: false - xy: 561, 185 + xy: 698, 229 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/shadow rotate: false - xy: 721, 269 + xy: 704, 263 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shieldgenerator rotate: false - xy: 709, 183 + xy: 642, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shotgunturret rotate: false - xy: 716, 257 + xy: 704, 251 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/shrub rotate: false - xy: 719, 193 + xy: 639, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/shrubshadow rotate: false - xy: 719, 183 + xy: 639, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/smelter rotate: false - xy: 726, 223 + xy: 599, 162 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/sniperturret rotate: false - xy: 716, 245 + xy: 587, 203 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/snow1 rotate: false - xy: 736, 224 + xy: 609, 162 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow2 rotate: false - xy: 746, 224 + xy: 619, 162 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snow3 rotate: false - xy: 729, 213 + xy: 629, 162 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock1 rotate: false - xy: 729, 203 + xy: 639, 158 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock2 rotate: false - xy: 729, 193 + xy: 652, 218 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowblock3 rotate: false - xy: 729, 183 + xy: 652, 208 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/snowedge rotate: false - xy: 575, 199 + xy: 805, 485 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/sorter rotate: false - xy: 739, 214 + xy: 649, 198 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyor rotate: false - xy: 739, 204 + xy: 649, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelconveyormove rotate: false - xy: 739, 194 + xy: 649, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/steelwall rotate: false - xy: 739, 184 + xy: 649, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -979,98 +979,98 @@ blocks/steelwall-large index: -1 blocks/steelwall-large-icon rotate: false - xy: 749, 214 + xy: 649, 158 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone1 rotate: false - xy: 749, 204 + xy: 662, 220 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone2 rotate: false - xy: 749, 194 + xy: 662, 210 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stone3 rotate: false - xy: 749, 184 + xy: 672, 220 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock1 rotate: false - xy: 756, 224 + xy: 672, 210 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock2 rotate: false - xy: 759, 214 + xy: 682, 219 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneblock3 rotate: false - xy: 759, 204 + xy: 692, 219 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonedrill rotate: false - xy: 759, 194 + xy: 702, 219 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stoneedge rotate: false - xy: 575, 185 + xy: 805, 471 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/stoneformer rotate: false - xy: 759, 184 + xy: 682, 209 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/stonewall rotate: false - xy: 519, 126 + xy: 692, 209 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter rotate: false - xy: 519, 116 + xy: 702, 209 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/teleporter-top rotate: false - xy: 625, 164 + xy: 493, 78 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/thermalgenerator rotate: false - xy: 637, 176 + xy: 503, 78 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1084,56 +1084,56 @@ blocks/titancannon index: -1 blocks/titancannon-icon rotate: false - xy: 716, 233 + xy: 587, 191 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/titanium1 rotate: false - xy: 635, 166 + xy: 513, 80 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium2 rotate: false - xy: 647, 172 + xy: 523, 80 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titanium3 rotate: false - xy: 657, 172 + xy: 1011, 479 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumdrill rotate: false - xy: 667, 172 + xy: 746, 254 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumpurifier rotate: false - xy: 677, 172 + xy: 746, 244 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumshieldwall rotate: false - xy: 645, 162 + xy: 746, 234 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/titaniumwall rotate: false - xy: 655, 162 + xy: 659, 198 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1147,70 +1147,70 @@ blocks/titaniumwall-large index: -1 blocks/titaniumwall-large-icon rotate: false - xy: 665, 162 + xy: 659, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/turret rotate: false - xy: 601, 172 + xy: 587, 179 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 blocks/uranium1 rotate: false - xy: 645, 152 + xy: 659, 158 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium2 rotate: false - xy: 655, 152 + xy: 669, 200 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uranium3 rotate: false - xy: 665, 152 + xy: 669, 190 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/uraniumdrill rotate: false - xy: 675, 152 + xy: 669, 180 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/water rotate: false - xy: 513, 70 + xy: 669, 170 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 blocks/wateredge rotate: false - xy: 513, 100 + xy: 819, 485 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 blocks/waveturret rotate: false - xy: 613, 172 + xy: 587, 167 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 bullet rotate: false - xy: 738, 234 + xy: 736, 244 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1294,14 +1294,14 @@ enemies/targetenemy-t1 index: -1 enemies/enemy-t2 rotate: false - xy: 533, 201 + xy: 521, 139 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 enemies/enemy-t3 rotate: false - xy: 533, 187 + xy: 513, 100 size: 12, 12 orig: 12, 12 offset: 0, 0 @@ -1392,63 +1392,63 @@ enemies/healerenemy-t3 index: -1 enemies/mortarenemy-t1 rotate: false - xy: 189, 89 + xy: 731, 298 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t2 rotate: false - xy: 205, 89 + xy: 747, 301 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/mortarenemy-t3 rotate: false - xy: 221, 89 + xy: 524, 215 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t1 rotate: false - xy: 237, 89 + xy: 540, 215 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t2 rotate: false - xy: 253, 89 + xy: 519, 199 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/rapidenemy-t3 rotate: false - xy: 731, 298 + xy: 519, 183 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t1 rotate: false - xy: 747, 301 + xy: 535, 199 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t2 rotate: false - xy: 524, 215 + xy: 535, 183 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 enemies/tankenemy-t3 rotate: false - xy: 540, 215 + xy: 521, 167 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1483,56 +1483,56 @@ enemyarrow index: -1 icon-coal rotate: false - xy: 659, 182 + xy: 483, 85 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-dirium rotate: false - xy: 669, 182 + xy: 493, 88 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-iron rotate: false - xy: 679, 182 + xy: 503, 88 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-steel rotate: false - xy: 269, 87 + xy: 513, 90 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-stone rotate: false - xy: 279, 87 + xy: 523, 90 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-titanium rotate: false - xy: 289, 87 + xy: 521, 129 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 icon-uranium rotate: false - xy: 299, 87 + xy: 519, 119 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 laser rotate: false - xy: 596, 215 + xy: 797, 406 size: 1, 12 orig: 1, 12 offset: 0, 0 @@ -1553,35 +1553,35 @@ laserfull index: -1 mechs/mech-standard rotate: false - xy: 582, 215 + xy: 684, 229 size: 12, 12 orig: 12, 12 offset: 0, 0 index: -1 shell rotate: false - xy: 709, 193 + xy: 642, 218 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot rotate: false - xy: 719, 213 + xy: 639, 198 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 shot-long rotate: false - xy: 719, 203 + xy: 639, 188 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 titanshell rotate: false - xy: 675, 162 + xy: 659, 178 size: 8, 8 orig: 8, 8 offset: 0, 0 @@ -1673,21 +1673,21 @@ ui/check-over index: -1 ui/clear rotate: false - xy: 556, 215 + xy: 819, 473 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/cursor rotate: false - xy: 645, 222 + xy: 92, 88 size: 4, 4 orig: 4, 4 offset: 0, 0 index: -1 ui/icon-areaDelete rotate: false - xy: 733, 286 + xy: 857, 487 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1701,14 +1701,14 @@ ui/icon-arrow index: -1 ui/icon-arrow-left rotate: false - xy: 656, 232 + xy: 869, 487 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-arrow-right rotate: false - xy: 668, 232 + xy: 805, 459 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1750,21 +1750,21 @@ ui/icon-close-over index: -1 ui/icon-crafting rotate: false - xy: 1012, 489 + xy: 801, 447 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-cursor rotate: false - xy: 704, 263 + xy: 801, 435 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-defense rotate: false - xy: 704, 251 + xy: 801, 423 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1778,7 +1778,7 @@ ui/icon-discord index: -1 ui/icon-distribution rotate: false - xy: 704, 239 + xy: 1012, 489 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1790,6 +1790,20 @@ ui/icon-donate orig: 14, 14 offset: 0, 0 index: -1 +ui/icon-file + rotate: false + xy: 640, 248 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +ui/icon-file-text + rotate: false + xy: 598, 232 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icon-fill rotate: false xy: 742, 349 @@ -1797,30 +1811,51 @@ ui/icon-fill orig: 16, 16 offset: 0, 0 index: -1 +ui/icon-folder + rotate: false + xy: 614, 232 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 +ui/icon-folder-parent + rotate: false + xy: 630, 232 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icon-hold rotate: false - xy: 589, 203 + xy: 551, 203 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-holdDelete rotate: false - xy: 589, 191 + xy: 551, 191 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 +ui/icon-home + rotate: false + xy: 693, 275 + size: 14, 14 + orig: 14, 14 + offset: 0, 0 + index: -1 ui/icon-info rotate: false - xy: 599, 220 + xy: 551, 179 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-load rotate: false - xy: 640, 248 + xy: 656, 260 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1834,21 +1869,21 @@ ui/icon-loading index: -1 ui/icon-menu rotate: false - xy: 611, 220 + xy: 556, 215 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-none rotate: false - xy: 623, 220 + xy: 568, 215 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-pause rotate: false - xy: 601, 208 + xy: 563, 203 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -1869,35 +1904,35 @@ ui/icon-pick index: -1 ui/icon-play rotate: false - xy: 601, 196 + xy: 563, 191 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-play-2 rotate: false - xy: 598, 232 + xy: 672, 260 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-power rotate: false - xy: 613, 208 + xy: 563, 179 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-production rotate: false - xy: 613, 196 + xy: 551, 167 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-quit rotate: false - xy: 614, 232 + xy: 656, 244 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1911,77 +1946,77 @@ ui/icon-redo index: -1 ui/icon-rotate rotate: false - xy: 630, 232 + xy: 672, 244 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-arrow rotate: false - xy: 693, 275 + xy: 688, 259 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-left rotate: false - xy: 656, 260 + xy: 688, 243 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-rotate-right rotate: false - xy: 672, 260 + xy: 189, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-save rotate: false - xy: 656, 244 + xy: 205, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-settings rotate: false - xy: 625, 208 + xy: 563, 167 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-terrain rotate: false - xy: 672, 244 + xy: 221, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-tools rotate: false - xy: 688, 259 + xy: 237, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 index: -1 ui/icon-touch rotate: false - xy: 625, 196 + xy: 737, 286 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-touchDelete rotate: false - xy: 589, 179 + xy: 749, 289 size: 10, 10 orig: 10, 10 offset: 0, 0 index: -1 ui/icon-tutorial rotate: false - xy: 688, 243 + xy: 253, 89 size: 14, 14 orig: 14, 14 offset: 0, 0 @@ -1995,7 +2030,7 @@ ui/icon-undo index: -1 ui/icon-weapon rotate: false - xy: 601, 184 + xy: 737, 274 size: 10, 10 orig: 10, 10 offset: 0, 0 @@ -2079,7 +2114,7 @@ ui/selection index: -1 ui/slider rotate: false - xy: 680, 234 + xy: 746, 264 size: 1, 8 orig: 1, 8 offset: 0, 0 @@ -2107,7 +2142,7 @@ ui/slider-knob-over index: -1 ui/slider-vertical rotate: false - xy: 706, 226 + xy: 592, 216 size: 8, 1 orig: 8, 1 offset: 0, 0 @@ -2216,42 +2251,42 @@ ui/window-empty index: -1 weapons/blaster rotate: false - xy: 738, 254 + xy: 726, 249 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/flamer rotate: false - xy: 649, 212 + xy: 279, 87 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/mortar rotate: false - xy: 483, 85 + xy: 961, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/multigun rotate: false - xy: 503, 88 + xy: 981, 485 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/railgun rotate: false - xy: 706, 229 + xy: 609, 192 size: 8, 8 orig: 8, 8 offset: 0, 0 index: -1 weapons/triblaster rotate: false - xy: 635, 156 + xy: 659, 168 size: 8, 8 orig: 8, 8 offset: 0, 0 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index ddfb6297ef..eced6084b0 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java index c5aa9ff0ff..91722e269e 100644 --- a/core/src/io/anuke/mindustry/Mindustry.java +++ b/core/src/io/anuke/mindustry/Mindustry.java @@ -13,6 +13,7 @@ import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; import io.anuke.ucore.function.Callable; import io.anuke.ucore.modules.ModuleCore; +import io.anuke.ucore.scene.ui.TextField; public class Mindustry extends ModuleCore { public static Callable donationsCallable; @@ -22,6 +23,7 @@ public class Mindustry extends ModuleCore { @Override public String format(Date date){ return "invalid date"; } @Override public String format(int number){ return number + ""; } @Override public void openLink(String link){ } + @Override public void addDialog(TextField field){} }; //always initialize blocks in this order, otherwise there are ID errors diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java index 3475b4d695..dc1d181fec 100644 --- a/core/src/io/anuke/mindustry/core/UI.java +++ b/core/src/io/anuke/mindustry/core/UI.java @@ -23,6 +23,7 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Blocks; import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.ucore.core.*; +import io.anuke.ucore.function.Listenable; import io.anuke.ucore.function.VisibilityProvider; import io.anuke.ucore.modules.SceneModule; import io.anuke.ucore.scene.Element; @@ -469,4 +470,16 @@ public class UI extends SceneModule{ ((HudFragment)hudfrag).updateItems(); } + public void showConfirm(String title, String text, Listenable confirmed){ + FloatingDialog dialog = new FloatingDialog(title); + dialog.content().add(text).pad(4f).units(Unit.dp); + dialog.buttons().defaults().size(200f, 54f).pad(2f).units(Unit.dp); + dialog.buttons().addButton("Cancel", dialog::hide); + dialog.buttons().addButton("OK", () -> { + dialog.hide(); + confirmed.listen(); + }); + dialog.show(); + } + } diff --git a/core/src/io/anuke/mindustry/input/AndroidInput.java b/core/src/io/anuke/mindustry/input/AndroidInput.java index fb5185d0f8..cdf661ab46 100644 --- a/core/src/io/anuke/mindustry/input/AndroidInput.java +++ b/core/src/io/anuke/mindustry/input/AndroidInput.java @@ -119,6 +119,7 @@ public class AndroidInput extends InputHandler{ @Override public void update(){ + enableHold = player.breakMode == PlaceMode.holdDelete; if(enableHold && player.recipe != null && Gdx.input.isTouched(0) && Mathf.near2d(lmousex, lmousey, Gdx.input.getX(0), Gdx.input.getY(0), Unit.dp.inPixels(50)) && !ui.hasMouse()){ diff --git a/core/src/io/anuke/mindustry/input/PlaceMode.java b/core/src/io/anuke/mindustry/input/PlaceMode.java index 64fbb35a0a..666b9cbab8 100644 --- a/core/src/io/anuke/mindustry/input/PlaceMode.java +++ b/core/src/io/anuke/mindustry/input/PlaceMode.java @@ -82,7 +82,7 @@ public enum PlaceMode{ holdDelete{ { delete = true; - shown = false; + shown = true; } public void draw(int tilex, int tiley, int endx, int endy){ diff --git a/core/src/io/anuke/mindustry/io/PlatformFunction.java b/core/src/io/anuke/mindustry/io/PlatformFunction.java index 28a142b34c..32e19363cd 100644 --- a/core/src/io/anuke/mindustry/io/PlatformFunction.java +++ b/core/src/io/anuke/mindustry/io/PlatformFunction.java @@ -2,8 +2,11 @@ package io.anuke.mindustry.io; import java.util.Date; +import io.anuke.ucore.scene.ui.TextField; + public interface PlatformFunction{ public String format(Date date); public String format(int number); public void openLink(String link); + public void addDialog(TextField field); } diff --git a/core/src/io/anuke/mindustry/mapeditor/EditorTool.java b/core/src/io/anuke/mindustry/mapeditor/EditorTool.java index edd1be18fc..15a59562d2 100644 --- a/core/src/io/anuke/mindustry/mapeditor/EditorTool.java +++ b/core/src/io/anuke/mindustry/mapeditor/EditorTool.java @@ -12,11 +12,19 @@ import io.anuke.mindustry.world.ColorMapper; public enum EditorTool{ pencil{ + { + edit = true; + } + public void touched(MapEditor editor, int x, int y){ editor.draw(x, y); } }, fill{ + { + edit = true; + } + public void touched(MapEditor editor, int x, int y){ Pixmap pix = editor.pixmap(); @@ -63,6 +71,7 @@ public enum EditorTool{ } }, zoom; + boolean edit; public void touched(MapEditor editor, int x, int y){ diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java index 99021f5e35..b18831f1f6 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditor.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditor.java @@ -84,13 +84,13 @@ public class MapEditor{ this.brushSize = 1; if(map.pixmap == null){ pixmap = new Pixmap(256, 256, Format.RGB888); - pixmap.setColor(ColorMapper.getColor(Blocks.stone)); + pixmap.setColor(ColorMapper.getColor(drawBlock)); pixmap.fill(); texture = new Texture(pixmap); }else{ pixmap = map.pixmap; - pixmap.setColor(ColorMapper.getColor(Blocks.stone)); texture = map.texture; + pixmap.setColor(ColorMapper.getColor(drawBlock)); } } @@ -161,8 +161,24 @@ public class MapEditor{ return pixmap; } + public void setPixmap(Pixmap out){ + if(pixmap.getWidth() == out.getWidth() && pixmap.getHeight() == out.getHeight()){ + pixmap.dispose(); + pixmap = out; + texture.draw(out, 0, 0); + }else{ + pixmap.dispose(); + texture.dispose(); + pixmap = out; + texture = new Texture(out); + } + pixmap.setColor(ColorMapper.getColor(drawBlock)); + map.pixmap = pixmap; + map.texture = texture; + } + public void resize(int width, int height){ - Pixmap out = Pixmaps.resize(pixmap, width, height); + Pixmap out = Pixmaps.resize(pixmap, width, height, ColorMapper.getColor(Blocks.stone)); pixmap.dispose(); pixmap = out; texture.dispose(); @@ -174,5 +190,6 @@ public class MapEditor{ filterPixmap = null; filterTexture = null; } + pixmap.setColor(ColorMapper.getColor(drawBlock)); } } diff --git a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java index 55e7bc36a2..8ba595d51b 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapEditorDialog.java @@ -1,8 +1,13 @@ package io.anuke.mindustry.mapeditor; +import java.util.Arrays; + +import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.ui.FileChooser; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.ColorMapper; import io.anuke.mindustry.world.ColorMapper.BlockPair; @@ -12,6 +17,7 @@ import io.anuke.mindustry.world.blocks.SpecialBlocks; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Timers; +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; @@ -24,6 +30,8 @@ public class MapEditorDialog extends Dialog{ private MapLoadDialog loadDialog; private MapSaveDialog saveDialog; private MapResizeDialog resizeDialog; + private FileChooser openFile, saveFile; + private boolean saved = false; private ButtonGroup blockgroup; @@ -33,8 +41,54 @@ public class MapEditorDialog extends Dialog{ dialog = new MapGenerateDialog(editor); view = new MapView(editor); + openFile = new FileChooser("Load Image", FileChooser.pngFilter, true, file -> { + Vars.ui.showLoading(); + Timers.run(3f, () -> { + try{ + Pixmap pixmap = new Pixmap(file); + if(verifySize(pixmap)){ + editor.setPixmap(pixmap); + }else{ + Vars.ui.showError("[orange]Invalid image dimensions![]\nValid map dimensions: " + Arrays.toString(MapEditor.validMapSizes)); + } + }catch (Exception e){ + Vars.ui.showError("Error loading image file!"); + e.printStackTrace(); + } + Vars.ui.hideLoading(); + }); + }); + + saveFile = new FileChooser("Save Image", false, file -> { + if(!file.extension().toLowerCase().equals(".png")){ + file = file.parent().child(file.nameWithoutExtension() + ".png"); + } + FileHandle result = file; + Vars.ui.showLoading(); + Timers.run(3f, () -> { + try{ + Pixmaps.write(editor.pixmap(), result); + }catch (Exception e){ + Vars.ui.showError("Error saving image file!"); + e.printStackTrace(); + } + Vars.ui.hideLoading(); + }); + }); + loadDialog = new MapLoadDialog(map -> { - editor.beginEdit(map); + saveDialog.setFieldText(map.name); + Vars.ui.showLoading(); + + Timers.run(3f, () -> { + Map copy = new Map(); + copy.name = map.name; + copy.id = -1; + copy.pixmap = Pixmaps.copy(map.pixmap); + copy.texture = new Texture(copy.pixmap); + editor.beginEdit(copy); + Vars.ui.hideLoading(); + }); }); resizeDialog = new MapResizeDialog(editor, (x, y) -> { @@ -51,6 +105,7 @@ public class MapEditorDialog extends Dialog{ saveDialog = new MapSaveDialog(name -> { Vars.ui.showLoading(); if(verifyMap()){ + saved = true; editor.getMap().name = name; Timers.run(10f, () -> { Vars.world.maps().saveAndReload(editor.getMap(), editor.pixmap()); @@ -70,11 +125,16 @@ public class MapEditorDialog extends Dialog{ build.end(); shown(() -> { + saved = true; editor.beginEdit(new Map()); Core.scene.setScrollFocus(view); }); } + public void resetSaved(){ + saved = false; + } + public void updateSelectedBlock(){ Block block = editor.getDrawBlock(); int i = 0; @@ -103,6 +163,12 @@ public class MapEditorDialog extends Dialog{ row(); + new imagebutton("icon-cursor", 10f*3f, () -> { + resizeDialog.show(); + }).text("resize").padTop(4f); + + row(); + new imagebutton("icon-load", isize, () -> { loadDialog.show(); }).text("load map"); @@ -116,25 +182,23 @@ public class MapEditorDialog extends Dialog{ row(); new imagebutton("icon-load", isize, () -> { - + openFile.show(); }).text("load image"); row(); new imagebutton("icon-save", isize, () -> { - + saveFile.show(); }).text("save image"); row(); - new imagebutton("icon-cursor", 10f*3f, () -> { - resizeDialog.show(); - }).text("resize").padTop(4f); - - row(); - new imagebutton("icon-arrow-left", isize, () -> { - hide(); + if(!saved){ + Vars.ui.showConfirm("Confirm Exit", "[scarlet]You have unsaved changes![]\nAre you sure you want to exit?", () -> hide()); + }else{ + hide(); + } }).padBottom(0).text("back"); }}.left().growY().end(); @@ -186,6 +250,18 @@ public class MapEditorDialog extends Dialog{ }}.grow().end(); } + private boolean verifySize(Pixmap pix){ + boolean w = false, h = false; + for(int i : MapEditor.validMapSizes){ + if(pix.getWidth() == i) + w = true; + if(pix.getHeight() == i) + h = true; + } + + return w && h; + } + private boolean verifyMap(){ int psc = ColorMapper.getColor(SpecialBlocks.playerSpawn); int esc = ColorMapper.getColor(SpecialBlocks.enemySpawn); @@ -221,6 +297,7 @@ public class MapEditorDialog extends Dialog{ private void addBlockSelection(Table table){ Table content = new Table(); ScrollPane pane = new ScrollPane(content, "volume"); + pane.setScrollingDisabled(true, false); pane.setFadeScrollBars(false); pane.setOverscroll(true, false); ButtonGroup group = new ButtonGroup<>(); @@ -242,10 +319,12 @@ public class MapEditorDialog extends Dialog{ } } - group.getButtons().get(3).setChecked(true); + content.padLeft(Unit.dp.inPixels(-5f)); + + group.getButtons().get(2).setChecked(true); Table extra = new Table("button"); - extra.addWrap(() -> editor.getDrawBlock().name).width(120f).center(); + extra.labelWrap(() -> editor.getDrawBlock().name).width(120f).center(); table.add(extra).growX(); table.row(); table.add(pane).growY().fillX(); diff --git a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java index cf3865018b..7b91138b85 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Scaling; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.mapeditor.MapFilter.GenPref; import io.anuke.mindustry.ui.BorderImage; import io.anuke.mindustry.ui.FloatingDialog; @@ -70,9 +71,15 @@ public class MapGenerateDialog extends FloatingDialog{ buttons().addButton("Update", () ->{ apply(); }); - buttons().addButton("Apply", () ->{ - editor.applyFilter(); - hide(); + buttons().addButton("Apply", () ->{ + Vars.ui.showLoading(); + + Timers.run(3f, () ->{ + editor.applyFilter(); + Vars.ui.hideLoading(); + Vars.ui.getEditorDialog().resetSaved(); + hide(); + }); }); shown(() ->{ diff --git a/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java index 82244f6db5..ef054b379c 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapResizeDialog.java @@ -16,6 +16,7 @@ public class MapResizeDialog extends FloatingDialog{ public MapResizeDialog(MapEditor editor, BiConsumer cons){ super("resize map"); shown(() -> { + content().clear(); Pixmap pix = editor.pixmap(); width = pix.getWidth(); height = pix.getHeight(); @@ -48,7 +49,7 @@ public class MapResizeDialog extends FloatingDialog{ table.row(); } - content().add(() -> + content().label(() -> width + height > 512 ? "[scarlet]Warning!\n[]Maps larger than 256 units may be laggy and unstable." : "" ).get().setAlignment(Align.center, Align.center); content().row(); diff --git a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java index b54f05600b..3b366b8adc 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapSaveDialog.java @@ -17,7 +17,7 @@ public class MapSaveDialog extends FloatingDialog{ shown(() -> { content().clear(); - content().add(() ->{ + content().label(() ->{ Map map = Vars.world.maps().getMap(field.getText()); if(map != null){ if(map.custom){ @@ -47,6 +47,11 @@ public class MapSaveDialog extends FloatingDialog{ buttons().add(button); } + public void setFieldText(String text){ + field.setText(text); + } + + private boolean invalid(){ if(field.getText().isEmpty()){ return true; diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java index 87b764af07..8cc03e1733 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapView.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapView.java @@ -11,12 +11,11 @@ import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; -import io.anuke.ucore.core.Core; -import io.anuke.ucore.core.Draw; -import io.anuke.ucore.core.Inputs; +import io.anuke.ucore.core.*; import io.anuke.ucore.scene.Element; import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.InputListener; +import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Tmp; @@ -36,6 +35,7 @@ public class MapView extends Element implements GestureListener{ this.editor = editor; Inputs.addProcessor(0, new GestureDetector(20, 0.5f, 2, 0.15f, this)); + setTouchable(Touchable.enabled); addListener(new InputListener(){ int lastx, lasty; @@ -48,6 +48,10 @@ public class MapView extends Element implements GestureListener{ lasty = p.y; tool.touched(editor, p.x, p.y); + if(tool.edit){ + Vars.ui.getEditorDialog().resetSaved(); + } + drawing = true; return true; } @@ -62,6 +66,7 @@ public class MapView extends Element implements GestureListener{ GridPoint2 p = project(x, y); if(drawing && tool == EditorTool.pencil){ + Vars.ui.getEditorDialog().resetSaved(); Array points = br.line(lastx, lasty, p.x, p.y); for(GridPoint2 point : points){ editor.draw(point.x, point.y); @@ -71,20 +76,6 @@ public class MapView extends Element implements GestureListener{ lasty = p.y; } }); - - addListener(new InputListener(){ - @Override - public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { - return tool == EditorTool.zoom; - } - - - @Override - public void touchDragged (InputEvent event, float x, float y, int pointer) { - //offsetx += Gdx.input.getDeltaX(pointer) / zoom; - //offsety -= Gdx.input.getDeltaY(pointer) / zoom; - } - }); } @Override @@ -106,23 +97,28 @@ public class MapView extends Element implements GestureListener{ } private GridPoint2 project(float x, float y){ - float size = Math.min(width, height)*zoom; - x = (x - getWidth()/2 + size/2 - offsetx*zoom) / size * editor.texture().getWidth(); - y = (y - getHeight()/2 + size/2 - offsety*zoom) / size * editor.texture().getHeight(); + float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight()); + float size = Math.min(width, height); + float sclwidth = size * zoom; + float sclheight = size * zoom * ratio; + x = (x - getWidth()/2 + sclwidth/2 - offsetx*zoom) / sclwidth * editor.texture().getWidth(); + y = (y - getHeight()/2 + sclheight/2 - offsety*zoom) / sclheight * editor.texture().getHeight(); return Tmp.g1.set((int)x, editor.texture().getHeight() - 1 - (int)y); } @Override public void draw(Batch batch, float alpha){ + float ratio = 1f / ((float)editor.pixmap().getWidth() / editor.pixmap().getHeight()); float size = Math.min(width, height); - float sclsize = size * zoom; + float sclwidth = size * zoom; + float sclheight = size * zoom * ratio; float centerx = x + width/2 + offsetx * zoom; float centery = y + height/2 + offsety * zoom; batch.flush(); boolean pop = ScissorStack.pushScissors(Tmp.r1.set(x + width/2 - size/2, y + height/2 - size/2, size, size)); - batch.draw(editor.texture(), centerx - sclsize/2, centery - sclsize/2, sclsize, sclsize); + batch.draw(editor.texture(), centerx - sclwidth/2, centery - sclheight/2, sclwidth, sclheight); batch.flush(); if(pop) ScissorStack.popScissors(); @@ -134,7 +130,10 @@ public class MapView extends Element implements GestureListener{ } private boolean active(){ - return Core.scene.getKeyboardFocus() != null && Core.scene.getKeyboardFocus().isDescendantOf(Vars.ui.getEditorDialog()) && Vars.ui.isEditing() && tool == EditorTool.zoom; + return Core.scene.getKeyboardFocus() != null + && Core.scene.getKeyboardFocus().isDescendantOf(Vars.ui.getEditorDialog()) + && Vars.ui.isEditing() && tool == EditorTool.zoom && + Core.scene.hit(Graphics.mouse().x, Graphics.mouse().y, true) == this; } @Override diff --git a/core/src/io/anuke/mindustry/ui/FileChooser.java b/core/src/io/anuke/mindustry/ui/FileChooser.java new file mode 100644 index 0000000000..4a063f85ab --- /dev/null +++ b/core/src/io/anuke/mindustry/ui/FileChooser.java @@ -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 filter; + private Consumer selectListener; + private boolean open; + + public FileChooser(String title, boolean open, Consumer result){ + this(title, defaultFilter, open, result); + } + + public FileChooser(String title, Predicate filter, boolean open, Consumer 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(){ + @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 group = new ButtonGroup(); + 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 listener){ + this.selectListener = listener; + } + + public class FileHistory{ + private Array history = new Array(); + 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 pngFilter = file -> file.extension().equalsIgnoreCase("png"); + public static Predicate jpegFilter = file -> file.extension().equalsIgnoreCase("png") || file.extension().equalsIgnoreCase("jpg") || file.extension().equalsIgnoreCase("jpeg"); + public static Predicate defaultFilter = file -> true; +} diff --git a/core/src/io/anuke/mindustry/ui/LevelDialog.java b/core/src/io/anuke/mindustry/ui/LevelDialog.java index 837d6f8531..45d732e393 100644 --- a/core/src/io/anuke/mindustry/ui/LevelDialog.java +++ b/core/src/io/anuke/mindustry/ui/LevelDialog.java @@ -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)); diff --git a/core/src/io/anuke/mindustry/world/Maps.java b/core/src/io/anuke/mindustry/world/Maps.java index d9b3cb5599..0fc6f0644d 100644 --- a/core/src/io/anuke/mindustry/world/Maps.java +++ b/core/src/io/anuke/mindustry/world/Maps.java @@ -51,6 +51,18 @@ public class Maps implements Disposable{ } } + public void removeMap(Map map){ + maps.remove(map.id); + mapNames.remove(map.name); + Array out = new Array<>(); + for(Map m : maps.values()){ + if(m.custom){ + out.add(m); + } + } + saveMaps(out, Vars.customMapDirectory.child("maps.json")); + } + public void saveAndReload(Map map, Pixmap out){ if(map.pixmap != null && out != map.pixmap && map.texture != null){ map.texture.dispose(); @@ -58,6 +70,7 @@ public class Maps implements Disposable{ }else if (out == map.pixmap){ map.texture.draw(out, 0, 0); } + map.pixmap = out; if(map.texture == null) map.texture = new Texture(map.pixmap); @@ -90,6 +103,7 @@ public class Maps implements Disposable{ if(map.custom){ if(map.name.equals(toSave.name)){ out.add(toSave); + toSave.id = map.id; added = true; }else{ out.add(map); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/production/NuclearReactor.java b/core/src/io/anuke/mindustry/world/blocks/types/production/NuclearReactor.java index 2ae2f53b9a..da112bf3a3 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/production/NuclearReactor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/production/NuclearReactor.java @@ -26,7 +26,7 @@ public class NuclearReactor extends LiquidItemPowerGenerator{ protected Color coolColor = new Color(1, 1, 1, 0f); protected Color hotColor = Color.valueOf("ff9575a3"); protected int fuelUseTime = 120; //time to consume 1 fuel - protected float powerMultiplier = 0.2f; //power per frame, depends on full capacity + protected float powerMultiplier = 0.3f; //power per frame, depends on full capacity protected float heating = 0.007f; //heating per frame protected float coolantPower = 0.007f; //how much heat decreases per coolant unit protected float smokeThreshold = 0.3f; //threshold at which block starts smoking diff --git a/desktop/mindustry-maps/desert2.png b/desktop/mindustry-maps/desert2.png new file mode 100644 index 0000000000..12ded3b574 Binary files /dev/null and b/desktop/mindustry-maps/desert2.png differ diff --git a/desktop/mindustry-maps/desert23.png b/desktop/mindustry-maps/desert23.png new file mode 100644 index 0000000000..12ded3b574 Binary files /dev/null and b/desktop/mindustry-maps/desert23.png differ diff --git a/desktop/mindustry-maps/desert2asd.png b/desktop/mindustry-maps/desert2asd.png new file mode 100644 index 0000000000..12ded3b574 Binary files /dev/null and b/desktop/mindustry-maps/desert2asd.png differ diff --git a/desktop/mindustry-maps/island2.png b/desktop/mindustry-maps/island2.png new file mode 100644 index 0000000000..12ded3b574 Binary files /dev/null and b/desktop/mindustry-maps/island2.png differ diff --git a/desktop/mindustry-maps/maps.json b/desktop/mindustry-maps/maps.json index ff76b43a3c..52840a2510 100644 --- a/desktop/mindustry-maps/maps.json +++ b/desktop/mindustry-maps/maps.json @@ -1 +1 @@ -{"maps":[{"id":13,"name":"custom","custom":true},{"id":14,"name":"wowmap","custom":true},{"id":15,"name":"moremap","custom":true},{"id":16,"name":"trash","custom":true},{"id":17,"name":"wonderifthisworks","custom":true}]} \ No newline at end of file +{"maps":[]} \ No newline at end of file diff --git a/desktop/mindustry-maps/maze2.png b/desktop/mindustry-maps/maze2.png new file mode 100644 index 0000000000..4ed536eef2 Binary files /dev/null and b/desktop/mindustry-maps/maze2.png differ diff --git a/desktop/mindustry-maps/sadfa.png b/desktop/mindustry-maps/sadfa.png new file mode 100644 index 0000000000..8223292cf4 Binary files /dev/null and b/desktop/mindustry-maps/sadfa.png differ diff --git a/desktop/mindustry-maps/spiral12.png b/desktop/mindustry-maps/spiral12.png new file mode 100644 index 0000000000..8223292cf4 Binary files /dev/null and b/desktop/mindustry-maps/spiral12.png differ diff --git a/desktop/mindustry-maps/trash.png b/desktop/mindustry-maps/trash.png index b0ec0968b0..6a08dac9e6 100644 Binary files a/desktop/mindustry-maps/trash.png and b/desktop/mindustry-maps/trash.png differ diff --git a/desktop/mindustry-maps/tundra213123.png b/desktop/mindustry-maps/tundra213123.png new file mode 100644 index 0000000000..09aa83745c Binary files /dev/null and b/desktop/mindustry-maps/tundra213123.png differ diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index 5a21731502..1569cd0ba7 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -14,6 +14,7 @@ import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.PlatformFunction; +import io.anuke.ucore.scene.ui.TextField; public class DesktopLauncher { @@ -47,6 +48,11 @@ public class DesktopLauncher { Vars.ui.showError("Error opening link."); } } + + @Override + public void addDialog(TextField field){ + + } }; Mindustry.args = Array.with(arg); diff --git a/html/src/io/anuke/mindustry/client/HtmlLauncher.java b/html/src/io/anuke/mindustry/client/HtmlLauncher.java index 613cc30abe..36039cf4c8 100644 --- a/html/src/io/anuke/mindustry/client/HtmlLauncher.java +++ b/html/src/io/anuke/mindustry/client/HtmlLauncher.java @@ -17,6 +17,7 @@ import com.google.gwt.user.client.ui.*; import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.io.PlatformFunction; +import io.anuke.ucore.scene.ui.TextField; public class HtmlLauncher extends GwtApplication { static final int WIDTH = 800; @@ -106,6 +107,11 @@ public class HtmlLauncher extends GwtApplication { public void openLink(String link){ Window.open(link, "_blank", ""); } + + @Override + public void addDialog(TextField field){ + + } }; return new Mindustry();