Graphics: fix handle.tag / gca() / clf() crash
[scilab.git] / scilab / modules / graphics / macros / clf.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA
3 // Copyright (C) 2017 - Samuel GOUGEON
4 //
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function clf(varargin)
15
16     nbArg = size(varargin);
17
18     if nbArg==0 then
19         h = gcf()
20         job = "clear"
21     elseif nbArg==1 then
22         if type(varargin(1))==1 then     // win num given
23             num = varargin(1)
24             h = [];
25             for k = 1:size(num,"*")
26                 h = [h ; get_figure_handle(num(k))];
27             end
28             job = "clear"
29         elseif type(varargin(1))==9 then // handle given
30             h = varargin(1);
31             job = "clear"
32         elseif type(varargin(1))==10 then // job given
33             h = gcf()
34             job = varargin(1)
35         end
36     elseif nbArg==2 then
37         if type(varargin(1))==1 then     // win num given
38             num = varargin(1)
39             h = [];
40             for k = 1:size(num,"*")
41                 h = [h ; get_figure_handle(num(k))];
42             end
43         elseif type(varargin(1))==9 then // handle given
44             h = varargin(1);
45         end
46         job = varargin(2);
47     else
48         msg = _("%s: Wrong number of input argument(s): %d to %d expected.")
49         error(msprintf(msg, "clf", 0, 2))
50     end
51
52     if and(job<>["clear","reset"]) then
53         msg = _("%s: Wrong value for input argument #%d: ''clear'' or ''reset'' expected.")
54         error(msprintf(msg, "clf", nbArg))
55     end
56
57     nbHandles = size(h,"*");
58     if nbHandles == 0 then
59         return
60     end
61
62     // check that all the handles are figures
63     for k = 1:nbHandles
64         curFig = h(k);
65         if curFig.type <> "Figure" & (curFig.type <> "uicontrol" | curFig.style <> "frame")
66             msg = _("%s: Wrong type for input argument #%d: A vector of ''Figure'' or ''Frame'' handle expected.")
67             error(msprintf(msg, "clf", 1))
68         end
69     end
70
71     // delete childrens
72     for k = 1:nbHandles
73         curFig = h(k)
74         if curFig.type == "uicontrol" then
75             haveAxes = %F;
76             for kChild = 1:size(curFig.children, "*")
77                 if curFig.children(kChild).type=="Axes" then
78                     haveAxes = %T;
79                     break
80                 end
81             end
82             delete(curFig.children);
83             if haveAxes then
84                 newaxes(curFig);
85             end
86         else
87             // Forces drawlater
88             immediateMode = curFig.immediate_drawing;
89             curFig.immediate_drawing = "off";
90             delete(curFig.children);
91             curFig.info_message = "";            // Clears the infobar message
92             curFig.event_handler_enable = "off"; // Disables the event handler
93             // Restores the drawlater entry status:
94             curFig.immediate_drawing = immediateMode;
95         end
96     end
97
98     // reset figures to default values if needed
99     if (job == "reset") then
100         defaultFig = gdf();
101         // This literal list should be replaced with a getproperties(gdf())
102         // when such a function will be available:
103         allprops = [
104         "children"
105         "figure_position"
106         "figure_size"
107         "axes_size"
108         "auto_resize"
109         "viewport"
110         "figure_name"
111         "figure_id"
112         "info_message"
113         "color_map"
114         "pixel_drawing_mode"
115         "anti_aliasing"
116         "immediate_drawing"
117         "background"
118         "visible"
119         "rotation_style"
120         "event_handler"
121         "event_handler_enable"
122         "user_data"
123         "resizefcn"
124         "closerequestfcn"
125         "resize"
126         "toolbar"
127         "toolbar_visible"
128         "menubar"
129         "menubar_visible"
130         "infobar_visible"
131         "dockable"
132         "layout"
133         "layout_options"
134         "default_axes"
135         "icon"
136         "tag"
137         ];
138         excluded0 = ["children" "dockable" "menubar" "toolbar" "immediate_drawing"]
139         excluded0 = [excluded0 "layout" "layout_options"] // http://bugzilla.scilab.org/14955
140         for k = 1: nbHandles
141             curFig = h(k);
142             if curFig.type == "uicontrol" then
143                 continue;
144             end
145
146             // Forces drawlater mode
147             curFig.immediate_drawing = "off";
148
149             // properties to set
150             excluded = excluded0
151             if isDocked(curFig)            // http://bugzilla.scilab.org/11476
152                 excluded = [excluded "figure_position" "figure_size" "axes_size"]
153             end
154             defaultProps = setdiff(allprops, excluded);
155
156             // Settings
157             for i = 1:size(defaultProps,"*")
158                 defaultValue = get(defaultFig, defaultProps(i));
159                 if (defaultProps(i) <> "figure_position" | defaultValue <> [-1,-1]) then
160                     // don't reset figure pos is defaultValue is [-1,-1]
161                     set(curFig, defaultProps(i), defaultValue);
162                 end
163             end
164             set(curFig, "immediate_drawing", defaultFig.immediate_drawing)
165         end
166     end
167 endfunction
168
169 function yn = isDocked(fh)
170     // http://fileexchange.scilab.org/toolboxes/360000
171     sf = size(fh)
172     fh = fh(:)
173     fs = matrix(fh.figure_size,2,-1)'
174     as = matrix(fh.axes_size,2,-1)'
175
176     yn = (fh.dockable=="on" & ((fs(:,1)-as(:,1)) > 20)')
177     // A test on vertical dimensions is more complicated, due to switchable
178     // menubar, toolbar and infobar.
179     yn = matrix(yn, sf)
180 endfunction
181