1   /****************************************************************************
2    * This demo file is part of yFiles for Java 2.14.
3    * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4    * 72070 Tuebingen, Germany. All rights reserved.
5    * 
6    * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7    * of demo files in source code or binary form, with or without
8    * modification, is not permitted.
9    * 
10   * Owners of a valid software license for a yFiles for Java version that this
11   * demo is shipped with are allowed to use the demo source code as basis
12   * for their own yFiles for Java powered applications. Use of such programs is
13   * governed by the rights and conditions as set out in the yFiles for Java
14   * license agreement.
15   * 
16   * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19   * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27   ***************************************************************************/
28  package demo.view.advanced.ports;
29  
30  import y.geom.YPoint;
31  import y.geom.YRectangle;
32  import y.view.GenericNodeRealizer;
33  import y.view.NodePort;
34  import y.view.NodeRealizer;
35  import y.view.PortConfigurationAdapter;
36  import y.view.SelectionPortPainter;
37  import y.view.ShapeNodePainter;
38  import y.view.ShapePortConfiguration;
39  import y.view.ShinyPlateNodePainter;
40  
41  import java.awt.Color;
42  import java.util.HashMap;
43  
44  /**
45   * Registers the different {@link y.view.NodePort} configurations that are
46   * showcased in the demo application.
47   *
48   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/realizer_related" target="_blank">Section Realizer-Related Features</a> in the yFiles for Java Developer's Guide
49   */
50  class PortConfigurations {
51    private static final Color PORT_COLOR = new Color(255, 153, 0);
52  
53    private static final String PORT_CONFIG_RECTANGLE = "PORT_RECTANGLE";
54    private static final String PORT_CONFIG_DYNAMIC = "PORT_DYNAMIC";
55    private static final String PORT_CONFIG_ELLIPSE = "PORT_ELLIPSE";
56  
57    static {
58      registerConfigurations();
59    }
60  
61    public static final PortConfigurations INSTANCE = new PortConfigurations();
62  
63  
64    /**
65     * Registers the different {@link y.view.NodePort} configurations that can be
66     * used when adding a new port.
67     */
68    private static void registerConfigurations() {
69      {
70        final ShinyPlateNodePainter impl = new ShinyPlateNodePainter();
71        final HashMap nodeImpls = new HashMap();
72        nodeImpls.put(GenericNodeRealizer.ContainsTest.class, impl);
73        nodeImpls.put(GenericNodeRealizer.Painter.class, impl);
74  
75        final PortConfigurationAdapter adapter =
76                new PortConfigurationAdapter(nodeImpls);
77        adapter.setFillColor(PORT_COLOR);
78        adapter.setFillColor2(null);
79        adapter.setLineColor(null);
80  
81        final HashMap portImpls = new HashMap();
82        portImpls.put(NodePort.ContainsTest.class, adapter);
83        portImpls.put(NodePort.Painter.class, new SelectionPortPainter(adapter));
84        final ShapePortConfiguration boundsProvider = new ShapePortConfiguration();
85        boundsProvider.setSize(20, 10);
86        portImpls.put(NodePort.BoundsProvider.class, boundsProvider);
87        NodePort.getFactory().addConfiguration(PORT_CONFIG_RECTANGLE, portImpls);
88      }
89  
90  
91      {
92        final HashMap nodeImpls = new HashMap();
93        nodeImpls.put(
94                GenericNodeRealizer.Painter.class,
95                new ShapeNodePainter(ShapeNodePainter.RECT));
96  
97        final PortConfigurationAdapter adapter =
98                new PortConfigurationAdapter(nodeImpls);
99        adapter.setFillColor(PORT_COLOR);
100       adapter.setFillColor2(null);
101       adapter.setLineColor(Color.DARK_GRAY);
102 
103       final DynamicBounds impl = new DynamicBounds();
104       final HashMap portImpls = new HashMap();
105       portImpls.put(NodePort.ContainsTest.class, impl);
106       portImpls.put(NodePort.Painter.class, new SelectionPortPainter(adapter));
107       portImpls.put(NodePort.BoundsProvider.class, impl);
108       NodePort.getFactory().addConfiguration(PORT_CONFIG_DYNAMIC, portImpls);
109     }
110 
111 
112     {
113       final ShapeNodePainter impl = new ShapeNodePainter(ShapeNodePainter.ELLIPSE);
114       final HashMap nodeImpls = new HashMap();
115       nodeImpls.put(GenericNodeRealizer.ContainsTest.class, impl);
116       nodeImpls.put(GenericNodeRealizer.Painter.class, impl);
117 
118       final PortConfigurationAdapter adapter =
119               new PortConfigurationAdapter(nodeImpls);
120       adapter.setFillColor(PORT_COLOR);
121       adapter.setFillColor2(null);
122       adapter.setLineColor(Color.DARK_GRAY);
123 
124       final HashMap portImpls = new HashMap();
125       portImpls.put(NodePort.ContainsTest.class, adapter);
126       portImpls.put(NodePort.Painter.class, new SelectionPortPainter(adapter));
127       final ShapePortConfiguration boundsProvider = new ShapePortConfiguration();
128       boundsProvider.setSize(10, 10);
129       portImpls.put(NodePort.BoundsProvider.class, boundsProvider);
130       NodePort.getFactory().addConfiguration(PORT_CONFIG_ELLIPSE, portImpls);
131     }
132   }
133 
134 
135 
136   final String portConfigRectangle;
137   final String portConfigDynamic;
138   final String portConfigEllipse;
139 
140   private PortConfigurations() {
141     portConfigRectangle = PORT_CONFIG_RECTANGLE;
142     portConfigDynamic = PORT_CONFIG_DYNAMIC;
143     portConfigEllipse = PORT_CONFIG_ELLIPSE;
144   }
145 
146 
147   /**
148    * <code>BoundsProvider</code> implementation that determines node port
149    * bounds dynamically according to the location of the node port in relation
150    * to its owner node.
151    */
152   private static final class DynamicBounds
153           implements NodePort.BoundsProvider, NodePort.ContainsTest {
154     private static final double EPS = 1e-8;
155     private static final double SIZE = 10;
156 
157     public YRectangle getBounds( final NodePort port ) {
158       final YPoint p = port.getLocation();
159       final NodeRealizer owner = port.getRealizer();
160 
161       final double x = owner.getX();
162       final double y = owner.getY();
163       final double w = owner.getWidth();
164       final double h = owner.getHeight();
165 
166       final double px = p.getX();
167       final double py = p.getY();
168 
169       if (Math.abs(px - x) < EPS) {
170         if (y <= py && py <= y + h) {
171           // left
172           return new YRectangle(px - SIZE, py - SIZE*0.5, SIZE, SIZE);
173         }
174       } else if (Math.abs(px - x - w) < EPS) {
175         if (y <= py && py <= y + h) {
176           // right
177           return new YRectangle(px, py - SIZE*0.5, SIZE, SIZE);
178         }
179       } else if (Math.abs(py - y) < EPS) {
180         if (x <= px && px <= x + w) {
181           // top
182           return new YRectangle(px - SIZE*0.5, py - SIZE, SIZE, SIZE);
183         }
184       } else if (Math.abs(py - y - h) < EPS) {
185         if (x <= px && px <= x + w) {
186           // bottom
187           return new YRectangle(px - SIZE*0.5, py, SIZE, SIZE);
188         }
189       }
190 
191       return new YRectangle(px - SIZE*0.5, py - SIZE*0.5, SIZE, SIZE);
192     }
193 
194     public boolean contains( final NodePort port, final double x, final double y ) {
195       final YRectangle bnds = port.getBounds();
196       return bnds.getX() <= x && x <= bnds.getX() + bnds.getWidth() &&
197              bnds.getY() <= y && y <= bnds.getY() + bnds.getHeight();
198     }
199   }
200 }
201