Shader Node's editor connections are now curved lines.
This commit is contained in:
parent
7f50f906aa
commit
400a03c507
@ -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.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package com.jme3.gde.materialdefinition.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
|
* @author Nehon
|
||||||
*/
|
*/
|
||||||
public class Connection extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener {
|
public class Connection extends ConnectionCurve{
|
||||||
|
|
||||||
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 Connection(Dot start, Dot end) {
|
public Connection(Dot start, Dot end) {
|
||||||
|
super(start, 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user