f0176d282d237fc55d2ec868b739a1a21ca77296
[scilab.git] / scilab / modules / gui / sci_gateway / c / sci_uicontrol.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007 - INRIA - Allan CORNET
4  * Copyright (C) 2007 - INRIA - Vincent COUVERT
5  * Copyright (C) 2010 - DIGITEO - Yann COLLETTE
6  * Copyright (C) 2011 - DIGITEO - Vincent COUVERT
7  *
8  * This file must be used under the terms of the CeCILL.
9  * This source file is licensed as described in the file COPYING, which
10  * you should have received as part of this distribution.  The terms
11  * are also available at
12  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13  *
14  */
15
16 #include "gw_gui.h"
17 /*--------------------------------------------------------------------------*/
18 #include "CreateUIControl.h"
19 #include "HandleManagement.h"
20 #include "MALLOC.h"             /* MALLOC */
21 #include "localization.h"
22 #include "stricmp.h"
23 #include "stack-c.h"
24 #include "SetPropertyStatus.h"
25 #include "SetHashTable.h"
26 #include "Scierror.h"
27 #include "FigureList.h"         /* getFigureFromIndex */
28 #include "Widget.h"             /* requestWidgetFocus */
29 #include "freeArrayOfString.h"
30 #include "setGraphicObjectProperty.h"
31 #include "getGraphicObjectProperty.h"
32 #include "graphicObjectProperties.h"
33 #include "CurrentFigure.h"
34 #include "BuildObjects.h"
35 #include "api_scilab.h"
36 /*--------------------------------------------------------------------------*/
37 #define NBPROPERTIES 28
38 #define MAXPROPERTYNAMELENGTH 20
39 /*--------------------------------------------------------------------------*/
40 int sci_uicontrol(char *fname, unsigned long fname_len)
41 {
42     int nbRow = 0, nbCol = 0, stkAdr = 0, k = 0;
43     char **stkAdrForStrings = NULL;
44
45     int setStatus = SET_PROPERTY_SUCCEED;
46
47     int NOT_FOUND = -1;
48
49     int inputIndex = 0, beginIndex = 0;
50
51     char *propertyName = NULL;
52     char *styleProperty = NULL;
53
54     char *pParentUID = NULL;
55     char *pUicontrol = NULL;
56
57     unsigned long GraphicHandle = 0;
58
59     int found = 0;              /* Does the property exists ? */
60
61     /* @TODO remove this crappy initialization */
62     /* DO NOT CHANGE ORDER !! */
63     char propertiesNames[NBPROPERTIES][MAXPROPERTYNAMELENGTH] =
64     {
65         "style", "parent", "backgroundcolor", "foregroundcolor", "string", "units", "fontweight", "min", "max", "tag", "position", "relief",
66         "horizontalalignment", "verticalalignment", "sliderstep", "fontname", "callback", "fontangle", "fontunits", "fontsize", "listboxtop", "user_data", "value", "userdata", "visible", "enable",
67         "callback_type", "tooltipstring"
68     };
69     int *propertiesValuesIndices = NULL;
70     int lw = 0;
71     char *propertyPart = NULL;
72
73     int iParentType = -1;
74     int *piParentType = &iParentType;
75     int iParentStyle = -1;
76     int *piParentStyle = &iParentStyle;
77     char const* pstCurrentFigure = NULL;
78
79     CheckLhs(0, 1);
80
81     if (Rhs == 0)
82     {
83         /* Create a pushbutton in current figure */
84
85         /* Create a new pushbutton */
86         GraphicHandle = getHandle(CreateUIControl(NULL));
87
88         /* Set current figure as parent */
89         pstCurrentFigure = getCurrentFigure();
90         if (pstCurrentFigure == NULL)
91         {
92             pstCurrentFigure = createNewFigureWithAxes();
93         }
94         setGraphicObjectRelationship(pstCurrentFigure, (char*)getObjectFromHandle(GraphicHandle));
95         pUicontrol = (char*)getObjectFromHandle(GraphicHandle);
96     }
97     else if (Rhs == 1)
98     {
99         /* Create a pushbutton in figure given as parameter */
100         /* Or give focus to the uicontrol given as parameter */
101
102         if (VarType(1) != sci_handles)
103         {
104             lw = 1 + Top - Rhs;
105             C2F(overload) (&lw, "uicontrol", 9);
106             return FALSE;
107         }
108         else                    /* Get parent ID */
109         {
110             GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
111
112             if (nbRow * nbCol != 1)
113             {
114                 Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
115                 return FALSE;
116             }
117             pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
118             if (pParentUID != NULL)
119             {
120                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
121                 if (iParentType == __GO_UICONTROL__)  /* Focus management */
122                 {
123                     GraphicHandle = (long) * hstk(stkAdr);
124                     requestFocus(pParentUID);
125                 }
126                 else if (iParentType == __GO_FIGURE__ || iParentType == __GO_UIMENU__)  /* PushButton creation */
127                 {
128                     /* Create a new pushbutton */
129                     GraphicHandle = getHandle(CreateUIControl(NULL));
130
131                     /* First parameter is the parent */
132                     setGraphicObjectRelationship(pParentUID, getObjectFromHandle(GraphicHandle));
133                     setStatus = callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol, (char *)propertiesNames[1]);
134                     if (setStatus == SET_PROPERTY_ERROR)
135                     {
136                         Scierror(999, _("%s: Could not set property '%s'.\n"), fname, propertyName);
137                         return FALSE;
138                     }
139                 }
140                 else
141                 {
142                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol",
143                              "Figure", "Uimenu");
144                     return FALSE;
145                 }
146             }
147             else
148             {
149                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s', '%s' or '%s' handle expected.\n"), fname, 1, "Uicontrol", "Figure",
150                          "Uimenu");
151                 return FALSE;
152             }
153             pUicontrol = (char*)getObjectFromHandle(GraphicHandle);
154         }
155     }
156     else
157     {
158         if ((VarType(1) != sci_handles) && (VarType(1) != sci_strings))
159         {
160             lw = 1 + Top - Rhs;
161             C2F(overload) (&lw, "uicontrol", 9);
162             return FALSE;
163         }
164
165         /* Allocate memory to store the position of properties in uicontrol call */
166         if ((propertiesValuesIndices = (int *)MALLOC(sizeof(int) * NBPROPERTIES)) == NULL)
167         {
168             Scierror(999, _("%s: No more memory.\n"), fname);
169             return FALSE;
170         }
171
172         /* Init all positions to NOT_FOUND */
173         for (inputIndex = 0; inputIndex < NBPROPERTIES; inputIndex++)
174         {
175             propertiesValuesIndices[inputIndex] = NOT_FOUND;    /* Property initialized as not found */
176         }
177
178         /**
179          * Odd number of input arguments
180          * First input is the parent ID
181          * All event inputs are property names
182          * All odd (except first) inputs are property values
183          */
184         if (Rhs % 2 == 1)
185         {
186             if (VarType(1) != sci_handles)
187             {
188                 if (VarType(1) == sci_matrix)
189                 {
190                     GetRhsVar(1, MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
191                     if (nbRow * nbCol == 1)
192                     {
193                         pParentUID = (char*)getFigureFromIndex((int)(*stk(stkAdr)));
194
195                         if (pParentUID == NULL)
196                         {
197                             Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
198                                      "Frame uicontrol");
199                             return FALSE;
200                         }
201                         getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
202                         if (iParentType != __GO_FIGURE__)
203                         {
204                             getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_int, (void **)&piParentStyle);
205                             if (iParentType != __GO_UICONTROL__ || iParentStyle != __GO_UI_FRAME__)
206                             {
207                                 Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
208                                          "Frame uicontrol");
209                                 return FALSE;
210                             }
211                         }
212                         /* First parameter is the parent */
213                         propertiesValuesIndices[1] = 1;
214                     }
215                     else
216                     {
217                         Scierror(999, _("%s: Wrong size for input argument #%d: A graphic handle expected.\n"), fname, 1);
218                         return FALSE;
219                     }
220                 }
221                 else
222                 {
223                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
224                              "Frame uicontrol");
225                     return FALSE;
226                 }
227             }
228             else                /* Get parent ID */
229             {
230                 GetRhsVar(1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
231
232                 if (nbRow * nbCol != 1)
233                 {
234                     Scierror(999, _("%s: Wrong size for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
235                              "Frame uicontrol");
236                     return FALSE;
237                 }
238                 pParentUID = (char*)getObjectFromHandle((long) * hstk(stkAdr));
239                 if (pParentUID == NULL)
240                 {
241                     Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
242                              "Frame uicontrol");
243                     return FALSE;
244                 }
245                 getGraphicObjectProperty(pParentUID, __GO_TYPE__, jni_int, (void **)&piParentType);
246                 if (iParentType != __GO_FIGURE__)
247                 {
248                     getGraphicObjectProperty(pParentUID, __GO_STYLE__, jni_int, (void **)&piParentStyle);
249                     if (iParentType != __GO_UICONTROL__ || iParentStyle != __GO_UI_FRAME__)
250                     {
251                         Scierror(999, _("%s: Wrong type for input argument #%d: A '%s' or a '%s' handle expected.\n"), fname, 1, "Figure",
252                                  "Frame uicontrol");
253                         return FALSE;
254                     }
255                 }
256                 /* First parameter is the parent */
257                 propertiesValuesIndices[1] = 1;
258             }
259
260             // First input parameter which is a property name
261             beginIndex = 2;
262         }
263         /**
264          * Even number of input arguments
265          * All odd inputs are property names
266          * All even inputs are property values
267          */
268         else
269         {
270             // First input parameter which is a property name
271             beginIndex = 1;
272         }
273
274         /* Get all properties positions */
275         for (inputIndex = beginIndex; inputIndex < Rhs; inputIndex = inputIndex + 2)
276         {
277             /* Read property name */
278             if (VarType(inputIndex) != sci_strings)
279             {
280                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, inputIndex);
281                 return FALSE;
282             }
283             else
284             {
285                 GetRhsVar(inputIndex, STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
286                 propertyName = cstk(stkAdr);
287
288                 /* Bug 3031 */
289                 /* We only want to compare propertyName along its length */
290                 /* 'posi' must be matched to 'position' */
291                 propertyPart = (char *)MALLOC(sizeof(char) * (MAXPROPERTYNAMELENGTH + 1));
292                 if (propertyPart == NULL)
293                 {
294                     Scierror(999, _("%s: No more memory.\n"), fname);
295                     return FALSE;
296                 }
297
298                 found = 0;
299                 for (k = 0; k < NBPROPERTIES; k++)
300                 {
301                     if (strlen(propertyName) <= MAXPROPERTYNAMELENGTH)
302                     {
303                         strncpy(propertyPart, propertiesNames[k], strlen(propertyName));
304                         propertyPart[strlen(propertyName)] = '\0';
305
306                         if (stricmp(propertyName, propertyPart) == 0)
307                         {
308                             propertiesValuesIndices[k] = inputIndex + 1;    /* Position of value for property */
309                             found = 1;
310                             break;
311                         }
312                     }
313                 }
314
315                 FREE(propertyPart);
316
317                 if (found == 0)
318                 {
319                     Scierror(999, _("%s: Unknown property: %s for '%s' handles.\n"), fname, propertyName, "Uicontrol");
320                     return FALSE;
321                 }
322             }
323         }
324
325         if (propertiesValuesIndices[0] != NOT_FOUND)    /* Style found */
326         {
327             if (VarType(propertiesValuesIndices[0]) == sci_strings)
328             {
329                 GetRhsVar(propertiesValuesIndices[0], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
330                 styleProperty = cstk(stkAdr);
331             }
332             else
333             {
334                 Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), fname, propertiesValuesIndices[0]);
335                 return FALSE;
336             }
337         }
338
339         /* Create a new uicontrol */
340         pUicontrol = CreateUIControl(styleProperty);
341         if (pUicontrol == NULL) /* Error in creation */
342         {
343             Scierror(999, _("%s: Could not create 'Uicontrol' handle.\n"), fname);
344             return FALSE;
345         }
346         GraphicHandle = getHandle(pUicontrol);
347
348         /* If no parent given then the current figure is the parent */
349         if (propertiesValuesIndices[1] == NOT_FOUND)
350         {
351             char *graphicObjectUID = (char*)getObjectFromHandle(GraphicHandle);
352
353             /* Set the parent */
354             pstCurrentFigure = (char*)getCurrentFigure();
355
356             if (pstCurrentFigure == NULL)
357             {
358                 pstCurrentFigure = createNewFigureWithAxes();
359             }
360             setGraphicObjectRelationship(pstCurrentFigure, graphicObjectUID);
361         }
362
363         /* Read and set all properties */
364         for (inputIndex = 1; inputIndex < NBPROPERTIES; inputIndex++)   /* Style has already been set */
365         {
366             if (propertiesValuesIndices[inputIndex] != NOT_FOUND)
367             {
368                 if (inputIndex == 21 || inputIndex == 23)   /* User data settings */
369                 {
370                     stkAdr = propertiesValuesIndices[inputIndex];   /* Special management */
371                     nbRow = -1;
372                     nbCol = -1;
373                     setStatus =
374                         callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, VarType(propertiesValuesIndices[inputIndex]), nbRow, nbCol,
375                                         (char *)propertiesNames[inputIndex]);
376                 }
377                 else            /* All other properties */
378                 {
379                     /* Read property value */
380                     switch (VarType(propertiesValuesIndices[inputIndex]))
381                     {
382                         case sci_matrix:
383                             GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_DOUBLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
384                             setStatus =
385                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_matrix, nbRow, nbCol,
386                                                 (char *)propertiesNames[inputIndex]);
387                             break;
388                         case sci_strings:
389                             /* Index for String & TooltipString properties: Can be more than one character string */
390                             if ((inputIndex == 4) || (inputIndex == 27))
391                             {
392                                 GetRhsVar(propertiesValuesIndices[inputIndex], MATRIX_OF_STRING_DATATYPE, &nbRow, &nbCol, &stkAdrForStrings);
393                                 setStatus =
394                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), (size_t) stkAdrForStrings, sci_strings, nbRow, nbCol,
395                                                     (char *)propertiesNames[inputIndex]);
396                                 freeArrayOfString(stkAdrForStrings, nbRow * nbCol);
397                             }
398                             else
399                             {
400                                 GetRhsVar(propertiesValuesIndices[inputIndex], STRING_DATATYPE, &nbRow, &nbCol, &stkAdr);
401                                 setStatus =
402                                     callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_strings, nbRow, nbCol,
403                                                     (char *)propertiesNames[inputIndex]);
404                             }
405                             break;
406                         case sci_handles:
407                             GetRhsVar(propertiesValuesIndices[inputIndex], GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
408                             setStatus =
409                                 callSetProperty(pvApiCtx, (char*)getObjectFromHandle(GraphicHandle), stkAdr, sci_handles, nbRow, nbCol,
410                                                 (char *)propertiesNames[inputIndex]);
411                             break;
412                         default:
413                             setStatus = SET_PROPERTY_ERROR;
414                             break;
415                     }
416                 }
417                 if (setStatus == SET_PROPERTY_ERROR)
418                 {
419                     Scierror(999, _("%s: Could not set property '%s'.\n"), fname, (char *)propertiesNames[inputIndex]);
420                     return FALSE;
421                 }
422             }
423         }
424     }
425
426     if ((Rhs < 2) || (propertiesValuesIndices[24] == NOT_FOUND))    /* Visible property not set */
427     {
428         /* Force the uicontrol to be visible because is invisible by default in the model (See bug #10346) */
429         int b = (int)TRUE;
430         setGraphicObjectProperty(pUicontrol, __GO_VISIBLE__, &b, jni_bool, 1);
431     }
432
433     if ((Rhs < 2) || (propertiesValuesIndices[14] == NOT_FOUND))    /* SliderStep property not set */
434     {
435         /* Set SliderStep property to [1/100*(Max-Min) 1/10*(Max-Min)] */
436         double maxValue = 0;
437         double* pdblMaxValue = &maxValue;
438         double minValue = 0;
439         double* pdblMinValue = &minValue;
440         double pdblStep[2];
441
442         getGraphicObjectProperty(pUicontrol, __GO_UI_MIN__, jni_double, (void**) &pdblMinValue);
443         getGraphicObjectProperty(pUicontrol, __GO_UI_MAX__, jni_double, (void**) &pdblMaxValue);
444
445         pdblStep[0] = 0.01 * (maxValue - minValue);
446         pdblStep[1] = 0.1 * (maxValue - minValue);
447
448         setGraphicObjectProperty(pUicontrol, __GO_UI_SLIDERSTEP__, pdblStep, jni_double_vector, 2);
449     }
450
451     FREE(propertiesValuesIndices);
452
453     /* Create return variable */
454     nbRow = 1;
455     nbCol = 1;
456     CreateVar(Rhs + 1, GRAPHICAL_HANDLE_DATATYPE, &nbRow, &nbCol, &stkAdr);
457     *hstk(stkAdr) = GraphicHandle;
458
459     LhsVar(1) = Rhs + 1;
460
461     PutLhsVar();
462
463     return TRUE;
464 }
465
466 /*--------------------------------------------------------------------------*/