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…
Reference in new issue