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
16 #include "api_scilab.h"
17 #include "localization.h"
19 #include "createGraphicObject.h"
20 #include "BuildObjects.h"
21 #include "setGraphicObjectProperty.h"
22 #include "getGraphicObjectProperty.h"
23 #include "graphicObjectProperties.h"
24 #include "CurrentFigure.h"
25 #include "CurrentSubwin.h"
26 #include "FigureList.h"
27 #include "FigureModel.h"
28 #include "HandleManagement.h"
29 #include "SetHashTable.h"
32 #include "strdup_windows.h"
38 /*--------------------------------------------------------------------------*/
39 int setDefaultProperties(int _iFig, BOOL bDefaultAxes, BOOL _axesSize);
40 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr);
41 /*--------------------------------------------------------------------------*/
42 int sci_figure(char * fname, unsigned long fname_len)
47 int iRhs = nbInputArgument(pvApiCtx);
53 int iPropertyOffset = 0;
54 BOOL bDoCreation = TRUE;
55 BOOL bVisible = TRUE; // Create a visible figure by default
56 BOOL bDockable = TRUE; // Create a dockable figure by default
57 BOOL bDefaultAxes = TRUE; // Create an Axes by default
58 double* figureSize = NULL;
59 double* axesSize = NULL;
60 double* position = NULL;
64 int iMenubarType = 1; // Create a 'figure' menubar by default
65 int iToolbarType = 1; // Create a 'figure' toolbar by default
69 //figure(num) -> scf(num)
72 //figure(x, "...", ...)
75 if (iRhs == 0) // Auto ID
77 iFig = createNewFigureWithAxes();
78 iAxes = setDefaultProperties(iFig, TRUE, TRUE);
79 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
80 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
81 ReturnArguments(pvApiCtx);
88 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
91 printError(&sciErr, 0);
92 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
96 if (isVarMatrixType(pvApiCtx, piAddr) == 0)
98 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
102 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
104 Scierror(999, _("%s: No more memory.\n"), fname);
108 iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
110 //get current fig from id
111 iFig = getFigureFromIndex(iId);
112 if (iFig == 0) // Figure does not exists, create a new one
114 iFig = createNewFigureWithAxes();
115 setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
116 iAxes = setDefaultProperties(iFig, TRUE, TRUE);
119 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
120 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
121 ReturnArguments(pvApiCtx);
125 // Prepare property analysis
128 //get highest value of winsid to create the new windows @ + 1
129 iNewId = getValidDefaultFigureId();
136 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
139 printError(&sciErr, 0);
140 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
144 if (isVarMatrixType(pvApiCtx, piAddr) == 0)
146 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
150 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
152 Scierror(999, _("%s: No more memory.\n"), fname);
156 iNewId = (int)(dblId + 0.5); //avoid 1.999 -> 1
157 //get current fig from id
158 iFig = getFigureFromIndex(iId);
159 if (iFig != 0) // Figure already exists
167 int* piAddrProp = NULL;
168 char* pstProName = NULL;
169 int* piAddrData = NULL;
170 for (i = iPos + 1 ; i <= iRhs ; i += 2)
173 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
176 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
180 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
182 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
186 if (stricmp(pstProName, "dockable") != 0 &&
187 stricmp(pstProName, "toolbar") != 0 &&
188 stricmp(pstProName, "menubar") != 0 &&
189 stricmp(pstProName, "default_axes") != 0 &&
190 stricmp(pstProName, "visible") != 0 &&
191 stricmp(pstProName, "figure_size") != 0 &&
192 stricmp(pstProName, "axes_size") != 0 &&
193 stricmp(pstProName, "position") != 0 &&
194 stricmp(pstProName, "menubar_visible") != 0 &&
195 stricmp(pstProName, "toolbar_visible") != 0 &&
196 stricmp(pstProName, "infobar_visible") != 0)
198 freeAllocatedSingleString(pstProName);
202 //get address of value on stack
203 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
206 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
210 //check property value to compatibility
211 if (stricmp(pstProName, "dockable") == 0)
213 bDockable = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
216 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "dockable", "on", "off");
217 freeAllocatedSingleString(pstProName);
221 else if (stricmp(pstProName, "toolbar") == 0)
224 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
226 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
227 freeAllocatedSingleString(pstProName);
230 getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal);
232 if (stricmp(pstVal, "none") == 0)
236 else if (stricmp(pstVal, "figure") == 0)
242 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar", "none", "figure");
243 freeAllocatedSingleString(pstProName);
244 freeAllocatedSingleString(pstVal);
248 freeAllocatedSingleString(pstVal);
250 else if (stricmp(pstProName, "menubar") == 0)
253 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
255 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
256 freeAllocatedSingleString(pstProName);
260 getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal);
262 if (stricmp(pstVal, "none") == 0)
266 else if (stricmp(pstVal, "figure") == 0)
272 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar", "none", "figure");
273 freeAllocatedSingleString(pstProName);
274 freeAllocatedSingleString(pstVal);
278 freeAllocatedSingleString(pstVal);
280 else if (stricmp(pstProName, "default_axes") == 0)
282 bDefaultAxes = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
283 if (bDefaultAxes == -1)
285 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "default_axes", "on", "off");
286 freeAllocatedSingleString(pstProName);
290 else if (stricmp(pstProName, "visible") == 0)
292 bVisible = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
295 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "visible", "on", "off");
296 freeAllocatedSingleString(pstProName);
300 else if (stricmp(pstProName, "figure_size") == 0)
304 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
306 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
310 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &figureSize);
311 if (iRows * iCols != 2)
313 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "figure_size", 2);
317 else if (stricmp(pstProName, "axes_size") == 0)
321 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
323 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
327 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &axesSize);
328 if (iRows * iCols != 2)
330 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "axes_size", 2);
334 else if (stricmp(pstProName, "position") == 0)
339 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
341 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
345 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &pdbl);
346 if (iRows * iCols != 4)
348 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "position", 4);
353 axesSize = (pdbl + 2);
355 else if (stricmp(pstProName, "menubar_visible") == 0)
357 bMenuBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
360 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar_visible", "on", "off");
361 freeAllocatedSingleString(pstProName);
365 else if (stricmp(pstProName, "toolbar_visible") == 0)
367 bToolBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
370 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar_visible", "on", "off");
371 freeAllocatedSingleString(pstProName);
375 else if (stricmp(pstProName, "infobar_visible") == 0)
377 bInfoBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
380 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "infobar_visible", "on", "off");
381 freeAllocatedSingleString(pstProName);
388 iFig = createFigure(bDockable, iMenubarType, iToolbarType, bDefaultAxes, bVisible, figureSize, axesSize, position, bMenuBar, bToolBar, bInfoBar);
389 setGraphicObjectProperty(iFig, __GO_ID__, &iNewId, jni_int, 1);
390 iAxes = setDefaultProperties(iFig, bDefaultAxes, figureSize || axesSize ? FALSE : TRUE);
393 //set(iFig, iPos, iPos + 1)
394 for (i = iPos + 1 ; i <= iRhs ; i += 2)
396 int isMatrixOfString = 0;
397 int* piAddrProp = NULL;
398 char* pstProName = NULL;
399 int* piAddrData = NULL;
402 void* _pvData = NULL;
406 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
409 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
413 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
415 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
420 stricmp(pstProName, "dockable") == 0 ||
421 stricmp(pstProName, "toolbar") == 0 ||
422 stricmp(pstProName, "menubar") == 0 ||
423 stricmp(pstProName, "default_axes") == 0 ||
424 stricmp(pstProName, "visible") == 0 ||
425 stricmp(pstProName, "figure_size") == 0 ||
426 stricmp(pstProName, "axes_size") == 0 ||
427 stricmp(pstProName, "position") == 0 ||
428 stricmp(pstProName, "menubar_visible") == 0 ||
429 stricmp(pstProName, "toolbar_visible") == 0 ||
430 stricmp(pstProName, "infobar_visible") == 0))
432 // Already set creating new figure
433 // but let the set_ function fail if figure already exists
437 //get address of value on stack
438 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
441 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
445 getVarType(pvApiCtx, piAddrData, &iType);
447 if ((strcmp(pstProName, "user_data") == 0) || (stricmp(pstProName, "userdata") == 0))
449 /* in this case set_user_data_property
450 * directly uses the third position in the stack
451 * to get the variable which is to be set in
452 * the user_data property (any data type is allowed) S. Steer */
453 _pvData = (void*)piAddrData; /*position in the stack */
454 iRows = -1; /*unused */
455 iCols = -1; /*unused */
463 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, (double**)&_pvData);
466 getMatrixOfBoolean(pvApiCtx, piAddrData, &iRows, &iCols, (int**)&_pvData);
469 getMatrixOfHandle(pvApiCtx, piAddrData, &iRows, &iCols, (long long**)&_pvData);
472 if ( strcmp(pstProName, "tics_labels") != 0 && strcmp(pstProName, "auto_ticks") != 0 &&
473 strcmp(pstProName, "axes_visible") != 0 && strcmp(pstProName, "axes_reverse") != 0 &&
474 strcmp(pstProName, "text") != 0 && stricmp(pstProName, "string") != 0 &&
475 stricmp(pstProName, "tooltipstring") != 0) /* Added for uicontrols */
477 if (getAllocatedSingleString(pvApiCtx, piAddrData, (char**)&_pvData))
479 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 3);
482 iRows = (int)strlen((char*)_pvData);
487 isMatrixOfString = 1;
488 getAllocatedMatrixOfString(pvApiCtx, piAddrData, &iRows, &iCols, (char***)&_pvData);
493 getListItemNumber(pvApiCtx, piAddrData, &iRows);
494 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
497 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
502 callSetProperty(pvApiCtx, iFig, _pvData, iType, iRows, iCols, pstProName);
504 // If backgroundcolor is set :
505 // * add it to colormap => performed by callSetProperty
506 // * set background to index => performed by callSetProperty
507 // * copy value into axes background property
508 if (stricmp(pstProName, "backgroundcolor") == 0 && iAxes > 0)
511 int *piBackground = &iBackground;
513 getGraphicObjectProperty(iFig, __GO_BACKGROUND__, jni_int, (void **)&piBackground);
514 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, piBackground, jni_int, 1);
517 if (iType == sci_strings)
520 if (isMatrixOfString == 1)
522 freeAllocatedMatrixOfString(iRows, iCols, (char**)_pvData);
526 freeAllocatedSingleString((char*)_pvData);
531 //return new created fig
532 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
533 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
534 ReturnArguments(pvApiCtx);
537 /*--------------------------------------------------------------------------*/
538 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr)
540 if (isScalar(_pvCtx, _piAddr))
542 if (isDoubleType(_pvCtx, _piAddr))
545 getScalarDouble(_pvCtx, _piAddr, &dbl);
546 return ((int)dbl == 0 ? FALSE : TRUE);
548 else if (isBooleanType(_pvCtx, _piAddr))
551 getScalarBoolean(_pvCtx, _piAddr, &i);
552 return (i == 0 ? FALSE : TRUE);
554 else if (isStringType(_pvCtx, _piAddr))
558 getAllocatedSingleString(_pvCtx, _piAddr, &pst);
560 if (stricmp(pst, "on") == 0)
565 freeAllocatedSingleString(pst);
572 /*--------------------------------------------------------------------------*/
573 int setDefaultProperties(int _iFig, BOOL _bDefaultAxes, BOOL _axesSize)
580 int iAxesVisible = 0;
581 int* piAxesSize = NULL;
582 double pdblNewColor[COLOR_COMPONENT] = {0.8, 0.8, 0.8};
584 setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
586 iColorIndex = addColor(_iFig, pdblNewColor);
588 setGraphicObjectProperty(_iFig, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
591 iAxes = getOrCreateDefaultSubwin();
592 //set background in figure and axes to new ( or existting ) color
593 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
596 setGraphicObjectProperty(iAxes, __GO_FILLED__, &iFilled, jni_bool, 1);
598 //a.axes_visible = "off"
599 setGraphicObjectProperty(iAxes, __GO_X_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
600 setGraphicObjectProperty(iAxes, __GO_Y_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
601 setGraphicObjectProperty(iAxes, __GO_Z_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
607 getGraphicObjectProperty(getFigureModel(), __GO_AXES_SIZE__, jni_int_vector, (void **)&piAxesSize);
608 setGraphicObjectProperty(_iFig, __GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
611 //f.immediate_drawing = "on"
613 setGraphicObjectProperty(_iFig, __GO_IMMEDIATE_DRAWING__, &iDrawing, jni_bool, 1);
617 /*--------------------------------------------------------------------------*/