|
@@ -95,6 +95,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
FileHandle skeletonFile;
|
|
FileHandle skeletonFile;
|
|
long lastModified;
|
|
long lastModified;
|
|
float lastModifiedCheck, reloadTimer;
|
|
float lastModifiedCheck, reloadTimer;
|
|
|
|
+ Preferences prefs;
|
|
|
|
|
|
public void create () {
|
|
public void create () {
|
|
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
|
|
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
|
|
@@ -104,16 +105,20 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+ prefs = Gdx.app.getPreferences("spine-skeletonviewer");
|
|
ui = new UI();
|
|
ui = new UI();
|
|
batch = new PolygonSpriteBatch();
|
|
batch = new PolygonSpriteBatch();
|
|
renderer = new SkeletonMeshRenderer();
|
|
renderer = new SkeletonMeshRenderer();
|
|
debugRenderer = new SkeletonRendererDebug();
|
|
debugRenderer = new SkeletonRendererDebug();
|
|
skeletonX = (int)(ui.window.getWidth() + (Gdx.graphics.getWidth() - ui.window.getWidth()) / 2);
|
|
skeletonX = (int)(ui.window.getWidth() + (Gdx.graphics.getWidth() - ui.window.getWidth()) / 2);
|
|
skeletonY = Gdx.graphics.getHeight() / 4;
|
|
skeletonY = Gdx.graphics.getHeight() / 4;
|
|
|
|
+ ui.loadPrefs();
|
|
|
|
|
|
loadSkeleton(
|
|
loadSkeleton(
|
|
Gdx.files.internal(Gdx.app.getPreferences("spine-skeletonviewer").getString("lastFile", "spineboy/spineboy.json")),
|
|
Gdx.files.internal(Gdx.app.getPreferences("spine-skeletonviewer").getString("lastFile", "spineboy/spineboy.json")),
|
|
false);
|
|
false);
|
|
|
|
+
|
|
|
|
+ ui.loadPrefs();
|
|
}
|
|
}
|
|
|
|
|
|
void loadSkeleton (final FileHandle skeletonFile, boolean reload) {
|
|
void loadSkeleton (final FileHandle skeletonFile, boolean reload) {
|
|
@@ -180,7 +185,6 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
});
|
|
});
|
|
|
|
|
|
this.skeletonFile = skeletonFile;
|
|
this.skeletonFile = skeletonFile;
|
|
- Preferences prefs = Gdx.app.getPreferences("spine-skeletonviewer");
|
|
|
|
prefs.putString("lastFile", skeletonFile.path());
|
|
prefs.putString("lastFile", skeletonFile.path());
|
|
prefs.flush();
|
|
prefs.flush();
|
|
lastModified = skeletonFile.lastModified();
|
|
lastModified = skeletonFile.lastModified();
|
|
@@ -205,12 +209,13 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
// Configure skeleton from UI.
|
|
// Configure skeleton from UI.
|
|
|
|
|
|
if (ui.skinList.getSelected() != null) skeleton.setSkin(ui.skinList.getSelected());
|
|
if (ui.skinList.getSelected() != null) skeleton.setSkin(ui.skinList.getSelected());
|
|
- if (ui.animationList.getSelected() != null) setAnimation();
|
|
|
|
|
|
+ setAnimation();
|
|
|
|
|
|
if (reload) ui.toast("Reloaded.");
|
|
if (reload) ui.toast("Reloaded.");
|
|
}
|
|
}
|
|
|
|
|
|
void setAnimation () {
|
|
void setAnimation () {
|
|
|
|
+ if (ui.animationList.getSelected() == null) return;
|
|
TrackEntry current = state.getCurrent(0);
|
|
TrackEntry current = state.getCurrent(0);
|
|
if (current == null) {
|
|
if (current == null) {
|
|
state.setEmptyAnimation(0, 0);
|
|
state.setEmptyAnimation(0, 0);
|
|
@@ -228,6 +233,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
|
|
|
|
float delta = Gdx.graphics.getDeltaTime();
|
|
float delta = Gdx.graphics.getDeltaTime();
|
|
|
|
|
|
|
|
+ // Draw skeleton origin lines.
|
|
ShapeRenderer shapes = debugRenderer.getShapeRenderer();
|
|
ShapeRenderer shapes = debugRenderer.getShapeRenderer();
|
|
if (state != null) {
|
|
if (state != null) {
|
|
shapes.setColor(Color.DARK_GRAY);
|
|
shapes.setColor(Color.DARK_GRAY);
|
|
@@ -238,6 +244,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
}
|
|
}
|
|
|
|
|
|
if (skeleton != null) {
|
|
if (skeleton != null) {
|
|
|
|
+ // Reload if skeleton file was modified.
|
|
if (reloadTimer <= 0) {
|
|
if (reloadTimer <= 0) {
|
|
lastModifiedCheck -= delta;
|
|
lastModifiedCheck -= delta;
|
|
if (lastModifiedCheck < 0) {
|
|
if (lastModifiedCheck < 0) {
|
|
@@ -250,6 +257,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
if (reloadTimer <= 0) loadSkeleton(skeletonFile, true);
|
|
if (reloadTimer <= 0) loadSkeleton(skeletonFile, true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Pose and render skeleton.
|
|
state.getData().setDefaultMix(ui.mixSlider.getValue());
|
|
state.getData().setDefaultMix(ui.mixSlider.getValue());
|
|
renderer.setPremultipliedAlpha(ui.premultipliedCheckbox.isChecked());
|
|
renderer.setPremultipliedAlpha(ui.premultipliedCheckbox.isChecked());
|
|
|
|
|
|
@@ -277,6 +285,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
debugRenderer.draw(skeleton);
|
|
debugRenderer.draw(skeleton);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Render UI.
|
|
ui.stage.act();
|
|
ui.stage.act();
|
|
ui.stage.draw();
|
|
ui.stage.draw();
|
|
|
|
|
|
@@ -340,10 +349,9 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
TextButton slotsSetupPoseButton = new TextButton("Slots", skin);
|
|
TextButton slotsSetupPoseButton = new TextButton("Slots", skin);
|
|
TextButton setupPoseButton = new TextButton("Both", skin);
|
|
TextButton setupPoseButton = new TextButton("Both", skin);
|
|
WidgetGroup toasts = new WidgetGroup();
|
|
WidgetGroup toasts = new WidgetGroup();
|
|
|
|
+ boolean prefsLoaded;
|
|
|
|
|
|
public UI () {
|
|
public UI () {
|
|
- // Configure widgets.
|
|
|
|
-
|
|
|
|
animationList.getSelection().setRequired(false);
|
|
animationList.getSelection().setRequired(false);
|
|
|
|
|
|
premultipliedCheckbox.setChecked(true);
|
|
premultipliedCheckbox.setChecked(true);
|
|
@@ -430,8 +438,6 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
table.add(toasts);
|
|
table.add(toasts);
|
|
}
|
|
}
|
|
|
|
|
|
- // Events.
|
|
|
|
-
|
|
|
|
window.addListener(new InputListener() {
|
|
window.addListener(new InputListener() {
|
|
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
|
|
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
|
|
event.cancel();
|
|
event.cancel();
|
|
@@ -548,7 +554,31 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
skeletonY = Gdx.graphics.getHeight() - screenY;
|
|
skeletonY = Gdx.graphics.getHeight() - screenY;
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ public boolean touchUp (int screenX, int screenY, int pointer, int button) {
|
|
|
|
+ savePrefs();
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
}));
|
|
}));
|
|
|
|
+
|
|
|
|
+ ChangeListener savePrefsListener = new ChangeListener() {
|
|
|
|
+ public void changed (ChangeEvent event, Actor actor) {
|
|
|
|
+ if (actor instanceof Slider && ((Slider)actor).isDragging()) return;
|
|
|
|
+ savePrefs();
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ debugBonesCheckbox.addListener(savePrefsListener);
|
|
|
|
+ debugRegionsCheckbox.addListener(savePrefsListener);
|
|
|
|
+ debugMeshHullCheckbox.addListener(savePrefsListener);
|
|
|
|
+ debugMeshTrianglesCheckbox.addListener(savePrefsListener);
|
|
|
|
+ debugPathsCheckbox.addListener(savePrefsListener);
|
|
|
|
+ premultipliedCheckbox.addListener(savePrefsListener);
|
|
|
|
+ loopCheckbox.addListener(savePrefsListener);
|
|
|
|
+ speedSlider.addListener(savePrefsListener);
|
|
|
|
+ mixSlider.addListener(savePrefsListener);
|
|
|
|
+ scaleSlider.addListener(savePrefsListener);
|
|
|
|
+ animationList.addListener(savePrefsListener);
|
|
|
|
+ skinList.addListener(savePrefsListener);
|
|
}
|
|
}
|
|
|
|
|
|
private Table table (Actor... actors) {
|
|
private Table table (Actor... actors) {
|
|
@@ -575,6 +605,43 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|
toasts.addActor(table);
|
|
toasts.addActor(table);
|
|
toasts.getParent().toFront();
|
|
toasts.getParent().toFront();
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ void savePrefs () {
|
|
|
|
+ if (!prefsLoaded) return;
|
|
|
|
+ prefs.putBoolean("debugBones", debugBonesCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("debugRegions", debugRegionsCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("debugMeshHull", debugMeshHullCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("debugMeshTriangles", debugMeshTrianglesCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("debugPaths", debugPathsCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("premultiplied", premultipliedCheckbox.isChecked());
|
|
|
|
+ prefs.putBoolean("loop", loopCheckbox.isChecked());
|
|
|
|
+ prefs.putFloat("speed", speedSlider.getValue());
|
|
|
|
+ prefs.putFloat("mix", mixSlider.getValue());
|
|
|
|
+ prefs.putFloat("scale", scaleSlider.getValue());
|
|
|
|
+ prefs.putInteger("x", skeletonX);
|
|
|
|
+ prefs.putInteger("y", skeletonY);
|
|
|
|
+ if (animationList.getSelected() != null) prefs.putString("animationName", animationList.getSelected());
|
|
|
|
+ if (skinList.getSelected() != null)prefs.putString("skinName", skinList.getSelected());
|
|
|
|
+ prefs.flush();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void loadPrefs () {
|
|
|
|
+ debugBonesCheckbox.setChecked(prefs.getBoolean("debugBones", true));
|
|
|
|
+ debugRegionsCheckbox.setChecked(prefs.getBoolean("debugRegions", false));
|
|
|
|
+ debugMeshHullCheckbox.setChecked(prefs.getBoolean("debugMeshHull", false));
|
|
|
|
+ debugMeshTrianglesCheckbox.setChecked(prefs.getBoolean("debugMeshTriangles", false));
|
|
|
|
+ debugPathsCheckbox.setChecked(prefs.getBoolean("debugPaths", true));
|
|
|
|
+ premultipliedCheckbox.setChecked(prefs.getBoolean("premultiplied", true));
|
|
|
|
+ loopCheckbox.setChecked(prefs.getBoolean("loop", false));
|
|
|
|
+ speedSlider.setValue(prefs.getFloat("speed", 0.3f));
|
|
|
|
+ mixSlider.setValue(prefs.getFloat("mix", 0.3f));
|
|
|
|
+ scaleSlider.setValue(prefs.getFloat("scale", 1));
|
|
|
|
+ skeletonX = prefs.getInteger("x", 0);
|
|
|
|
+ skeletonY = prefs.getInteger("y", 0);
|
|
|
|
+ animationList.setSelected(prefs.getString("animationName", null));
|
|
|
|
+ skinList.setSelected(prefs.getString("skinName", null));
|
|
|
|
+ prefsLoaded = true;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static public void main (String[] args) throws Exception {
|
|
static public void main (String[] args) throws Exception {
|