Plug back 'unzoom' function and 'unzoom' buttons.
[scilab.git] / scilab / modules / graphics / src / c / axesScale.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
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-en.txt
11  *
12  */
13
14 /*------------------------------------------------------------------------*/
15 /* file: axesScale.c                                                      */
16 /* desc : Contains functions to compute scale changes in a specific       */
17 /*        subwindow.                                                      */
18 /*------------------------------------------------------------------------*/
19
20 #include <string.h>
21
22 #include "axesScale.h"
23 #include "math_graphics.h"
24 #include "GetProperty.h"
25 #include "SetProperty.h"
26 #include "Scierror.h"
27 #include "localization.h"
28 #include "SetPropertyStatus.h"
29 #include "SetJavaProperty.h"
30 #include "Interaction.h"
31 #include "JavaInteraction.h"
32 #include "HandleManagement.h"
33
34 #include "setGraphicObjectProperty.h"
35 #include "getGraphicObjectProperty.h"
36 #include "graphicObjectProperties.h"
37
38 /*------------------------------------------------------------------------------*/
39 static void zoomSubwin(sciPointObj * pSubwin, int posX, int posY, int width, int height);
40 static void zoomFigure(sciPointObj * pFigure, int posX, int posY, int width, int height);
41 /*------------------------------------------------------------------------------*/
42 /**
43  * Specify new zoom box for a subwin object.
44  * @param subwinUID the subwin's identifier.
45  * @param zoomRect vector [xMin, yMin, xMax, yMax].
46  */
47 int sciZoom2D(char * subwinUID, const double zoomRect[4])
48 {
49     double* zoomBox;
50
51     // add Z scale to data bounds.
52     getGraphicObjectProperty(subwinUID, __GO_DATA_BOUNDS__, jni_double_vector, &zoomBox);
53
54     zoomBox[0] = zoomRect[0];
55     zoomBox[1] = zoomRect[1];
56     zoomBox[2] = zoomRect[2];
57     zoomBox[3] = zoomRect[3];
58
59     return sciZoom3D(subwinUID, zoomBox);
60 }
61 /*------------------------------------------------------------------------------*/
62 /**
63  * Specify a new zoom box for a subwin object
64  * @param subwinUID the subwin's identifier.
65  * @param zoomBox vector [xMin, yMin, xMax, yMax, zMin, zMax].
66  */
67 int sciZoom3D(char * subwinUID, const double zoomBox[6])
68 {
69     BOOL status;
70     int zoomEnabled = 1;
71
72     // convert zoomBox to [xMin, xMax, yMin, yMax, zMin, zMax]
73     double zoomBox3D[6];
74     zoomBox3D[0] = zoomBox[0];
75     zoomBox3D[1] = zoomBox[2];
76     zoomBox3D[2] = zoomBox[1];
77     zoomBox3D[3] = zoomBox[3];
78     zoomBox3D[4] = zoomBox[4];
79     zoomBox3D[5] = zoomBox[5];
80
81     if (!checkDataBounds(subwinUID, zoomBox3D[0], zoomBox3D[1], zoomBox3D[2],
82                          zoomBox3D[3], zoomBox3D[4], zoomBox3D[5]))
83     {
84         return SET_PROPERTY_ERROR;
85     }
86
87     status = setGraphicObjectProperty(subwinUID, __GO_ZOOM_BOX__, zoomBox3D, jni_double_vector, 6);
88
89     if (status != TRUE)
90     {
91         Scierror(999, _("'%s' property does not exist for this handle.\n"),"zoom_box");
92         return SET_PROPERTY_ERROR;
93     }
94
95     status = setGraphicObjectProperty(subwinUID, __GO_ZOOM_ENABLED__, &zoomEnabled, jni_bool, 1);
96
97     if (status == TRUE)
98     {
99         return SET_PROPERTY_SUCCEED;
100     }
101     else
102     {
103         return SET_PROPERTY_ERROR;
104     }
105
106 }
107 /*------------------------------------------------------------------------------*/
108 /**
109  * get the zoom box to dispplay in Scilab for a sunwin object
110  * @param[out] zoomBox [xMin, yMin, xMax, yMax, zMin, zMax];
111  */
112 void sciGetZoom3D(sciPointObj * pObj, double zoomBox[6])
113 {
114   double temp;
115
116   // here we get [xMin, xMax, yMin, yMax, zMin, zMax]
117   // we need to switch xMax and yMin
118   sciGetZoomBox(pObj, zoomBox);
119   temp = zoomBox[1];
120   zoomBox[1] = zoomBox[2];
121   zoomBox[2] = temp;
122 }
123 /*------------------------------------------------------------------------------*/
124 int sciZoomRect(sciPointObj * pObj, const double zoomRect[4])
125 {
126   int status = SET_PROPERTY_ERROR;
127   if (sciGetEntityType(pObj) == SCI_FIGURE)
128   {
129     status = sciFigureZoom2D(pObj, zoomRect);
130   }
131   else if (sciGetEntityType(pObj) == SCI_SUBWIN)
132   {
133     status = sciZoom2D(pObj, zoomRect);
134   }
135
136   /* redraw everything */
137   if (status == SET_PROPERTY_SUCCEED)
138   {
139     //sciDrawObj(pObj);
140   }
141
142   return status;
143 }
144 /*------------------------------------------------------------------------------*/
145 int sciDefaultZoom2D(const double zoomRect[4])
146 {
147   sciPointObj * curFigure = NULL;
148   //startGraphicDataWriting();
149   curFigure = sciGetCurrentFigure();
150   //endGraphicDataWriting();
151
152   return sciZoomRect(curFigure, zoomRect);
153 }
154 /*------------------------------------------------------------------------------*/
155 int sciFigureZoom2D(sciPointObj * figure, const double zoomRect[4])
156 {
157   /* try to zoom on all the subwindows */
158   sciSons * pSons = sciGetSons(figure);
159   while (pSons != NULL)
160   {
161     sciPointObj * curObj = pSons->pointobj;
162     if (sciGetEntityType(curObj) == SCI_SUBWIN)
163     {
164       int status = sciZoom2D(curObj, zoomRect);
165       if (status == SET_PROPERTY_SUCCEED)
166       {
167         //forceRedraw(curObj);
168       }
169       else
170       {
171         return SET_PROPERTY_ERROR;
172       }
173     }
174     pSons = pSons->pnext;
175   }
176
177   return SET_PROPERTY_SUCCEED;
178
179 }
180 /*------------------------------------------------------------------------------*/
181 /**
182  * Try to zoom on a single subwindow using a selection area
183  */
184 static void zoomSubwin(sciPointObj * pSubwin, int posX, int posY, int width, int height)
185 {
186   if (sciJavaZoomRect(pSubwin, posX, posY, width, height))
187   {
188     /* subwindow has been zoomed */
189     /* force zooming */
190     sciSetZooming(pSubwin, TRUE);
191
192     // window has changed
193     //forceRedraw(pSubwin);
194   }
195 }
196 /*------------------------------------------------------------------------------*/
197 /**
198  * Zoom a figure using an already computed selection area
199  */
200 static void zoomFigure(sciPointObj * pFigure, int posX, int posY, int width, int height)
201 {
202   /* try to zoom on all the subwindows */
203   sciSons * pSons = sciGetSons(pFigure);
204   while (pSons != NULL)
205   {
206     sciPointObj * curObj = pSons->pointobj;
207     if (sciGetEntityType(curObj) == SCI_SUBWIN)
208     {
209       zoomSubwin(curObj, posX, posY, width, height);
210     }
211     pSons = pSons->pnext;
212   }
213 }
214 /*------------------------------------------------------------------------------*/
215 void sciZoomObject(sciPointObj * pObj, int x1, int y1, int x2, int y2)
216 {
217         /* convert found data to [x,y,w,h] */
218   int x = Min(x1, x2);
219   int y = Min(y1, y2);
220   int w = Abs(x1 - x2);
221   int h = Abs(y1 - y2);
222
223         if (w == 0 || h == 0)
224         {
225                 /* Zoom is not possible */
226                 return;
227         }
228
229         if (sciGetEntityType(pObj) == SCI_FIGURE)
230         {
231                 zoomFigure(pObj, x, y, w, h);
232         }
233         else if (sciGetEntityType(pObj) == SCI_SUBWIN)
234         {
235                 zoomSubwin(pObj, x, y, w, h);
236         }
237 }
238 /*------------------------------------------------------------------------------*/
239 /**
240  * Perform an interactive zoom (rectangular selection +  zoom)
241  * @param pObj object on which the zoom will be applied.
242  *             Might be a Figure or a Subwindow. If it is a figure the zoom
243  *             is applied to the axes children of the figure
244  */
245 void sciInteractiveZoom(sciPointObj * pObj)
246 {
247         interactiveZoom(pObj);
248 }
249 /*------------------------------------------------------------------------------*/
250 /**
251  * Perform a zoom rect (rectangular selection + zoom) on the current figure
252  */
253 void sciDefaultInteractiveZoom(void)
254 {
255   sciPointObj * curFigure;
256
257  // startGraphicDataWriting();
258   curFigure = sciGetCurrentFigure();
259   //endGraphicDataWriting();
260
261
262   /* zoom current figure */
263   interactiveZoom(curFigure);
264 }
265 /*------------------------------------------------------------------------------*/
266 /**
267  * Check if the following data bounds can be used as new data bounds for the subwin object
268  * @param subwinUID the subwin's identifier.
269  * @param the lower x bound.
270  * @param the upper x bound.
271  * @param the lower y bound.
272  * @param the upper y bound.
273  * @param the lower z bound.
274  * @param the upper z bound.
275  * @return TRUE if values can be used, false otherwise
276  */
277 BOOL checkDataBounds(char * subwinUID, double xMin, double xMax,
278                      double yMin, double yMax, double zMin, double zMax)
279 {
280     char logFlags[3];
281
282     sciGetLogFlags(subwinUID, logFlags);
283
284     /* check if there is not an inf within the values */
285     /* since this has not any meaning */
286     if (    !finite(xMin) || !finite(xMax)
287          || !finite(yMin) || !finite(yMax)
288          || !finite(zMin) || !finite(zMax) )
289     {
290         Scierror(999, "Error : data bounds values must be finite.");
291         return FALSE;
292     }
293
294     /* check if the bounds are correct */
295     /* allows equality with bounds since it is working */
296     if ( xMin > xMax || yMin > yMax || zMin > zMax )
297     {
298         Scierror(999, "Error : Min and Max values for one axis do not verify Min <= Max.\n");
299         return FALSE;
300     }
301
302     /* check for logflags that values are greater than 0 */
303     if (   ( logFlags[0] == 'l' && xMin <= 0.0 )
304         || ( logFlags[1] == 'l' && yMin <= 0.0 )
305         || ( logFlags[2] == 'l' && zMin <= 0.0 ) )
306     {
307         Scierror(999, "Error: Bounds on axis must be strictly positive to use logarithmic mode.\n" );
308         return FALSE;
309     }
310
311     return TRUE;
312 }
313 /*------------------------------------------------------------------------------*/
314 /**
315  * Unzoom a single subwindow
316  */
317 void sciUnzoomSubwin(char* subwinUID)
318 {
319     char* parentFigure = NULL;
320     int zoomEnabled = 0;
321
322     getGraphicObjectProperty(subwinUID, __GO_PARENT_FIGURE__, jni_string, (void **) &parentFigure);
323
324     if( subwinUID == NULL || parentFigure == NULL )
325     {
326         return;
327     }
328
329     setGraphicObjectProperty(subwinUID, __GO_ZOOM_ENABLED__, (void **) &zoomEnabled, jni_bool, 1);
330 }
331 /*------------------------------------------------------------------------------*/
332 void unzoomSubwin(sciPointObj * pSubwin)
333 {
334         int currentStatus;
335   currentStatus = sciSetZooming(pSubwin, FALSE);
336   if (currentStatus == 0)
337   {
338     /* redraw only if needed */
339     //forceRedraw(pSubwin);
340   }
341 }
342 /*------------------------------------------------------------------------------*/
343 /**
344  * Unzoom all the subwindows contained in a figure
345  */
346 void sciUnzoomFigure(char* figureUID)
347 {
348   char* pstType;
349   char** pstChildrenUID;
350   
351   int i; 
352   int zoomEnabled = 0;
353   int childrenCount;
354   int* piChildrenCount = &childrenCount;
355   
356   getGraphicObjectProperty(figureUID, __GO_CHILDREN__, jni_string_vector, (void **) &pstChildrenUID);
357   getGraphicObjectProperty(figureUID, __GO_CHILDREN_COUNT__, jni_int, (void **) &piChildrenCount);
358   
359   if (piChildrenCount != NULL)
360   {
361
362     for (i = 0; i < childrenCount; i++)
363     {
364       getGraphicObjectProperty(pstChildrenUID[i], __GO_TYPE__, jni_string, (void **) &pstType);
365       if (strcmp(pstType, __GO_AXES__) == 0)
366         setGraphicObjectProperty(pstChildrenUID[i], __GO_ZOOM_ENABLED__, (void **) &zoomEnabled, jni_bool, 1);
367       }
368   }
369 }
370 /*------------------------------------------------------------------------------*/
371 /**
372  * Unzoom a set of subwindows and figures
373  * @param objectsUID array of figure and subwindow objects id.
374  * @param nbObjects number of objects.
375  */
376 void sciUnzoomArray(char* objectsUID[], int nbObjects)
377 {
378   /* object type */
379   char* pstType;
380   int i;
381   for (i = 0; i < nbObjects; i++)
382   {
383     getGraphicObjectProperty(objectsUID[i], __GO_TYPE__, jni_string, (void **) &pstType);
384     if (strcmp(pstType, __GO_FIGURE__) == 0)
385     {
386       /* Unzoom all subwindows of the figure */
387       sciUnzoomFigure(objectsUID[i]);
388     }
389     else if (strcmp(pstType, __GO_AXES__) == 0)
390     {
391       /* Unzoom the axes */
392       sciUnzoomSubwin(objectsUID[i]);
393     }
394
395   }
396 }
397 /*--------------------------------------------------------------------------------*/
398 void updateSubwinScale(char * pSubwinUID)
399 {
400     sciJavaUpdateSubwinScale(pSubwinUID);
401 }
402 /*------------------------------------------------------------------------------*/
403 void updateTextBounds(char * pTextUID)
404 {
405     char* parentAxes = NULL;
406
407     /* Update coordinate transformation if needed */
408     getGraphicObjectProperty(pTextUID, __GO_PARENT_AXES__, jni_string, &parentAxes);
409     updateSubwinScale(parentAxes);
410
411     /* Compute the bounding box of the text */
412     sciJavaUpdateTextBoundingBox(pTextUID);
413 }
414 /*------------------------------------------------------------------------------*/