Replace ShapeRenderer with ShapeDrawer for graph connections
This commit is contained in:
+28
-1
@@ -2153,7 +2153,7 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button class="collapsible">libGDX-graph</button>
|
||||
<button class="collapsible">libGDX-graph - MIT License</button>
|
||||
<div class="content">
|
||||
<p>
|
||||
MIT License
|
||||
@@ -2180,6 +2180,33 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button class="collapsible">Shape Drawer - MIT License</button>
|
||||
<div class="content">
|
||||
<p>
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 earlygrey
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
|
||||
@@ -20,6 +20,7 @@ version '0.0.2'
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -31,6 +32,7 @@ ext {
|
||||
spineVersion = '3.8.55.1'
|
||||
visuiVersion = '1.4.7-SNAPSHOT'
|
||||
typingLabelVersion = '1.2.0'
|
||||
shapedrawerVersion = '2.3.0'
|
||||
|
||||
packMain = ["art/textures", "assets/style/", "uiskin"]
|
||||
packSplash = ["art/splash_textures", "assets/splash/", "splash"]
|
||||
@@ -96,6 +98,7 @@ dependencies {
|
||||
implementation project(":hyperlap2d-runtime-libgdx")
|
||||
implementation project(":h2d-libgdx-spine-extension")
|
||||
|
||||
implementation "space.earlygrey:shapedrawer:$shapedrawerVersion"
|
||||
implementation "com.rafaskoberg.gdx:typing-label:$typingLabelVersion"
|
||||
implementation "com.kotcrab.vis:vis-ui:$visuiVersion"
|
||||
implementation "com.esotericsoftware.spine:spine-libgdx:$spineVersion"
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import games.rednblack.editor.graph.ui.WhitePixel;
|
||||
import games.rednblack.editor.proxy.CommandManager;
|
||||
import games.rednblack.editor.proxy.SettingsManager;
|
||||
import games.rednblack.editor.splash.SplashScreenAdapter;
|
||||
@@ -69,6 +70,7 @@ public class HyperLap2D implements IProxy, ApplicationListener, Lwjgl3WindowList
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
WhitePixel.initializeShared();
|
||||
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("freetypefonts/DejaVuSans.ttf"));
|
||||
FreeTypeFontGenerator monoGenerator = new FreeTypeFontGenerator(Gdx.files.internal("freetypefonts/DejaVuSansMono.ttf"));
|
||||
|
||||
@@ -227,6 +229,7 @@ public class HyperLap2D implements IProxy, ApplicationListener, Lwjgl3WindowList
|
||||
@Override
|
||||
public boolean closeRequested() {
|
||||
facade.sendNotification(MsgAPI.CHECK_EDITS_ACTION, (Runnable) () -> {
|
||||
WhitePixel.disposeShared();
|
||||
sendNotification(MsgAPI.DISPOSE);
|
||||
VisUI.dispose();
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.DragListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.kotcrab.vis.ui.FocusManager;
|
||||
import games.rednblack.editor.graph.data.FieldType;
|
||||
import games.rednblack.editor.graph.data.GraphConnection;
|
||||
@@ -28,6 +29,7 @@ import games.rednblack.editor.graph.data.GraphValidator;
|
||||
import games.rednblack.editor.graph.data.NodeConnector;
|
||||
import games.rednblack.editor.graph.data.NodeGroup;
|
||||
import games.rednblack.editor.graph.property.PropertyBox;
|
||||
import games.rednblack.editor.graph.ui.WhitePixel;
|
||||
import games.rednblack.editor.graph.ui.preview.NavigableCanvas;
|
||||
import com.kotcrab.vis.ui.VisUI;
|
||||
import com.kotcrab.vis.ui.util.InputValidator;
|
||||
@@ -36,6 +38,9 @@ import com.kotcrab.vis.ui.util.dialog.InputDialogListener;
|
||||
import com.kotcrab.vis.ui.widget.MenuItem;
|
||||
import com.kotcrab.vis.ui.widget.PopupMenu;
|
||||
import com.kotcrab.vis.ui.widget.VisWindow;
|
||||
import games.rednblack.editor.utils.poly.PolygonUtils;
|
||||
import space.earlygrey.shapedrawer.JoinType;
|
||||
import space.earlygrey.shapedrawer.ShapeDrawer;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Shape;
|
||||
@@ -49,9 +54,10 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
private static final float GROUP_LABEL_HEIGHT = 20f;
|
||||
private static final float CONNECTOR_LENGTH = 10;
|
||||
private static final float CONNECTOR_RADIUS = 5;
|
||||
private static final int LINE_WEIGHT = 4;
|
||||
|
||||
private static final Color GROUP_BACKGROUND_COLOR = new Color(1f, 1f, 1f, 0.3f);
|
||||
private static final Color LINE_COLOR = Color.WHITE;
|
||||
private static final Color LINE_COLOR = new Color(1, 1, 1,.7f);
|
||||
private static final Color VALID_CONNECTOR_COLOR = Color.WHITE;
|
||||
private static final Color INVALID_CONNECTOR_COLOR = Color.RED;
|
||||
|
||||
@@ -78,6 +84,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
private Map<NodeGroupImpl, Rectangle> nodeGroups = new HashMap<>();
|
||||
|
||||
private ShapeRenderer shapeRenderer;
|
||||
private ShapeDrawer shapeDrawer;
|
||||
private final Color shapeDrawerColor = new Color();
|
||||
|
||||
private NodeConnector drawingFromConnector;
|
||||
private GraphValidator.ValidationResult<GraphBox<T>, GraphConnection, PropertyBox<T>, T> validationResult = new GraphValidator.ValidationResult<>();
|
||||
@@ -650,31 +658,20 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
if (shapeDrawer == null) {
|
||||
shapeDrawer = new ShapeDrawer(batch, WhitePixel.sharedInstance.textureRegion);
|
||||
}
|
||||
validate();
|
||||
batch.end();
|
||||
Gdx.gl.glEnable(GL20.GL_BLEND);
|
||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
drawGroups(batch);
|
||||
drawConnections(parentAlpha);
|
||||
Gdx.gl.glDisable(GL20.GL_BLEND);
|
||||
batch.begin();
|
||||
drawShapeConnections(parentAlpha);
|
||||
super.draw(batch, parentAlpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getX() {
|
||||
if (parentWindow != null)
|
||||
return super.getX() + parentWindow.getX();
|
||||
return super.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getY() {
|
||||
if (parentWindow != null)
|
||||
return super.getY() + parentWindow.getY();
|
||||
return super.getY();
|
||||
}
|
||||
|
||||
private void drawGroups(Batch batch) {
|
||||
if (!nodeGroups.isEmpty()) {
|
||||
float x = getX();
|
||||
@@ -701,17 +698,13 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
}
|
||||
|
||||
private void drawConnections(float parentAlpha) {
|
||||
private void drawShapeConnections(float parentAlpha) {
|
||||
float x = getX();
|
||||
float y = getY();
|
||||
|
||||
Vector2 from = new Vector2();
|
||||
Vector2 to = new Vector2();
|
||||
|
||||
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
|
||||
shapeRenderer.setColor(LINE_COLOR);
|
||||
shapeRenderer.getColor().a = parentAlpha;
|
||||
|
||||
for (Map.Entry<String, VisWindow> windowEntry : boxWindows.entrySet()) {
|
||||
String nodeId = windowEntry.getKey();
|
||||
Window window = windowEntry.getValue();
|
||||
@@ -723,8 +716,12 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
from.add(x, y);
|
||||
to.add(x, y);
|
||||
|
||||
shapeRenderer.line(from, to);
|
||||
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
shapeDrawerColor.set(VALID_CONNECTOR_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
|
||||
shapeDrawer.line(from, to);
|
||||
shapeDrawer.circle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,50 +730,35 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
from.add(x, y);
|
||||
to.add(x, y);
|
||||
|
||||
shapeRenderer.line(from, to);
|
||||
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
shapeDrawerColor.set(VALID_CONNECTOR_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
|
||||
shapeDrawer.line(from, to);
|
||||
shapeDrawer.circle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
}
|
||||
}
|
||||
|
||||
for (GraphConnection graphConnection : graphConnections) {
|
||||
NodeConnector fromNode = getNodeInfo(graphConnection.getNodeFrom(), graphConnection.getFieldFrom());
|
||||
Window fromWindow = boxWindows.get(fromNode.getNodeId());
|
||||
GraphBoxOutputConnector<T> output = getGraphBoxById(fromNode.getNodeId()).getOutputs().get(fromNode.getFieldId());
|
||||
calculateConnection(from, fromWindow, output);
|
||||
NodeConnector toNode = getNodeInfo(graphConnection.getNodeTo(), graphConnection.getFieldTo());
|
||||
Window toWindow = boxWindows.get(toNode.getNodeId());
|
||||
GraphBoxInputConnector<T> input = getGraphBoxById(toNode.getNodeId()).getInputs().get(toNode.getFieldId());
|
||||
calculateConnection(to, toWindow, input);
|
||||
|
||||
boolean error = validationResult.getErrorConnections().contains(graphConnection);
|
||||
shapeRenderer.setColor(error ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
|
||||
shapeRenderer.getColor().a = parentAlpha;
|
||||
|
||||
from.add(x, y);
|
||||
to.add(x, y);
|
||||
|
||||
float xDiff = Math.min(150, Math.abs(from.x - to.x));
|
||||
shapeRenderer.curve(from.x, from.y, from.x + xDiff, from.y, to.x - xDiff, to.y, to.x, to.y, 50);
|
||||
}
|
||||
|
||||
if (drawingFromConnector != null) {
|
||||
shapeRenderer.setColor(LINE_COLOR);
|
||||
shapeRenderer.getColor().a = parentAlpha;
|
||||
GraphBox<T> drawingFromNode = getGraphBoxById(drawingFromConnector.getNodeId());
|
||||
Window fromWindow = getBoxWindow(drawingFromConnector.getNodeId());
|
||||
if (drawingFromNode.isInputField(drawingFromConnector.getFieldId())) {
|
||||
GraphBoxInputConnector<T> input = drawingFromNode.getInputs().get(drawingFromConnector.getFieldId());
|
||||
calculateConnection(from, fromWindow, input);
|
||||
shapeRenderer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
|
||||
shapeDrawerColor.set(LINE_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
shapeDrawer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY(), LINE_WEIGHT);
|
||||
} else {
|
||||
GraphBoxOutputConnector<T> output = drawingFromNode.getOutputs().get(drawingFromConnector.getFieldId());
|
||||
calculateConnection(from, fromWindow, output);
|
||||
shapeRenderer.line(x + from.x, y + from.y, Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY());
|
||||
shapeDrawerColor.set(LINE_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
shapeDrawer.line(x + from.x, y + from.y, Gdx.input.getX() - parentWindow.getX(), Gdx.graphics.getHeight() - Gdx.input.getY() - parentWindow.getY(), LINE_WEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
|
||||
|
||||
for (Map.Entry<String, VisWindow> windowEntry : boxWindows.entrySet()) {
|
||||
String nodeId = windowEntry.getKey();
|
||||
Window window = windowEntry.getValue();
|
||||
@@ -795,15 +777,44 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
break;
|
||||
}
|
||||
}
|
||||
shapeRenderer.setColor(isErrorous ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
|
||||
shapeRenderer.getColor().a = parentAlpha;
|
||||
|
||||
shapeRenderer.line(from, to);
|
||||
shapeRenderer.circle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
shapeDrawerColor.set(isErrorous ? INVALID_CONNECTOR_COLOR : VALID_CONNECTOR_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
shapeDrawer.line(from, to);
|
||||
shapeDrawer.filledCircle(from.x, from.y, CONNECTOR_RADIUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
shapeRenderer.end();
|
||||
|
||||
for (GraphConnection graphConnection : graphConnections) {
|
||||
NodeConnector fromNode = getNodeInfo(graphConnection.getNodeFrom(), graphConnection.getFieldFrom());
|
||||
Window fromWindow = boxWindows.get(fromNode.getNodeId());
|
||||
GraphBoxOutputConnector<T> output = getGraphBoxById(fromNode.getNodeId()).getOutputs().get(fromNode.getFieldId());
|
||||
calculateConnection(from, fromWindow, output);
|
||||
NodeConnector toNode = getNodeInfo(graphConnection.getNodeTo(), graphConnection.getFieldTo());
|
||||
Window toWindow = boxWindows.get(toNode.getNodeId());
|
||||
GraphBoxInputConnector<T> input = getGraphBoxById(toNode.getNodeId()).getInputs().get(toNode.getFieldId());
|
||||
calculateConnection(to, toWindow, input);
|
||||
|
||||
boolean error = validationResult.getErrorConnections().contains(graphConnection);
|
||||
|
||||
from.add(x, y);
|
||||
to.add(x, y);
|
||||
|
||||
float xDiff = Math.min(150, Math.abs(from.x - to.x));
|
||||
to.y = from.y - to.y == 0 ? to.y + 1 : to.y;
|
||||
|
||||
shapeDrawerColor.set(error ? INVALID_CONNECTOR_COLOR : LINE_COLOR);
|
||||
shapeDrawerColor.a *= parentAlpha;
|
||||
shapeDrawer.setColor(shapeDrawerColor);
|
||||
|
||||
Array<Vector2> path = PolygonUtils.getCurvedLine(from, to,
|
||||
PolygonUtils.vector2Pool.obtain().set(from.x + xDiff, from.y),
|
||||
PolygonUtils.vector2Pool.obtain().set(to.x - xDiff, to.y), 50);
|
||||
shapeDrawer.path(path, LINE_WEIGHT, JoinType.SMOOTH,true);
|
||||
PolygonUtils.vector2Pool.freeAll(path);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateConnector(Vector2 from, Vector2 to, Window window, GraphBoxOutputConnector<T> connector) {
|
||||
|
||||
@@ -20,17 +20,20 @@ public class WhitePixel {
|
||||
public TextureRegion textureRegion;
|
||||
|
||||
public WhitePixel() {
|
||||
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGB888);
|
||||
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
|
||||
pixmap.setColor(Color.WHITE);
|
||||
pixmap.fill();
|
||||
|
||||
texture = new Texture(pixmap);
|
||||
texture = new Texture(pixmap, true);
|
||||
texture.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.MipMapLinearLinear);
|
||||
textureRegion = new TextureRegion(texture);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
texture.dispose();
|
||||
texture = null;
|
||||
textureRegion = null;
|
||||
if (texture != null) {
|
||||
texture.dispose();
|
||||
texture = null;
|
||||
textureRegion = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package games.rednblack.editor.utils;
|
||||
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Pool;
|
||||
|
||||
public class Vector2Pool extends Pool<Vector2> {
|
||||
|
||||
public Vector2Pool(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vector2 newObject() {
|
||||
return new Vector2();
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,9 @@ package games.rednblack.editor.utils.poly;
|
||||
|
||||
import com.badlogic.gdx.math.Intersector;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Pool;
|
||||
import games.rednblack.editor.utils.Vector2Pool;
|
||||
import games.rednblack.editor.view.stage.Sandbox;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -116,4 +119,52 @@ public class PolygonUtils {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Pool<Vector2> vector2Pool = new Vector2Pool(60);
|
||||
private static final Array<Vector2> tmpResult = new Array<>();
|
||||
|
||||
public static Array<Vector2> getCurvedLine(Vector2 from, Vector2 to, Vector2 center1, Vector2 center2, int segments) {
|
||||
tmpResult.clear();
|
||||
|
||||
float subdiv_step = 1f / segments;
|
||||
float subdiv_step2 = subdiv_step * subdiv_step;
|
||||
float subdiv_step3 = subdiv_step * subdiv_step * subdiv_step;
|
||||
|
||||
float pre1 = 3 * subdiv_step;
|
||||
float pre2 = 3 * subdiv_step2;
|
||||
float pre4 = 6 * subdiv_step2;
|
||||
float pre5 = 6 * subdiv_step3;
|
||||
|
||||
float tmp1x = from.x - center1.x * 2 + center2.x;
|
||||
float tmp1y = from.y - center1.y * 2 + center2.y;
|
||||
|
||||
float tmp2x = (center1.x - center2.x) * 3 - from.x + to.x;
|
||||
float tmp2y = (center1.y - center2.y) * 3 - from.y + to.y;
|
||||
|
||||
float fx = from.x;
|
||||
float fy = from.y;
|
||||
|
||||
float dfx = (center1.x - from.x) * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3;
|
||||
float dfy = (center1.y - from.y) * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3;
|
||||
|
||||
float ddfx = tmp1x * pre4 + tmp2x * pre5;
|
||||
float ddfy = tmp1y * pre4 + tmp2y * pre5;
|
||||
|
||||
float dddfx = tmp2x * pre5;
|
||||
float dddfy = tmp2y * pre5;
|
||||
|
||||
while (segments-- > 0) {
|
||||
tmpResult.add(vector2Pool.obtain().set(fx, fy));
|
||||
fx += dfx;
|
||||
fy += dfy;
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
}
|
||||
tmpResult.add(vector2Pool.obtain().set(fx, fy));
|
||||
tmpResult.add(vector2Pool.obtain().set(to.x, to.y));
|
||||
|
||||
return tmpResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ public class AboutDialog extends H2DDialog {
|
||||
contentTable.add(new LinkLabel("- LibGDX Spriter [https://github.com/Trixt0r/gdx-spriter]", "https://github.com/Trixt0r/gdx-spriter")).padLeft(6).left().row();
|
||||
contentTable.add(new LinkLabel("- Physics Body Editor [https://www.aurelienribon.com]", "https://www.aurelienribon.com")).padLeft(6).left().row();
|
||||
contentTable.add(new LinkLabel("- Typing Label [https://github.com/rafaskb/typing-label]", "https://github.com/rafaskb/typing-label")).padLeft(6).left().row();
|
||||
contentTable.add(new LinkLabel("- Shape Drawer [https://github.com/earlygrey/shapedrawer]", "https://github.com/earlygrey/shapedrawer")).padLeft(6).left().row();
|
||||
contentTable.add("\n").row();
|
||||
VisTable legalTable = new VisTable();
|
||||
legalTable.add(new LinkLabel("See Contributors list", "https://github.com/rednblackgames/HyperLap2D/blob/master/AUTHORS"));
|
||||
|
||||
Reference in New Issue
Block a user