Xcos: be compatible with Scilab 5.5.2 zcos files
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / port / Orientation.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Clement DAVID
4  * Copyright (C) 2011-2015 - Scilab Enterprises - Clement DAVID
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.xcos.port;
18
19 import com.mxgraph.util.mxConstants;
20 import org.scilab.modules.xcos.port.command.CommandPort;
21 import org.scilab.modules.xcos.port.output.OutputPort;
22
23 /**
24  * Represent a port orientation related to the associated block. These
25  * orientation semantics are valid when there is no rotation/mirror/flip applied
26  * to the block.
27  */
28 public enum Orientation {
29     /** The port is on the left (west) side of the block */
30     WEST,
31     /** The port is on the top (north) side of the block */
32     NORTH,
33     /** The port is on the right (east) side of the block */
34     EAST,
35     /** The port is on the bottom (south) side of the block */
36     SOUTH;
37
38     private static final int MAX_ROTATION = 360;
39     private static final int PERPENDICULAR_ROTATION = 90;
40
41     /**
42      * Get the orientation angle linked to its parent block.
43      *
44      * @param blockAngle
45      *            The value of the block angle
46      * @param klass
47      *            The kind of port
48      * @param flipped
49      *            The block flip state
50      * @param mirrored
51      *            The block mirror state
52      * @return The value of the angle.
53      */
54     public int getRelativeAngle(int blockAngle, Class <? extends BasicPort > klass, boolean flipped, boolean mirrored) {
55         final int orientation = getOrientationAngle();
56         final int base = getBaseAngle(klass, orientation);
57
58         return getFlippedAndMirroredAngle(base + blockAngle, flipped, mirrored);
59     }
60
61     /**
62      * @param klass
63      *            the kind of port
64      * @param flipped
65      *            the flip status
66      * @param mirrored
67      *            the mirror status
68      * @return the real angle
69      */
70     public int getAbsoluteAngle(Class <? extends BasicPort > klass,
71     boolean flipped, boolean mirrored) {
72         final int orientation = getOrientationAngle();
73         final int base = getBaseAngle(klass, orientation);
74
75         return getFlippedAndMirroredAngle(base, flipped, mirrored);
76     }
77
78     /**
79      * Update the base angle according to the flipped and mirrored flag.
80      *
81      * @param base
82      *            the previous angle
83      * @param flipped
84      *            the flip status
85      * @param mirrored
86      *            the mirror status
87      * @return the updated angle.
88      */
89     private int getFlippedAndMirroredAngle(int base, boolean flipped, boolean mirrored) {
90         int angle = base;
91
92         switch (this) {
93             case NORTH:
94             case SOUTH:
95                 if (flipped) {
96                     angle = angle + (MAX_ROTATION / 2);
97                 }
98                 break;
99
100             case WEST:
101             case EAST:
102                 if (mirrored) {
103                     angle = angle + (MAX_ROTATION / 2);
104                 }
105                 break;
106
107             default:
108                 break;
109         }
110
111         /* Calculate angle */
112         return angle % MAX_ROTATION;
113     }
114
115     /**
116      * @return the angle associated with this orientation.
117      */
118     private int getOrientationAngle() {
119         return ordinal() * PERPENDICULAR_ROTATION;
120     }
121
122     /**
123      * As the orientation angle is calculated as an input (default jgraphx
124      * triangle direction), we have to update it for output blocks.
125      *
126      * @param klass
127      *            kind of block
128      * @param orientationAngle
129      *            calculated orientation angle
130      * @return updated angle
131      */
132     private int getBaseAngle(Class <? extends BasicPort > klass, int orientationAngle) {
133         final boolean isOutput = OutputPort.class.isAssignableFrom(klass)
134                                  || CommandPort.class.isAssignableFrom(klass);
135
136         if (isOutput) {
137             return orientationAngle + (MAX_ROTATION / 2);
138         }
139
140         return orientationAngle;
141     }
142
143     /**
144      * @return The label position of the current port.
145      * @see com.mxgraph.util.mxConstants#STYLE_LABEL_POSITION
146      */
147     public String getLabelPosition() {
148         final String ret;
149
150         switch (this) {
151             case EAST:
152                 ret = mxConstants.ALIGN_RIGHT;
153                 break;
154             case WEST:
155                 ret = mxConstants.ALIGN_LEFT;
156                 break;
157             default:
158                 ret = mxConstants.ALIGN_CENTER;
159                 break;
160         }
161
162         return ret;
163     }
164
165     /**
166      * @return The vertical label position of the current port.
167      * @see com.mxgraph.util.mxConstants#STYLE_VERTICAL_LABEL_POSITION
168      */
169     public String getVerticalLabelPosition() {
170         final String ret;
171
172         switch (this) {
173             case NORTH:
174                 ret = mxConstants.ALIGN_TOP;
175                 break;
176             case SOUTH:
177                 ret = mxConstants.ALIGN_BOTTOM;
178                 break;
179             default:
180                 ret = mxConstants.ALIGN_MIDDLE;
181                 break;
182         }
183
184         return ret;
185     }
186
187     /**
188      * @return the spacing side to increment
189      * @see com.mxgraph.util.mxConstants#STYLE_SPACING_BOTTOM
190      * @see com.mxgraph.util.mxConstants#STYLE_SPACING_LEFT
191      * @see com.mxgraph.util.mxConstants#STYLE_SPACING_RIGHT
192      * @see com.mxgraph.util.mxConstants#STYLE_SPACING_TOP
193      */
194     public String getSpacingSide() {
195         final String ret;
196
197         switch (this) {
198             case NORTH:
199                 ret = mxConstants.STYLE_SPACING_TOP;
200                 break;
201             case SOUTH:
202                 ret = mxConstants.STYLE_SPACING_BOTTOM;
203                 break;
204             case EAST:
205                 ret = mxConstants.STYLE_SPACING_RIGHT;
206                 break;
207             case WEST:
208             default:
209                 ret = mxConstants.STYLE_SPACING_LEFT;
210                 break;
211         }
212
213         return ret;
214     }
215 }