Shader Node's editor connections are now curved lines.

experimental
Nehon 10 years ago
parent 7f50f906aa
commit 400a03c507
  1. 529
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java
  2. 442
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java
  3. 541
      sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java

@ -1,539 +1,18 @@
/*
* To change this template, choose Tools | Templates
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.gde.materialdefinition.editor;
import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock;
import com.jme3.gde.materialdefinition.utils.MaterialUtils;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuDragMouseEvent;
import javax.swing.event.MouseInputListener;
/**
*
* @author Nehon
*/
public class Connection extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener {
protected Dot start;
protected Dot end;
private Point[] points = new Point[6];
private int pointsSize = 6;
private Corner[] corners = new Corner[6];
private String key = "";
protected MappingBlock mapping;
private MouseEvent convertEvent(MouseEvent e) {
MouseEvent me = null;
//workaround for swing utilities removing mouse button when converting events.
if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) {
SwingUtilities.convertMouseEvent(this, e, getDiagram());
} else {
Point p = SwingUtilities.convertPoint(this, new Point(e.getX(),
e.getY()),
getDiagram());
me = new MouseEvent(getDiagram(),
e.getID(),
e.getWhen(),
e.getModifiers()
| e.getModifiersEx(),
p.x, p.y,
e.getXOnScreen(),
e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
e.getButton());
}
return me;
}
private enum Corner {
RightBottom,
BottomRight,
BottomLeft,
LeftBottom,
RightTop,
TopRight,
LeftTop,
TopLeft,
Top,
Bottom,
None,}
public class Connection extends ConnectionCurve{
public Connection(Dot start, Dot end) {
if (start.getParamType() == Dot.ParamType.Output
|| (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output)
|| (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) {
this.start = start;
this.end = end;
} else {
this.start = end;
this.end = start;
}
for (int i = 0; i < 6; i++) {
points[i] = new Point();
}
resize(this.start, this.end);
addMouseMotionListener(this);
addMouseListener(this);
addKeyListener(this);
setFocusable(true);
setOpaque(false);
}
private void translate(Point p, Point store) {
store.x = p.x - getLocation().x - 1;
store.y = p.y - getLocation().y - 1;
}
private Point p1 = new Point();
private Point p2 = new Point();
private Point tp1 = new Point();
private Point bp1 = new Point();
private Point tp2 = new Point();
private Point bp2 = new Point();
@Override
protected void paintBorder(Graphics g) {
// super.paintBorder(g);
//
// g.setColor(Color.GRAY);
// g.drawLine(0, 0, getWidth(), 0);
// g.drawLine(getWidth(), 0, getWidth(), getHeight() - 1);
// g.drawLine(getWidth(), getHeight() - 1, 0, getHeight() - 1);
// g.drawLine(0, getHeight() - 1, 0, 0);
}
public String getKey() {
return key;
}
protected void makeKey(MappingBlock mapping, String techName) {
this.mapping = mapping;
key = MaterialUtils.makeKey(mapping, techName);
}
private void adjustCorners(Corner corner, Point tp, Point bp) {
switch (corner) {
case LeftTop:
case TopLeft:
tp.x -= 1;
bp.x += 1;
tp.y += 1;
bp.y -= 1;
break;
case RightBottom:
case BottomRight:
tp.x += 1;
bp.x -= 1;
tp.y -= 1;
bp.y += 1;
break;
case RightTop:
case TopRight:
tp.x -= 1;
bp.x += 1;
tp.y -= 1;
bp.y += 1;
break;
case LeftBottom:
case BottomLeft:
tp.x += 1;
bp.x -= 1;
tp.y += 1;
bp.y -= 1;
break;
case None:
tp.y -= 1;
bp.y += 1;
break;
case Top:
tp.x -= 1;
bp.x += 1;
break;
case Bottom:
tp.x += 1;
bp.x -= 1;
break;
}
}
@Override
protected void paintComponent(Graphics g) {
if (paintDebug) {
for (int i = 0; i < pointsSize - 1; i++) {
translate(points[i], p1);
p1.x -= MARGIN;
p1.y -= MARGIN;
translate(points[i + 1], p2);
p2.x += MARGIN;
p2.y += MARGIN;
g.setColor(Color.GRAY);
g.drawLine(p1.x, p1.y, p2.x, p1.y);
g.drawLine(p2.x, p1.y, p2.x, p2.y);
g.drawLine(p2.x, p2.y, p1.x, p2.y);
g.drawLine(p1.x, p2.y, p1.x, p1.y);
}
paintDebug = false;
}
for (int i = 0; i < pointsSize - 1; i++) {
g.setColor(Color.YELLOW);
translate(points[i], p1);
translate(points[i + 1], p2);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
if (getDiagram().selectedItem == this) {
g.setColor(Color.CYAN);
} else {
g.setColor(Color.GRAY);
}
tp1.setLocation(p1);
bp1.setLocation(p1);
tp2.setLocation(p2);
bp2.setLocation(p2);
adjustCorners(corners[i], tp1, bp1);
adjustCorners(corners[i + 1], tp2, bp2);
g.drawLine(tp1.x, tp1.y, tp2.x, tp2.y);
g.drawLine(bp1.x, bp1.y, bp2.x, bp2.y);
}
}
public final static int MARGIN = 10;
private int getOffset() {
return 5 * start.getIndex();
}
private int getHMiddle() {
int st = start.getNode().getLocation().y + start.getNode().getHeight();
int diff = end.getNode().getLocation().y - st;
return st + diff / 2 + getOffset();
}
private int getVMiddleStart() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset();
}
private int getVMiddleStartClampedRight() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int right = end.getNode().getLocation().x + end.getNode().getWidth() + MARGIN;
int loc = startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2);
return Math.max(loc, right) + getOffset();
}
private int getVMiddleEnd() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset());
}
private int getVMiddleEndClampedLeft() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int left = start.getNode().getLocation().x - MARGIN;//+ end.getNode().getWidth() + MARGIN;
int loc = endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2));
return Math.min(loc, left) + getOffset();
}
private int getHBottom() {
int endBottom = end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN;
int startBottom = start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN;
return Math.max(endBottom, startBottom) + getOffset();
}
public final void resize(Dot start, Dot end) {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
if (start.getParamType() == Dot.ParamType.Both) {
startLocation.x = endLocation.x - MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = startLocation.x;
points[1].y = endLocation.y;
points[2].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[0] = Corner.Bottom;
corners[1] = Corner.BottomRight;
corners[2] = Corner.None;
} else {
corners[0] = Corner.Top;
corners[1] = Corner.TopRight;
corners[2] = Corner.None;
}
} else if (end.getParamType() == Dot.ParamType.Both) {
endLocation.x = startLocation.x + MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = endLocation.x;
points[1].y = startLocation.y;
points[2].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[0] = Corner.None;
corners[1] = Corner.RightBottom;
corners[2] = Corner.Bottom;
} else {
corners[0] = Corner.None;
corners[1] = Corner.RightTop;
corners[2] = Corner.Top;
}
} else if (startLocation.x + MARGIN <= endLocation.x - MARGIN) {
pointsSize = 4;
points[0].setLocation(startLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[2].x = getVMiddleStart();
points[2].y = endLocation.y;
corners[0] = Corner.None;
corners[3] = Corner.None;
points[3].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomRight;
} else {
corners[1] = Corner.RightTop;
corners[2] = Corner.TopRight;
}
} else {
pointsSize = 6;
points[0].setLocation(startLocation);
points[5].setLocation(endLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[4].x = getVMiddleEnd();
points[4].y = endLocation.y;
corners[0] = Corner.None;
corners[5] = Corner.None;
if ((start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN
> end.getNode().getLocation().y - MARGIN)
&& (end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN
> start.getNode().getLocation().y - MARGIN)) {
if (startLocation.y + MARGIN <= endLocation.y - MARGIN) {
points[1].x = getVMiddleStartClampedRight();
points[2].x = getVMiddleStartClampedRight();
} else {
points[1].x = getVMiddleStart();
points[2].x = getVMiddleStart();
}
points[2].y = getHBottom();
if (startLocation.y + MARGIN > endLocation.y - MARGIN) {
points[3].x = getVMiddleEndClampedLeft();
points[4].x = getVMiddleEndClampedLeft();
} else {
points[3].x = getVMiddleEnd();
points[4].x = getVMiddleEnd();
}
points[3].y = getHBottom();
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomLeft;
corners[3] = Corner.LeftTop;
corners[4] = Corner.TopRight;
} else {
points[2].x = getVMiddleStart();
points[2].y = getHMiddle();
points[3].x = getVMiddleEnd();
points[3].y = getHMiddle();
if (startLocation.y <= endLocation.y) {
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomLeft;
corners[3] = Corner.LeftBottom;
corners[4] = Corner.BottomRight;
} else {
corners[1] = Corner.RightTop;
corners[2] = Corner.TopLeft;
corners[3] = Corner.LeftTop;
corners[4] = Corner.TopRight;
}
}
}
updateBounds();
}
private void updateBounds() {
int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
for (int i = 0; i < pointsSize; i++) {
if (points[i].x < minX) {
minX = points[i].x;
}
if (points[i].y < minY) {
minY = points[i].y;
}
if (points[i].x > maxX) {
maxX = points[i].x;
}
if (points[i].y > maxY) {
maxY = points[i].y;
}
}
maxX += MARGIN;
maxY += MARGIN;
minX -= MARGIN;
minY -= MARGIN;
setLocation(minX, minY);
setSize(maxX - minX, maxY - minY);
}
private Diagram getDiagram() {
return (Diagram) start.getDiagram();
}
@Override
public void mouseDragged(MouseEvent e) {
dispatchEventToDiagram(e);
}
private void dispatchEventToDiagram(MouseEvent e) {
MouseEvent me = null;
me = convertEvent(e);
getDiagram().dispatchEvent(me);
}
@Override
public void mouseMoved(MouseEvent e) {
dispatchEventToDiagram(e);
}
private boolean paintDebug = false;
private void debug() {
paintDebug = true;
repaint();
}
@Override
public void mouseClicked(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mousePressed(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mouseReleased(MouseEvent e) {
dispatchEventToDiagram(e);
}
public void select(MouseEvent e) {
boolean selected = false;
requestFocusInWindow(true);
for (int i = 0; i < pointsSize - 1; i++) {
translate(points[i], p1);
translate(points[i + 1], p2);
if (p1.x > p2.x || p1.y > p2.y) {
tp1.setLocation(p1);
p1.setLocation(p2);
p2.setLocation(tp1);
}
p1.x -= MARGIN / 2;
p1.y -= MARGIN / 2;
p2.x += MARGIN / 2;
p2.y += MARGIN / 2;
if (e.getX() >= p1.x && e.getX() <= p2.x
&& e.getY() >= p1.y && e.getY() <= p2.y) {
selected = true;
}
}
if (selected) {
getDiagram().select(this);
e.consume();
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
super(start, end);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
Diagram diag = getDiagram();
if (diag.selectedItem == this) {
diag.removeSelectedConnection();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
public void componentResized(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
resize(start, end);
}
public void componentShown(ComponentEvent e) {
}
public void componentHidden(ComponentEvent e) {
}
public void propertyChange(PropertyChangeEvent evt) {
MappingBlock mapping = (MappingBlock) evt.getSource();
key = MaterialUtils.makeKey(mapping, getDiagram().getCurrentTechniqueName());
}
}

@ -0,0 +1,442 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.gde.materialdefinition.editor;
import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock;
import com.jme3.gde.materialdefinition.utils.MaterialUtils;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Path2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuDragMouseEvent;
import javax.swing.event.MouseInputListener;
/**
*
* @author Nehon
*/
public class ConnectionCurve extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener {
protected Dot start;
protected Dot end;
private final Point[] points = new Point[7];
private int pointsSize = 7;
private int nbCurve = 2;
private final CubicCurve2D[] curves = new CubicCurve2D[2];
private String key = "";
protected MappingBlock mapping;
private MouseEvent convertEvent(MouseEvent e) {
MouseEvent me = null;
//workaround for swing utilities removing mouse button when converting events.
if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) {
SwingUtilities.convertMouseEvent(this, e, getDiagram());
} else {
Point p = SwingUtilities.convertPoint(this, new Point(e.getX(),
e.getY()),
getDiagram());
me = new MouseEvent(getDiagram(),
e.getID(),
e.getWhen(),
e.getModifiers()
| e.getModifiersEx(),
p.x, p.y,
e.getXOnScreen(),
e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
e.getButton());
}
return me;
}
private enum Corner {
RightBottom,
BottomRight,
BottomLeft,
LeftBottom,
RightTop,
TopRight,
LeftTop,
TopLeft,
Top,
Bottom,
None,
}
@SuppressWarnings("LeakingThisInConstructor")
public ConnectionCurve(Dot start, Dot end) {
if (start.getParamType() == Dot.ParamType.Output
|| (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output)
|| (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) {
this.start = start;
this.end = end;
} else {
this.start = end;
this.end = start;
}
for (int i = 0; i < 7; i++) {
points[i] = new Point();
}
for (int i = 0; i < nbCurve; i++) {
curves[i] = new CubicCurve2D.Double();
}
resize(this.start, this.end);
addMouseMotionListener(this);
addMouseListener(this);
addKeyListener(this);
setFocusable(true);
setOpaque(false);
}
private void translate(Point p, Point store) {
store.x = p.x - getLocation().x - 1;
store.y = p.y - getLocation().y - 1;
}
private final Point p1 = new Point();
private final Point p2 = new Point();
private final Point p3 = new Point();
private final Point p4 = new Point();
public String getKey() {
return key;
}
protected void makeKey(MappingBlock mapping, String techName) {
this.mapping = mapping;
key = MaterialUtils.makeKey(mapping, techName);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = ((Graphics2D) g);
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(4));
Path2D.Double path1 = new Path2D.Double();
g.setColor(Color.DARK_GRAY);
if (pointsSize < 4) {
translate(points[0], p1);
translate(points[1], p2);
translate(points[1], p3);
translate(points[2], p4);
path1.moveTo(p1.x, p1.y);
path1.curveTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
curves[0].setCurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
nbCurve = 1;
}
for (int i = 0; i < pointsSize - 3; i += 3) {
translate(points[i], p1);
translate(points[i + 1], p2);
translate(points[i + 2], p3);
translate(points[i + 3], p4);
path1.moveTo(p1.x, p1.y);
path1.curveTo(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
if (i > 1) {
curves[1].setCurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
nbCurve = 2;
} else {
curves[0].setCurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);
nbCurve = 1;
}
}
((Graphics2D) g).draw(path1);
g2.setStroke(new BasicStroke(2));
if (getDiagram().selectedItem == this) {
g.setColor(Color.WHITE);
} else {
g.setColor(LIGHT_GREY);
}
((Graphics2D) g).draw(path1);
}
private final static Color LIGHT_GREY = new Color(120, 120, 120);
public final static int MARGIN = 15;
private int getOffset() {
return 5 * start.getIndex();
}
private int getHMiddle() {
int st = start.getNode().getLocation().y + start.getNode().getHeight();
int diff = end.getNode().getLocation().y - st;
return st + diff / 2 + getOffset();
}
private int getVMiddleStart() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset();
}
private int getVMiddleStartNoMargin() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return startLocation.x + ((endLocation.x - startLocation.x) / 2) + getOffset();
}
private int getVMiddleStartClampedRight() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int right = end.getNode().getLocation().x + end.getNode().getWidth() + MARGIN;
int loc = startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2);
return Math.max(loc, right) + getOffset();
}
private int getVMiddleEnd() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset());
}
private int getVMiddleEndClampedLeft() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int left = start.getNode().getLocation().x - MARGIN;//+ end.getNode().getWidth() + MARGIN;
int loc = endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2));
return Math.min(loc, left) + getOffset();
}
private int getHBottom() {
int endBottom = end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN;
int startBottom = start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN;
return Math.max(endBottom, startBottom) + getOffset();
}
public final void resize(Dot start, Dot end) {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
if (start.getParamType() == Dot.ParamType.Both) {
startLocation.x = endLocation.x - MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = startLocation.x;
points[1].y = endLocation.y;
points[2].setLocation(endLocation);
} else if (end.getParamType() == Dot.ParamType.Both) {
endLocation.x = startLocation.x + MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = endLocation.x;
points[1].y = startLocation.y;
points[2].setLocation(endLocation);
} else if (startLocation.x + MARGIN <= endLocation.x - MARGIN) {
pointsSize = 4;
points[0].setLocation(startLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[2].x = getVMiddleStart();
points[2].y = endLocation.y;
points[3].setLocation(endLocation);
} else if (startLocation.x <= endLocation.x) {
pointsSize = 4;
points[0].setLocation(startLocation);
points[1].x = getVMiddleStartNoMargin();
points[1].y = startLocation.y;
points[2].x = getVMiddleStartNoMargin();
points[2].y = endLocation.y;
points[3].setLocation(endLocation);
} else {
pointsSize = 7;
points[0].setLocation(startLocation);
points[6].setLocation(endLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[5].x = getVMiddleEnd();
points[5].y = endLocation.y;
if ((start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN
> end.getNode().getLocation().y - MARGIN)
&& (end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN
> start.getNode().getLocation().y - MARGIN)) {
if (startLocation.y + MARGIN <= endLocation.y - MARGIN) {
points[1].x = getVMiddleStartClampedRight();
points[2].x = getVMiddleStartClampedRight();
} else {
points[1].x = getVMiddleStart();
points[2].x = getVMiddleStart();
}
points[2].y = getHBottom();
points[4].y = getHBottom();
if (startLocation.y + MARGIN > endLocation.y - MARGIN) {
points[4].x = getVMiddleEndClampedLeft();
points[5].x = getVMiddleEndClampedLeft();
points[3].x = points[4].x + (points[2].x - points[4].x) / 2;
} else {
points[4].x = getVMiddleEnd();
points[5].x = getVMiddleEnd();
points[3].x = points[4].x + (points[2].x - points[4].x) / 2;
}
points[3].y = getHBottom();
} else {
points[2].x = getVMiddleStart();
points[2].y = getHMiddle();
points[3].x = points[4].x + (points[2].x - points[4].x) / 2;
points[3].y = getHMiddle();
points[4].x = getVMiddleEnd();
points[4].y = points[3].y;
}
}
updateBounds();
}
private void updateBounds() {
int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
for (int i = 0; i < pointsSize; i++) {
if (points[i].x < minX) {
minX = points[i].x;
}
if (points[i].y < minY) {
minY = points[i].y;
}
if (points[i].x > maxX) {
maxX = points[i].x;
}
if (points[i].y > maxY) {
maxY = points[i].y;
}
}
maxX += MARGIN;
maxY += MARGIN;
minX -= MARGIN;
minY -= MARGIN;
setLocation(minX, minY);
setSize(maxX - minX, maxY - minY);
}
private Diagram getDiagram() {
return (Diagram) start.getDiagram();
}
@Override
public void mouseDragged(MouseEvent e) {
dispatchEventToDiagram(e);
}
private void dispatchEventToDiagram(MouseEvent e) {
MouseEvent me = convertEvent(e);
getDiagram().dispatchEvent(me);
}
@Override
public void mouseMoved(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mouseClicked(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mousePressed(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mouseReleased(MouseEvent e) {
dispatchEventToDiagram(e);
}
public void select(MouseEvent e) {
requestFocusInWindow(true);
int margin = MARGIN / 2;
boolean selected = false;
for (int i = 0; i < nbCurve && !selected; i++) {
selected = curves[i].intersects(e.getX() - margin, e.getY() - margin, e.getX() + margin, e.getY() + margin);
}
if (selected) {
getDiagram().select(this);
e.consume();
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
Diagram diag = getDiagram();
if (diag.selectedItem == this) {
diag.removeSelectedConnection();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
public void componentResized(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
resize(start, end);
}
public void componentShown(ComponentEvent e) {
}
public void componentHidden(ComponentEvent e) {
}
public void propertyChange(PropertyChangeEvent evt) {
MappingBlock map = (MappingBlock) evt.getSource();
key = MaterialUtils.makeKey(map, getDiagram().getCurrentTechniqueName());
}
}

@ -0,0 +1,541 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.gde.materialdefinition.editor;
import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock;
import com.jme3.gde.materialdefinition.utils.MaterialUtils;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.MenuDragMouseEvent;
import javax.swing.event.MouseInputListener;
/**
*
* Kept this class in case of.
* This is the old staright connection class, now ConnectionCurve is used
* @author Nehon
*/
@Deprecated
public class ConnectionStraight extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener {
protected Dot start;
protected Dot end;
private Point[] points = new Point[6];
private int pointsSize = 6;
private Corner[] corners = new Corner[6];
private String key = "";
protected MappingBlock mapping;
private MouseEvent convertEvent(MouseEvent e) {
MouseEvent me = null;
//workaround for swing utilities removing mouse button when converting events.
if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) {
SwingUtilities.convertMouseEvent(this, e, getDiagram());
} else {
Point p = SwingUtilities.convertPoint(this, new Point(e.getX(),
e.getY()),
getDiagram());
me = new MouseEvent(getDiagram(),
e.getID(),
e.getWhen(),
e.getModifiers()
| e.getModifiersEx(),
p.x, p.y,
e.getXOnScreen(),
e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
e.getButton());
}
return me;
}
private enum Corner {
RightBottom,
BottomRight,
BottomLeft,
LeftBottom,
RightTop,
TopRight,
LeftTop,
TopLeft,
Top,
Bottom,
None,}
public ConnectionStraight(Dot start, Dot end) {
if (start.getParamType() == Dot.ParamType.Output
|| (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output)
|| (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) {
this.start = start;
this.end = end;
} else {
this.start = end;
this.end = start;
}
for (int i = 0; i < 6; i++) {
points[i] = new Point();
}
resize(this.start, this.end);
addMouseMotionListener(this);
addMouseListener(this);
addKeyListener(this);
setFocusable(true);
setOpaque(false);
}
private void translate(Point p, Point store) {
store.x = p.x - getLocation().x - 1;
store.y = p.y - getLocation().y - 1;
}
private Point p1 = new Point();
private Point p2 = new Point();
private Point tp1 = new Point();
private Point bp1 = new Point();
private Point tp2 = new Point();
private Point bp2 = new Point();
@Override
protected void paintBorder(Graphics g) {
// super.paintBorder(g);
//
// g.setColor(Color.GRAY);
// g.drawLine(0, 0, getWidth(), 0);
// g.drawLine(getWidth(), 0, getWidth(), getHeight() - 1);
// g.drawLine(getWidth(), getHeight() - 1, 0, getHeight() - 1);
// g.drawLine(0, getHeight() - 1, 0, 0);
}
public String getKey() {
return key;
}
protected void makeKey(MappingBlock mapping, String techName) {
this.mapping = mapping;
key = MaterialUtils.makeKey(mapping, techName);
}
private void adjustCorners(Corner corner, Point tp, Point bp) {
switch (corner) {
case LeftTop:
case TopLeft:
tp.x -= 1;
bp.x += 1;
tp.y += 1;
bp.y -= 1;
break;
case RightBottom:
case BottomRight:
tp.x += 1;
bp.x -= 1;
tp.y -= 1;
bp.y += 1;
break;
case RightTop:
case TopRight:
tp.x -= 1;
bp.x += 1;
tp.y -= 1;
bp.y += 1;
break;
case LeftBottom:
case BottomLeft:
tp.x += 1;
bp.x -= 1;
tp.y += 1;
bp.y -= 1;
break;
case None:
tp.y -= 1;
bp.y += 1;
break;
case Top:
tp.x -= 1;
bp.x += 1;
break;
case Bottom:
tp.x += 1;
bp.x -= 1;
break;
}
}
@Override
protected void paintComponent(Graphics g) {
if (paintDebug) {
for (int i = 0; i < pointsSize - 1; i++) {
translate(points[i], p1);
p1.x -= MARGIN;
p1.y -= MARGIN;
translate(points[i + 1], p2);
p2.x += MARGIN;
p2.y += MARGIN;
g.setColor(Color.GRAY);
g.drawLine(p1.x, p1.y, p2.x, p1.y);
g.drawLine(p2.x, p1.y, p2.x, p2.y);
g.drawLine(p2.x, p2.y, p1.x, p2.y);
g.drawLine(p1.x, p2.y, p1.x, p1.y);
}
paintDebug = false;
}
for (int i = 0; i < pointsSize - 1; i++) {
g.setColor(Color.YELLOW);
translate(points[i], p1);
translate(points[i + 1], p2);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
if (getDiagram().selectedItem == this) {
g.setColor(Color.CYAN);
} else {
g.setColor(Color.GRAY);
}
tp1.setLocation(p1);
bp1.setLocation(p1);
tp2.setLocation(p2);
bp2.setLocation(p2);
adjustCorners(corners[i], tp1, bp1);
adjustCorners(corners[i + 1], tp2, bp2);
g.drawLine(tp1.x, tp1.y, tp2.x, tp2.y);
g.drawLine(bp1.x, bp1.y, bp2.x, bp2.y);
}
}
public final static int MARGIN = 10;
private int getOffset() {
return 5 * start.getIndex();
}
private int getHMiddle() {
int st = start.getNode().getLocation().y + start.getNode().getHeight();
int diff = end.getNode().getLocation().y - st;
return st + diff / 2 + getOffset();
}
private int getVMiddleStart() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset();
}
private int getVMiddleStartClampedRight() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int right = end.getNode().getLocation().x + end.getNode().getWidth() + MARGIN;
int loc = startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2);
return Math.max(loc, right) + getOffset();
}
private int getVMiddleEnd() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
return endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset());
}
private int getVMiddleEndClampedLeft() {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
int left = start.getNode().getLocation().x - MARGIN;//+ end.getNode().getWidth() + MARGIN;
int loc = endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2));
return Math.min(loc, left) + getOffset();
}
private int getHBottom() {
int endBottom = end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN;
int startBottom = start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN;
return Math.max(endBottom, startBottom) + getOffset();
}
public final void resize(Dot start, Dot end) {
Point startLocation = start.getStartLocation();
Point endLocation = end.getEndLocation();
if (start.getParamType() == Dot.ParamType.Both) {
startLocation.x = endLocation.x - MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = startLocation.x;
points[1].y = endLocation.y;
points[2].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[0] = Corner.Bottom;
corners[1] = Corner.BottomRight;
corners[2] = Corner.None;
} else {
corners[0] = Corner.Top;
corners[1] = Corner.TopRight;
corners[2] = Corner.None;
}
} else if (end.getParamType() == Dot.ParamType.Both) {
endLocation.x = startLocation.x + MARGIN * 2;
pointsSize = 3;
points[0].setLocation(startLocation);
points[1].x = endLocation.x;
points[1].y = startLocation.y;
points[2].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[0] = Corner.None;
corners[1] = Corner.RightBottom;
corners[2] = Corner.Bottom;
} else {
corners[0] = Corner.None;
corners[1] = Corner.RightTop;
corners[2] = Corner.Top;
}
} else if (startLocation.x + MARGIN <= endLocation.x - MARGIN) {
pointsSize = 4;
points[0].setLocation(startLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[2].x = getVMiddleStart();
points[2].y = endLocation.y;
corners[0] = Corner.None;
corners[3] = Corner.None;
points[3].setLocation(endLocation);
if (startLocation.y <= endLocation.y) {
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomRight;
} else {
corners[1] = Corner.RightTop;
corners[2] = Corner.TopRight;
}
} else {
pointsSize = 6;
points[0].setLocation(startLocation);
points[5].setLocation(endLocation);
points[1].x = getVMiddleStart();
points[1].y = startLocation.y;
points[4].x = getVMiddleEnd();
points[4].y = endLocation.y;
corners[0] = Corner.None;
corners[5] = Corner.None;
if ((start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN
> end.getNode().getLocation().y - MARGIN)
&& (end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN
> start.getNode().getLocation().y - MARGIN)) {
if (startLocation.y + MARGIN <= endLocation.y - MARGIN) {
points[1].x = getVMiddleStartClampedRight();
points[2].x = getVMiddleStartClampedRight();
} else {
points[1].x = getVMiddleStart();
points[2].x = getVMiddleStart();
}
points[2].y = getHBottom();
if (startLocation.y + MARGIN > endLocation.y - MARGIN) {
points[3].x = getVMiddleEndClampedLeft();
points[4].x = getVMiddleEndClampedLeft();
} else {
points[3].x = getVMiddleEnd();
points[4].x = getVMiddleEnd();
}
points[3].y = getHBottom();
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomLeft;
corners[3] = Corner.LeftTop;
corners[4] = Corner.TopRight;
} else {
points[2].x = getVMiddleStart();
points[2].y = getHMiddle();
points[3].x = getVMiddleEnd();
points[3].y = getHMiddle();
if (startLocation.y <= endLocation.y) {
corners[1] = Corner.RightBottom;
corners[2] = Corner.BottomLeft;
corners[3] = Corner.LeftBottom;
corners[4] = Corner.BottomRight;
} else {
corners[1] = Corner.RightTop;
corners[2] = Corner.TopLeft;
corners[3] = Corner.LeftTop;
corners[4] = Corner.TopRight;
}
}
}
updateBounds();
}
private void updateBounds() {
int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE;
for (int i = 0; i < pointsSize; i++) {
if (points[i].x < minX) {
minX = points[i].x;
}
if (points[i].y < minY) {
minY = points[i].y;
}
if (points[i].x > maxX) {
maxX = points[i].x;
}
if (points[i].y > maxY) {
maxY = points[i].y;
}
}
maxX += MARGIN;
maxY += MARGIN;
minX -= MARGIN;
minY -= MARGIN;
setLocation(minX, minY);
setSize(maxX - minX, maxY - minY);
}
private Diagram getDiagram() {
return (Diagram) start.getDiagram();
}
@Override
public void mouseDragged(MouseEvent e) {
dispatchEventToDiagram(e);
}
private void dispatchEventToDiagram(MouseEvent e) {
MouseEvent me = null;
me = convertEvent(e);
getDiagram().dispatchEvent(me);
}
@Override
public void mouseMoved(MouseEvent e) {
dispatchEventToDiagram(e);
}
private boolean paintDebug = false;
private void debug() {
paintDebug = true;
repaint();
}
@Override
public void mouseClicked(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mousePressed(MouseEvent e) {
dispatchEventToDiagram(e);
}
@Override
public void mouseReleased(MouseEvent e) {
dispatchEventToDiagram(e);
}
public void select(MouseEvent e) {
boolean selected = false;
requestFocusInWindow(true);
for (int i = 0; i < pointsSize - 1; i++) {
translate(points[i], p1);
translate(points[i + 1], p2);
if (p1.x > p2.x || p1.y > p2.y) {
tp1.setLocation(p1);
p1.setLocation(p2);
p2.setLocation(tp1);
}
p1.x -= MARGIN / 2;
p1.y -= MARGIN / 2;
p2.x += MARGIN / 2;
p2.y += MARGIN / 2;
if (e.getX() >= p1.x && e.getX() <= p2.x
&& e.getY() >= p1.y && e.getY() <= p2.y) {
selected = true;
}
}
if (selected) {
getDiagram().select(this);
e.consume();
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE) {
Diagram diag = getDiagram();
if (diag.selectedItem == this) {
diag.removeSelectedConnection();
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
public void componentResized(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
resize(start, end);
}
public void componentShown(ComponentEvent e) {
}
public void componentHidden(ComponentEvent e) {
}
public void propertyChange(PropertyChangeEvent evt) {
MappingBlock mapping = (MappingBlock) evt.getSource();
key = MaterialUtils.makeKey(mapping, getDiagram().getCurrentTechniqueName());
}
}
Loading…
Cancel
Save