* Bug #13690 fixed - tight_limits property can now manage X, Y and Z axis separately.
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / editor / AxesHandler.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Pedro Arthur dos S. Souza
4  * Copyright (C) 2012 - Caio Lucas dos S. Souza
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.gui.editor;
15
16 import java.lang.Math;
17
18 import org.scilab.modules.graphic_objects.graphicController.GraphicController;
19 import org.scilab.modules.graphic_objects.graphicModel.GraphicModel;
20 import org.scilab.modules.graphic_objects.graphicObject.GraphicObjectProperties;
21 import org.scilab.modules.graphic_objects.axes.Axes;
22 import org.scilab.modules.graphic_objects.axes.AxesContainer;
23 import org.scilab.modules.graphic_objects.ScilabNativeView;
24
25 import org.scilab.modules.gui.editor.ObjectSearcher;
26 import org.scilab.modules.gui.editor.PolylineHandler;
27
28 /**
29 * Implements all axes manipulation functions for the editor.
30 *
31 * @author Caio Souza <caioc2bolado@gmail.com>
32 * @author Pedro Souza <bygrandao@gmail.com>
33 *
34 * @since 2012-06-01
35 */
36 public class AxesHandler {
37
38     public enum axisTo { __X__, __Y__, __Z__, __TITLE__ };
39
40     private static Integer lastAxes;
41
42     private static Integer[] searchAxes(Integer uid) {
43         return (new ObjectSearcher()).search(uid, GraphicObjectProperties.__GO_AXES__);
44     }
45
46     public static Axes getAxesFromUid(Integer uid) {
47         return (Axes)GraphicController.getController().getObjectFromId(uid);
48     }
49
50     /**
51     * Given a mouse coordinate point (x, y) in pixels
52     * retrieves the axes wich the point belongs.
53     *
54     * @param figure Figure unique identifier.
55     * @param position Vector with mouse position x and y.
56     * @return Retrieved axes or null if there isn't an axes.
57     */
58     public static Integer clickedAxes(Integer figure, Integer[] position) {
59         Integer[] axes = searchAxes(figure);
60         if (axes == null) {
61             return lastAxes;
62         }
63
64         AxesContainer container = (AxesContainer) GraphicController.getController().getObjectFromId(figure);
65         Integer[] figureSize = container.getAxesSize();
66
67         for (Integer i = 0; i < axes.length; i++) {
68             Double[] axesBound = (Double[])GraphicController.getController().getProperty(axes[i], GraphicObjectProperties.__GO_AXES_BOUNDS__);
69             Double xi, xf, yi, yf;
70
71             xi = (figureSize[0] * axesBound[0]);
72             xf = (figureSize[0] * (axesBound[0] + axesBound[2]));
73             yi = (figureSize[1] * axesBound[1]);
74             yf = (figureSize[1] * (axesBound[1] + axesBound[3]));
75
76             if (position[0] > xi && position[0] < xf && position[1] > yi && position[1] < yf) {
77                 lastAxes = axes[i];
78                 return axes[i];
79             }
80         }
81         return lastAxes;
82     }
83
84
85
86     /**
87      * Change the status from the axes to visible and the axis too
88      *
89      * @param axes Axes to set visible
90      */
91     public static void setAxesVisible(Integer axes) {
92
93         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_X_AXIS_VISIBLE__, true);
94         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_Y_AXIS_VISIBLE__, true);
95         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_Z_AXIS_VISIBLE__, true);
96         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_VISIBLE__, true);
97         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_CLIP_STATE__, 1);
98         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_X_TIGHT_LIMITS__, true);
99         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_Y_TIGHT_LIMITS__, true);
100         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_Z_TIGHT_LIMITS__, true);
101         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_BOX_TYPE__, 1);
102         GraphicController.getController().setProperty(axes, GraphicObjectProperties.__GO_FILLED__, true);
103     }
104
105     /**
106      * Clone an axes and delete all their children's, change the labels from axes to empty
107      *
108      * @param axes The axes to duplicate
109      * @return Return a duplicated axes without childrens
110      */
111     public static Integer duplicateAxes(Integer axes) {
112
113         Integer newAxes = GraphicController.getController().cloneObject(axes);
114         setAxesVisible(newAxes);
115         PolylineHandler.getInstance().deleteAll(newAxes);
116         return newAxes;
117     }
118
119     /**
120      * Set the AxesTo bounds with the max bounds between axesFrom
121      * and axesTo(used when paste new objects to make all object visible)
122      *
123      * @param axesFrom Axes from you want to merge the bounds
124      * @param axesTo Axes that will be set the max bounds between the two axes
125      */
126     public static void axesBound(Integer axesFrom, Integer axesTo) {
127
128         if (axesFrom == axesTo) {
129             return;
130         }
131
132         Double[] axesFB = (Double[])GraphicController.getController().getProperty(axesFrom, GraphicObjectProperties.__GO_DATA_BOUNDS__);
133         Double[] axesTB = (Double[])GraphicController.getController().getProperty(axesTo, GraphicObjectProperties.__GO_REAL_DATA_BOUNDS__);
134         Double[] newBounds = {0., 0., 0., 0., 0., 0.};
135
136         newBounds[0] = Math.min(axesFB[0], axesTB[0]);
137         newBounds[1] = Math.max(axesFB[1], axesTB[1]);
138         newBounds[2] = Math.min(axesFB[2], axesTB[2]);
139         newBounds[3] = Math.max(axesFB[3], axesTB[3]);
140         newBounds[4] = Math.min(axesFB[4], axesTB[4]);
141         newBounds[5] = Math.max(axesFB[5], axesTB[5]);
142
143         GraphicController.getController().setProperty(axesTo, GraphicObjectProperties.__GO_DATA_BOUNDS__, newBounds);
144
145         Boolean x_tight_lim = (Boolean)GraphicController.getController().getProperty(axesFrom, GraphicObjectProperties.__GO_X_TIGHT_LIMITS__);
146         GraphicController.getController().setProperty(axesTo, GraphicObjectProperties.__GO_X_TIGHT_LIMITS__, x_tight_lim);
147         Boolean y_tight_lim = (Boolean)GraphicController.getController().getProperty(axesFrom, GraphicObjectProperties.__GO_Y_TIGHT_LIMITS__);
148         GraphicController.getController().setProperty(axesTo, GraphicObjectProperties.__GO_Y_TIGHT_LIMITS__, y_tight_lim);
149         Boolean z_tight_lim = (Boolean)GraphicController.getController().getProperty(axesFrom, GraphicObjectProperties.__GO_Z_TIGHT_LIMITS__);
150         GraphicController.getController().setProperty(axesTo, GraphicObjectProperties.__GO_Z_TIGHT_LIMITS__, z_tight_lim);
151     }
152
153     /**
154      * Checks if zoombox is enebled in the given axes.
155      *
156      * @param uid axes unique identifier.
157      * @return True if enabled, false otherwise.
158      */
159     public static Boolean isZoomBoxEnabled(Integer uid) {
160         return (Boolean)GraphicController.getController().getProperty(uid, GraphicObjectProperties.__GO_ZOOM_ENABLED__);
161     }
162
163     /**
164      * Checks if the given point (x,y) is in zoombox bounds.
165      *
166      * @param uid Axes unique identifier.
167      * @param x position on x axis.
168      * @param y position on y axis.
169      * @return True if the point is within the bounds, false otherwise.
170      */
171     public static Boolean isInZoomBoxBounds(Integer uid, double x, double y) {
172         Double[] bounds = (Double[])GraphicController.getController().getProperty(uid, GraphicObjectProperties.__GO_ZOOM_BOX__);
173         if (x >= bounds[0] && x <= bounds[1]) {
174             if (y >= bounds[2] && y <= bounds[3]) {
175                 return true;
176             }
177         }
178         return false;
179     }
180
181     /**
182      * Checks if the given figure have any object visible.
183      *
184      * @param figure Figure unique identifier.
185      * @return True if there is any object visible, false otherwise.
186      */
187     public static boolean isAxesNotBlank(Integer figure) {
188
189         Integer[] axes = searchAxes(figure);
190         if (axes == null) {
191             return false;
192         }
193         boolean flag = false;
194         for ( Integer j = 0; j < axes.length; j++) {
195
196             Integer childCount = (Integer)GraphicController.getController().getProperty(axes[j], GraphicObjectProperties.__GO_CHILDREN_COUNT__);
197             Integer[] child = (Integer[])GraphicController.getController().getProperty(axes[j], GraphicObjectProperties.__GO_CHILDREN__);
198             for (Integer i = 0; i < childCount; i++) {
199                 flag = isBlank(child[i]);
200                 if (flag) {
201                     return flag;
202                 }
203             }
204         }
205         return false;
206     }
207
208     public static boolean isAxesEmpty(Integer axes) {
209
210         Integer childCount = (Integer)GraphicController.getController().getProperty(axes, GraphicObjectProperties.__GO_CHILDREN_COUNT__);
211         Integer[] child = (Integer[])GraphicController.getController().getProperty(axes, GraphicObjectProperties.__GO_CHILDREN__);
212         for (Integer i = 0; i < childCount; i++) {
213             Integer type = (Integer)GraphicController.getController().getProperty(child[i], GraphicObjectProperties.__GO_TYPE__);
214             if (type != GraphicObjectProperties.__GO_LABEL__) {
215                 return false;
216             }
217         }
218         return true;
219     }
220
221     /**
222      * Checks if the given object is visible or if it has child check its children.
223      *
224      * @param objectID Object unique identifier.
225      * @return True if there is any object visible, false otherwise.
226      */
227     private static boolean isBlank(Integer objectID) {
228
229         Integer type = (Integer)GraphicController.getController().getProperty(objectID, GraphicObjectProperties.__GO_TYPE__);
230         boolean flag = (Boolean) GraphicController.getController().getProperty(objectID, GraphicObjectProperties.__GO_VISIBLE__);
231         if (flag) {
232             if (type != GraphicObjectProperties.__GO_LABEL__ && type != GraphicObjectProperties.__GO_COMPOUND__) {
233                 return flag;
234             } else if (type == GraphicObjectProperties.__GO_COMPOUND__) {
235                 Integer childCount = (Integer)GraphicController.getController().getProperty(objectID, GraphicObjectProperties.__GO_CHILDREN_COUNT__);
236                 Integer[] child = (Integer[])GraphicController.getController().getProperty(objectID, GraphicObjectProperties.__GO_CHILDREN__);
237                 for (Integer i = 0; i < childCount; i++) {
238                     flag = (Boolean) GraphicController.getController().getProperty(child[i], GraphicObjectProperties.__GO_VISIBLE__);
239                     if (flag) {
240                         return flag;
241                     }
242                 }
243             }
244         }
245         return false;
246     }
247
248     public static void pasteRotationAngles(Integer obj, Integer figure, Integer[] pos) {
249
250         Integer axesFrom = (new ObjectSearcher()).searchParent(obj, GraphicObjectProperties.__GO_AXES__);
251         Integer axesTo = AxesHandler.clickedAxes(figure, pos);
252
253         Double[] angles = (Double[])GraphicController.getController().getProperty(axesFrom, GraphicObjectProperties.__GO_ROTATION_ANGLES__);
254         GraphicController.getController().setProperty(axesTo, GraphicObjectProperties.__GO_ROTATION_ANGLES__, angles);
255     }
256
257     /**
258     * Clone an axes with the same properties from the original
259     *
260     * @param axesFromUID The uid from the axes to clone
261     * @return The cloned axes UID
262     */
263     public static Integer cloneAxesWithStyle(Integer axesFromUID) {
264
265         Integer cloneUID = GraphicController.getController().cloneObject(axesFromUID);
266         Axes clone = (Axes)GraphicController.getController().getObjectFromId(cloneUID);
267         Axes axesFrom = (Axes)GraphicController.getController().getObjectFromId(axesFromUID);
268
269         //Cloning the Axes does not clone the labels/title, so we need do it manualy
270
271         Integer xLabelUID = GraphicController.getController().cloneObject(axesFrom.getXAxisLabel());
272         Integer yLabelUID = GraphicController.getController().cloneObject(axesFrom.getYAxisLabel());
273         Integer zLabelUID = GraphicController.getController().cloneObject(axesFrom.getZAxisLabel());
274         Integer titleUID = GraphicController.getController().cloneObject(axesFrom.getTitle());
275
276         GraphicController.getController().setGraphicObjectRelationship(cloneUID, xLabelUID);
277         GraphicController.getController().setGraphicObjectRelationship(cloneUID, yLabelUID);
278         GraphicController.getController().setGraphicObjectRelationship(cloneUID, zLabelUID);
279         GraphicController.getController().setGraphicObjectRelationship(cloneUID, titleUID);
280
281         //Set the correct position to the labels/title in the new Axes
282
283         GraphicController.getController().setProperty(xLabelUID, GraphicObjectProperties.__GO_AUTO_POSITION__, true);
284         GraphicController.getController().setProperty(yLabelUID, GraphicObjectProperties.__GO_AUTO_POSITION__, true);
285         GraphicController.getController().setProperty(zLabelUID, GraphicObjectProperties.__GO_AUTO_POSITION__, true);
286         GraphicController.getController().setProperty(titleUID, GraphicObjectProperties.__GO_AUTO_POSITION__, true);
287
288         Double[] margins = axesFrom.getMargins();
289         Integer boxType = axesFrom.getBoxType();
290         boolean markMode = axesFrom.getMarkMode();
291         Integer clipState = axesFrom.getClipState();
292         Integer markSize = axesFrom.getMarkSize();
293         Integer markStyle = axesFrom.getMarkStyle();
294         Integer markForeground = axesFrom.getMarkForeground();
295         Integer markBackground = axesFrom.getMarkBackground();
296         boolean lineMode = axesFrom.getLineMode();
297         Integer lineStyle = axesFrom.getLineStyle();
298         Double lineThickness = axesFrom.getLineThickness();
299         Integer lineColor = axesFrom.getLineColor();
300         Double[] rotationAngles = axesFrom.getRotationAngles();
301         boolean XAxisVisible = axesFrom.getXAxisVisible();
302         boolean YAxisVisible = axesFrom.getYAxisVisible();
303         boolean ZAxisVisible = axesFrom.getZAxisVisible();
304         boolean XAxisReverse = axesFrom.getXAxisReverse();
305         boolean YAxisReverse = axesFrom.getYAxisReverse();
306         boolean ZAxisReverse = axesFrom.getZAxisReverse();
307         Integer XAxisGridColor = axesFrom.getXAxisGridColor();
308         Integer YAxisGridColor = axesFrom.getYAxisGridColor();
309         Integer ZAxisGridColor = axesFrom.getZAxisGridColor();
310         Integer fontStyle = axesFrom.getFontStyle();
311         Double fontSize = axesFrom.getFontSize();
312         Integer fontColor = axesFrom.getFontColor();
313         boolean fontFractional = axesFrom.getFontFractional();
314         Integer hiddenColor = axesFrom.getHiddenColor();
315         boolean XTightLimits = axesFrom.getXTightLimits();
316         boolean YTightLimits = axesFrom.getYTightLimits();
317         boolean ZTightLimits = axesFrom.getZTightLimits();
318
319         clone.setXAxisLabel(xLabelUID);
320         clone.setYAxisLabel(yLabelUID);
321         clone.setZAxisLabel(zLabelUID);
322         clone.setTitle(titleUID);
323
324         clone.setMargins(margins);
325         clone.setBoxType(boxType);
326         clone.setClipState(clipState);
327         clone.setMarkMode(markMode);
328         clone.setMarkStyle(markStyle);
329         clone.setMarkSize(markSize);
330         clone.setMarkBackground(markBackground);
331         clone.setMarkForeground(markForeground);
332         clone.setLineMode(lineMode);
333         clone.setLineStyle(lineStyle);
334         clone.setLineThickness(lineThickness);
335         clone.setLineColor(lineColor);
336
337
338         clone.setRotationAngles(rotationAngles);
339         clone.setXAxisVisible(XAxisVisible);
340         clone.setYAxisVisible(YAxisVisible);
341         clone.setZAxisVisible(ZAxisVisible);
342         clone.setXAxisReverse(XAxisReverse);
343         clone.setYAxisReverse(YAxisReverse);
344         clone.setZAxisReverse(ZAxisReverse);
345         clone.setXAxisGridColor(XAxisGridColor);
346         clone.setYAxisGridColor(YAxisGridColor);
347         clone.setZAxisGridColor(ZAxisGridColor);
348         clone.setFontStyle(fontStyle);
349         clone.setFontSize(fontSize);
350         clone.setFontColor(fontColor);
351         clone.setFontFractional(fontFractional);
352         clone.setHiddenColor(hiddenColor);
353         clone.setXTightLimits(XTightLimits);
354         clone.setYTightLimits(YTightLimits);
355         clone.setZTightLimits(ZTightLimits);
356
357         return cloneUID;
358     }
359
360     /**
361     * Cuts the original from the figure, paste the new axes in the figure and copy
362     * the childrens, data bounds and title from the original axes to the new one
363     *
364     * @param newAxesUID The uid from the new axes to paste
365     * @param axesToUID The uid from the axes to be cut
366     */
367     public static void pasteAxesStyle(Integer newAxesUID, Integer axesToUID, boolean bounds) {
368
369         if (newAxesUID == null || axesToUID == null) {
370             return;
371         }
372         Axes newAxes = (Axes)GraphicController.getController().getObjectFromId(newAxesUID);
373         Axes axesTo = (Axes)GraphicController.getController().getObjectFromId(axesToUID);
374
375         Integer[] children = axesTo.getChildren();
376         Integer parentUID = axesTo.getParent();
377         String[] titleText = (String[])GraphicController.getController().getProperty(axesTo.getTitle(), GraphicObjectProperties.__GO_TEXT_STRINGS__);
378         String[] xLabelText = (String[])GraphicController.getController().getProperty(axesTo.getXAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__);
379         String[] yLabelText = (String[])GraphicController.getController().getProperty(axesTo.getYAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__);
380         String[] zLabelText = (String[])GraphicController.getController().getProperty(axesTo.getZAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__);
381
382         GraphicController.getController().setProperty(newAxes.getTitle(), GraphicObjectProperties.__GO_TEXT_STRINGS__, titleText);
383         GraphicController.getController().setProperty(newAxes.getXAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__, xLabelText);
384         GraphicController.getController().setProperty(newAxes.getYAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__, yLabelText);
385         GraphicController.getController().setProperty(newAxes.getZAxisLabel(), GraphicObjectProperties.__GO_TEXT_STRINGS__, zLabelText);
386
387         if (bounds) {
388             Double[] dataBounds = axesTo.getDataBounds();
389             Double[] realDataBounds = axesTo.getRealDataBounds();
390             newAxes.setDataBounds(dataBounds);
391             newAxes.setRealDataBounds(realDataBounds);
392         }
393
394         for (Integer i = 0; i < children.length; i++) {
395             GraphicController.getController().setGraphicObjectRelationship(newAxesUID, children[i]);
396         }
397         GraphicController.getController().setGraphicObjectRelationship(parentUID, newAxesUID);
398         GraphicController.getController().setGraphicObjectRelationship(0, axesToUID);
399         ScilabNativeView.ScilabNativeView__setCurrentSubWin(newAxesUID);
400     }
401 }
402