* Bug #12264 fixed - ENDBLK block threw nullpointer exception when double-clicking...
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / block / SplitBlock.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2009 - DIGITEO - Bruno JOFRET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 package org.scilab.modules.xcos.block;
13
14 import java.util.logging.Logger;
15
16 import org.scilab.modules.types.ScilabDouble;
17 import org.scilab.modules.types.ScilabList;
18 import org.scilab.modules.xcos.port.BasicPort;
19 import org.scilab.modules.xcos.port.BasicPort.Type;
20 import org.scilab.modules.xcos.port.command.CommandPort;
21 import org.scilab.modules.xcos.port.control.ControlPort;
22 import org.scilab.modules.xcos.port.input.ExplicitInputPort;
23 import org.scilab.modules.xcos.port.input.ImplicitInputPort;
24 import org.scilab.modules.xcos.port.output.ExplicitOutputPort;
25 import org.scilab.modules.xcos.port.output.ImplicitOutputPort;
26
27 import com.mxgraph.model.mxGeometry;
28 import com.mxgraph.model.mxICell;
29
30 /**
31  * A SplitBlock is used on a junction between links.
32  */
33 public final class SplitBlock extends BasicBlock {
34
35     /** The default size */
36     public static final int DEFAULT_SIZE = 7;
37     /** The default color value */
38     public static final int DEFAULT_COLOR = 7;
39
40     private static final long serialVersionUID = 5817243367840540106L;
41
42     /**
43      * Constructor
44      */
45     public SplitBlock() {
46         super();
47     }
48
49     /**
50      * Add connection port depending on the type of the source.
51      *
52      * @param source
53      *            the type of the split
54      */
55     public void addConnection(BasicPort source) {
56         if (source.getType() == Type.EXPLICIT) {
57             addPort(new ExplicitInputPort());
58             addPort(new ExplicitOutputPort());
59             addPort(new ExplicitOutputPort());
60
61             setInterfaceFunctionName("SPLIT_f");
62         } else if (source.getType() == Type.IMPLICIT) {
63             addPort(new ImplicitInputPort());
64             addPort(new ImplicitOutputPort());
65             addPort(new ImplicitOutputPort());
66
67             setInterfaceFunctionName("IMPSPLIT_f");
68         } else {
69             addPort(new ControlPort());
70             addPort(new CommandPort());
71             addPort(new CommandPort());
72
73             setInterfaceFunctionName("CLKSPLIT_f");
74         }
75
76         getChildAt(0).setVisible(false);
77         getChildAt(1).setVisible(false);
78         getChildAt(2).setVisible(false);
79     }
80
81     /**
82      * Initialize the block with the default values
83      */
84     @Override
85     protected void setDefaultValues() {
86         super.setDefaultValues();
87         setInterfaceFunctionName("SPLIT_f");
88         setStyle(getInterfaceFunctionName());
89         setSimulationFunctionName("lsplit");
90         setRealParameters(new ScilabDouble());
91         setIntegerParameters(new ScilabDouble());
92         setObjectsParameters(new ScilabList());
93         setExprs(new ScilabDouble());
94     }
95
96     /**
97      * Add a port on the block.
98      *
99      * @param child
100      *            the port to add
101      * @param index
102      *            index where to put the child
103      */
104     @Override
105     public mxICell insert(mxICell child, int index) {
106         child.setVisible(false);
107         return super.insert(child, index);
108     }
109
110     /**
111      * @return input port
112      */
113     public BasicPort getIn() {
114         sortChildren();
115         return (BasicPort) getChildAt(0);
116     }
117
118     /**
119      * @return first output port
120      */
121     public BasicPort getOut1() {
122         sortChildren();
123         return (BasicPort) getChildAt(1);
124     }
125
126     /**
127      * @return second output port
128      */
129     public BasicPort getOut2() {
130         sortChildren();
131         return (BasicPort) getChildAt(2);
132     }
133
134     /**
135      * Set the geometry of the block
136      *
137      * @param geometry
138      *            change split block geometry
139      */
140     @Override
141     public void setGeometry(mxGeometry geometry) {
142         if (geometry != null) {
143             geometry.setWidth(DEFAULT_SIZE);
144             geometry.setHeight(DEFAULT_SIZE);
145
146             /*
147              * Align the geometry on the grid
148              */
149             if (getParentDiagram() != null && getParentDiagram().isGridEnabled()) {
150                 final double cx = getParentDiagram().snap(geometry.getCenterX());
151                 final double cy = getParentDiagram().snap(geometry.getCenterY());
152
153                 geometry.setX(cx - (DEFAULT_SIZE / 2));
154                 geometry.setY(cy - (DEFAULT_SIZE / 2));
155             }
156         }
157
158         super.setGeometry(geometry);
159     }
160
161     /**
162      * @return true if the split is connectable, false otherwise
163      * @see org.scilab.modules.xcos.block.BasicBlock#isConnectable()
164      */
165     @Override
166     public boolean isConnectable() {
167         if (getChildCount() != 0) {
168             boolean hasNoEdges = true;
169             for (int i = 0; i < getChildCount() && hasNoEdges; i++) {
170                 final mxICell cell = getChildAt(i);
171                 hasNoEdges = cell.getEdgeCount() == 0;
172             }
173
174             return hasNoEdges;
175         } else {
176             return false;
177         }
178     }
179
180     /**
181      * Insert edges as children port edges
182      *
183      * @param edge
184      *            the current edge
185      * @param isOutgoing
186      *            if it is an input port or output one
187      * @return the inserted edges
188      * @see com.mxgraph.model.mxCell#insertEdge(com.mxgraph.model.mxICell,
189      *      boolean)
190      */
191     @Override
192     public mxICell insertEdge(mxICell edge, boolean isOutgoing) {
193         final mxICell ret;
194
195         if (isOutgoing) {
196             if (getOut1().getEdgeCount() == 0) {
197                 ret = getOut1().insertEdge(edge, isOutgoing);
198             } else if (getOut2().getEdgeCount() == 0) {
199                 ret = getOut2().insertEdge(edge, isOutgoing);
200             } else {
201                 ret = null;
202             }
203         } else {
204             if (getIn().getEdgeCount() == 0) {
205                 ret = getIn().insertEdge(edge, isOutgoing);
206             } else {
207                 ret = null;
208             }
209         }
210
211         if (ret == null) {
212             Logger.getLogger(SplitBlock.class.getName()).severe("Unable to connect : " + edge);
213             return super.insertEdge(edge, isOutgoing);
214         } else {
215             return ret;
216         }
217     }
218 }