convert figure macro to gateway
[scilab.git] / scilab / modules / gui / sci_gateway / c / sci_figure.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
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 #include "gw_gui.h"
14 #include "MALLOC.h"
15 #include "api_scilab.h"
16 #include "localization.h"
17 #include "Scierror.h"
18 #include "createGraphicObject.h"
19 #include "BuildObjects.h"
20 #include "setGraphicObjectProperty.h"
21 #include "getGraphicObjectProperty.h"
22 #include "graphicObjectProperties.h"
23 #include "CurrentFigure.h"
24 #include "CurrentSubwin.h"
25 #include "FigureList.h"
26 #include "HandleManagement.h"
27 #include "SetHashTable.h"
28 #include "stricmp.h"
29 #ifdef _MSC_VER
30 #include "strdup_windows.h"
31 #endif
32
33 #include "sciprint.h"
34
35 #define COLOR_COMPONENT 3
36 /*--------------------------------------------------------------------------*/
37 void setDefaultProperties(int _iFig, BOOL _bAlreadyExist);
38 int addColor(int _iFig, double* _pdblColor);
39 /*--------------------------------------------------------------------------*/
40 int sci_figure(char * fname, unsigned long fname_len)
41 {
42     SciErr sciErr;
43     int* piAddr = NULL;
44     int iFig = 0;
45     int iRhs = nbInputArgument(pvApiCtx);
46     int iId = 0;
47     int iPos = 0;
48     int i = 0;
49
50
51     //figure(num) -> scf(num)
52     //figure() -> scf()
53
54     //figure(x, "...", ...)
55     // -> f = scf(x);
56     //      set(f, "...", ...);
57
58     if (iRhs % 2 == 0)
59     {
60         int i = 0;
61         int iNewId = -1;
62         int iAxes = 0;
63         int* piAxes = &iAxes;
64
65         //get higher value of winsid to create the new windows @ + 1
66         int nbFigure = sciGetNbFigure();
67
68         if (nbFigure)
69         {
70             int * ids = (int*)MALLOC(nbFigure * sizeof(int));
71
72             if (ids == NULL)
73             {
74                 Scierror(999, _("%s: No more memory.\n"), fname);
75                 return 0;
76             }
77             sciGetFiguresId(ids);
78
79             //find higher value
80             for (i = 0 ; i < nbFigure ; i++)
81             {
82                 if (ids[i] > iNewId)
83                 {
84                     iNewId = ids[i];
85                 }
86             }
87         }
88
89         //use next value
90         iNewId = iNewId + 1;
91
92         //create a new window with id = iNewId
93         iFig = createNewFigureWithAxes();
94         setGraphicObjectProperty(iFig, __GO_ID__, &iNewId, jni_int, 1);
95         setCurrentFigure(iFig);
96
97         getGraphicObjectProperty(iFig, __GO_SELECTED_CHILD__, jni_int,  (void**)&piAxes);
98         setCurrentSubWin(iAxes);
99
100         //setting up new figure
101         setDefaultProperties(iFig, FALSE);
102     }
103     else
104     {
105         //create or set current figure to x
106
107         int iAxes = 0;
108         int* piAxes = &iAxes;
109         double dblId = 0;
110         //figure(x);
111         sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
112         if (sciErr.iErr)
113         {
114             printError(&sciErr, 0);
115             Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
116             return 0;
117         }
118
119         if (isVarMatrixType(pvApiCtx, piAddr) == 0)
120         {
121             Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
122             return 0;
123         }
124
125         if (getScalarDouble(pvApiCtx, piAddr, &dblId))
126         {
127             Scierror(999, _("%s: No more memory.\n"), fname);
128             return 0;
129         }
130
131         iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
132
133         //get current fig from id
134         iFig = getFigureFromIndex(iId);
135         if (iFig == 0)
136         {
137             // No Figure available with this index, should create it  !!
138             iFig = createNewFigureWithAxes();
139             setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
140         }
141
142         setCurrentFigure(iFig);
143         getGraphicObjectProperty(iFig, __GO_SELECTED_CHILD__, jni_int,  (void**)&piAxes);
144         setCurrentSubWin(iAxes);
145
146         //setting up new figure
147         setDefaultProperties(iFig, FALSE);
148
149         iPos = 1;
150     }
151
152     if (iRhs > 1)
153     {
154         //set(iFig, iPos, iPos + 1)
155         for (i = iPos + 1 ; i <= iRhs ; i += 2)
156         {
157             int isMatrixOfString = 0;
158             int* piAddrProp = NULL;
159             char* pstProName = NULL;
160             int* piAddrData = NULL;
161             int iRows = 0;
162             int iCols = 0;
163             void* _pvData = NULL;
164             int iType = 0;
165
166             //get property name
167             sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
168             if (sciErr.iErr)
169             {
170                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
171                 return 1;
172             }
173
174             if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
175             {
176                 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
177                 return 1;
178             }
179
180             //check property value to compatibility
181             if (stricmp(pstProName, "backgroundcolor") == 0)
182             {
183                 freeAllocatedSingleString(pstProName);
184                 pstProName = strdup("background");
185             }
186             else if (stricmp(pstProName, "foregroundcolor") == 0)
187             {
188                 freeAllocatedSingleString(pstProName);
189                 pstProName = strdup("foreground");
190             }
191
192             //get address of value on stack
193             sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
194             if (sciErr.iErr)
195             {
196                 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
197                 return 1;
198             }
199
200             getVarType(pvApiCtx, piAddrData, &iType);
201
202             if ((strcmp(pstProName, "user_data") == 0) || (stricmp(pstProName, "userdata") == 0))
203             {
204                 /* in this case set_user_data_property
205                 * directly uses the  third position in the stack
206                 * to get the variable which is to be set in
207                 * the user_data property (any data type is allowed) S. Steer */
208                 _pvData = (void*)piAddrData;         /*position in the stack */
209                 iRows = -1;   /*unused */
210                 iCols = -1;   /*unused */
211                 iType = -1;
212             }
213             else
214             {
215                 switch (iType)
216                 {
217                     case sci_matrix :
218                         getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, (double**)&_pvData);
219                         break;
220                     case sci_boolean :
221                         getMatrixOfBoolean(pvApiCtx, piAddrData, &iRows, &iCols, (int**)&_pvData);
222                         break;
223                     case sci_handles :
224                         getMatrixOfHandle(pvApiCtx, piAddrData, &iRows, &iCols, (long long**)&_pvData);
225                         break;
226                     case sci_strings :
227                         if (   strcmp(pstProName, "tics_labels") != 0 && strcmp(pstProName, "auto_ticks") != 0 &&
228                                 strcmp(pstProName, "axes_visible") != 0 && strcmp(pstProName, "axes_reverse") != 0 &&
229                                 strcmp(pstProName, "text") != 0 && stricmp(pstProName, "string") != 0 &&
230                                 stricmp(pstProName, "tooltipstring") != 0) /* Added for uicontrols */
231                         {
232                             if (getAllocatedSingleString(pvApiCtx, piAddrData, (char**)&_pvData))
233                             {
234                                 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 3);
235                                 return 1;
236                             }
237                             iRows = (int)strlen((char*)_pvData);
238                             iCols = 1;
239                         }
240                         else
241                         {
242                             isMatrixOfString = 1;
243                             getAllocatedMatrixOfString(pvApiCtx, piAddrData, &iRows, &iCols, (char***)&_pvData);
244                         }
245                         break;
246                     case sci_list :
247                         iCols = 1;
248                         getListItemNumber(pvApiCtx, piAddrData, &iRows);
249                         _pvData = (void*)piAddrData;         /* In this case l3 is the list position in stack */
250                         break;
251                     default :
252                         _pvData = (void*)piAddrData;         /* In this case l3 is the list position in stack */
253                         break;
254                 }
255
256                 callSetProperty(pvApiCtx, iFig, _pvData, iType, iRows, iCols, pstProName);
257                 if (iType == sci_strings)
258                 {
259                     //free allacted data
260                     if (isMatrixOfString == 1)
261                     {
262                         freeAllocatedMatrixOfString(iRows, iCols, (char**)_pvData);
263                     }
264                     else
265                     {
266                         freeAllocatedSingleString((char*)_pvData);
267                     }
268                 }
269             }
270         }
271     }
272
273     //return new created fig
274     createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
275     AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
276     ReturnArguments(pvApiCtx);
277     return 0;
278 }
279 /*--------------------------------------------------------------------------*/
280 void setDefaultProperties(int _iFig, BOOL _bAlreadyExist)
281 {
282     //get figure axes
283     int iAxes = getOrCreateDefaultSubwin();
284     int iDrawing = 0;
285     int iColorIndex = 0;
286     int iFilled = 0;
287     int iAxesVisible = 0;
288
289     setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
290
291     if (_bAlreadyExist == FALSE)
292     {
293         double pdblNewColor[COLOR_COMPONENT] = {0.8, 0.8, 0.8};
294         iColorIndex = addColor(_iFig, pdblNewColor);
295
296         //set background in figure and axes to new ( or existting ) color
297         setGraphicObjectProperty(_iFig, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
298         setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
299     }
300
301     //a.filled = "off"
302     setGraphicObjectProperty(iAxes, __GO_FILLED__, &iFilled, jni_bool, 1);
303
304     //a.axes_visible = "off"
305     setGraphicObjectProperty(iAxes, __GO_X_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
306     setGraphicObjectProperty(iAxes, __GO_Y_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
307     setGraphicObjectProperty(iAxes, __GO_Z_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
308
309     //f.immediate_drawing = "on"
310     iDrawing = 1;
311     setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
312 }
313 /*--------------------------------------------------------------------------*/
314 int addColor(int _iFig, double* _pdblNewColor)
315 {
316     int iColorIndex = 0;
317     int i = 0, j = 0;
318     int iColorMapSize = 0;
319     int* piColorMapSize = &iColorMapSize;
320     double* pdblColorMap = NULL;
321     //for new figure, we have to set figure and axes background to [0.8 0.8 0.8]
322     //to do that, we have to update figure.colormap to add new color if not exist.
323     //or get index of color in current color_map
324
325     //first get figure.color_map
326     getGraphicObjectProperty(_iFig, __GO_COLORMAP_SIZE__, jni_int, (void**)&piColorMapSize);
327     getGraphicObjectProperty(_iFig, __GO_COLORMAP__, jni_double_vector, (void **)&pdblColorMap);
328
329     //check if newColor already in coloMap
330     for (i = 0 ; i < iColorMapSize ; i++)
331     {
332         BOOL bFound = TRUE;
333         double* pdblCurrentColor = pdblColorMap + i;
334         for (j = 0 ; j < COLOR_COMPONENT ; j++)
335         {
336             if (*(pdblCurrentColor + j * iColorMapSize) != _pdblNewColor[j])
337             {
338                 bFound = FALSE;
339                 break;
340             }
341         }
342
343         if (bFound)
344         {
345             iColorIndex = i + 1;
346             break;
347         }
348     }
349
350     //not found in current color map
351     if (iColorIndex == 0)
352     {
353         int iNewColorMapSize = (iColorMapSize + 1) * COLOR_COMPONENT;
354         double* pdblNewColorMap = (double*)MALLOC(sizeof(double) * iNewColorMapSize);
355         //we have to add the new color at the end of the current color map
356         for (i = 0 ; i < COLOR_COMPONENT ; i++)
357         {
358             memcpy(pdblNewColorMap + i * (iColorMapSize + 1),
359                    pdblColorMap + (i * iColorMapSize),
360                    iColorMapSize * sizeof(double));
361
362             pdblNewColorMap[i * (iColorMapSize + 1) + iColorMapSize] = _pdblNewColor[i];
363         }
364
365         setGraphicObjectProperty(_iFig, __GO_COLORMAP__, pdblNewColorMap, jni_double_vector, iNewColorMapSize);
366
367         iColorIndex = iColorMapSize + 1;
368     }
369     return iColorIndex;
370 }
371 /*--------------------------------------------------------------------------*/