mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-06 02:36:56 +08:00
Skeleton Viewer UI improvements.
This commit is contained in:
parent
21d63cd228
commit
bfe0a54a4e
@ -62,7 +62,9 @@ import com.badlogic.gdx.scenes.scene2d.InputEvent;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
import com.badlogic.gdx.scenes.scene2d.InputListener;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||||
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
import com.badlogic.gdx.scenes.scene2d.Touchable;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.ButtonGroup;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
|
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.List;
|
import com.badlogic.gdx.scenes.scene2d.ui.List;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
||||||
@ -73,7 +75,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
||||||
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.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.StringBuilder;
|
||||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||||
import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter;
|
import com.esotericsoftware.spine.AnimationState.AnimationStateAdapter;
|
||||||
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
import com.esotericsoftware.spine.AnimationState.TrackEntry;
|
||||||
@ -94,6 +98,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
FileHandle skeletonFile;
|
FileHandle skeletonFile;
|
||||||
long lastModified;
|
long lastModified;
|
||||||
float lastModifiedCheck, reloadTimer;
|
float lastModifiedCheck, reloadTimer;
|
||||||
|
StringBuilder status = new StringBuilder();
|
||||||
Preferences prefs;
|
Preferences prefs;
|
||||||
|
|
||||||
public void create () {
|
public void create () {
|
||||||
@ -114,17 +119,16 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
ui.loadPrefs();
|
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);
|
|
||||||
|
|
||||||
ui.loadPrefs();
|
ui.loadPrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSkeleton (final FileHandle skeletonFile, boolean reload) {
|
void loadSkeleton (final FileHandle skeletonFile) {
|
||||||
if (skeletonFile == null) return;
|
if (skeletonFile == null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// A regular texture atlas would normally usually be used. This returns a white image for images not found in the atlas.
|
// Setup a texture atlas that uses a white image for images not found in the atlas.
|
||||||
Pixmap pixmap = new Pixmap(32, 32, Format.RGBA8888);
|
Pixmap pixmap = new Pixmap(32, 32, Format.RGBA8888);
|
||||||
pixmap.setColor(new Color(1, 1, 1, 0.33f));
|
pixmap.setColor(new Color(1, 1, 1, 0.33f));
|
||||||
pixmap.fill();
|
pixmap.fill();
|
||||||
@ -153,6 +157,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Load skeleton data.
|
||||||
String extension = skeletonFile.extension();
|
String extension = skeletonFile.extension();
|
||||||
if (extension.equalsIgnoreCase("json") || extension.equalsIgnoreCase("txt")) {
|
if (extension.equalsIgnoreCase("json") || extension.equalsIgnoreCase("txt")) {
|
||||||
SkeletonJson json = new SkeletonJson(atlas);
|
SkeletonJson json = new SkeletonJson(atlas);
|
||||||
@ -178,6 +183,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
|
|
||||||
state = new AnimationState(new AnimationStateData(skeletonData));
|
state = new AnimationState(new AnimationStateData(skeletonData));
|
||||||
state.addListener(new AnimationStateAdapter() {
|
state.addListener(new AnimationStateAdapter() {
|
||||||
|
|
||||||
public void event (TrackEntry entry, Event event) {
|
public void event (TrackEntry entry, Event event) {
|
||||||
ui.toast(event.getData().getName());
|
ui.toast(event.getData().getName());
|
||||||
}
|
}
|
||||||
@ -193,6 +199,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
|
|
||||||
ui.window.getTitleLabel().setText(skeletonFile.name());
|
ui.window.getTitleLabel().setText(skeletonFile.name());
|
||||||
{
|
{
|
||||||
|
|
||||||
Array<String> items = new Array();
|
Array<String> items = new Array();
|
||||||
for (Skin skin : skeletonData.getSkins())
|
for (Skin skin : skeletonData.getSkins())
|
||||||
items.add(skin.getName());
|
items.add(skin.getName());
|
||||||
@ -204,27 +211,29 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
items.add(animation.getName());
|
items.add(animation.getName());
|
||||||
ui.animationList.setItems(items);
|
ui.animationList.setItems(items);
|
||||||
}
|
}
|
||||||
|
ui.trackButtons.getButtons().first().setChecked(true);
|
||||||
|
|
||||||
// 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());
|
||||||
setAnimation();
|
setAnimation();
|
||||||
|
|
||||||
if (reload) ui.toast("Reloaded.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAnimation () {
|
void setAnimation () {
|
||||||
if (ui.animationList.getSelected() == null) return;
|
if (ui.animationList.getSelected() == null) return;
|
||||||
TrackEntry current = state.getCurrent(0);
|
int track = ui.trackButtons.getCheckedIndex();
|
||||||
|
TrackEntry current = state.getCurrent(track);
|
||||||
|
TrackEntry entry;
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
state.setEmptyAnimation(0, 0);
|
state.setEmptyAnimation(track, 0);
|
||||||
TrackEntry entry = state.addAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked(), 0);
|
entry = state.addAnimation(track, ui.animationList.getSelected(), ui.loopCheckbox.isChecked(), 0);
|
||||||
entry.setMixDuration(ui.mixSlider.getValue());
|
entry.setMixDuration(ui.mixSlider.getValue());
|
||||||
entry.setTrackEnd(Integer.MAX_VALUE);
|
entry.setTrackEnd(Integer.MAX_VALUE);
|
||||||
} else {
|
} else {
|
||||||
TrackEntry entry = state.setAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
|
entry = state.setAnimation(track, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
|
||||||
entry.setTrackEnd(Integer.MAX_VALUE);
|
entry.setTrackEnd(Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
entry.setAlpha(ui.alphaSlider.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render () {
|
public void render () {
|
||||||
@ -253,21 +262,23 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reloadTimer -= delta;
|
reloadTimer -= delta;
|
||||||
if (reloadTimer <= 0) loadSkeleton(skeletonFile, true);
|
if (reloadTimer <= 0) {
|
||||||
|
loadSkeleton(skeletonFile);
|
||||||
|
ui.toast("Reloaded.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pose and render skeleton.
|
// 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());
|
||||||
|
|
||||||
|
skeleton.setFlip(ui.flipXCheckbox.isChecked(), ui.flipYCheckbox.isChecked());
|
||||||
|
skeleton.setPosition(skeletonX, skeletonY);
|
||||||
|
|
||||||
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
|
delta = Math.min(delta, 0.032f) * ui.speedSlider.getValue();
|
||||||
skeleton.update(delta);
|
skeleton.update(delta);
|
||||||
skeleton.setFlip(ui.flipXCheckbox.isChecked(), ui.flipYCheckbox.isChecked());
|
state.update(delta);
|
||||||
if (!ui.pauseButton.isChecked()) {
|
state.apply(skeleton);
|
||||||
state.update(delta);
|
|
||||||
state.apply(skeleton);
|
|
||||||
}
|
|
||||||
skeleton.setPosition(skeletonX, skeletonY);
|
|
||||||
skeleton.updateWorldTransform();
|
skeleton.updateWorldTransform();
|
||||||
|
|
||||||
batch.setColor(Color.WHITE);
|
batch.setColor(Color.WHITE);
|
||||||
@ -284,9 +295,22 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
debugRenderer.draw(skeleton);
|
debugRenderer.draw(skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnimationState status.
|
||||||
|
status.setLength(0);
|
||||||
|
for (int i = 0, n = state.getTracks().size; i < n; i++) {
|
||||||
|
TrackEntry entry = state.getTracks().get(i);
|
||||||
|
if (entry == null) continue;
|
||||||
|
status.append(i);
|
||||||
|
status.append(": [LIGHT_GRAY]");
|
||||||
|
status(entry);
|
||||||
|
status.append("[WHITE]");
|
||||||
|
status.append(entry.animation.name);
|
||||||
|
status.append('\n');
|
||||||
|
}
|
||||||
|
ui.statusLabel.setText(status);
|
||||||
|
|
||||||
// Render UI.
|
// Render UI.
|
||||||
ui.stage.act();
|
ui.render();
|
||||||
ui.stage.draw();
|
|
||||||
|
|
||||||
// Draw indicator lines for animation and mix times.
|
// Draw indicator lines for animation and mix times.
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
@ -297,18 +321,28 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
float percent = entry.getAnimationTime() / entry.getAnimationEnd();
|
float percent = entry.getAnimationTime() / entry.getAnimationEnd();
|
||||||
float x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
|
float x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
|
||||||
shapes.setColor(Color.CYAN);
|
shapes.setColor(Color.CYAN);
|
||||||
shapes.line(x, 0, x, 20);
|
shapes.line(x, 0, x, 12);
|
||||||
|
|
||||||
percent = entry.getMixDuration() == 0 ? 1 : Math.min(1, entry.getMixTime() / entry.getMixDuration());
|
percent = entry.getMixDuration() == 0 ? 1 : Math.min(1, entry.getMixTime() / entry.getMixDuration());
|
||||||
x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
|
x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
|
||||||
shapes.setColor(Color.RED);
|
shapes.setColor(Color.RED);
|
||||||
shapes.line(x, 0, x, 20);
|
shapes.line(x, 0, x, 12);
|
||||||
|
|
||||||
shapes.end();
|
shapes.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void status (TrackEntry entry) {
|
||||||
|
TrackEntry from = entry.mixingFrom;
|
||||||
|
if (from == null) return;
|
||||||
|
status(from);
|
||||||
|
status.append(from.animation.name);
|
||||||
|
status.append(' ');
|
||||||
|
status.append(Math.min(100, (int)(entry.mixTime / entry.mixDuration * 100)));
|
||||||
|
status.append("% -> ");
|
||||||
|
}
|
||||||
|
|
||||||
public void resize (int width, int height) {
|
public void resize (int width, int height) {
|
||||||
batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
|
batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height);
|
||||||
debugRenderer.getShapeRenderer().setProjectionMatrix(batch.getProjectionMatrix());
|
debugRenderer.getShapeRenderer().setProjectionMatrix(batch.getProjectionMatrix());
|
||||||
@ -325,7 +359,9 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
Table root = new Table(skin);
|
Table root = new Table(skin);
|
||||||
TextButton openButton = new TextButton("Open", skin);
|
TextButton openButton = new TextButton("Open", skin);
|
||||||
List<String> animationList = new List(skin);
|
List<String> animationList = new List(skin);
|
||||||
|
ScrollPane animationScroll = new ScrollPane(animationList, skin, "bg");
|
||||||
List<String> skinList = new List(skin);
|
List<String> skinList = new List(skin);
|
||||||
|
ScrollPane skinScroll = new ScrollPane(skinList, skin, "bg");
|
||||||
CheckBox loopCheckbox = new CheckBox("Loop", skin);
|
CheckBox loopCheckbox = new CheckBox("Loop", skin);
|
||||||
CheckBox premultipliedCheckbox = new CheckBox("Premultiplied", skin);
|
CheckBox premultipliedCheckbox = new CheckBox("Premultiplied", skin);
|
||||||
Slider mixSlider = new Slider(0, 4, 0.01f, false, skin);
|
Slider mixSlider = new Slider(0, 4, 0.01f, false, skin);
|
||||||
@ -342,15 +378,29 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
CheckBox debugPathsCheckbox = new CheckBox("Paths", skin);
|
CheckBox debugPathsCheckbox = new CheckBox("Paths", skin);
|
||||||
Slider scaleSlider = new Slider(0.1f, 3, 0.01f, false, skin);
|
Slider scaleSlider = new Slider(0.1f, 3, 0.01f, false, skin);
|
||||||
Label scaleLabel = new Label("1.0", skin);
|
Label scaleLabel = new Label("1.0", skin);
|
||||||
TextButton pauseButton = new TextButton("Pause", skin, "toggle");
|
|
||||||
TextButton minimizeButton = new TextButton("-", skin);
|
TextButton minimizeButton = new TextButton("-", skin);
|
||||||
TextButton bonesSetupPoseButton = new TextButton("Bones", skin);
|
TextButton bonesSetupPoseButton = new TextButton("Bones", skin);
|
||||||
TextButton slotsSetupPoseButton = new TextButton("Slots", skin);
|
TextButton slotsSetupPoseButton = new TextButton("Slots", skin);
|
||||||
TextButton setupPoseButton = new TextButton("Both", skin);
|
TextButton setupPoseButton = new TextButton("Both", skin);
|
||||||
|
Label statusLabel = new Label("", skin);
|
||||||
WidgetGroup toasts = new WidgetGroup();
|
WidgetGroup toasts = new WidgetGroup();
|
||||||
|
ButtonGroup<TextButton> trackButtons = new ButtonGroup();
|
||||||
|
Slider alphaSlider = new Slider(0, 1, 0.01f, false, skin);
|
||||||
|
Label alphaLabel = new Label("1.0", skin);
|
||||||
boolean prefsLoaded;
|
boolean prefsLoaded;
|
||||||
|
|
||||||
public UI () {
|
UI () {
|
||||||
|
initialize();
|
||||||
|
layout();
|
||||||
|
events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize () {
|
||||||
|
skin.getFont("default").getData().markupEnabled = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
trackButtons.add(new TextButton(i + "", skin, "toggle"));
|
||||||
|
|
||||||
animationList.getSelection().setRequired(false);
|
animationList.getSelection().setRequired(false);
|
||||||
|
|
||||||
premultipliedCheckbox.setChecked(true);
|
premultipliedCheckbox.setChecked(true);
|
||||||
@ -366,6 +416,9 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
speedSlider.setValue(1);
|
speedSlider.setValue(1);
|
||||||
speedSlider.setSnapToValues(new float[] {0.5f, 0.75f, 1, 1.25f, 1.5f, 2, 2.5f}, 0.1f);
|
speedSlider.setSnapToValues(new float[] {0.5f, 0.75f, 1, 1.25f, 1.5f, 2, 2.5f}, 0.1f);
|
||||||
|
|
||||||
|
alphaSlider.setValue(1);
|
||||||
|
alphaSlider.setDisabled(true);
|
||||||
|
|
||||||
window.setMovable(false);
|
window.setMovable(false);
|
||||||
window.setResizable(false);
|
window.setResizable(false);
|
||||||
window.setKeepWithinStage(false);
|
window.setKeepWithinStage(false);
|
||||||
@ -376,14 +429,12 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
window.getTitleTable().add(openButton).space(3);
|
window.getTitleTable().add(openButton).space(3);
|
||||||
window.getTitleTable().add(minimizeButton).width(20);
|
window.getTitleTable().add(minimizeButton).width(20);
|
||||||
|
|
||||||
ScrollPane skinScroll = new ScrollPane(skinList, skin, "bg");
|
|
||||||
skinScroll.setFadeScrollBars(false);
|
skinScroll.setFadeScrollBars(false);
|
||||||
|
|
||||||
ScrollPane animationScroll = new ScrollPane(animationList, skin, "bg");
|
|
||||||
animationScroll.setFadeScrollBars(false);
|
animationScroll.setFadeScrollBars(false);
|
||||||
|
}
|
||||||
|
|
||||||
// Layout.
|
void layout () {
|
||||||
|
|
||||||
root.defaults().space(6);
|
root.defaults().space(6);
|
||||||
root.columnDefaults(0).top().right().padTop(3);
|
root.columnDefaults(0).top().right().padTop(3);
|
||||||
root.columnDefaults(1).left();
|
root.columnDefaults(1).left();
|
||||||
@ -400,15 +451,38 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
root.add(table(debugBonesCheckbox, debugRegionsCheckbox, debugBoundingBoxesCheckbox)).row();
|
root.add(table(debugBonesCheckbox, debugRegionsCheckbox, debugBoundingBoxesCheckbox)).row();
|
||||||
root.add();
|
root.add();
|
||||||
root.add(table(debugMeshHullCheckbox, debugMeshTrianglesCheckbox, debugPathsCheckbox)).row();
|
root.add(table(debugMeshHullCheckbox, debugMeshTrianglesCheckbox, debugPathsCheckbox)).row();
|
||||||
root.add("Alpha:");
|
root.add("Atlas alpha:");
|
||||||
root.add(premultipliedCheckbox).row();
|
root.add(premultipliedCheckbox).row();
|
||||||
root.add("Skin:");
|
|
||||||
root.add(skinScroll).expand().fill().minHeight(75).row();
|
root.add(new Image(skin.newDrawable("white", new Color(0x4e4e4eff)))).height(1).fillX().colspan(2).pad(-3, 0, 1, 0)
|
||||||
|
.row();
|
||||||
|
|
||||||
root.add("Setup pose:");
|
root.add("Setup pose:");
|
||||||
root.add(table(bonesSetupPoseButton, slotsSetupPoseButton, setupPoseButton)).row();
|
root.add(table(bonesSetupPoseButton, slotsSetupPoseButton, setupPoseButton)).row();
|
||||||
|
root.add("Skin:");
|
||||||
|
root.add(skinScroll).expand().fill().row();
|
||||||
|
|
||||||
|
root.add(new Image(skin.newDrawable("white", new Color(0x4e4e4eff)))).height(1).fillX().colspan(2).pad(1,0,1,0)
|
||||||
|
.row();
|
||||||
|
|
||||||
|
root.add("Track:");
|
||||||
|
{
|
||||||
|
Table table = table();
|
||||||
|
for (TextButton button : trackButtons.getButtons())
|
||||||
|
table.add(button);
|
||||||
|
table.add(loopCheckbox);
|
||||||
|
root.add(table).row();
|
||||||
|
}
|
||||||
|
root.add("Entry alpha:");
|
||||||
|
{
|
||||||
|
Table table = table();
|
||||||
|
table.add(alphaLabel).width(29);
|
||||||
|
table.add(alphaSlider).fillX().expandX();
|
||||||
|
root.add(table).fill().row();
|
||||||
|
}
|
||||||
root.add("Animation:");
|
root.add("Animation:");
|
||||||
root.add(animationScroll).expand().fill().minHeight(75).row();
|
root.add(animationScroll).expand().fill().row();
|
||||||
root.add("Mix:");
|
root.add("Default mix:");
|
||||||
{
|
{
|
||||||
Table table = table();
|
Table table = table();
|
||||||
table.add(mixLabel).width(29);
|
table.add(mixLabel).width(29);
|
||||||
@ -422,19 +496,19 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
table.add(speedSlider).fillX().expandX();
|
table.add(speedSlider).fillX().expandX();
|
||||||
root.add(table).fill().row();
|
root.add(table).fill().row();
|
||||||
}
|
}
|
||||||
root.add("Playback:");
|
|
||||||
root.add(table(pauseButton, loopCheckbox)).row();
|
|
||||||
|
|
||||||
window.add(root).expand().fill();
|
window.add(root).expand().fill();
|
||||||
window.pack();
|
window.pack();
|
||||||
stage.addActor(window);
|
stage.addActor(window);
|
||||||
|
|
||||||
|
stage.addActor(statusLabel);
|
||||||
|
|
||||||
{
|
{
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.setFillParent(true);
|
table.setFillParent(true);
|
||||||
table.setTouchable(Touchable.disabled);
|
table.setTouchable(Touchable.disabled);
|
||||||
stage.addActor(table);
|
stage.addActor(table);
|
||||||
table.pad(10).bottom().right();
|
table.pad(10, 10, 22, 10).bottom().right();
|
||||||
table.add(toasts);
|
table.add(toasts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,10 +518,12 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
table.setTouchable(Touchable.disabled);
|
table.setTouchable(Touchable.disabled);
|
||||||
stage.addActor(table);
|
stage.addActor(table);
|
||||||
table.pad(10).top().right();
|
table.pad(10).top().right();
|
||||||
|
table.defaults().right();
|
||||||
table.add(new Label("", skin, "default", Color.LIGHT_GRAY)); // Version.
|
table.add(new Label("", skin, "default", Color.LIGHT_GRAY)); // Version.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Events.
|
void 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();
|
||||||
@ -463,7 +539,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
String name = fileDialog.getFile();
|
String name = fileDialog.getFile();
|
||||||
String dir = fileDialog.getDirectory();
|
String dir = fileDialog.getDirectory();
|
||||||
if (name == null || dir == null) return;
|
if (name == null || dir == null) return;
|
||||||
loadSkeleton(new FileHandle(new File(dir, name).getAbsolutePath()), false);
|
loadSkeleton(new FileHandle(new File(dir, name).getAbsolutePath()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -505,7 +581,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
scaleSlider.addListener(new ChangeListener() {
|
scaleSlider.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
scaleLabel.setText(Float.toString((int)(scaleSlider.getValue() * 100) / 100f));
|
scaleLabel.setText(Float.toString((int)(scaleSlider.getValue() * 100) / 100f));
|
||||||
if (!scaleSlider.isDragging()) loadSkeleton(skeletonFile, false);
|
if (!scaleSlider.isDragging()) loadSkeleton(skeletonFile);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -515,6 +591,17 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
alphaSlider.addListener(new ChangeListener() {
|
||||||
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
|
alphaLabel.setText(Float.toString((int)(alphaSlider.getValue() * 100) / 100f));
|
||||||
|
int track = trackButtons.getCheckedIndex();
|
||||||
|
if (track > 0) {
|
||||||
|
TrackEntry current = state.getCurrent(track);
|
||||||
|
if (current != null) current.setAlpha(alphaSlider.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mixSlider.addListener(new ChangeListener() {
|
mixSlider.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
mixLabel.setText(Float.toString((int)(mixSlider.getValue() * 100) / 100f));
|
mixLabel.setText(Float.toString((int)(mixSlider.getValue() * 100) / 100f));
|
||||||
@ -527,7 +614,7 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
if (state != null) {
|
if (state != null) {
|
||||||
String name = animationList.getSelected();
|
String name = animationList.getSelected();
|
||||||
if (name == null)
|
if (name == null)
|
||||||
state.setEmptyAnimation(0, ui.mixSlider.getValue());
|
state.setEmptyAnimation(trackButtons.getCheckedIndex(), ui.mixSlider.getValue());
|
||||||
else
|
else
|
||||||
setAnimation();
|
setAnimation();
|
||||||
}
|
}
|
||||||
@ -553,6 +640,22 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ChangeListener trackButtonListener = new ChangeListener() {
|
||||||
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
|
int track = ui.trackButtons.getCheckedIndex();
|
||||||
|
if (track == -1) return;
|
||||||
|
TrackEntry current = state.getCurrent(track);
|
||||||
|
animationList.getSelection().setProgrammaticChangeEvents(false);
|
||||||
|
animationList.setSelected(current == null ? null : current.animation.name);
|
||||||
|
animationList.getSelection().setProgrammaticChangeEvents(true);
|
||||||
|
|
||||||
|
alphaSlider.setDisabled(track == 0);
|
||||||
|
alphaSlider.setValue(current == null ? 1 : current.alpha);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (TextButton button : trackButtons.getButtons())
|
||||||
|
button.addListener(trackButtonListener);
|
||||||
|
|
||||||
Gdx.input.setInputProcessor(new InputMultiplexer(stage, new InputAdapter() {
|
Gdx.input.setInputProcessor(new InputMultiplexer(stage, new InputAdapter() {
|
||||||
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
|
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
|
||||||
touchDragged(screenX, screenY, pointer);
|
touchDragged(screenX, screenY, pointer);
|
||||||
@ -591,13 +694,24 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
skinList.addListener(savePrefsListener);
|
skinList.addListener(savePrefsListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Table table (Actor... actors) {
|
Table table (Actor... actors) {
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.defaults().space(6);
|
table.defaults().space(6);
|
||||||
table.add(actors);
|
table.add(actors);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render () {
|
||||||
|
statusLabel.pack();
|
||||||
|
if (minimizeButton.isChecked())
|
||||||
|
statusLabel.setPosition(10, 25, Align.bottom | Align.left);
|
||||||
|
else
|
||||||
|
statusLabel.setPosition(window.getWidth() + 6, 5, Align.bottom | Align.left);
|
||||||
|
|
||||||
|
stage.act();
|
||||||
|
stage.draw();
|
||||||
|
}
|
||||||
|
|
||||||
void toast (String text) {
|
void toast (String text) {
|
||||||
Table table = new Table();
|
Table table = new Table();
|
||||||
table.add(new Label(text, skin));
|
table.add(new Label(text, skin));
|
||||||
@ -630,7 +744,12 @@ public class SkeletonViewer extends ApplicationAdapter {
|
|||||||
prefs.putFloat("scale", scaleSlider.getValue());
|
prefs.putFloat("scale", scaleSlider.getValue());
|
||||||
prefs.putInteger("x", skeletonX);
|
prefs.putInteger("x", skeletonX);
|
||||||
prefs.putInteger("y", skeletonY);
|
prefs.putInteger("y", skeletonY);
|
||||||
if (animationList.getSelected() != null) prefs.putString("animationName", animationList.getSelected());
|
TrackEntry current = state.getCurrent(0);
|
||||||
|
if (current != null) {
|
||||||
|
String name = current.animation.name;
|
||||||
|
if (name.equals("<empty>")) name = current.next == null ? "" : current.next.animation.name;
|
||||||
|
prefs.putString("animationName", name);
|
||||||
|
}
|
||||||
if (skinList.getSelected() != null) prefs.putString("skinName", skinList.getSelected());
|
if (skinList.getSelected() != null) prefs.putString("skinName", skinList.getSelected());
|
||||||
prefs.flush();
|
prefs.flush();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user