2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
4 * Copyright (C) 2014 - Scilab Enterprises - Bruno JOFRET
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
17 #include "api_scilab.h"
18 #include "localization.h"
20 #include "createGraphicObject.h"
21 #include "BuildObjects.h"
22 #include "setGraphicObjectProperty.h"
23 #include "getGraphicObjectProperty.h"
24 #include "graphicObjectProperties.h"
25 #include "CurrentFigure.h"
26 #include "CurrentSubwin.h"
27 #include "FigureList.h"
28 #include "FigureModel.h"
29 #include "HandleManagement.h"
30 #include "SetHashTable.h"
33 #include "strdup_windows.h"
39 /*--------------------------------------------------------------------------*/
40 int setDefaultProperties(int _iFig, BOOL bDefaultAxes, BOOL _axesSize);
41 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr);
42 /*--------------------------------------------------------------------------*/
43 int sci_figure(char * fname, unsigned long fname_len)
48 int iRhs = nbInputArgument(pvApiCtx);
54 int iPropertyOffset = 0;
55 BOOL bDoCreation = TRUE;
56 BOOL bVisible = TRUE; // Create a visible figure by default
57 BOOL bDockable = TRUE; // Create a dockable figure by default
58 BOOL bDefaultAxes = TRUE; // Create an Axes by default
59 double* figureSize = NULL;
60 double* axesSize = NULL;
61 double* position = NULL;
66 int iMenubarType = 1; // Create a 'figure' menubar by default
67 int iToolbarType = 1; // Create a 'figure' toolbar by default
71 //figure(num) -> scf(num)
74 //figure(x, "...", ...)
77 if (iRhs == 0) // Auto ID
79 iFig = createNewFigureWithAxes();
80 iAxes = setDefaultProperties(iFig, TRUE, TRUE);
81 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
82 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
83 ReturnArguments(pvApiCtx);
90 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
93 printError(&sciErr, 0);
94 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
98 if (isVarMatrixType(pvApiCtx, piAddr) == 0)
100 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
104 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
106 Scierror(999, _("%s: No more memory.\n"), fname);
110 iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
112 //get current fig from id
113 iFig = getFigureFromIndex(iId);
114 if (iFig == 0) // Figure does not exists, create a new one
116 iFig = createNewFigureWithAxes();
117 setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
118 iAxes = setDefaultProperties(iFig, TRUE, TRUE);
121 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
122 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
123 ReturnArguments(pvApiCtx);
127 // Prepare property analysis
130 //get highest value of winsid to create the new windows @ + 1
131 iNewId = getValidDefaultFigureId();
138 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
141 printError(&sciErr, 0);
142 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
146 if (isVarMatrixType(pvApiCtx, piAddr) == 0)
148 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
152 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
154 Scierror(999, _("%s: No more memory.\n"), fname);
158 iNewId = (int)(dblId + 0.5); //avoid 1.999 -> 1
159 //get current fig from id
160 iFig = getFigureFromIndex(iId);
161 if (iFig != 0) // Figure already exists
169 int* piAddrProp = NULL;
170 char* pstProName = NULL;
171 int* piAddrData = NULL;
172 for (i = iPos + 1 ; i <= iRhs ; i += 2)
175 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
178 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
182 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
184 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
188 if (stricmp(pstProName, "dockable") != 0 &&
189 stricmp(pstProName, "toolbar") != 0 &&
190 stricmp(pstProName, "menubar") != 0 &&
191 stricmp(pstProName, "default_axes") != 0 &&
192 stricmp(pstProName, "visible") != 0 &&
193 stricmp(pstProName, "figure_size") != 0 &&
194 stricmp(pstProName, "axes_size") != 0 &&
195 stricmp(pstProName, "position") != 0 &&
196 stricmp(pstProName, "menubar_visible") != 0 &&
197 stricmp(pstProName, "toolbar_visible") != 0 &&
198 stricmp(pstProName, "infobar_visible") != 0)
200 freeAllocatedSingleString(pstProName);
204 //get address of value on stack
205 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
208 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
212 //check property value to compatibility
213 if (stricmp(pstProName, "dockable") == 0)
215 bDockable = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
218 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "dockable", "on", "off");
219 freeAllocatedSingleString(pstProName);
223 else if (stricmp(pstProName, "toolbar") == 0)
226 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
228 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
229 freeAllocatedSingleString(pstProName);
232 getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal);
234 if (stricmp(pstVal, "none") == 0)
238 else if (stricmp(pstVal, "figure") == 0)
244 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar", "none", "figure");
245 freeAllocatedSingleString(pstProName);
246 freeAllocatedSingleString(pstVal);
250 freeAllocatedSingleString(pstVal);
252 else if (stricmp(pstProName, "menubar") == 0)
255 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
257 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
258 freeAllocatedSingleString(pstProName);
262 getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal);
264 if (stricmp(pstVal, "none") == 0)
268 else if (stricmp(pstVal, "figure") == 0)
274 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar", "none", "figure");
275 freeAllocatedSingleString(pstProName);
276 freeAllocatedSingleString(pstVal);
280 freeAllocatedSingleString(pstVal);
282 else if (stricmp(pstProName, "default_axes") == 0)
284 bDefaultAxes = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
285 if (bDefaultAxes == -1)
287 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "default_axes", "on", "off");
288 freeAllocatedSingleString(pstProName);
292 else if (stricmp(pstProName, "visible") == 0)
294 bVisible = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
297 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "visible", "on", "off");
298 freeAllocatedSingleString(pstProName);
302 else if (stricmp(pstProName, "figure_size") == 0)
306 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
308 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
312 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &figureSize);
313 if (iRows * iCols != 2)
315 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "figure_size", 2);
319 else if (stricmp(pstProName, "axes_size") == 0)
323 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
325 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
329 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &axesSize);
330 if (iRows * iCols != 2)
332 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "axes_size", 2);
336 else if (stricmp(pstProName, "position") == 0)
341 if (isDoubleType(pvApiCtx, piAddrData))
343 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &pdbl);
344 if (iRows * iCols != 4)
346 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "position", 4);
351 axesSize = (pdbl + 2);
353 else if (isStringType(pvApiCtx, piAddrData) && isScalar(pvApiCtx, piAddrData))
358 getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal);
360 iVal = sscanf(pstVal, "%lf|%lf|%lf|%lf", &val[0], &val[1], &val[2], &val[3]);
361 freeAllocatedSingleString(pstVal);
364 Scierror(999, _("Wrong value for '%s' property: A string or a 1 x %d real row vector expected.\n"), "position", 4);
369 axesSize = (val + 2);
373 Scierror(999, _("Wrong value for '%s' property: A string or a 1 x %d real row vector expected.\n"), "position", 4);
377 else if (stricmp(pstProName, "menubar_visible") == 0)
379 bMenuBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
382 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar_visible", "on", "off");
383 freeAllocatedSingleString(pstProName);
387 else if (stricmp(pstProName, "toolbar_visible") == 0)
389 bToolBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
392 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar_visible", "on", "off");
393 freeAllocatedSingleString(pstProName);
397 else if (stricmp(pstProName, "infobar_visible") == 0)
399 bInfoBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
402 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "infobar_visible", "on", "off");
403 freeAllocatedSingleString(pstProName);
410 iFig = createFigure(bDockable, iMenubarType, iToolbarType, bDefaultAxes, bVisible, figureSize, axesSize, position, bMenuBar, bToolBar, bInfoBar);
411 setGraphicObjectProperty(iFig, __GO_ID__, &iNewId, jni_int, 1);
412 iAxes = setDefaultProperties(iFig, bDefaultAxes, figureSize || axesSize ? FALSE : TRUE);
415 //set(iFig, iPos, iPos + 1)
416 for (i = iPos + 1 ; i <= iRhs ; i += 2)
418 int isMatrixOfString = 0;
419 int* piAddrProp = NULL;
420 char* pstProName = NULL;
421 int* piAddrData = NULL;
424 void* _pvData = NULL;
428 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
431 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
435 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
437 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
442 stricmp(pstProName, "dockable") == 0 ||
443 stricmp(pstProName, "toolbar") == 0 ||
444 stricmp(pstProName, "menubar") == 0 ||
445 stricmp(pstProName, "default_axes") == 0 ||
446 stricmp(pstProName, "visible") == 0 ||
447 stricmp(pstProName, "figure_size") == 0 ||
448 stricmp(pstProName, "axes_size") == 0 ||
449 stricmp(pstProName, "position") == 0 ||
450 stricmp(pstProName, "menubar_visible") == 0 ||
451 stricmp(pstProName, "toolbar_visible") == 0 ||
452 stricmp(pstProName, "infobar_visible") == 0))
454 // Already set creating new figure
455 // but let the set_ function fail if figure already exists
459 //get address of value on stack
460 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
463 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
467 getVarType(pvApiCtx, piAddrData, &iType);
469 if ((strcmp(pstProName, "user_data") == 0) || (stricmp(pstProName, "userdata") == 0))
471 /* in this case set_user_data_property
472 * directly uses the third position in the stack
473 * to get the variable which is to be set in
474 * the user_data property (any data type is allowed) S. Steer */
475 _pvData = (void*)piAddrData; /*position in the stack */
476 iRows = -1; /*unused */
477 iCols = -1; /*unused */
485 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, (double**)&_pvData);
488 getMatrixOfBoolean(pvApiCtx, piAddrData, &iRows, &iCols, (int**)&_pvData);
491 getMatrixOfHandle(pvApiCtx, piAddrData, &iRows, &iCols, (long long**)&_pvData);
494 if ( strcmp(pstProName, "tics_labels") != 0 && strcmp(pstProName, "auto_ticks") != 0 &&
495 strcmp(pstProName, "axes_visible") != 0 && strcmp(pstProName, "axes_reverse") != 0 &&
496 strcmp(pstProName, "text") != 0 && stricmp(pstProName, "string") != 0 &&
497 stricmp(pstProName, "tooltipstring") != 0) /* Added for uicontrols */
499 if (getAllocatedSingleString(pvApiCtx, piAddrData, (char**)&_pvData))
501 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 3);
504 iRows = (int)strlen((char*)_pvData);
509 isMatrixOfString = 1;
510 getAllocatedMatrixOfString(pvApiCtx, piAddrData, &iRows, &iCols, (char***)&_pvData);
515 getListItemNumber(pvApiCtx, piAddrData, &iRows);
516 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
519 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
524 callSetProperty(pvApiCtx, iFig, _pvData, iType, iRows, iCols, pstProName);
526 // If backgroundcolor is set :
527 // * add it to colormap => performed by callSetProperty
528 // * set background to index => performed by callSetProperty
529 // * copy value into axes background property
530 if (stricmp(pstProName, "backgroundcolor") == 0 && iAxes > 0)
533 int *piBackground = &iBackground;
535 getGraphicObjectProperty(iFig, __GO_BACKGROUND__, jni_int, (void **)&piBackground);
536 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, piBackground, jni_int, 1);
539 if (iType == sci_strings)
542 if (isMatrixOfString == 1)
544 freeAllocatedMatrixOfString(iRows, iCols, (char**)_pvData);
548 freeAllocatedSingleString((char*)_pvData);
553 //return new created fig
554 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
555 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
556 ReturnArguments(pvApiCtx);
559 /*--------------------------------------------------------------------------*/
560 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr)
562 if (isScalar(_pvCtx, _piAddr))
564 if (isDoubleType(_pvCtx, _piAddr))
567 getScalarDouble(_pvCtx, _piAddr, &dbl);
568 return ((int)dbl == 0 ? FALSE : TRUE);
570 else if (isBooleanType(_pvCtx, _piAddr))
573 getScalarBoolean(_pvCtx, _piAddr, &i);
574 return (i == 0 ? FALSE : TRUE);
576 else if (isStringType(_pvCtx, _piAddr))
580 getAllocatedSingleString(_pvCtx, _piAddr, &pst);
582 if (stricmp(pst, "on") == 0)
587 freeAllocatedSingleString(pst);
594 /*--------------------------------------------------------------------------*/
595 int setDefaultProperties(int _iFig, BOOL _bDefaultAxes, BOOL _axesSize)
602 int iAxesVisible = 0;
603 int* piAxesSize = NULL;
604 double pdblNewColor[COLOR_COMPONENT] = {0.8, 0.8, 0.8};
606 setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
608 iColorIndex = addColor(_iFig, pdblNewColor);
610 setGraphicObjectProperty(_iFig, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
613 iAxes = getOrCreateDefaultSubwin();
614 //set background in figure and axes to new ( or existting ) color
615 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
618 setGraphicObjectProperty(iAxes, __GO_FILLED__, &iFilled, jni_bool, 1);
620 //a.axes_visible = "off"
621 setGraphicObjectProperty(iAxes, __GO_X_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
622 setGraphicObjectProperty(iAxes, __GO_Y_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
623 setGraphicObjectProperty(iAxes, __GO_Z_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
629 getGraphicObjectProperty(getFigureModel(), __GO_AXES_SIZE__, jni_int_vector, (void **)&piAxesSize);
630 setGraphicObjectProperty(_iFig, __GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
633 //f.immediate_drawing = "on"
635 setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
639 /*--------------------------------------------------------------------------*/