1
28 package demo.view.advanced.ports;
29
30 import y.base.Node;
31 import y.base.NodeList;
32 import y.geom.YPoint;
33 import y.geom.YRectangle;
34 import y.view.Graph2D;
35 import y.view.HitInfo;
36 import y.view.NodeLabel;
37 import y.view.NodePort;
38 import y.view.NodeRealizer;
39 import y.view.NodeScaledPortLocationModel;
40 import y.view.PopupMode;
41 import y.view.PortLabelModel;
42 import y.view.PortLocationModel;
43 import y.view.ShapeNodeRealizer;
44
45 import java.awt.Component;
46 import java.awt.Graphics;
47 import java.awt.Graphics2D;
48 import java.awt.event.ActionEvent;
49 import javax.swing.AbstractAction;
50 import javax.swing.Icon;
51 import javax.swing.JMenu;
52 import javax.swing.JPopupMenu;
53
54
58 final class NodePortPopupMode extends PopupMode {
59 private YPoint point;
60
61
62
67 public JPopupMenu getNodeLabelPopup( final NodeLabel label ) {
68 final JPopupMenu jpm = new JPopupMenu("NodeLabel");
69 jpm.add(new AbstractAction("Edit Label") {
70 public void actionPerformed( final ActionEvent e ) {
71 editLabel(label);
72 }
73 });
74 jpm.add(new AbstractAction("Delete Label") {
75 public void actionPerformed( final ActionEvent e ) {
76 final NodeRealizer nr = label.getRealizer();
77 nr.removeLabel(label);
78 getGraph2D().updateViews();
79 }
80 });
81 return jpm;
82 }
83
84
89 public JPopupMenu getNodePopup( final Node v ) {
90 final JPopupMenu jpm = new JPopupMenu("Node");
91 jpm.add(new AbstractAction("Add NodePort") {
92 {
93 setEnabled(false);
94 }
95 public void actionPerformed( final ActionEvent e ) {
96 }
97 });
98 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigRectangle, v));
99 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigDynamic, v));
100 jpm.add(new AddPortAction(PortConfigurations.INSTANCE.portConfigEllipse, v));
101 return jpm;
102 }
103
104
112 public JPopupMenu getNodePortPopup( final NodePort port ) {
113 final JPopupMenu jpm = new JPopupMenu("NodePort");
114
115 jpm.add(new AbstractAction("Add Label") {
116 public void actionPerformed( final ActionEvent e ) {
117 editLabel(addPortLabel(port.getRealizer(), port, "Port"));
118 }
119 });
120
121 final JMenu policies = new JMenu("Change Location Policy");
122 policies.add(new ChangeLocationPolicyAction(
123 port, NodeScaledPortLocationModel.POLICY_DISCRETE));
124 policies.add(new ChangeLocationPolicyAction(
125 port, NodeScaledPortLocationModel.POLICY_BOUNDARY));
126 policies.add(new ChangeLocationPolicyAction(
127 port, NodeScaledPortLocationModel.POLICY_BOUNDARY_CENTER));
128 policies.add(new ChangeLocationPolicyAction(
129 port, NodeScaledPortLocationModel.POLICY_BOUNDARY_INSIDE));
130 policies.add(new ChangeLocationPolicyAction(
131 port, NodeScaledPortLocationModel.POLICY_FREE));
132 policies.addSeparator();
133 policies.add(new ChangeSideLocationAction(
134 port, SidePortLocationModel.SIDE_TOP));
135 policies.add(new ChangeSideLocationAction(
136 port, SidePortLocationModel.SIDE_LEFT));
137 policies.add(new ChangeSideLocationAction(
138 port, SidePortLocationModel.SIDE_BOTTOM));
139 policies.add(new ChangeSideLocationAction(
140 port, SidePortLocationModel.SIDE_RIGHT));
141 jpm.add(policies);
142
143 jpm.add(new AbstractAction("Remove Port") {
144 public void actionPerformed( final ActionEvent e ) {
145 final Graph2D graph = getGraph2D();
146 graph.firePreEvent();
147 try {
148 removePortImpl(graph, port);
149 } finally {
150 graph.firePostEvent();
151 }
152
153 graph.updateViews();
154 }
155
156 private void removePortImpl( final Graph2D graph, final NodePort port ) {
157 final NodeRealizer nr = port.getRealizer();
158 final Node node = nr.getNode();
159 graph.backupRealizers((new NodeList(node)).nodes());
160
161 NodePort.remove(port);
162 }
163 });
164 return jpm;
165 }
166
167
176 protected JPopupMenu getPopup(
177 final HitInfo hitInfo,
178 final double x,
179 final double y,
180 final int popupType
181 ) {
182 point = new YPoint(x ,y);
183 return super.getPopup(hitInfo, x, y, popupType);
184 }
185
186
187
188 private NodeLabel addPortLabel(
189 final NodeRealizer nr,
190 final NodePort port,
191 final String text
192 ) {
193 final NodeLabel nl = nr.createNodeLabel();
194 nl.setText(text);
195 nl.setLabelModel(new PortLabelModel(3),
196 PortLabelModel.createParameter(port, PortLabelModel.NORTH));
197 nr.addLabel(nl);
198 return nl;
199 }
200
201 private void editLabel( final NodeLabel label ) {
202 final YRectangle bnds = label.getBox();
203 view.openLabelEditor(
204 label,
205 bnds.getX(),
206 bnds.getY(),
207 null,
208 true
209 );
210 }
211
212
213
218 private final class ChangeLocationPolicyAction extends AbstractAction {
219 private final byte policy;
220 private final NodePort port;
221
222
228 ChangeLocationPolicyAction( final NodePort port, final byte policy ) {
229 super(createActionName(policy));
230 this.policy = policy;
231 this.port = port;
232
233 final PortLocationModel model = port.getModelParameter().getModel();
234 if (model instanceof NodeScaledPortLocationModel &&
235 ((NodeScaledPortLocationModel) model).getPortLocationPolicy() == policy) {
236 setEnabled(false);
237 }
238 }
239
240 public void actionPerformed( final ActionEvent e ) {
241 final Graph2D graph = getGraph2D();
242 graph.firePreEvent();
243 try {
244 changeLocationPolicyImpl(port, policy);
245 } finally {
246 graph.firePostEvent();
247 }
248
249 graph.updateViews();
250 }
251
252
259 private void changeLocationPolicyImpl(
260 final NodePort port, final byte policy
261 ) {
262 final YPoint location = port.getLocation();
263 final PortLocationModel model = port.getModelParameter().getModel();
264 if (model instanceof NodeScaledPortLocationModel) {
265 ((NodeScaledPortLocationModel) model).setPortLocationPolicy(policy);
266 port.setModelParameter(model.createParameter(port.getRealizer(), location));
267 } else {
268 final NodeScaledPortLocationModel nsplm = new NodeScaledPortLocationModel();
269 nsplm.setPortLocationPolicy(policy);
270 port.setModelParameter(nsplm.createParameter(port.getRealizer(), location));
271 }
272 }
273 }
274
275
281 private static String createActionName( final byte policy ) {
282 switch (policy) {
283 case NodeScaledPortLocationModel.POLICY_DISCRETE:
284 return "Discrete";
285 case NodeScaledPortLocationModel.POLICY_BOUNDARY:
286 return "Boundary";
287 case NodeScaledPortLocationModel.POLICY_BOUNDARY_CENTER:
288 return "Boundary or Center";
289 case NodeScaledPortLocationModel.POLICY_BOUNDARY_INSIDE:
290 return "Inside";
291 case NodeScaledPortLocationModel.POLICY_FREE:
292 return "Free";
293 default:
294 return "Unknown";
295 }
296 }
297
298
303 private final class ChangeSideLocationAction extends AbstractAction {
304 private final int side;
305 private final NodePort port;
306
307
313 ChangeSideLocationAction( final NodePort port, final int side ) {
314 super(createActionName(side));
315 this.side = side;
316 this.port = port;
317
318 final PortLocationModel model = port.getModelParameter().getModel();
319 if (model instanceof SidePortLocationModel &&
320 ((SidePortLocationModel) model).getSides() == side) {
321 setEnabled(false);
322 }
323 }
324
325 public void actionPerformed( final ActionEvent e ) {
326 final Graph2D graph = getGraph2D();
327 graph.firePreEvent();
328 try {
329 changeSideLocationImpl(port, side);
330 } finally {
331 graph.firePostEvent();
332 }
333
334 graph.updateViews();
335 }
336
337
344 private void changeSideLocationImpl( final NodePort port, final int side ) {
345 final YPoint location = port.getLocation();
346 final SidePortLocationModel splm = SidePortLocationModel.newInstance(side);
347 port.setModelParameter(splm.createParameter(port.getRealizer(), location));
348 }
349 }
350
351
358 private static String createActionName( final int side ) {
359 switch (side) {
360 case SidePortLocationModel.SIDE_TOP:
361 return "Top only";
362 case SidePortLocationModel.SIDE_LEFT:
363 return "Left only";
364 case SidePortLocationModel.SIDE_BOTTOM:
365 return "Bottom only";
366 case SidePortLocationModel.SIDE_RIGHT:
367 return "Right only";
368 default:
369 return "Unknown";
370 }
371 }
372
373
377 private final class AddPortAction extends AbstractAction {
378 private final Node node;
379 private final String configuration;
380
381
388 AddPortAction( final String configurationName, final Node node ) {
389 super(createActionName(configurationName));
390 this.configuration = configurationName;
391 this.node = node;
392 putValue(SMALL_ICON, new PortIcon(configurationName));
393 }
394
395 public void actionPerformed( final ActionEvent e ) {
396 final Graph2D graph = getGraph2D();
397 graph.firePreEvent();
398 try {
399 addPortImpl(graph, node, configuration);
400 } finally {
401 graph.firePostEvent();
402 }
403
404 graph.updateViews();
405 }
406
407
414 private void addPortImpl(
415 final Graph2D graph,
416 final Node node,
417 final String portConfigId
418 ) {
419 graph.backupRealizers((new NodeList(node)).nodes());
420
421 final NodeRealizer nr = graph.getRealizer(node);
422 final YPoint location =
423 point == null
424 ? new YPoint(nr.getCenterX(), nr.getCenterY())
425 : point;
426
427 final NodeScaledPortLocationModel model = new NodeScaledPortLocationModel();
428 model.setPortLocationPolicy(NodeScaledPortLocationModel.POLICY_BOUNDARY);
429 final NodePort port = new NodePort();
430 port.setModelParameter(model.createParameter(nr, location));
431 port.setConfiguration(portConfigId);
432 nr.addPort(port);
433
434 addPortLabel(nr, port, "Port " + nr.portCount());
435 }
436 }
437
438
444 private static String createActionName( final String portConfigId ) {
445 String s = portConfigId;
446 if (s != null) {
447 s = s.trim();
448 if (s.length() > 0) {
449 s = s.toUpperCase();
450 if (s.startsWith("PORT_")) {
451 s = s.substring(5);
452 }
453 if (s.length() > 1) {
454 s = s.charAt(0) + s.substring(1).toLowerCase();
455 }
456
457 return s;
458 }
459 }
460 return null;
461 }
462
463
466 private static final class PortIcon implements Icon {
467 private static final int MARGIN = 2;
468
469 private final NodePort port;
470 private final double x;
471 private final double y;
472 private final int w;
473 private final int h;
474
475 PortIcon( final String configuration ) {
476 final NodeRealizer dummy = new ShapeNodeRealizer();
477 dummy.setFrame(0, 0, 10, 10);
478 port = new NodePort();
479 dummy.addPort(port);
480 port.setConfiguration(configuration);
481 final YRectangle bnds = port.getBounds();
482 w = (int) Math.ceil(bnds.getWidth()) + 2*MARGIN;
483 h = (int) Math.ceil(bnds.getHeight()) + 2*MARGIN;
484 x = bnds.getX() - MARGIN;
485 y = bnds.getY() - MARGIN;
486 }
487
488 public int getIconHeight() {
489 return h;
490 }
491
492 public int getIconWidth() {
493 return w;
494 }
495
496 public void paintIcon( final Component c, final Graphics g, final int x, final int y ) {
497 final Graphics2D gfx = (Graphics2D) g.create();
498 gfx.translate(x - this.x, y - this.y);
499 port.paint(gfx);
500 gfx.dispose();
501 }
502 }
503 }
504