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 * Copyright (C) 2012 - 2016 - Scilab Enterprises
8 * This file is hereby licensed under the terms of the GNU GPL v2.0,
9 * pursuant to article 5.3.4 of the CeCILL v.2.1.
10 * This file was originally licensed under the terms of the CeCILL v2.1,
11 * and continues to be available under such terms.
12 * For more information, see the COPYING file which you should have received
13 * along with this program.
19 #include "sci_malloc.h"
20 #include "api_scilab.h"
21 #include "localization.h"
23 #include "createGraphicObject.h"
24 #include "BuildObjects.h"
25 #include "setGraphicObjectProperty.h"
26 #include "getGraphicObjectProperty.h"
27 #include "graphicObjectProperties.h"
28 #include "CurrentFigure.h"
29 #include "CurrentSubwin.h"
30 #include "FigureList.h"
31 #include "FigureModel.h"
32 #include "HandleManagement.h"
33 #include "SetHashTable.h"
34 #include "os_string.h"
38 /*--------------------------------------------------------------------------*/
39 int setDefaultProperties(int _iFig, BOOL bDefaultAxes);
40 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr);
41 void initBar(int iFig, BOOL menubar, BOOL toolbar, BOOL infobar);
42 /*--------------------------------------------------------------------------*/
43 int sci_figure(char * fname, void* pvApiCtx)
49 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;
67 int iMenubarType = 1; // Create a 'figure' menubar by default
68 int iToolbarType = 1; // Create a 'figure' toolbar by default
72 //figure(num) -> scf(num)
75 //figure(x, "...", ...)
78 if (iRhs == 0) // Auto ID
80 iId = getValidDefaultFigureId();
81 iFig = createNewFigureWithAxes();
82 setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
83 iAxes = setDefaultProperties(iFig, TRUE);
84 initBar(iFig, bMenuBar, bToolBar, bInfoBar);
85 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
86 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
87 ReturnArguments(pvApiCtx);
94 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
97 printError(&sciErr, 0);
98 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
102 sciErr = getVarType(pvApiCtx, piAddr, &iType);
103 if (sciErr.iErr || iType != sci_matrix)
105 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
109 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
111 Scierror(999, _("%s: No more memory.\n"), fname);
115 iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
117 //get current fig from id
118 iFig = getFigureFromIndex(iId);
119 if (iFig == 0) // Figure does not exist, create a new one
121 iFig = createNewFigureWithAxes();
122 setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
123 iAxes = setDefaultProperties(iFig, TRUE);
126 initBar(iFig, bMenuBar, bToolBar, bInfoBar);
127 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
128 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
129 ReturnArguments(pvApiCtx);
133 // Prepare property analysis
136 //get highest value of winsid to create the new windows @ + 1
137 iId = getValidDefaultFigureId();
144 sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
147 printError(&sciErr, 0);
148 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, 1);
152 if (isVarMatrixType(pvApiCtx, piAddr) == 0)
154 Scierror(999, _("%s: Wrong type for input argument #%d: An integer value expected.\n"), fname, 1);
158 if (getScalarDouble(pvApiCtx, piAddr, &dblId))
160 Scierror(999, _("%s: No more memory.\n"), fname);
164 iId = (int)(dblId + 0.5); //avoid 1.999 -> 1
165 //get current fig from id
166 iFig = getFigureFromIndex(iId);
167 if (iFig != 0) // Figure already exists
175 int* piAddrProp = NULL;
176 char* pstProName = NULL;
177 int* piAddrData = NULL;
178 for (i = iPos + 1 ; i <= iRhs ; i += 2)
181 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
184 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
188 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
190 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
194 if (stricmp(pstProName, "dockable") != 0 &&
195 stricmp(pstProName, "toolbar") != 0 &&
196 stricmp(pstProName, "menubar") != 0 &&
197 stricmp(pstProName, "default_axes") != 0 &&
198 stricmp(pstProName, "visible") != 0 &&
199 stricmp(pstProName, "figure_size") != 0 &&
200 stricmp(pstProName, "axes_size") != 0 &&
201 stricmp(pstProName, "position") != 0 &&
202 stricmp(pstProName, "menubar_visible") != 0 &&
203 stricmp(pstProName, "toolbar_visible") != 0 &&
204 stricmp(pstProName, "resize") != 0 &&
205 stricmp(pstProName, "infobar_visible") != 0)
207 freeAllocatedSingleString(pstProName);
211 //get address of value on stack
212 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
215 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
216 freeAllocatedSingleString(pstProName);
220 //check property value to compatibility
221 if (stricmp(pstProName, "dockable") == 0)
223 bDockable = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
226 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "dockable", "on", "off");
227 freeAllocatedSingleString(pstProName);
231 else if (stricmp(pstProName, "toolbar") == 0)
234 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
236 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
237 freeAllocatedSingleString(pstProName);
241 if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
243 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
244 freeAllocatedSingleString(pstProName);
248 if (stricmp(pstVal, "none") == 0)
252 else if (stricmp(pstVal, "figure") == 0)
258 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar", "none", "figure");
259 freeAllocatedSingleString(pstProName);
260 freeAllocatedSingleString(pstVal);
264 freeAllocatedSingleString(pstVal);
266 else if (stricmp(pstProName, "menubar") == 0)
269 if (isStringType(pvApiCtx, piAddrData) == FALSE || isScalar(pvApiCtx, piAddrData) == FALSE)
271 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
272 freeAllocatedSingleString(pstProName);
276 if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
278 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
279 freeAllocatedSingleString(pstProName);
283 if (stricmp(pstVal, "none") == 0)
287 else if (stricmp(pstVal, "figure") == 0)
293 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar", "none", "figure");
294 freeAllocatedSingleString(pstProName);
295 freeAllocatedSingleString(pstVal);
299 freeAllocatedSingleString(pstVal);
301 else if (stricmp(pstProName, "default_axes") == 0)
303 bDefaultAxes = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
304 if (bDefaultAxes == -1)
306 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "default_axes", "on", "off");
307 freeAllocatedSingleString(pstProName);
311 else if (stricmp(pstProName, "visible") == 0)
313 bVisible = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
316 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "visible", "on", "off");
317 freeAllocatedSingleString(pstProName);
321 else if (stricmp(pstProName, "figure_size") == 0)
325 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
327 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
328 freeAllocatedSingleString(pstProName);
332 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &figureSize);
333 if (iRows * iCols != 2)
335 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "figure_size", 2);
336 freeAllocatedSingleString(pstProName);
340 else if (stricmp(pstProName, "axes_size") == 0)
344 if (isDoubleType(pvApiCtx, piAddrData) == FALSE)
346 Scierror(999, _("%s: Wrong type for input argument #%d: A double vector expected.\n"), fname, i + 1);
347 freeAllocatedSingleString(pstProName);
351 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &axesSize);
352 if (iRows * iCols != 2)
354 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "axes_size", 2);
355 freeAllocatedSingleString(pstProName);
359 else if (stricmp(pstProName, "position") == 0)
364 if (isDoubleType(pvApiCtx, piAddrData))
366 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, &pdbl);
367 if (iRows * iCols != 4)
369 Scierror(999, _("Wrong size for '%s' property: %d elements expected.\n"), "position", 4);
370 freeAllocatedSingleString(pstProName);
375 axesSize = (pdbl + 2);
377 else if (isStringType(pvApiCtx, piAddrData) && isScalar(pvApiCtx, piAddrData))
382 if (getAllocatedSingleString(pvApiCtx, piAddrData, &pstVal))
384 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i + 1);
385 freeAllocatedSingleString(pstProName);
389 iVal = sscanf(pstVal, "%lf|%lf|%lf|%lf", &val[0], &val[1], &val[2], &val[3]);
390 freeAllocatedSingleString(pstVal);
393 Scierror(999, _("Wrong value for '%s' property: string or 1 x %d real row vector expected.\n"), "position", 4);
394 freeAllocatedSingleString(pstProName);
399 axesSize = (val + 2);
403 Scierror(999, _("Wrong value for '%s' property: string or 1 x %d real row vector expected.\n"), "position", 4);
404 freeAllocatedSingleString(pstProName);
408 else if (stricmp(pstProName, "resize") == 0)
410 bResize = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
413 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "resize", "on", "off");
414 freeAllocatedSingleString(pstProName);
418 else if (stricmp(pstProName, "menubar_visible") == 0)
420 bMenuBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
423 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "menubar_visible", "on", "off");
424 freeAllocatedSingleString(pstProName);
428 else if (stricmp(pstProName, "toolbar_visible") == 0)
430 bToolBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
433 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "toolbar_visible", "on", "off");
434 freeAllocatedSingleString(pstProName);
438 else if (stricmp(pstProName, "infobar_visible") == 0)
440 bInfoBar = getStackArgumentAsBoolean(pvApiCtx, piAddrData);
443 Scierror(999, _("Wrong value for '%s' property: '%s' or '%s' expected."), "infobar_visible", "on", "off");
444 freeAllocatedSingleString(pstProName);
448 freeAllocatedSingleString(pstProName);
451 iFig = createFigure(bDockable, iMenubarType, iToolbarType, bDefaultAxes, bVisible);
452 setGraphicObjectProperty(iFig, __GO_ID__, &iId, jni_int, 1);
453 iAxes = setDefaultProperties(iFig, bDefaultAxes);
456 //set(iFig, iPos, iPos + 1)
457 for (i = iPos + 1 ; i <= iRhs ; i += 2)
459 int isMatrixOfString = 0;
460 int* piAddrProp = NULL;
461 char* pstProName = NULL;
462 int* piAddrData = NULL;
465 void* _pvData = NULL;
469 sciErr = getVarAddressFromPosition(pvApiCtx, i, &piAddrProp);
472 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i);
476 if (getAllocatedSingleString(pvApiCtx, piAddrProp, &pstProName))
478 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, i);
483 stricmp(pstProName, "dockable") == 0 ||
484 stricmp(pstProName, "toolbar") == 0 ||
485 stricmp(pstProName, "menubar") == 0 ||
486 stricmp(pstProName, "default_axes") == 0 ||
487 stricmp(pstProName, "visible") == 0 ||
488 stricmp(pstProName, "figure_size") == 0 ||
489 stricmp(pstProName, "axes_size") == 0 ||
490 stricmp(pstProName, "position") == 0 ||
491 stricmp(pstProName, "resize") == 0 ||
492 stricmp(pstProName, "menubar_visible") == 0 ||
493 stricmp(pstProName, "toolbar_visible") == 0 ||
494 stricmp(pstProName, "infobar_visible") == 0))
496 // Already set creating new figure
497 // but let the set_ function fail if figure already exists
498 freeAllocatedSingleString(pstProName);
502 //get address of value on stack
503 sciErr = getVarAddressFromPosition(pvApiCtx, i + 1, &piAddrData);
506 Scierror(999, _("%s: Can not read input argument #%d.\n"), fname, i + 1);
507 freeAllocatedSingleString(pstProName);
511 getVarType(pvApiCtx, piAddrData, &iType);
513 if ((strcmp(pstProName, "user_data") == 0) || (stricmp(pstProName, "userdata") == 0))
515 /* in this case set_user_data_property
516 * directly uses the third position in the stack
517 * to get the variable which is to be set in
518 * the user_data property (any data type is allowed) S. Steer */
519 _pvData = (void*)piAddrData; /*position in the stack */
520 iRows = -1; /*unused */
521 iCols = -1; /*unused */
529 getMatrixOfDouble(pvApiCtx, piAddrData, &iRows, &iCols, (double**)&_pvData);
532 getMatrixOfBoolean(pvApiCtx, piAddrData, &iRows, &iCols, (int**)&_pvData);
535 getMatrixOfHandle(pvApiCtx, piAddrData, &iRows, &iCols, (long long**)&_pvData);
538 if ( strcmp(pstProName, "tics_labels") != 0 && strcmp(pstProName, "auto_ticks") != 0 &&
539 strcmp(pstProName, "axes_visible") != 0 && strcmp(pstProName, "axes_reverse") != 0 &&
540 strcmp(pstProName, "text") != 0 && stricmp(pstProName, "string") != 0 &&
541 stricmp(pstProName, "tooltipstring") != 0) /* Added for uicontrols */
543 if (getAllocatedSingleString(pvApiCtx, piAddrData, (char**)&_pvData))
545 Scierror(999, _("%s: Wrong size for input argument #%d: A single string expected.\n"), fname, 3);
546 freeAllocatedSingleString(pstProName);
549 iRows = (int)strlen((char*)_pvData);
554 isMatrixOfString = 1;
555 if (getAllocatedMatrixOfString(pvApiCtx, piAddrData, &iRows, &iCols, (char***)&_pvData))
557 Scierror(999, _("%s: Wrong type for argument #%d: string expected.\n"), fname, 3);
558 freeAllocatedSingleString(pstProName);
565 getListItemNumber(pvApiCtx, piAddrData, &iRows);
566 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
569 _pvData = (void*)piAddrData; /* In this case l3 is the list position in stack */
574 callSetProperty(pvApiCtx, iFig, _pvData, iType, iRows, iCols, pstProName);
576 // If backgroundcolor is set :
577 // * add it to colormap => performed by callSetProperty
578 // * set background to index => performed by callSetProperty
579 // * copy value into axes background property
580 if (stricmp(pstProName, "backgroundcolor") == 0 && iAxes > 0)
583 int *piBackground = &iBackground;
585 getGraphicObjectProperty(iFig, __GO_BACKGROUND__, jni_int, (void **)&piBackground);
586 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, piBackground, jni_int, 1);
589 freeAllocatedSingleString(pstProName);
590 if (iType == sci_strings)
593 if (isMatrixOfString == 1)
595 freeAllocatedMatrixOfString(iRows, iCols, (char**)_pvData);
599 freeAllocatedSingleString((char*)_pvData);
607 pos[0] = (int)position[0];
608 pos[1] = (int)position[1];
609 setGraphicObjectProperty(iFig, __GO_POSITION__, pos, jni_int_vector, 2);
616 axes[0] = (int)axesSize[0];
617 axes[1] = (int)axesSize[1];
618 setGraphicObjectProperty(iFig, __GO_AXES_SIZE__, axes, jni_int_vector, 2);
620 else //no size, use default axes_size
622 int* piAxesSize = NULL;
623 getGraphicObjectProperty(getFigureModel(), __GO_AXES_SIZE__, jni_int_vector, (void **)&piAxesSize);
624 setGraphicObjectProperty(iFig, __GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
625 releaseGraphicObjectProperty(__GO_AXES_SIZE__, piAxesSize, jni_int_vector, 2);
628 initBar(iFig, bMenuBar, bToolBar, bInfoBar);
630 if (axesSize == NULL && figureSize) //figure_size
633 figure[0] = (int)figureSize[0];
634 figure[1] = (int)figureSize[1];
635 setGraphicObjectProperty(iFig, __GO_SIZE__, figure, jni_int_vector, 2);
639 setGraphicObjectProperty(iFig, __GO_RESIZE__, (void*)&bResize, jni_bool, 1);
641 //return new created fig
642 createScalarHandle(pvApiCtx, iRhs + 1, getHandle(iFig));
643 AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
644 ReturnArguments(pvApiCtx);
647 /*--------------------------------------------------------------------------*/
648 int getStackArgumentAsBoolean(void* _pvCtx, int* _piAddr)
650 if (isScalar(_pvCtx, _piAddr))
652 if (isDoubleType(_pvCtx, _piAddr))
655 getScalarDouble(_pvCtx, _piAddr, &dbl);
656 return ((int)dbl == 0 ? FALSE : TRUE);
658 else if (isBooleanType(_pvCtx, _piAddr))
661 getScalarBoolean(_pvCtx, _piAddr, &i);
662 return (i == 0 ? FALSE : TRUE);
664 else if (isStringType(_pvCtx, _piAddr))
668 if (getAllocatedSingleString(_pvCtx, _piAddr, &pst))
673 if (stricmp(pst, "on") == 0)
678 freeAllocatedSingleString(pst);
685 /*--------------------------------------------------------------------------*/
686 int setDefaultProperties(int _iFig, BOOL _bDefaultAxes)
693 int iAxesVisible = 0;
694 int* piAxesSize = NULL;
695 double pdblNewColor[COLOR_COMPONENT] = {0.8, 0.8, 0.8};
697 iColorIndex = addColor(_iFig, pdblNewColor);
699 setGraphicObjectProperty(_iFig, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
702 iAxes = getOrCreateDefaultSubwin();
703 //set background in figure and axes to new ( or existting ) color
704 setGraphicObjectProperty(iAxes, __GO_BACKGROUND__, &iColorIndex, jni_int, 1);
707 setGraphicObjectProperty(iAxes, __GO_FILLED__, &iFilled, jni_bool, 1);
709 //a.axes_visible = "off"
710 setGraphicObjectProperty(iAxes, __GO_X_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
711 setGraphicObjectProperty(iAxes, __GO_Y_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
712 setGraphicObjectProperty(iAxes, __GO_Z_AXIS_VISIBLE__, &iAxesVisible, jni_bool, 1);
717 /*--------------------------------------------------------------------------*/
718 void initBar(int iFig, BOOL menubar, BOOL toolbar, BOOL infobar)
720 BOOL notmenubar = !menubar;
721 BOOL nottoolbar = !toolbar;
722 BOOL notinfobar = !infobar;
724 setGraphicObjectProperty(iFig, __GO_MENUBAR_VISIBLE__, (void*)¬menubar, jni_bool, 1);
725 setGraphicObjectProperty(iFig, __GO_TOOLBAR_VISIBLE__, (void*)¬toolbar, jni_bool, 1);
726 setGraphicObjectProperty(iFig, __GO_INFOBAR_VISIBLE__, (void*)¬infobar, jni_bool, 1);
728 //set menubar, infobar, toolbar visibility
729 setGraphicObjectProperty(iFig, __GO_MENUBAR_VISIBLE__, (void*)&menubar, jni_bool, 1);
730 setGraphicObjectProperty(iFig, __GO_TOOLBAR_VISIBLE__, (void*)&toolbar, jni_bool, 1);
731 setGraphicObjectProperty(iFig, __GO_INFOBAR_VISIBLE__, (void*)&infobar, jni_bool, 1);
734 /*--------------------------------------------------------------------------*/