Because rotation is the default mode,
[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     // We directly do a call to unzoomSubwin instead off path through the java code
320     // See bug 4979
321     // javaUnzoomSubwin(pSubwin);
322
323     char* parentFigure = NULL;
324     int zoomEnabled = 0;
325
326     getGraphicObjectProperty(subwinUID, __GO_PARENT_FIGURE__, jni_string, &parentFigure);
327
328     if( subwinUID == NULL || parentFigure == NULL )
329     {
330         return;
331     }
332
333     setGraphicObjectProperty(subwinUID, __GO_ZOOM_ENABLED__, &zoomEnabled, jni_bool, 1);
334
335     /*
336      * Deactivated since it performs drawing operations.
337      * To be implemented.
338      */
339 #if 0
340   startFigureDataWriting(parentFigure);
341     unzoomSubwin(pSubwin);
342   endFigureDataWriting(parentFigure);
343 #endif
344
345 }
346 /*------------------------------------------------------------------------------*/
347 void unzoomSubwin(sciPointObj * pSubwin)
348 {
349         int currentStatus;
350   currentStatus = sciSetZooming(pSubwin, FALSE);
351   if (currentStatus == 0)
352   {
353     /* redraw only if needed */
354     //forceRedraw(pSubwin);
355   }
356 }
357 /*------------------------------------------------------------------------------*/
358 /**
359  * Unzoom all the subwindows contained in a figure
360  */
361 void sciUnzoomFigure(sciPointObj * figure)
362 {
363   /* Copy subwins into the array */
364   sciSons * pSons = sciGetSons(figure);
365   while (pSons != NULL)
366   {
367     sciPointObj * curObj = pSons->pointobj;
368     if (sciGetEntityType(curObj) == SCI_SUBWIN)
369     {
370       sciUnzoomSubwin(curObj);
371     }
372     pSons = pSons->pnext;
373   }
374 }
375 /*------------------------------------------------------------------------------*/
376 /**
377  * Un zoom all the subwindow of a figure
378  */
379 void sciUnzoomAll(void)
380 {
381   sciPointObj * pFigure = NULL;
382
383   //startGraphicDataWriting();
384   pFigure = sciGetCurrentFigure();
385   //endGraphicDataWriting();
386
387   /* unzoom current figure */
388   sciUnzoomFigure(pFigure);
389
390   //sciDrawObj(pFigure);
391 }
392 /*------------------------------------------------------------------------------*/
393 /**
394  * Unzoom a set of subwindows and figures
395  * @param zoomedObjects array of figure and subwindow objects
396  */
397 void sciUnzoomArray(sciPointObj * zoomedObjects[], int nbObjects)
398 {
399   int i;
400   /* list of parent figure to redraw */
401   DoublyLinkedList * redrawnFigures = DoublyLinkedList_new();
402   for (i = 0; i < nbObjects; i++)
403   {
404     sciPointObj * parentFigure = sciGetParentFigure(zoomedObjects[i]);
405
406     if (sciGetEntityType(zoomedObjects[i]) == SCI_FIGURE)
407     {
408       /* Unzoom all subwindows of the figure */
409       sciUnzoomFigure(zoomedObjects[i]);
410     }
411     else if (sciGetEntityType(zoomedObjects[i]) == SCI_SUBWIN)
412     {
413       /* Unzoom only figure */
414       sciUnzoomSubwin(zoomedObjects[i]);
415     }
416
417     if (List_find(redrawnFigures, parentFigure) == NULL)
418     {
419       /* figure not already added for redraw */
420       redrawnFigures = List_push(redrawnFigures, parentFigure);
421     }
422   }
423
424   /* redraw only needed figures */
425   while (!List_is_empty(redrawnFigures))
426   {
427     sciPointObj * curFigure = NULL;
428     redrawnFigures = List_pop(redrawnFigures, (void**)&curFigure);
429     //sciDrawObj(curFigure);
430   }
431
432   List_free(redrawnFigures);
433 }
434 /*--------------------------------------------------------------------------------*/
435 void updateSubwinScale(char * pSubwinUID)
436 {
437     sciJavaUpdateSubwinScale(pSubwinUID);
438 }
439 /*------------------------------------------------------------------------------*/
440 void updateTextBounds(char * pTextUID)
441 {
442     char* parentAxes = NULL;
443
444     /* Update coordinate transformation if needed */
445     getGraphicObjectProperty(pTextUID, __GO_PARENT_AXES__, jni_string, &parentAxes);
446     updateSubwinScale(parentAxes);
447
448     /* Compute the bounding box of the text */
449     sciJavaUpdateTextBoundingBox(pTextUID);
450 }
451 /*------------------------------------------------------------------------------*/