From 400a03c5079498d0b166a0f66bcf45df10f208c4 Mon Sep 17 00:00:00 2001 From: Nehon Date: Mon, 9 Feb 2015 23:05:20 +0100 Subject: [PATCH] Shader Node's editor connections are now curved lines. --- .../materialdefinition/editor/Connection.java | 531 +---------------- .../editor/ConnectionCurve.java | 442 ++++++++++++++ .../editor/ConnectionStraight.java | 541 ++++++++++++++++++ 3 files changed, 988 insertions(+), 526 deletions(-) create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java create mode 100644 sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java index 0503aa909..d63a81b9f 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Connection.java @@ -1,539 +1,18 @@ /* - * To change this template, choose Tools | Templates + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.jme3.gde.materialdefinition.editor; -import com.jme3.gde.materialdefinition.fileStructure.leaves.MappingBlock; -import com.jme3.gde.materialdefinition.utils.MaterialUtils; -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Point; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import java.awt.event.MouseWheelEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import javax.swing.JPanel; -import javax.swing.SwingUtilities; -import javax.swing.event.MenuDragMouseEvent; -import javax.swing.event.MouseInputListener; - /** * * @author Nehon */ -public class Connection extends JPanel implements ComponentListener, MouseInputListener, KeyListener, Selectable, PropertyChangeListener { - - protected Dot start; - protected Dot end; - private Point[] points = new Point[6]; - private int pointsSize = 6; - private Corner[] corners = new Corner[6]; - private String key = ""; - protected MappingBlock mapping; - - private MouseEvent convertEvent(MouseEvent e) { - MouseEvent me = null; - //workaround for swing utilities removing mouse button when converting events. - if (e instanceof MouseWheelEvent || e instanceof MenuDragMouseEvent) { - SwingUtilities.convertMouseEvent(this, e, getDiagram()); - } else { - Point p = SwingUtilities.convertPoint(this, new Point(e.getX(), - e.getY()), - getDiagram()); - - me = new MouseEvent(getDiagram(), - e.getID(), - e.getWhen(), - e.getModifiers() - | e.getModifiersEx(), - p.x, p.y, - e.getXOnScreen(), - e.getYOnScreen(), - e.getClickCount(), - e.isPopupTrigger(), - e.getButton()); - } - return me; - } - - private enum Corner { - - RightBottom, - BottomRight, - BottomLeft, - LeftBottom, - RightTop, - TopRight, - LeftTop, - TopLeft, - Top, - Bottom, - None,} +public class Connection extends ConnectionCurve{ public Connection(Dot start, Dot end) { - - - if (start.getParamType() == Dot.ParamType.Output - || (start.getParamType() == Dot.ParamType.Both && end.getParamType() != Dot.ParamType.Output) - || (end.getParamType() == Dot.ParamType.Both && start.getParamType() != Dot.ParamType.Input)) { - this.start = start; - this.end = end; - } else { - this.start = end; - this.end = start; - } - - for (int i = 0; i < 6; i++) { - points[i] = new Point(); - } - resize(this.start, this.end); - addMouseMotionListener(this); - addMouseListener(this); - addKeyListener(this); - setFocusable(true); - setOpaque(false); - - } - - private void translate(Point p, Point store) { - store.x = p.x - getLocation().x - 1; - store.y = p.y - getLocation().y - 1; - } - private Point p1 = new Point(); - private Point p2 = new Point(); - private Point tp1 = new Point(); - private Point bp1 = new Point(); - private Point tp2 = new Point(); - private Point bp2 = new Point(); - - @Override - protected void paintBorder(Graphics g) { -// super.paintBorder(g); -// -// g.setColor(Color.GRAY); -// g.drawLine(0, 0, getWidth(), 0); -// g.drawLine(getWidth(), 0, getWidth(), getHeight() - 1); -// g.drawLine(getWidth(), getHeight() - 1, 0, getHeight() - 1); -// g.drawLine(0, getHeight() - 1, 0, 0); - } - - public String getKey() { - return key; - } - - protected void makeKey(MappingBlock mapping, String techName) { - this.mapping = mapping; - key = MaterialUtils.makeKey(mapping, techName); - } - - private void adjustCorners(Corner corner, Point tp, Point bp) { - switch (corner) { - case LeftTop: - case TopLeft: - tp.x -= 1; - bp.x += 1; - tp.y += 1; - bp.y -= 1; - break; - case RightBottom: - case BottomRight: - tp.x += 1; - bp.x -= 1; - tp.y -= 1; - bp.y += 1; - break; - case RightTop: - case TopRight: - tp.x -= 1; - bp.x += 1; - tp.y -= 1; - bp.y += 1; - break; - case LeftBottom: - case BottomLeft: - tp.x += 1; - bp.x -= 1; - tp.y += 1; - bp.y -= 1; - break; - case None: - tp.y -= 1; - bp.y += 1; - break; - case Top: - tp.x -= 1; - bp.x += 1; - break; - case Bottom: - tp.x += 1; - bp.x -= 1; - break; - } - } - - @Override - protected void paintComponent(Graphics g) { - if (paintDebug) { - for (int i = 0; i < pointsSize - 1; i++) { - translate(points[i], p1); - p1.x -= MARGIN; - p1.y -= MARGIN; - translate(points[i + 1], p2); - p2.x += MARGIN; - p2.y += MARGIN; - g.setColor(Color.GRAY); - g.drawLine(p1.x, p1.y, p2.x, p1.y); - g.drawLine(p2.x, p1.y, p2.x, p2.y); - g.drawLine(p2.x, p2.y, p1.x, p2.y); - g.drawLine(p1.x, p2.y, p1.x, p1.y); - - - } - - paintDebug = false; - } - - for (int i = 0; i < pointsSize - 1; i++) { - - g.setColor(Color.YELLOW); - translate(points[i], p1); - translate(points[i + 1], p2); - g.drawLine(p1.x, p1.y, p2.x, p2.y); - - - if (getDiagram().selectedItem == this) { - g.setColor(Color.CYAN); - } else { - g.setColor(Color.GRAY); - } - tp1.setLocation(p1); - bp1.setLocation(p1); - tp2.setLocation(p2); - bp2.setLocation(p2); - adjustCorners(corners[i], tp1, bp1); - adjustCorners(corners[i + 1], tp2, bp2); - g.drawLine(tp1.x, tp1.y, tp2.x, tp2.y); - g.drawLine(bp1.x, bp1.y, bp2.x, bp2.y); - - } - - } - public final static int MARGIN = 10; - - private int getOffset() { - return 5 * start.getIndex(); - } - - private int getHMiddle() { - int st = start.getNode().getLocation().y + start.getNode().getHeight(); - int diff = end.getNode().getLocation().y - st; - return st + diff / 2 + getOffset(); - - } - - private int getVMiddleStart() { - Point startLocation = start.getStartLocation(); - Point endLocation = end.getEndLocation(); - return startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset(); - } - - private int getVMiddleStartClampedRight() { - Point startLocation = start.getStartLocation(); - Point endLocation = end.getEndLocation(); - int right = end.getNode().getLocation().x + end.getNode().getWidth() + MARGIN; - int loc = startLocation.x + Math.max(MARGIN, (endLocation.x - startLocation.x) / 2); - return Math.max(loc, right) + getOffset(); - } - - private int getVMiddleEnd() { - Point startLocation = start.getStartLocation(); - Point endLocation = end.getEndLocation(); - return endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2) + getOffset()); - - } - - private int getVMiddleEndClampedLeft() { - Point startLocation = start.getStartLocation(); - Point endLocation = end.getEndLocation(); - int left = start.getNode().getLocation().x - MARGIN;//+ end.getNode().getWidth() + MARGIN; - int loc = endLocation.x - Math.max(0, Math.max(MARGIN, (endLocation.x - startLocation.x) / 2)); - return Math.min(loc, left) + getOffset(); - - } - - private int getHBottom() { - int endBottom = end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN; - int startBottom = start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN; - return Math.max(endBottom, startBottom) + getOffset(); - - } - - public final void resize(Dot start, Dot end) { - Point startLocation = start.getStartLocation(); - Point endLocation = end.getEndLocation(); - - if (start.getParamType() == Dot.ParamType.Both) { - startLocation.x = endLocation.x - MARGIN * 2; - pointsSize = 3; - points[0].setLocation(startLocation); - points[1].x = startLocation.x; - points[1].y = endLocation.y; - points[2].setLocation(endLocation); - if (startLocation.y <= endLocation.y) { - corners[0] = Corner.Bottom; - corners[1] = Corner.BottomRight; - corners[2] = Corner.None; - } else { - corners[0] = Corner.Top; - corners[1] = Corner.TopRight; - corners[2] = Corner.None; - } - } else if (end.getParamType() == Dot.ParamType.Both) { - endLocation.x = startLocation.x + MARGIN * 2; - pointsSize = 3; - points[0].setLocation(startLocation); - points[1].x = endLocation.x; - points[1].y = startLocation.y; - points[2].setLocation(endLocation); - if (startLocation.y <= endLocation.y) { - corners[0] = Corner.None; - corners[1] = Corner.RightBottom; - corners[2] = Corner.Bottom; - } else { - corners[0] = Corner.None; - corners[1] = Corner.RightTop; - corners[2] = Corner.Top; - } - } else if (startLocation.x + MARGIN <= endLocation.x - MARGIN) { - pointsSize = 4; - points[0].setLocation(startLocation); - points[1].x = getVMiddleStart(); - points[1].y = startLocation.y; - points[2].x = getVMiddleStart(); - points[2].y = endLocation.y; - corners[0] = Corner.None; - corners[3] = Corner.None; - points[3].setLocation(endLocation); - if (startLocation.y <= endLocation.y) { - corners[1] = Corner.RightBottom; - corners[2] = Corner.BottomRight; - } else { - corners[1] = Corner.RightTop; - corners[2] = Corner.TopRight; - } - - } else { - pointsSize = 6; - points[0].setLocation(startLocation); - points[5].setLocation(endLocation); - points[1].x = getVMiddleStart(); - points[1].y = startLocation.y; - - points[4].x = getVMiddleEnd(); - points[4].y = endLocation.y; - corners[0] = Corner.None; - corners[5] = Corner.None; - if ((start.getNode().getLocation().y + start.getNode().getHeight() + MARGIN - > end.getNode().getLocation().y - MARGIN) - && (end.getNode().getLocation().y + end.getNode().getHeight() + MARGIN - > start.getNode().getLocation().y - MARGIN)) { - - if (startLocation.y + MARGIN <= endLocation.y - MARGIN) { - points[1].x = getVMiddleStartClampedRight(); - points[2].x = getVMiddleStartClampedRight(); - } else { - points[1].x = getVMiddleStart(); - points[2].x = getVMiddleStart(); - } - points[2].y = getHBottom(); - - if (startLocation.y + MARGIN > endLocation.y - MARGIN) { - points[3].x = getVMiddleEndClampedLeft(); - points[4].x = getVMiddleEndClampedLeft(); - - } else { - points[3].x = getVMiddleEnd(); - points[4].x = getVMiddleEnd(); - } - - points[3].y = getHBottom(); - - corners[1] = Corner.RightBottom; - corners[2] = Corner.BottomLeft; - corners[3] = Corner.LeftTop; - corners[4] = Corner.TopRight; - - } else { - - points[2].x = getVMiddleStart(); - points[2].y = getHMiddle(); - - points[3].x = getVMiddleEnd(); - points[3].y = getHMiddle(); - - - if (startLocation.y <= endLocation.y) { - corners[1] = Corner.RightBottom; - corners[2] = Corner.BottomLeft; - corners[3] = Corner.LeftBottom; - corners[4] = Corner.BottomRight; - } else { - corners[1] = Corner.RightTop; - corners[2] = Corner.TopLeft; - corners[3] = Corner.LeftTop; - corners[4] = Corner.TopRight; - } - } - } - updateBounds(); - } - - private void updateBounds() { - int minX = Integer.MAX_VALUE, minY = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxY = Integer.MIN_VALUE; - for (int i = 0; i < pointsSize; i++) { - if (points[i].x < minX) { - minX = points[i].x; - } - if (points[i].y < minY) { - minY = points[i].y; - } - - if (points[i].x > maxX) { - maxX = points[i].x; - } - if (points[i].y > maxY) { - maxY = points[i].y; - } - } - maxX += MARGIN; - maxY += MARGIN; - minX -= MARGIN; - minY -= MARGIN; - - setLocation(minX, minY); - setSize(maxX - minX, maxY - minY); - } - - private Diagram getDiagram() { - return (Diagram) start.getDiagram(); - } - - @Override - public void mouseDragged(MouseEvent e) { - dispatchEventToDiagram(e); - } - - private void dispatchEventToDiagram(MouseEvent e) { - MouseEvent me = null; - me = convertEvent(e); - getDiagram().dispatchEvent(me); - } - - @Override - public void mouseMoved(MouseEvent e) { - dispatchEventToDiagram(e); - } - private boolean paintDebug = false; - - private void debug() { - paintDebug = true; - repaint(); - } - - @Override - public void mouseClicked(MouseEvent e) { - dispatchEventToDiagram(e); - } - - @Override - public void mousePressed(MouseEvent e) { - dispatchEventToDiagram(e); - } - - @Override - public void mouseReleased(MouseEvent e) { - dispatchEventToDiagram(e); - } - - public void select(MouseEvent e) { - boolean selected = false; - requestFocusInWindow(true); - for (int i = 0; i < pointsSize - 1; i++) { - translate(points[i], p1); - translate(points[i + 1], p2); - if (p1.x > p2.x || p1.y > p2.y) { - tp1.setLocation(p1); - p1.setLocation(p2); - p2.setLocation(tp1); - } - - p1.x -= MARGIN / 2; - p1.y -= MARGIN / 2; - - p2.x += MARGIN / 2; - p2.y += MARGIN / 2; - - - if (e.getX() >= p1.x && e.getX() <= p2.x - && e.getY() >= p1.y && e.getY() <= p2.y) { - selected = true; - } - } - - if (selected) { - getDiagram().select(this); - e.consume(); - } - } - - @Override - public void mouseEntered(MouseEvent e) { - } - - @Override - public void mouseExited(MouseEvent e) { - } - - @Override - public void keyTyped(KeyEvent e) { - } - - @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()); + super(start, end); } + } diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java new file mode 100644 index 000000000..942dd6e70 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionCurve.java @@ -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()); + } +} diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java new file mode 100644 index 000000000..3eba66a23 --- /dev/null +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/ConnectionStraight.java @@ -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()); + } +}