Search code examples
stringvectorstructscilabuicontrol

Scilab: size of elements of figure.user_data cannot be changed


the version of Scilab is 5.5.1 . I've met a problem with the user_data property of figure handle:

I've defined the user_data as a struct (see MWE at the bottom)

But when i try to store a variable to figure.user_data field, if the vector size has changed, an error is raised (with vector of any type)

Doing it ouside of the user_data works perfectly, so a solution could be to erase the figure.user_data value, then define a new struct with my value, then define user_data at this new value.

Yet, this does not solve the initial problem.

Below, an MWE with the figure.user_data vector size problem, and the error raised

//
clc
clear
xdel(winsid())

strct = struct('int',0,'str','str','vstr',['a';'b'])
old_strct = strct

// changing vectors size in a struct works
strct.int = [0,1,2]   // ok
strct.str = ['a';'b'] // ok
strct.vstr =['b','c'] // ok
strct.vstr =['a','b','c'] // ok

f=figure('visible','off')
f.user_data = old_strct // ok
// but changing it inside the user_data property doesn't
f.user_data.int = strct.int // see error below
f.user_data.str = strct.str // error 
f.user_data.vstr = ['b';'c'] // ok as size is the same
f.user_data.vstr =['a','b','c'] // error

// we can still erase all the struct with a new one, though
f.user_data = strct //ok but not efficient to delete all the field to change one

  !--error 15 
Sub-matrix not well defined.
at line      45 of function generic_i_h called by :  
at line       2 of function %s_i_h called by :  
f.user_data.int = strct.int // error
at line      21 of exec file called by :    
exec('/net/jabba/home0/pp607946/brouillon.sce', -1)

Solution

  • That seems to be a bug in Scilab 5.5.1. I tried reproducing it using Scilab 6.0.0 on Windows 7 and it worked just fine.

    When I used older versions (5.3.3), I found that sometimes setting a figure's property could be tricky. What always worked, however, was using the set() function instead of the dot operator you're using. You will need to set all fields of user_data in one go, though, as you've mentioned yourself. To set a single field, use a temporary variable or reuse an old variable.

    //all new fields
    set(f,'user_data',strct);
    
    //one field at a time
    old_strct.int = strct.int; set(f,'user_data',old_strct);
    old_strct.str = strct.str; set(f,'user_data',old_strct);
    old_strct.vstr = strct.vstr; set(f,'user_data',old_strct);