1
14 package demo.view.advanced.ports;
15
16 import y.base.Node;
17 import y.base.NodeList;
18 import y.geom.YPoint;
19 import y.geom.YRectangle;
20 import y.view.Graph2D;
21 import y.view.HitInfo;
22 import y.view.NodeLabel;
23 import y.view.NodePort;
24 import y.view.NodeRealizer;
25 import y.view.NodeScaledPortLocationModel;
26 import y.view.PopupMode;
27 import y.view.PortLabelModel;
28 import y.view.PortLocationModel;
29 import y.view.ShapeNodeRealizer;
30
31 import java.awt.Component;
32 import java.awt.Graphics;
33 import java.awt.Graphics2D;
34 import java.awt.event.ActionEvent;
35 import javax.swing.AbstractAction;
36 import javax.swing.Icon;
37 import javax.swing.JMenu;
38 import javax.swing.JPopupMenu;
39
40
44 final class NodePortPopupMode extends PopupMode {
45 private YPoint point;
46
47
48
53 public JPopupMenu getNodeLabelPopup( final NodeLabel label ) {
54 final JPopupMenu jpm = new JPopupMenu("NodeLabel");
55 jpm.add(new AbstractAction("Edit Label") {
56 public void actionPerformed( final ActionEvent e ) {
57 editLabel(label);
58 }
59 });
60 jpm.add(new AbstractAction("Delete Label") {
61 public void actionPerformed( final ActionEvent e ) {
62 final NodeRealizer nr = label.getRealizer();
63 nr.removeLabel(label);
64 getGraph2D().updateViews();
65 }
66 });
67 return jpm;
68 }
69
70
75 public JPopupMenu getNodePopup( final Node v ) {
76 final JPopupMenu jpm = new JPopupMenu("Node");
77 jpm.add(new AbstractAction("Add NodePort") {
78 {
79 setEnabled(false);
80 }
81 public void actionPerformed( final ActionEvent e ) {
82 }
83 });
84 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigRectangle, v));
85 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigDynamic, v));
86 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigEllipse, v));
87 return jpm;
88 }
89
90
98 public JPopupMenu getNodePortPopup( final NodePort port ) {
99 final JPopupMenu jpm = new JPopupMenu("NodePort");
100
101 jpm.add(new AbstractAction("Add Label") {
102 public void actionPerformed( final ActionEvent e ) {
103 editLabel(addPortLabel(port.getRealizer(), port, "Port"));
104 }
105 });
106
107 final JMenu policies = new JMenu("Change Location Policy");
108 policies.add(new ChangeLocationPolicyAction(
109 port, NodeScaledPortLocationModel.POLICY_DISCRETE));
110 policies.add(new ChangeLocationPolicyAction(
111 port, NodeScaledPortLocationModel.POLICY_BOUNDARY));
112 policies.add(new ChangeLocationPolicyAction(
113 port, NodeScaledPortLocationModel.POLICY_BOUNDARY_CENTER));
114 policies.add(new ChangeLocationPolicyAction(
115 port, NodeScaledPortLocationModel.POLICY_BOUNDARY_INSIDE));
116 policies.add(new ChangeLocationPolicyAction(
117 port, NodeScaledPortLocationModel.POLICY_FREE));
118 jpm.add(policies);
119
120 jpm.add(new AbstractAction("Remove Port") {
121 public void actionPerformed( final ActionEvent e ) {
122 final Graph2D graph = getGraph2D();
123 graph.firePreEvent();
124 try {
125 removePortImpl(graph, port);
126 } finally {
127 graph.firePostEvent();
128 }
129
130 graph.updateViews();
131 }
132
133 private void removePortImpl( final Graph2D graph, final NodePort port ) {
134 final NodeRealizer nr = port.getRealizer();
135 final Node node = nr.getNode();
136 graph.backupRealizers((new NodeList(node)).nodes());
137
138 NodePort.remove(port);
139 }
140 });
141 return jpm;
142 }
143
144
153 protected JPopupMenu getPopup(
154 final HitInfo hitInfo,
155 final double x,
156 final double y,
157 final int popupType
158 ) {
159 point = new YPoint(x ,y);
160 return super.getPopup(hitInfo, x, y, popupType);
161 }
162
163
164
165 private NodeLabel addPortLabel(
166 final NodeRealizer nr,
167 final NodePort port,
168 final String text
169 ) {
170 final NodeLabel nl = nr.createNodeLabel();
171 nl.setText(text);
172 nl.setLabelModel(new PortLabelModel(3));
173 nl.setModelParameter(PortLabelModel.createParameter(port, PortLabelModel.NORTH));
174 nr.addLabel(nl);
175 return nl;
176 }
177
178 private void editLabel( final NodeLabel label ) {
179 final YRectangle bnds = label.getBox();
180 view.openLabelEditor(
181 label,
182 bnds.getX(),
183 bnds.getY(),
184 null,
185 true
186 );
187 }
188
189
190
195 private final class ChangeLocationPolicyAction extends AbstractAction {
196 private final byte policy;
197 private final NodePort port;
198
199
205 ChangeLocationPolicyAction( final NodePort port, final byte policy ) {
206 super(createActionName(policy));
207 this.policy = policy;
208 this.port = port;
209
210 final PortLocationModel model = port.getModelParameter().getModel();
211 if (model instanceof NodeScaledPortLocationModel &&
212 ((NodeScaledPortLocationModel) model).getPortLocationPolicy() == policy) {
213 setEnabled(false);
214 }
215 }
216
217 public void actionPerformed( final ActionEvent e ) {
218 final Graph2D graph = getGraph2D();
219 graph.firePreEvent();
220 try {
221 changeLocationPolicyImpl(port, policy);
222 } finally {
223 graph.firePostEvent();
224 }
225
226 graph.updateViews();
227 }
228
229
236 private void changeLocationPolicyImpl(
237 final NodePort port, final byte policy
238 ) {
239 final YPoint location = port.getLocation();
240 final PortLocationModel model = port.getModelParameter().getModel();
241 if (model instanceof NodeScaledPortLocationModel) {
242 ((NodeScaledPortLocationModel) model).setPortLocationPolicy(policy);
243 port.setModelParameter(model.createParameter(port.getRealizer(), location));
244 } else {
245 final NodeScaledPortLocationModel nsplm = new NodeScaledPortLocationModel();
246 nsplm.setPortLocationPolicy(policy);
247 port.setModelParameter(nsplm.createParameter(port.getRealizer(), location));
248 }
249 }
250 }
251
252
258 private static String createActionName( final byte policy ) {
259 switch (policy) {
260 case NodeScaledPortLocationModel.POLICY_DISCRETE:
261 return "Discrete";
262 case NodeScaledPortLocationModel.POLICY_BOUNDARY:
263 return "Boundary";
264 case NodeScaledPortLocationModel.POLICY_BOUNDARY_CENTER:
265 return "Boundary or Center";
266 case NodeScaledPortLocationModel.POLICY_BOUNDARY_INSIDE:
267 return "Inside";
268 case NodeScaledPortLocationModel.POLICY_FREE:
269 return "Free";
270 default:
271 return "Unknown";
272 }
273 }
274
275
279 private final class AddPortAction extends AbstractAction {
280 private final Node node;
281 private final String configuration;
282
283
290 AddPortAction( final String configurationName, final Node node ) {
291 super(createActionName(configurationName));
292 this.configuration = configurationName;
293 this.node = node;
294 putValue(SMALL_ICON, new PortIcon(configurationName));
295 }
296
297 public void actionPerformed( final ActionEvent e ) {
298 final Graph2D graph = getGraph2D();
299 graph.firePreEvent();
300 try {
301 addPortImpl(graph, node, configuration);
302 } finally {
303 graph.firePostEvent();
304 }
305
306 graph.updateViews();
307 }
308
309
316 private void addPortImpl(
317 final Graph2D graph,
318 final Node node,
319 final String portConfigId
320 ) {
321 graph.backupRealizers((new NodeList(node)).nodes());
322
323 final NodeRealizer nr = graph.getRealizer(node);
324 final YPoint location =
325 point == null
326 ? new YPoint(nr.getCenterX(), nr.getCenterY())
327 : point;
328
329 final NodeScaledPortLocationModel model = new NodeScaledPortLocationModel();
330 model.setPortLocationPolicy(NodeScaledPortLocationModel.POLICY_BOUNDARY);
331 final NodePort port = new NodePort();
332 port.setModelParameter(model.createParameter(nr, location));
333 port.setConfiguration(portConfigId);
334 nr.addPort(port);
335
336 addPortLabel(nr, port, "Port " + nr.portCount());
337 }
338 }
339
340
346 private static String createActionName( final String portConfigId ) {
347 String s = portConfigId;
348 if (s != null) {
349 s = s.trim();
350 if (s.length() > 0) {
351 s = s.toUpperCase();
352 if (s.startsWith("PORT_")) {
353 s = s.substring(5);
354 }
355 if (s.length() > 1) {
356 s = s.charAt(0) + s.substring(1).toLowerCase();
357 }
358
359 return s;
360 }
361 }
362 return null;
363 }
364
365
368 private static final class PortIcon implements Icon {
369 private static final int MARGIN = 2;
370
371 private final NodePort port;
372 private final double x;
373 private final double y;
374 private final int w;
375 private final int h;
376
377 PortIcon( final String configuration ) {
378 final NodeRealizer dummy = new ShapeNodeRealizer();
379 dummy.setFrame(0, 0, 10, 10);
380 port = new NodePort();
381 dummy.addPort(port);
382 port.setConfiguration(configuration);
383 final YRectangle bnds = port.getBounds();
384 w = (int) Math.ceil(bnds.getWidth()) + 2*MARGIN;
385 h = (int) Math.ceil(bnds.getHeight()) + 2*MARGIN;
386 x = bnds.getX() - MARGIN;
387 y = bnds.getY() - MARGIN;
388 }
389
390 public int getIconHeight() {
391 return h;
392 }
393
394 public int getIconWidth() {
395 return w;
396 }
397
398 public void paintIcon( final Component c, final Graphics g, final int x, final int y ) {
399 final Graphics2D gfx = (Graphics2D) g.create();
400 gfx.translate(x - this.x, y - this.y);
401 port.paint(gfx);
402 gfx.dispose();
403 }
404 }
405 }
406