4f8e48fca9306cbf6064761e35716e0925bcea3e
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / datatip / DatatipOrientation.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Gustavo Barbosa Libotte
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.1-en.txt
10  *
11  */
12
13 package org.scilab.modules.gui.datatip;
14
15 import org.scilab.modules.gui.datatip.DatatipCommon;
16 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
17 import static org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties.*;
18 import org.scilab.modules.gui.editor.AxesHandler;
19 import org.scilab.modules.gui.editor.EntityPicker;
20 import org.scilab.modules.renderer.CallRenderer;
21
22 import org.scilab.modules.action_binding.InterpreterManagement;
23
24 /**
25  * Orientate the datatip for "upper left", "upper right", "lower left" or "lower right" according to the quadrant position.
26  * @author Gustavo Barbosa Libotte
27  */
28 public class DatatipOrientation {
29
30     /**
31      * Setup the datatip orientation according with the curve segment inclination
32      *
33      * @param datatip the datatip uid
34      */
35     public static void setOrientation(Integer datatip) {
36         Integer polyline = DatatipCommon.getParentPolyline(datatip);
37         if (polyline != null) {
38             Integer[] indexes = (Integer[])GraphicController.getController().getProperty(datatip, __GO_DATATIP_INDEXES__);
39             DatatipCommon.Segment seg = EntityPicker.getSegment(polyline, indexes[0]);
40             if (seg != null) {
41                 setOrientation(datatip, seg);
42             }
43         }
44     }
45
46     /**
47      * Setup the datatip orientation according with the mouse movement.
48      *
49      * @param datatip the datatip uid
50      */
51     public static void setOrientation(Integer datatip, Integer lastClick[], Integer[] curClick) {
52         int dx = curClick[0] - lastClick[0];
53         int dy = curClick[1] - lastClick[1];
54         Integer finalOrientation = 0;
55
56         if (dx > 0) {
57             if (dy < 0) {
58                 finalOrientation = 1;
59             } else {
60                 finalOrientation = 3;
61             }
62         } else {
63             if (dy < 0) {
64                 finalOrientation = 0;
65             } else {
66                 finalOrientation = 2;
67             }
68         }
69         GraphicController.getController().setProperty(datatip, __GO_DATATIP_ORIENTATION__, finalOrientation);
70     }
71
72     /**
73      * Setup the datatip orientation according with the curve segment inclination
74      *
75      * @param datatip the datatip uid
76      * @param seg the line segment
77      */
78     public static void setOrientation(Integer datatip, DatatipCommon.Segment seg) {
79         Double[] bounds;
80         Integer finalOrientation;
81
82         double dx = seg.x1 - seg.x0;
83         double dy = seg.y1 - seg.y0;
84
85         /* dx < 0 ? flip dy*/
86         if (dx < 0) {
87             dy = -dy;
88         }
89
90         Integer axesUid = (Integer)GraphicController.getController().getProperty(datatip, __GO_PARENT_AXES__);
91         if (AxesHandler.isZoomBoxEnabled(axesUid)) {
92             bounds = (Double[])GraphicController.getController().getProperty(axesUid, __GO_ZOOM_BOX__);
93         } else {
94             bounds = (Double[])GraphicController.getController().getProperty(axesUid, __GO_DATA_BOUNDS__);
95         }
96
97         /* dy > 0 ? crescent (use top left) : decrescent (use top right) */
98         finalOrientation = dy > 0 ? 0 : 1;
99         Double[] tip_pos = (Double[])GraphicController.getController().getProperty(datatip, __GO_DATATIP_DATA__);
100         /* tip_pos.y  is below the middle of the axes? use bottom instead of top orientation*/
101         Double middle = bounds[2] + ((bounds[3] - bounds[2]) / 2.0);
102         if (tip_pos[1] < middle) {
103             finalOrientation = flipOrientation(finalOrientation);
104         }
105
106         GraphicController.getController().setProperty(datatip, __GO_DATATIP_ORIENTATION__, finalOrientation);
107
108         /* check if the tip is visible*/
109         CallRenderer.updateTextBounds(datatip);
110         Double[] corners = (Double[])GraphicController.getController().getProperty(datatip, __GO_CORNERS__);
111
112         /*if the tip is out of the  axes bounds try flip it*/
113         if (!isInBounds(corners[0], corners[1], bounds) || !isInBounds(corners[6], corners[7], bounds)) {
114             GraphicController.getController().setProperty(datatip, __GO_DATATIP_ORIENTATION__, flipOrientation(finalOrientation));
115         }
116     }
117
118     /**
119      * Check if the given position (x, y) is in bounds
120      *
121      * @param x position in X axis
122      * @param y position in Y axis
123      * @param bounds vector with the bounds
124      */
125     private static boolean isInBounds(Double x, Double y, Double[] bounds) {
126         if (x >= bounds[0] && x <= bounds[1]) {
127             if (y >= bounds[2] && y <= bounds[3]) {
128                 return true;
129             }
130         }
131         return false;
132     }
133
134     /**
135      * Flip the given orientation
136      * @param orientation the iven orientation
137      * @return the flipped orientation
138      */
139     private static Integer flipOrientation(Integer orientation) {
140         switch (orientation) {
141                 /* top left*/
142             case 0:
143                 return 3;
144                 /* top right*/
145             case 1:
146                 return 2;
147                 /* bottom left*/
148             case 2:
149                 return 1;
150                 /* bottom right*/
151             case 3:
152                 return 0;
153                 /* do nothing*/
154             default:
155                 return orientation;
156         }
157     }
158
159     /**
160      * Setup the datatip orientation by program.
161      *
162      * @param datatipUid the datatip uid.
163      * @param datatipOrientation String with datatip orientation.
164      * @param datatipOrientationNum Integer with datatip orientation to set property.
165      */
166     public static void datatipSetOrientation(int datatipUid, String datatipOrientation, int datatipOrientationNum) {
167         switch (datatipOrientationNum) {
168             case 0: // upper left
169                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_AUTOORIENTATION__, false);
170                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_ORIENTATION__, 0);
171                 break;
172             case 1: // upper right
173                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_AUTOORIENTATION__, false);
174                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_ORIENTATION__, 1);
175                 break;
176             case 2: // lower left
177                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_AUTOORIENTATION__, false);
178                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_ORIENTATION__, 2);
179                 break;
180             case 3: // lower right
181                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_AUTOORIENTATION__, false);
182                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_ORIENTATION__, 3);
183                 break;
184             case 4: // automatic
185                 GraphicController.getController().setProperty(datatipUid, __GO_DATATIP_AUTOORIENTATION__, true);
186                 break;
187             default:
188                 String errorMsg = "error(msprintf(_( \"%s: Unknown input argument #%d: ''%s'' is not valid.\n\"),\"datatipSetOrientation\",2,\"" + datatipOrientation + "\"));";
189                 InterpreterManagement.requestScilabExec(errorMsg);
190         }
191     }
192 }