issue #1340 made it possible to create custom adventures from the user data folder

This commit is contained in:
Grimm
2022-09-20 02:02:52 +02:00
parent 099502bbb9
commit 38748301ae
7 changed files with 159 additions and 17 deletions

View File

@@ -233,11 +233,6 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>com.github.jetopto1</groupId>
<artifactId>cling</artifactId>
<version>1.0.0</version>
</dependency>
<dependency> <dependency>
<groupId>com.badlogicgames.gdx</groupId> <groupId>com.badlogicgames.gdx</groupId>
<artifactId>gdx</artifactId> <artifactId>gdx</artifactId>

View File

@@ -3,45 +3,117 @@ package forge.adventure.scene;
import com.badlogic.gdx.Input; import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraButton;
import com.github.tommyettinger.textra.TextraLabel; import com.github.tommyettinger.textra.TextraLabel;
import forge.Forge; import forge.Forge;
import forge.adventure.util.Config; import forge.adventure.util.Config;
import forge.adventure.util.Controls; import forge.adventure.util.Controls;
import forge.adventure.util.UIActor;
import forge.gui.GuiBase; import forge.gui.GuiBase;
import forge.localinstance.properties.ForgePreferences; import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel; import forge.model.FModel;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/** /**
* Scene to handle settings of the base forge and adventure mode * Scene to handle settings of the base forge and adventure mode
*/ */
public class SettingsScene extends UIScene { public class SettingsScene extends UIScene {
static public ForgePreferences Preference; static public ForgePreferences Preference;
Stage stage;
Texture Background; Texture Background;
private final Table settingGroup; private final Table settingGroup;
TextraButton backButton; TextraButton backButton;
TextraButton newPlane;
ScrollPane scrollPane; ScrollPane scrollPane;
SelectBox selectSourcePlane;
TextField newPlaneName;
private void copyNewPlane() {
String plane=(String) selectSourcePlane.getSelected();
Path source= Paths.get(Config.instance().getPlanePath(plane));
Path destination= Paths.get(Config.instance().getPlanePath("<user>"+newPlaneName.getText()));
AtomicBoolean somethingWentWrong= new AtomicBoolean(false);
try (Stream<Path> stream = Files.walk(source))
{
Files.createDirectories(destination);
stream.forEach(s -> {
try { Files.copy(s, destination.resolve(source.relativize(s)), REPLACE_EXISTING); }
catch (IOException e) {
somethingWentWrong.set(true);
}
});
} catch (IOException e) {
somethingWentWrong.set(true);
}
if(somethingWentWrong.get())
{
Dialog dialog=ui.showDialog(stage,"Something went wrong", UIActor.ButtonOk|UIActor.ButtonAbort,null);
dialog.text("Copy was not successful check your access right\n and if the folder is in use");
dialog.show(stage);
}
else
{
Dialog dialog=ui.showDialog(stage,"Copied plane", UIActor.ButtonOk|UIActor.ButtonAbort,null);
dialog.text("New plane "+newPlaneName.getText()+" was created\nYou can now start the editor to change the plane\n" +
"or edit it manually from the folder\n" +
Config.instance().getPlanePath("<user>"+newPlaneName.getText()));
Config.instance().getSettingData().plane = "<user>"+newPlaneName.getText();
Config.instance().saveSettings();
dialog.show(stage);
}
}
private void createNewPlane() {
Dialog dialog=ui.showDialog(stage,"Create your own Plane", UIActor.ButtonOk|UIActor.ButtonAbort,()->copyNewPlane());
dialog.text("Select a plane to copy");
dialog.getContentTable().row();
dialog.getContentTable().add(selectSourcePlane);
dialog.getContentTable().row();
dialog.text("Set new plane name");
dialog.getContentTable().row();
dialog.getContentTable().add(newPlaneName);
newPlaneName.setText(selectSourcePlane.getSelected().toString()+"_copy");
dialog.show(stage);
}
private SettingsScene() { private SettingsScene() {
super(Forge.isLandscapeMode() ? "ui/settings.json" : "ui/settings_portrait.json"); super(Forge.isLandscapeMode() ? "ui/settings.json" : "ui/settings_portrait.json");
selectSourcePlane = new SelectBox<String>(Controls.getSkin());
newPlaneName = Controls.newTextField("");
settingGroup = new Table(); settingGroup = new Table();
if (Preference == null) { if (Preference == null) {
Preference = new ForgePreferences(); Preference = new ForgePreferences();
} }
selectSourcePlane.setItems(Config.instance().getAllAdventures());
SelectBox plane = Controls.newComboBox(Config.instance().getAllAdventures(), Config.instance().getSettingData().plane, o -> { SelectBox plane = Controls.newComboBox(Config.instance().getAllAdventures(), Config.instance().getSettingData().plane, o -> {
Config.instance().getSettingData().plane = (String) o; Config.instance().getSettingData().plane = (String) o;
Config.instance().saveSettings(); Config.instance().saveSettings();
return null; return null;
}); });
newPlane=Controls.newTextButton("Create own plane");
newPlane.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
createNewPlane();
}
});
addLabel(Forge.getLocalizer().getMessage("lblWorld")); addLabel(Forge.getLocalizer().getMessage("lblWorld"));
settingGroup.add(plane).align(Align.right).pad(2); settingGroup.add(plane).align(Align.right).pad(2);
addLabel(Forge.getLocalizer().getMessage("lblCreate")+Forge.getLocalizer().getMessage("lblWorld"));
settingGroup.add(newPlane).align(Align.right).pad(2);
if (!GuiBase.isAndroid()) { if (!GuiBase.isAndroid()) {
SelectBox videomode = Controls.newComboBox(new String[]{"720p", "768p", "900p", "1080p"}, Config.instance().getSettingData().videomode, o -> { SelectBox videomode = Controls.newComboBox(new String[]{"720p", "768p", "900p", "1080p"}, Config.instance().getSettingData().videomode, o -> {

View File

@@ -28,7 +28,7 @@ import forge.adventure.util.UIActor;
*/ */
public class UIScene extends Scene { public class UIScene extends Scene {
protected UIActor ui; protected UIActor ui;
Stage stage; protected Stage stage;
String uiFile; String uiFile;
private final Dialog keyboardDialog; private final Dialog keyboardDialog;

View File

@@ -2,6 +2,7 @@ package forge.adventure.util;
import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonWriter; import com.badlogic.gdx.utils.JsonWriter;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
@@ -43,7 +44,7 @@ public class Config {
} }
private Config() { private Config() {
String path= GuiBase.isAndroid() ? ForgeConstants.ASSETS_DIR : Files.exists(Paths.get("./res"))?"./":"../forge-gui/"; String path= resPath();
adventures = new File(GuiBase.isAndroid() ? ForgeConstants.ADVENTURE_DIR : path + "/res/adventure").list(); adventures = new File(GuiBase.isAndroid() ? ForgeConstants.ADVENTURE_DIR : path + "/res/adventure").list();
try try
{ {
@@ -59,6 +60,7 @@ public class Config {
if(adventures!=null&&adventures.length>=1) if(adventures!=null&&adventures.length>=1)
settingsData.plane=adventures[0]; settingsData.plane=adventures[0];
} }
plane=settingsData.plane;
if(settingsData.width==0||settingsData.height==0) if(settingsData.width==0||settingsData.height==0)
{ {
@@ -80,10 +82,9 @@ public class Config {
if(settingsData.cardTooltipAdjLandscape == null || settingsData.cardTooltipAdjLandscape == 0f) if(settingsData.cardTooltipAdjLandscape == null || settingsData.cardTooltipAdjLandscape == 0f)
settingsData.cardTooltipAdjLandscape=1f; settingsData.cardTooltipAdjLandscape=1f;
this.plane = settingsData.plane; prefix = getPlanePath(settingsData.plane);
currentConfig = this;
prefix = path + "/res/adventure/" + plane + "/"; currentConfig = this;
if (FModel.getPreferences() != null) if (FModel.getPreferences() != null)
Lang = FModel.getPreferences().getPref(ForgePreferences.FPref.UI_LANGUAGE); Lang = FModel.getPreferences().getPref(ForgePreferences.FPref.UI_LANGUAGE);
try try
@@ -99,6 +100,22 @@ public class Config {
} }
private String resPath() {
return GuiBase.isAndroid() ? ForgeConstants.ASSETS_DIR : Files.exists(Paths.get("./res"))?"./":"../forge-gui/";
}
public String getPlanePath(String plane) {
if(plane.startsWith("<user>"))
{
return ForgeConstants.USER_ADVENTURE_DIR + "/userplanes/" + plane.substring("<user>".length()) + "/";
}
else
{
return resPath() + "/res/adventure/" + plane + "/";
}
}
public ConfigData getConfigData() { public ConfigData getConfigData() {
return configData; return configData;
} }
@@ -130,7 +147,7 @@ public class Config {
public String getPlane() { public String getPlane() {
return plane; return plane.replace("<user>","user_");
} }
public String[] colorIdNames() { public String[] colorIdNames() {
@@ -174,8 +191,17 @@ public class Config {
{ {
return settingsData; return settingsData;
} }
public String[] getAllAdventures() public Array<String> getAllAdventures()
{ {
String path=ForgeConstants.USER_ADVENTURE_DIR + "/userplanes/";
Array<String> adventures = new Array<String>();
if(new File(path).exists())
adventures.addAll(new File(path).list());
for(int i=0;i<adventures.size;i++)
{
adventures.set(i,"<user>"+adventures.get(i));
}
adventures.addAll(this.adventures);
return adventures; return adventures;
} }

View File

@@ -12,6 +12,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Null; import com.badlogic.gdx.utils.Null;
import com.github.tommyettinger.textra.Font; import com.github.tommyettinger.textra.Font;
import com.github.tommyettinger.textra.TextraButton; import com.github.tommyettinger.textra.TextraButton;
@@ -99,6 +100,26 @@ public class Controls {
return ret; return ret;
} }
static public SelectBox newComboBox(Array<String> text, String item, Function<Object, Void> func) {
SelectBox ret = new SelectBox<String>(getSkin());
ret.getStyle().listStyle.selection.setTopHeight(4);
ret.setItems(text);
ret.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
try {
func.apply(((SelectBox) actor).getSelected());
} catch (Exception e) {
e.printStackTrace();
}
}
});
func.apply(item);
ret.getList().setAlignment(Align.center);
ret.setSelected(item);
ret.setAlignment(Align.right);
return ret;
}
static public SelectBox newComboBox(Float[] text, float item, Function<Object, Void> func) { static public SelectBox newComboBox(Float[] text, float item, Function<Object, Void> func) {
SelectBox ret = new SelectBox<Float>(getSkin()); SelectBox ret = new SelectBox<Float>(getSkin());
ret.getStyle().listStyle.selection.setTopHeight(4); ret.getStyle().listStyle.selection.setTopHeight(4);

View File

@@ -7,6 +7,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.Group;
import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
@@ -286,4 +287,31 @@ public class UIActor extends Group {
} }
}); });
} }
static final public int ButtonYes=0x1;
static final public int ButtonNo=0x2;
static final public int ButtonOk=0x4;
static final public int ButtonAbort=0x8;
public Dialog showDialog(Stage stage, String header, int buttons, Runnable onOkOrYes) {
Dialog dialog =new Dialog(header, Controls.getSkin())
{
protected void result(Object object)
{
if(onOkOrYes!=null&&object!=null&&object.equals(true))
onOkOrYes.run();
this.hide();
removeActor(this);
}
};
if((buttons&ButtonYes)!=0)
dialog.button(Forge.getLocalizer().getMessage("lblYes"), true);
if((buttons&ButtonNo)!=0)
dialog.button(Forge.getLocalizer().getMessage("lblNo"), false);
if((buttons&ButtonOk)!=0)
dialog.button(Forge.getLocalizer().getMessage("lblOk"), true);
if((buttons&ButtonAbort)!=0)
dialog.button(Forge.getLocalizer().getMessage("lblAbort"), false);
addActor(dialog);
dialog.show(stage);
return dialog;
}
} }

View File

@@ -73,9 +73,9 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.jetopto1.cling</groupId> <groupId>org.fourthline.cling</groupId>
<artifactId>cling-core</artifactId> <artifactId>cling-core</artifactId>
<version>1.0.0</version> <version>2.1.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>