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. | ||||
|  */ | ||||
| package com.jme3.gde.materialdefinition.editor; | ||||
| 
 | ||||
| import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; | ||||
| import com.jme3.gde.materialdefinition.utils.MaterialUtils; | ||||
| import java.awt.Color; | ||||
| import java.awt.Component; | ||||
| import java.awt.Graphics; | ||||
| import java.awt.Point; | ||||
| import java.awt.event.ComponentEvent; | ||||
| import java.awt.event.ComponentListener; | ||||
| import java.awt.event.KeyEvent; | ||||
| import java.awt.event.KeyListener; | ||||
| import java.awt.event.MouseEvent; | ||||
| import java.awt.event.MouseWheelEvent; | ||||
| import java.beans.PropertyChangeEvent; | ||||
| import java.beans.PropertyChangeListener; | ||||
| import javax.swing.JPanel; | ||||
| import javax.swing.SwingUtilities; | ||||
| import javax.swing.event.MenuDragMouseEvent; | ||||
| import javax.swing.event.MouseInputListener; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * @author Nehon | ||||
|  */ | ||||
| public class Connection extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener { | ||||
| 
 | ||||
|     protected Dot start; | ||||
|     protected Dot end; | ||||
|     private Point[] points = new Point[6]; | ||||
|     private int pointsSize = 6; | ||||
|     private Corner[] corners = new Corner[6]; | ||||
|     private String key = ""; | ||||
|     protected MappingBlock mapping; | ||||
| 
 | ||||
|     private MouseEvent convertEvent(MouseEvent e) { | ||||
|         MouseEvent me = null; | ||||
|         //workaround for swing utilities removing mouse button when converting events. | ||||
|         if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) { | ||||
|             SwingUtilities.convertMouseEvent(this, e, getDiagram()); | ||||
|         } else { | ||||
|             Point p = SwingUtilities.convertPoint(this, new Point(e.getX(), | ||||
|                     e.getY()), | ||||
|                     getDiagram()); | ||||
| 
 | ||||
|             me = new MouseEvent(getDiagram(), | ||||
|                     e.getID(), | ||||
|                     e.getWhen(), | ||||
|                     e.getModifiers() | ||||
|                     | e.getModifiersEx(), | ||||
|                     p.x, p.y, | ||||
|                     e.getXOnScreen(), | ||||
|                     e.getYOnScreen(), | ||||
|                     e.getClickCount(), | ||||
|                     e.isPopupTrigger(), | ||||
|                     e.getButton()); | ||||
|         } | ||||
|         return me; | ||||
|     } | ||||
| 
 | ||||
|     private enum Corner { | ||||
| 
 | ||||
|         RightBottom, | ||||
|         BottomRight, | ||||
|         BottomLeft, | ||||
|         LeftBottom, | ||||
|         RightTop, | ||||
|         TopRight, | ||||
|         LeftTop, | ||||
|         TopLeft, | ||||
|         Top, | ||||
|         Bottom, | ||||
|         None,} | ||||
| public class Connection extends ConnectionCurve{ | ||||
| 
 | ||||
|     public Connection(Dot start, Dot end) { | ||||
| 
 | ||||
| 
 | ||||
|         if (start.getParamType() == Dot.ParamType.Output | ||||
|                 || (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output) | ||||
|                 || (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) { | ||||
|             this.start = start; | ||||
|             this.end = end; | ||||
|         } else { | ||||
|             this.start = end; | ||||
|             this.end = start; | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < 6; i++) { | ||||
|             points[i] = new Point(); | ||||
|         } | ||||
|         resize(this.start, this.end); | ||||
|         addMouseMotionListener(this); | ||||
|         addMouseListener(this); | ||||
|         addKeyListener(this); | ||||
|         setFocusable(true); | ||||
|         setOpaque(false); | ||||
| 
 | ||||
|         super(start, end); | ||||
|     } | ||||
|      | ||||
|     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