New Graph Node Editor Skin
@@ -3,6 +3,9 @@
|
||||
- Experimental Code Editor for:
|
||||
* Typing Labels
|
||||
* GLSL Fragment shaders
|
||||
- Experimental Node Graph Editor for:
|
||||
* Create complex actions
|
||||
- Actions Library
|
||||
- Animations and UI/UX enhancements
|
||||
- Better cursor management
|
||||
- Track total time spent using HyperLap2D
|
||||
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -168,6 +168,16 @@
|
||||
background: window-noborder,
|
||||
titleFontColor: white
|
||||
},
|
||||
node: {
|
||||
titleFont: big-font,
|
||||
background: window-node,
|
||||
titleFontColor: white
|
||||
},
|
||||
node-selected: {
|
||||
titleFont: big-font,
|
||||
background: window-node-selected,
|
||||
titleFontColor: white
|
||||
},
|
||||
dialog: {
|
||||
titleFont: big-font,
|
||||
background: window,
|
||||
@@ -416,6 +426,11 @@
|
||||
up: button-window-bg,
|
||||
imageUp: icon-close-white
|
||||
},
|
||||
close-node-window: {
|
||||
imageDown: close-node-pressed,
|
||||
imageOver: close-node-hover,
|
||||
imageUp: close-node
|
||||
},
|
||||
close-panel: {
|
||||
down: button-red,
|
||||
up: button-panel-bg,
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 54 KiB |
@@ -5,7 +5,7 @@ plugins {
|
||||
apply plugin: 'com.novoda.bintray-release'
|
||||
|
||||
group 'games.rednblack'
|
||||
version '0.0.1'
|
||||
version '0.0.2'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
@@ -16,7 +16,7 @@ repositories {
|
||||
publish {
|
||||
def groupProjectID = 'games.rednblack.editor'
|
||||
def artifactProjectID = 'hyperlap2d-runtime-libgdx'
|
||||
def publishVersionID = '0.0.1'
|
||||
def publishVersionID = '0.0.2'
|
||||
|
||||
userOrg = 'rednblackgames'
|
||||
repoName = 'HyperLap2D'
|
||||
|
||||
@@ -11,14 +11,17 @@ import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.*;
|
||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Label;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
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 com.kotcrab.vis.ui.widget.VisImageButton;
|
||||
import games.rednblack.editor.graph.data.FieldType;
|
||||
import games.rednblack.editor.graph.data.GraphConnection;
|
||||
import games.rednblack.editor.graph.data.GraphNodeInput;
|
||||
@@ -69,6 +72,7 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
|
||||
private float canvasX;
|
||||
private float canvasY;
|
||||
private final Vector2 canvasPos = new Vector2();
|
||||
private float canvasWidth;
|
||||
private float canvasHeight;
|
||||
private boolean navigating;
|
||||
@@ -459,7 +463,7 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
windowPositions.put(window, new Vector2(x, y));
|
||||
window.setPosition(x, y);
|
||||
addActor(window);
|
||||
window.setSize(Math.max(150, window.getPrefWidth()), window.getPrefHeight());
|
||||
window.setSize(Math.max(150, window.getPrefWidth() + 20), window.getPrefHeight() + 20);
|
||||
window.setOrigin(Align.center);
|
||||
window.addAction(Actions.sequence(
|
||||
Actions.scaleTo(0, 0),
|
||||
@@ -467,6 +471,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
));
|
||||
boxWindows.put(graphBox.getId(), window);
|
||||
fire(new GraphChangedEvent(true, false));
|
||||
|
||||
updateSelectedVisuals();
|
||||
}
|
||||
|
||||
public void addNodeGroup(String name, Set<String> nodeIds) {
|
||||
@@ -517,8 +523,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
|
||||
private void updateSelectedVisuals() {
|
||||
Window.WindowStyle notSelectedStyle = VisUI.getSkin().get("noborder", Window.WindowStyle.class);
|
||||
Window.WindowStyle selectedStyle = VisUI.getSkin().get("noborder", Window.WindowStyle.class);
|
||||
Window.WindowStyle notSelectedStyle = VisUI.getSkin().get("node", Window.WindowStyle.class);
|
||||
Window.WindowStyle selectedStyle = VisUI.getSkin().get("node-selected", Window.WindowStyle.class);
|
||||
|
||||
for (Map.Entry<String, VisWindow> windowEntry : boxWindows.entrySet()) {
|
||||
Window.WindowStyle newStyle = selectedNodes.contains(windowEntry.getKey()) ? selectedStyle : notSelectedStyle;
|
||||
@@ -609,11 +615,11 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
Window window = windowEntry.getValue();
|
||||
GraphBox<T> graphBox = graphBoxes.get(nodeId);
|
||||
float windowX = window.getX();
|
||||
float windowY = window.getY();
|
||||
float windowY = window.getY() + 14;
|
||||
for (GraphBoxInputConnector<T> connector : graphBox.getInputs().values()) {
|
||||
switch (connector.getSide()) {
|
||||
case Left:
|
||||
from.set(windowX - CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
from.set(windowX - CONNECTOR_LENGTH + 7, windowY + connector.getOffset());
|
||||
break;
|
||||
case Top:
|
||||
from.set(windowX + connector.getOffset(), windowY + window.getHeight() + CONNECTOR_LENGTH);
|
||||
@@ -628,7 +634,7 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
for (GraphBoxOutputConnector<T> connector : graphBox.getOutputs().values()) {
|
||||
switch (connector.getSide()) {
|
||||
case Right:
|
||||
from.set(windowX + window.getWidth() + CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
from.set(windowX + window.getWidth() + CONNECTOR_LENGTH - 7, windowY + connector.getOffset());
|
||||
break;
|
||||
case Bottom:
|
||||
from.set(windowX + connector.getOffset(), windowY - CONNECTOR_LENGTH);
|
||||
@@ -840,8 +846,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
|
||||
private void calculateConnector(Vector2 from, Vector2 to, Window window, GraphBoxOutputConnector<T> connector) {
|
||||
float windowX = window.getX();
|
||||
float windowY = window.getY();
|
||||
float windowX = window.getX() - 7;
|
||||
float windowY = window.getY() + 14;
|
||||
switch (connector.getSide()) {
|
||||
case Right:
|
||||
from.set(windowX + window.getWidth() + CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
@@ -855,8 +861,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
|
||||
private void calculateConnector(Vector2 from, Vector2 to, Window window, GraphBoxInputConnector<T> connector) {
|
||||
float windowX = window.getX();
|
||||
float windowY = window.getY();
|
||||
float windowX = window.getX() + 7;
|
||||
float windowY = window.getY() + 14;
|
||||
switch (connector.getSide()) {
|
||||
case Left:
|
||||
from.set(windowX - CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
@@ -895,8 +901,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
|
||||
private void calculateConnection(Vector2 position, Window window, GraphBoxInputConnector<T> connector) {
|
||||
float windowX = window.getX();
|
||||
float windowY = window.getY();
|
||||
float windowX = window.getX() + 7;
|
||||
float windowY = window.getY() + 14;
|
||||
switch (connector.getSide()) {
|
||||
case Left:
|
||||
position.set(windowX - CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
@@ -908,8 +914,8 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
}
|
||||
|
||||
private void calculateConnection(Vector2 position, Window window, GraphBoxOutputConnector<T> connector) {
|
||||
float windowX = window.getX();
|
||||
float windowY = window.getY();
|
||||
float windowX = window.getX() - 7;
|
||||
float windowY = window.getY() + 14;
|
||||
switch (connector.getSide()) {
|
||||
case Right:
|
||||
position.set(windowX + window.getWidth() + CONNECTOR_LENGTH, windowY + connector.getOffset());
|
||||
@@ -1052,6 +1058,32 @@ public class GraphContainer<T extends FieldType> extends Table implements Naviga
|
||||
removeConnection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCloseButton() {
|
||||
Label titleLabel = getTitleLabel();
|
||||
Table titleTable = getTitleTable();
|
||||
|
||||
VisImageButton closeButton = new VisImageButton("close-node-window");
|
||||
titleTable.add(closeButton).padRight(-getPadRight() + 1.7f);
|
||||
closeButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
close();
|
||||
}
|
||||
});
|
||||
closeButton.addListener(new ClickListener() {
|
||||
@Override
|
||||
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
|
||||
event.cancel();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (titleLabel.getLabelAlign() == Align.center && titleTable.getChildren().size == 2)
|
||||
titleTable.getCell(titleLabel).padLeft(closeButton.getWidth() * 2);
|
||||
titleTable.padTop(5);
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject serializeGraph() {
|
||||
|
||||
@@ -28,6 +28,7 @@ import games.rednblack.editor.graph.producer.value.ValueVector2BoxProducer;
|
||||
import games.rednblack.editor.graph.property.PropertyBox;
|
||||
import games.rednblack.editor.proxy.ProjectManager;
|
||||
import games.rednblack.editor.view.stage.Sandbox;
|
||||
import games.rednblack.editor.view.ui.widget.actors.StaticGrid;
|
||||
import games.rednblack.h2d.common.H2DDialog;
|
||||
import games.rednblack.h2d.common.MsgAPI;
|
||||
import games.rednblack.h2d.common.view.ui.StandardWidgetsFactory;
|
||||
@@ -54,6 +55,9 @@ public class NodeEditorDialog extends H2DDialog implements Graph<GraphBox<Action
|
||||
public NodeEditorDialog() {
|
||||
super("Node Editor");
|
||||
|
||||
StaticGrid gridView = new StaticGrid(this);
|
||||
getContentTable().addActor(gridView);
|
||||
|
||||
addCloseButton();
|
||||
setResizable(true);
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package games.rednblack.editor.view.ui.widget.actors;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Window;
|
||||
|
||||
public class StaticGrid extends Actor {
|
||||
|
||||
private final Window window;
|
||||
|
||||
private final Vector2 tmp = new Vector2();
|
||||
|
||||
private ShapeRenderer shapeRenderer;
|
||||
|
||||
public StaticGrid(Window window) {
|
||||
this.window = window;
|
||||
shapeRenderer = new ShapeRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw (Batch batch, float parentAlpha) {
|
||||
super.draw(batch, parentAlpha);
|
||||
batch.end();
|
||||
|
||||
Gdx.gl.glEnable(GL20.GL_BLEND);
|
||||
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
|
||||
|
||||
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
|
||||
drawGrid(window.getX(), window.getY(), window.getWidth(), window.getHeight(), parentAlpha);
|
||||
shapeRenderer.end();
|
||||
|
||||
Gdx.gl.glDisable(GL20.GL_BLEND);
|
||||
batch.begin();
|
||||
}
|
||||
|
||||
private void drawGrid (float x, float y, float windowWidth, float windowHeight, float parentAlpha) {
|
||||
tmp.set(x + windowWidth / 2, y + windowHeight / 2);
|
||||
|
||||
int lineCount = (int)(windowWidth / 28f);
|
||||
|
||||
for (int i = -lineCount / 2 - 1; i < lineCount / 2 + 1; i++) {
|
||||
float spacing = windowWidth / lineCount;
|
||||
shapeRenderer.setColor(0.2f, 0.2f, 0.2f, parentAlpha);
|
||||
|
||||
float posX = tmp.x - i * spacing - tmp.x % spacing;
|
||||
float posY = tmp.y + i * spacing - tmp.y % spacing;
|
||||
shapeRenderer.rectLine(posX, tmp.y - windowHeight/2f, posX, tmp.y + windowHeight/2f, 2f); // vertical
|
||||
shapeRenderer.rectLine(tmp.x - windowWidth/2f, posY, tmp.x + windowWidth/2f, posY, 2f); // horizontal
|
||||
}
|
||||
}
|
||||
}
|
||||