| PortCreateEdgeModeDemo.java |
1 /****************************************************************************
2 **
3 ** This file is part of yFiles-2.6.
4 **
5 ** yWorks proprietary/confidential. Use is subject to license terms.
6 **
7 ** Redistribution of this file or of an unauthorized byte-code version
8 ** of this file is strictly forbidden.
9 **
10 ** Copyright (c) 2000-2008 by yWorks GmbH, Vor dem Kreuzberg 28,
11 ** 72070 Tuebingen, Germany. All rights reserved.
12 **
13 ***************************************************************************/
14 package demo.view.viewmode;
15
16
17 import demo.view.DemoBase;
18 import y.base.Edge;
19 import y.base.Node;
20 import y.base.YCursor;
21 import y.base.YList;
22 import y.view.CreateEdgeMode;
23 import y.view.EdgeRealizer;
24 import y.view.EditMode;
25 import y.view.Graph2D;
26 import y.view.NodeRealizer;
27 import y.view.Port;
28
29 /**
30 * Demonstrates how CreateEdgeMode can be customized in order to
31 * control automatic assignments of ports for edges.
32 * Edges are created in such a way, that the source port is always on
33 * the top side of the source node and the target port is always on the bottom
34 * side of the target node.
35 */
36 public class PortCreateEdgeModeDemo extends DemoBase
37 {
38
39 protected void registerViewModes() {
40 EditMode editMode = new EditMode();
41 view.addViewMode( editMode );
42 //set a custom CreateEdgeMode for the edge mode
43 editMode.setCreateEdgeMode( new PortCreateEdgeMode() );
44 }
45
46 public static class PortCreateEdgeMode extends CreateEdgeMode
47 {
48 private Edge edge; // need this for the hook
49
50 /**
51 * If a node was hit at the given coordinates, that node
52 * will be used as target node for the newly created edge.
53 *
54 */
55 public void mouseReleasedLeft(double x, double y)
56 {
57 // simulate a pressed shift...
58 // this will trigger CreateEdgeMode, to preassign offset
59 // to source and target ports
60 super.mouseShiftReleasedLeft(x, y);
61
62 if (edge != null){ // the edge has just been created
63 Graph2D graph = (Graph2D) edge.getGraph();
64 EdgeRealizer er = graph.getRealizer(edge);
65
66 // get a list of port candidates
67 YList ports = getPorts(edge.source(), edge);
68 Port p = er.getSourcePort();
69 // snap to one of them
70 snap(er, true, p.getOffsetX(), p.getOffsetY(), ports);
71
72 // get a list of port candidates
73 ports = getPorts(edge.target(), edge);
74 p = er.getTargetPort();
75 // snap to one of them
76 snap(er, false, p.getOffsetX(), p.getOffsetY(), ports);
77
78 // do some clean up
79 edge = null;
80 graph.updateViews();
81 }
82
83 }
84
85 /**
86 * Initiates the creation of an edge.
87 *
88 */
89 public void mousePressedLeft(double x, double y)
90 {
91 // simulate a pressed shift...
92 // this will trigger CreateEdgeMode, to preassign offset
93 // to source and target ports
94 super.mouseShiftPressedLeft(x, y);
95 }
96
97
98 public void edgeCreated(Edge e){
99 //remember the edge...
100 this.edge = e;
101 }
102
103 /**
104 * This method finds a list of Port objects for a specific edge/node pair
105 *
106 * @param onNode the node
107 * @param forEdge the edge
108 * @return a list of Port objects
109 */
110 public YList getPorts(Node onNode, Edge forEdge) {
111 YList list = new YList();
112 Graph2D graph = (Graph2D) onNode.getGraph();
113 NodeRealizer nr = graph.getRealizer(onNode);
114 EdgeRealizer er = graph.getRealizer(forEdge);
115
116 if (onNode == forEdge.source()) {
117 // source ports are centered on top of the node
118 list.add(new Port(0, -nr.getHeight() / 2));
119 } else {
120 // target ports are centered at the bottom of the node
121 list.add(new Port(0, nr.getHeight() / 2));
122 }
123 return list;
124 }
125
126 /**
127 * This method calculates a metric for ports and points
128 *
129 * @param x the initial x offset
130 * @param y the initial y offset
131 * @param port the port
132 * @return the distance between the point (x,y) and the port
133 */
134 public static double getDistance(double x, double y, Port port) {
135 return Math.sqrt((x - port.getOffsetX()) * (x - port.getOffsetX())
136 + (y - port.getOffsetY()) * (y - port.getOffsetY()));
137 }
138
139 /**
140 * This method chooses from a list of given ports for an edge
141 * a suitable port, given an initial placement.
142 *
143 * @param edge the affected edge
144 * @param source whether we look at the source node
145 * @param x the initial x offset
146 * @param y the initial y offset
147 * @param ports a list of Port objects (candidates)
148 */
149 public void snap(EdgeRealizer edge, boolean source, double x, double y, YList ports) {
150 if (ports == null || ports.size() < 1) return; // do nothing
151
152 // find the closest port with regards to the getDistance function
153 Port closest = (Port) ports.first();
154 double dist = getDistance(x, y, closest);
155
156 for (YCursor cursor = ports.cursor(); cursor.ok(); cursor.next()) {
157 Port p = (Port) cursor.current();
158 double d2 = getDistance(x, y, p);
159 if (d2 < dist) {
160 dist = d2;
161 closest = p;
162 }
163 }
164
165 // assign the port
166 if (source) {
167 edge.setSourcePort(closest);
168 } else {
169 edge.setTargetPort(closest);
170 }
171 }
172
173 }
174
175 public static void main(String args[])
176 {
177 PortCreateEdgeModeDemo demo = new PortCreateEdgeModeDemo();
178 demo.start("Port Demo");
179 }
180 }
181
182
183
184