Mercurial > hg > octave-lyh
comparison scripts/plot/struct2hdl.m @ 15011:f34bea431e4f
maint: Use Octave coding standards for copyobj.m, hdl2struct.m, struct2hdl.m.
* copyobj.m, hdl2struct.m, struct2hdl.m: Use Octave coding standards.
author | Rik <rik@octave.org> |
---|---|
date | Tue, 24 Jul 2012 13:41:41 -0700 |
parents | 8f0e3c5bfa5f |
children | a1d1386daeed |
comparison
equal
deleted
inserted
replaced
15010:f7bcfb3b96e7 | 15011:f34bea431e4f |
---|---|
16 | 16 |
17 ## -*- texinfo -*- | 17 ## -*- texinfo -*- |
18 ## @deftypefn {Function File} {@var{h} =} struct2hdl (@var{s}) | 18 ## @deftypefn {Function File} {@var{h} =} struct2hdl (@var{s}) |
19 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}) | 19 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}) |
20 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}, @var{hilev}) | 20 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}, @var{hilev}) |
21 ## Construct an object from the structure @var{s}. The structure must | 21 ## Construct a handle object @var{h} from the structure @var{s}. The structure |
22 ## contain the fields "handle", "type", "children", "properties", and | 22 ## must contain the fields "handle", "type", "children", "properties", and |
23 ## "special". If the handle of an existing figure or axes is specified, | 23 ## "special". If the handle of an existing figure or axes is specified, |
24 ## @var{p}, the new object will be created as a child to that object. | 24 ## @var{p}, the new object will be created as a child of that object. |
25 ## If no object handle is provided, then a new figure and the necessary | 25 ## If no object handle is provided then a new figure and the necessary |
26 ## children will be constructed using the default object values from | 26 ## children will be constructed using the default object values from |
27 ## the root figure. | 27 ## the root figure. |
28 ## | 28 ## |
29 ## A third boolean argument @var{hilev} can be passed to specify wether | 29 ## A third boolean argument @var{hilev} can be passed to specify whether |
30 ## the function should try to preserve listeners/calbacks e.g., for | 30 ## the function should try to preserve listeners/callbacks, e.g., for |
31 ## legends or hggroups. Default is false. | 31 ## legends or hggroups. The default is false. |
32 ## @seealso{findobj, get, hdl2struct, set} | 32 ## @seealso{hdl2struct, findobj, get, set} |
33 ## @end deftypefn | 33 ## @end deftypefn |
34 | 34 |
35 ## Author: pdiribarne <pdiribarne@new-host.home> | 35 ## Author: pdiribarne <pdiribarne@new-host.home> |
36 ## Created: 2012-03-04 | 36 ## Created: 2012-03-04 |
37 | 37 |
38 function [ h, matchout ] = struct2hdl (hgS, matchin=[], hilev = false) | 38 function [h, pout] = struct2hdl (s, p=[], hilev = false) |
39 | 39 |
40 fields = { "handle", "type", "children", "properties", "special"}; | 40 fields = {"handle", "type", "children", "properties", "special"}; |
41 partypes = {"root", "figure", "axes", "hggroup"}; | 41 partypes = {"root", "figure", "axes", "hggroup"}; |
42 othertypes = {"line", "patch", "surface", "image", "text"}; | 42 othertypes = {"line", "patch", "surface", "image", "text"}; |
43 alltypes = [partypes othertypes]; | 43 alltypes = [partypes othertypes]; |
44 | 44 |
45 if (nargin > 3 || ! isstruct (hgS)) | 45 if (nargin > 3 || ! isstruct (s)) |
46 print_usage (); | 46 print_usage (); |
47 elseif (! all (isfield (hgS, fields))) | 47 elseif (! all (isfield (s, fields))) |
48 print_usage (); | 48 print_usage (); |
49 elseif (isscalar (matchin)) | 49 elseif (isscalar (p)) |
50 if (! ishandle (matchin)) | 50 if (! ishandle (p)) |
51 error ("struct2hdl: argument #2 is not a handle to graphic object") | 51 error ("struct2hdl: P is not a handle to a graphic object"); |
52 endif | 52 endif |
53 if (any (strcmp (get (matchin).type, partypes))) | 53 if (any (strcmp (get (p).type, partypes))) |
54 paridx = find (strcmp (get (matchin).type, alltypes)); | 54 paridx = find (strcmp (get (p).type, alltypes)); |
55 kididx = find (strcmp (hgS.type, alltypes)); | 55 kididx = find (strcmp (s.type, alltypes)); |
56 if (kididx <= paridx) | 56 if (kididx <= paridx) |
57 error ("struct2hdl: incompatible input handles") | 57 error ("struct2hdl: incompatible input handles"); |
58 endif | 58 endif |
59 else | 59 else |
60 error ("struct2hdl: %s object can't be parent object", get (matchin).type) | 60 error ("struct2hdl: %s object can't be parent object", get (p).type); |
61 endif | 61 endif |
62 hpar = matchin; | 62 hpar = p; |
63 matchin = [NaN; hpar]; | 63 p = [NaN; hpar]; |
64 ## create appropriate parent if needed | 64 ## create appropriate parent if needed |
65 if (any (strcmp (hgS.type, othertypes))) | 65 if (any (strcmp (s.type, othertypes))) |
66 for ii = (paridx+1) : (numel (partypes)-1) | 66 for ii = (paridx+1) : (numel (partypes)-1) |
67 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); | 67 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); |
68 matchin = [matchin [NaN; hpar]]; | 68 p = [p [NaN; hpar]]; |
69 endfor | 69 endfor |
70 elseif (any (strcmp (hgS.type, {"hggroup", "axes"}))) | 70 elseif (any (strcmp (s.type, {"hggroup", "axes"}))) |
71 for ii = (paridx+1) : (kididx-1) | 71 for ii = (paridx+1) : (kididx-1) |
72 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); | 72 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); |
73 matchin = [matchin [NaN; hpar]]; | 73 p = [p [NaN; hpar]]; |
74 endfor | 74 endfor |
75 else | 75 else |
76 par = NaN; | 76 par = NaN; |
77 endif | 77 endif |
78 elseif (isempty (matchin)) | 78 elseif (isempty (p)) |
79 if (any (strcmp (hgS.type, othertypes))) | 79 if (any (strcmp (s.type, othertypes))) |
80 par = axes (); | 80 par = axes (); |
81 elseif (any (strcmp (hgS.type, {"hggroup", "axes"}))) | 81 elseif (any (strcmp (s.type, {"hggroup", "axes"}))) |
82 par = figure (); | 82 par = figure (); |
83 else | 83 else |
84 par = NaN; | 84 par = NaN; |
85 endif | 85 endif |
86 matchin = [NaN; par]; | 86 p = [NaN; par]; |
87 endif | 87 endif |
88 ## read parent (last column) in matchin and remove it if duplicate | 88 ## read parent (last column) in p and remove it if duplicate |
89 par = matchin (2,end); | 89 par = p(2,end); |
90 tst = find (matchin (2,:) == par); | 90 tst = find (p(2,:) == par); |
91 if (numel (tst) > 1) | 91 if (numel (tst) > 1) |
92 matchin = matchin (1:2, 1:(tst(end)-1)); | 92 p = p(1:2, 1:(tst(end)-1)); |
93 endif | 93 endif |
94 | 94 |
95 ## create object | 95 ## create object |
96 if (strcmpi (hgS.type, "root")) | 96 if (strcmp (s.type, "root")) |
97 h = 0; | 97 h = 0; |
98 hgS.properties = rmfield (hgS.properties, ... | 98 s.properties = rmfield (s.properties, ... |
99 {"callbackobject", "commandwindowsize", ... | 99 {"callbackobject", "commandwindowsize", ... |
100 "screendepth", "screenpixelsperinch", ... | 100 "screendepth", "screenpixelsperinch", ... |
101 "screensize"}); | 101 "screensize"}); |
102 elseif (strcmpi (hgS.type, "figure")) | 102 elseif (strcmp (s.type, "figure")) |
103 h = figure (); | 103 h = figure (); |
104 elseif (strcmpi (hgS.type, "axes")) | 104 elseif (strcmp (s.type, "axes")) |
105 ## legends and colorbars are "transformed" in normal axes | 105 ## legends and colorbars are "transformed" in normal axes |
106 ## if hilev is not requested | 106 ## if hilev is not requested |
107 if (! hilev) | 107 if (! hilev) |
108 if (strcmp (hgS.properties.tag, "legend")) | 108 if (strcmp (s.properties.tag, "legend")) |
109 hgS.properties.tag = ""; | 109 s.properties.tag = ""; |
110 hgS.properties.userdata = []; | 110 s.properties.userdata = []; |
111 par = gcf; | 111 par = gcf; |
112 elseif (strcmp (hgS.properties.tag, "colorbar")) | 112 elseif (strcmp (s.properties.tag, "colorbar")) |
113 hgS.properties.tag = ""; | 113 s.properties.tag = ""; |
114 hgS.properties.userdata = []; | 114 s.properties.userdata = []; |
115 par = gcf; | 115 par = gcf; |
116 endif | 116 endif |
117 endif | 117 endif |
118 | 118 |
119 [h, hgS] = createaxes (hgS, matchin, par); | 119 [h, s] = createaxes (s, p, par); |
120 elseif (strcmpi (hgS.type, "line")) | 120 elseif (strcmp (s.type, "line")) |
121 h = createline (hgS, par); | 121 h = createline (s, par); |
122 elseif (strcmpi (hgS.type, "patch")) | 122 elseif (strcmp (s.type, "patch")) |
123 [h, hgS] = createpatch (hgS, par); | 123 [h, s] = createpatch (s, par); |
124 elseif (strcmpi (hgS.type, "text")) | 124 elseif (strcmp (s.type, "text")) |
125 h = createtext (hgS, par); | 125 h = createtext (s, par); |
126 elseif (strcmpi (hgS.type, "image")) | 126 elseif (strcmp (s.type, "image")) |
127 h = createimage (hgS, par); | 127 h = createimage (s, par); |
128 elseif (strcmpi (hgS.type, "surface")) | 128 elseif (strcmp (s.type, "surface")) |
129 h = createsurface (hgS, par); | 129 h = createsurface (s, par); |
130 elseif (strcmpi (hgS.type, "hggroup")) | 130 elseif (strcmp (s.type, "hggroup")) |
131 [h, hgS, matchin] = createhg (hgS, matchin, par, hilev); | 131 [h, s, p] = createhg (s, p, par, hilev); |
132 endif | 132 endif |
133 | 133 |
134 ## children | 134 ## children |
135 matchin = [matchin [hgS.handle; h]]; # [original; new] | 135 p = [p [s.handle; h]]; # [original; new] |
136 kids = hgS.children; | 136 kids = s.children; |
137 nkids = length (kids); | 137 nkids = length (kids); |
138 ii = 0; | 138 ii = 0; |
139 while nkids | 139 while (nkids) |
140 ii++; | 140 ii++; |
141 if (! any (ii == hgS.special)) | 141 if (! any (ii == s.special)) |
142 [h2, matchin] = struct2hdl (hgS.children(ii), | 142 [h2, p] = struct2hdl (s.children(ii), [p [s.handle; h]], hilev); |
143 [matchin [hgS.handle; h]], hilev); | |
144 endif | 143 endif |
145 nkids--; | 144 nkids--; |
146 endwhile | 145 endwhile |
147 | 146 |
148 ## paste properties | 147 ## paste properties |
149 setprops (hgS, h, matchin, hilev); | 148 setprops (s, h, p, hilev); |
150 | 149 |
151 matchout = matchin; | 150 pout = p; |
152 | 151 |
153 endfunction | 152 endfunction |
154 | 153 |
155 function [h, hgSout] = createaxes (hgS, matchin, par); | 154 function [h, sout] = createaxes (s, p, par) |
156 ## regular axes | 155 ## regular axes |
157 if (strcmpi (hgS.properties.tag, "")) | 156 if (strcmp (s.properties.tag, "")) |
158 propval = {"position", hgS.properties.position}; | 157 propval = {"position", s.properties.position}; |
159 hid = {"autopos_tag", "looseinset"}; | 158 hid = {"autopos_tag", "looseinset"}; |
160 for ii = 1:numel (hid) | 159 for ii = 1:numel (hid) |
161 prop = hid{ii}; | 160 prop = hid{ii}; |
162 if (isfield (hgS.properties, prop)) | 161 if (isfield (s.properties, prop)) |
163 val = hgS.properties.(prop); | 162 val = s.properties.(prop); |
164 propval = [propval, prop, val]; | 163 propval = [propval, prop, val]; |
165 endif | 164 endif |
166 endfor | 165 endfor |
167 h = axes (propval{:}, "parent", par); | 166 h = axes (propval{:}, "parent", par); |
168 | 167 |
169 if isfield (hgS.properties, "__plotyy_axes__") | 168 if (isfield (s.properties, "__plotyy_axes__")) |
170 plty = hgS.properties.__plotyy_axes__; | 169 plty = s.properties.__plotyy_axes__; |
171 addproperty ("__plotyy_axes__", h, "any") | 170 addproperty ("__plotyy_axes__", h, "any"); |
172 tmp = [matchin [hgS.handle; h]]; | 171 tmp = [p [s.handle; h]]; |
173 tst = arrayfun (@(x) any (plty == x), tmp (1:2:end)); | 172 tst = arrayfun (@(x) any (plty == x), tmp(1:2:end)); |
174 if sum (tst) == numel (plty) | 173 if (sum (tst) == numel (plty)) |
175 for ii = 1:numel (plty) | 174 for ii = 1:numel (plty) |
176 plty(ii) = tmp (find (tmp == plty(ii)) + 1); | 175 plty(ii) = tmp(find (tmp == plty(ii)) + 1); |
177 endfor | 176 endfor |
178 for ii = 1:numel (plty) | 177 for ii = 1:numel (plty) |
179 set (plty(ii), "__plotyy_axes__", plty); | 178 set (plty(ii), "__plotyy_axes__", plty); |
180 endfor | 179 endfor |
181 endif | 180 endif |
182 hgS.properties = rmfield (hgS.properties, "__plotyy_axes__"); | 181 s.properties = rmfield (s.properties, "__plotyy_axes__"); |
183 endif | 182 endif |
184 | 183 |
185 ## delete non-default and already set properties | 184 ## delete non-default and already set properties |
186 fields = fieldnames (hgS.properties); | 185 fields = fieldnames (s.properties); |
187 tst = cellfun (@(x) isprop (h, x), fields); | 186 tst = cellfun (@(x) isprop (h, x), fields); |
188 hgS.properties = rmfield (hgS.properties, fields(find (tst == 0))); | 187 s.properties = rmfield (s.properties, fields(find (tst == 0))); |
189 | 188 |
190 elseif (strcmpi (hgS.properties.tag, "legend")) | 189 elseif (strcmp (s.properties.tag, "legend")) |
191 ## legends | 190 ## legends |
192 oldax = hgS.properties.userdata.handle; | 191 oldax = s.properties.userdata.handle; |
193 idx = find (matchin == oldax); | 192 idx = find (p == oldax); |
194 newax = matchin(idx+1); | 193 newax = p(idx+1); |
195 strings = {}; | 194 strings = {}; |
196 kids = hgS.children; | 195 kids = s.children; |
197 kids(hgS.special) = []; | 196 kids(s.special) = []; |
198 oldh = unique (arrayfun (@(x) x.properties.userdata(end), kids)); | 197 oldh = unique (arrayfun (@(x) x.properties.userdata(end), kids)); |
199 for ii = 1:length (oldh) | 198 for ii = 1:length (oldh) |
200 idx = find (matchin(1:2:end) == oldh(ii)) * 2; | 199 idx = find (p(1:2:end) == oldh(ii)) * 2; |
201 if (! isempty (idx)) | 200 if (! isempty (idx)) |
202 newh(ii) = matchin (idx); | 201 newh(ii) = p(idx); |
203 if (! strcmp (get (newh(ii), "type"), "hggroup")) | 202 if (! strcmp (get (newh(ii), "type"), "hggroup")) |
204 str = get (newh(ii), "displayname"); | 203 str = get (newh(ii), "displayname"); |
205 strings = [strings str]; | 204 strings = [strings str]; |
206 else | 205 else |
207 str = get (get (newh(ii), "children")(1), "displayname"); | 206 str = get (get (newh(ii), "children")(1), "displayname"); |
208 strings = [strings str]; | 207 strings = [strings str]; |
209 endif | 208 endif |
210 else | 209 else |
211 error ("struct2hdl: didn't find a legend item") | 210 error ("struct2hdl: didn't find a legend item"); |
212 endif | 211 endif |
213 endfor | 212 endfor |
214 location = hgS.properties.location; | 213 location = s.properties.location; |
215 orientation = hgS.properties.orientation; | 214 orientation = s.properties.orientation; |
216 textpos = hgS.properties.textposition; | 215 textpos = s.properties.textposition; |
217 box = hgS.properties.box; | 216 box = s.properties.box; |
218 | 217 |
219 h = legend (newax, newh, strings, "location", location, ... | 218 h = legend (newax, newh, strings, "location", location, ... |
220 "orientation", orientation); | 219 "orientation", orientation); |
221 set (h, "textposition", textpos); # bug makes "textposition" | 220 set (h, "textposition", textpos); # bug makes "textposition" |
222 # redefine the legend | 221 # redefine the legend |
223 h = legend (newax, newh, strings, "location", location, ... | 222 h = legend (newax, newh, strings, "location", location, ... |
224 "orientation", orientation); | 223 "orientation", orientation); |
225 ## box | 224 ## box |
226 if (strcmp (box, "on")) | 225 if (strcmp (box, "on")) |
227 legend boxon | 226 legend ("boxon"); |
228 endif | 227 endif |
229 | 228 |
230 ## visibility | 229 ## visibility |
231 tst = arrayfun (@(x) strcmp (x.properties.visible, "on"), kids); | 230 tst = arrayfun (@(x) strcmp (x.properties.visible, "on"), kids); |
232 if !any (tst) | 231 if (! any (tst)) |
233 legend ("hide"); | 232 legend ("hide"); |
234 endif | 233 endif |
235 | 234 |
236 ## remove all properties such as "textposition" that redefines | 235 ## remove all properties such as "textposition" that redefines |
237 ## the entire legend. Also remove chidren | 236 ## the entire legend. Also remove chidren |
238 hgS.properties = rmfield (hgS.properties, ... | 237 s.properties = rmfield (s.properties, ... |
239 {"userdata", "xlabel",... | 238 {"userdata", "xlabel",... |
240 "ylabel", "zlabel", "location", ... | 239 "ylabel", "zlabel", "location", ... |
241 "title", "string","orientation", ... | 240 "title", "string","orientation", ... |
242 "visible", "textposition"}); | 241 "visible", "textposition"}); |
243 | 242 |
244 hgS.children = []; | 243 s.children = []; |
245 | 244 |
246 elseif (strcmpi (hgS.properties.tag, "colorbar")) | 245 elseif (strcmp (s.properties.tag, "colorbar")) |
247 ## colorbar | 246 ## colorbar |
248 oldax = hgS.properties.axes; | 247 oldax = s.properties.axes; |
249 if (! isempty (idx = find (oldax == matchin))) | 248 if (! isempty (idx = find (oldax == p))) |
250 ax = matchin(idx+1); | 249 ax = p(idx+1); |
251 location = hgS.properties.location; | 250 location = s.properties.location; |
252 h = colorbar ("peer", ax, location); | 251 h = colorbar ("peer", ax, location); |
253 hgS.properties = rmfield (hgS.properties, ... | 252 s.properties = rmfield (s.properties, ... |
254 {"userdata", "xlabel" ... | 253 {"userdata", "xlabel" ... |
255 "ylabel", "zlabel", ... | 254 "ylabel", "zlabel", ... |
256 "title", "axes"}); | 255 "title", "axes"}); |
257 hgS.children= []; | 256 s.children= []; |
258 else | 257 else |
259 error ("hdl2struct: didn't find an object") | 258 error ("hdl2struct: didn't find an object"); |
260 endif | 259 endif |
261 endif | 260 endif |
262 hgSout = hgS; | 261 sout = s; |
263 endfunction | 262 endfunction |
264 | 263 |
265 function [h] = createline (hgS, par); | 264 function h = createline (s, par) |
266 h = line ("parent", par); | 265 h = line ("parent", par); |
267 addmissingprops (h, hgS.properties); | 266 addmissingprops (h, s.properties); |
268 endfunction | 267 endfunction |
269 | 268 |
270 function [h, hgSout] = createpatch (hgS, par); | 269 function [h, sout] = createpatch (s, par) |
271 prp.faces = hgS.properties.faces; | 270 prp.faces = s.properties.faces; |
272 prp.vertices = hgS.properties.vertices; | 271 prp.vertices = s.properties.vertices; |
273 prp.facevertexcdata = hgS.properties.facevertexcdata; | 272 prp.facevertexcdata = s.properties.facevertexcdata; |
274 h = patch (prp); | 273 h = patch (prp); |
275 set (h, "parent", par); | 274 set (h, "parent", par); |
276 hgS.properties = rmfield (hgS.properties, | 275 s.properties = rmfield (s.properties, |
277 {"faces", "vertices", "facevertexcdata"}); | 276 {"faces", "vertices", "facevertexcdata"}); |
278 addmissingprops (h, hgS.properties); | 277 addmissingprops (h, s.properties); |
279 hgSout = hgS; | 278 sout = s; |
280 endfunction | 279 endfunction |
281 | 280 |
282 function [h] = createtext (hgS, par); | 281 function h = createtext (s, par) |
283 h = text ("parent", par); | 282 h = text ("parent", par); |
284 addmissingprops (h, hgS.properties) | 283 addmissingprops (h, s.properties); |
285 endfunction | 284 endfunction |
286 | 285 |
287 function [h] = createimage (hgS, par); | 286 function h = createimage (s, par) |
288 h = image ("parent", par); | 287 h = image ("parent", par); |
289 addmissingprops (h, hgS.properties) | 288 addmissingprops (h, s.properties); |
290 endfunction | 289 endfunction |
291 | 290 |
292 function [h] = createsurface (hgS, par); | 291 function h = createsurface (s, par) |
293 h = surface ("parent", par); | 292 h = surface ("parent", par); |
294 addmissingprops (h, hgS.properties) | 293 addmissingprops (h, s.properties); |
295 endfunction | 294 endfunction |
296 | 295 |
297 function [h, hgSout, matchout] = createhg (hgS, matchin, par, hilev) | 296 function [h, sout, pout] = createhg (s, p, par, hilev) |
298 ## Here we infer from properties the type of hggroup we should build | 297 ## Here we infer from properties the type of hggroup we should build |
299 ## an call corresponding high level functions | 298 ## an call corresponding high level functions |
300 ## We manually set "hold on" to avoid next hggroup be deleted | 299 ## We manually set "hold on" to avoid next hggroup be deleted |
301 ## the proper value of axes "nextplot" will finally be recovered | 300 ## the proper value of axes "nextplot" will finally be recovered |
302 | 301 |
303 hold on; | 302 hold on; |
304 if (hilev) | 303 if (hilev) |
305 [h, hgS, matchin] = createhg_hilev (hgS, matchin, par); | 304 [h, s, p] = createhg_hilev (s, p, par); |
306 if (numel (hgS.children) != numel (get (h).children)) | 305 if (numel (s.children) != numel (get (h).children)) |
307 warning (["struct2hdl: couldn't infer the hggroup type. ", ... | 306 warning (["struct2hdl: could not infer the hggroup type. ", ... |
308 "Will build objects but listener/callback functions ", ... | 307 "Will build objects but listener/callback functions ", ... |
309 "will be lost"]); | 308 "will be lost"]); |
310 if isfield (h, "bargroup") | 309 if (isfield (h, "bargroup")) |
311 delete (get (h).bargroup); | 310 delete (get (h).bargroup); |
312 else | 311 else |
313 delete (h); | 312 delete (h); |
314 endif | 313 endif |
315 h = hggroup ("parent", par); | 314 h = hggroup ("parent", par); |
316 addmissingprops (h, hgS.properties); | 315 addmissingprops (h, s.properties); |
317 hgS.special = []; | 316 s.special = []; |
318 else | 317 else |
319 oldkids = hgS.children; | 318 oldkids = s.children; |
320 newkids = get (h).children; | 319 newkids = get (h).children; |
321 nkids = numel (oldkids); | 320 nkids = numel (oldkids); |
322 ii = 1; | 321 ii = 1; |
323 while nkids | 322 while (nkids) |
324 matchin = [matchin [oldkids(ii++).handle; newkids(nkids--)]]; | 323 p = [p [oldkids(ii++).handle; newkids(nkids--)]]; |
325 endwhile | 324 endwhile |
326 endif | 325 endif |
327 else | 326 else |
328 h = hggroup ("parent", par); | 327 h = hggroup ("parent", par); |
329 addmissingprops (h, hgS.properties); | 328 addmissingprops (h, s.properties); |
330 hgS.special = []; | 329 s.special = []; |
331 endif | 330 endif |
332 hgSout = hgS; | 331 sout = s; |
333 matchout = matchin; | 332 pout = p; |
334 endfunction | 333 endfunction |
335 | 334 |
336 function [h, hgSout, matchout] = createhg_hilev (hgS, matchin, par) | 335 function [h, sout, pout] = createhg_hilev (s, p, par) |
337 fields = hgS.properties; | 336 fields = s.properties; |
338 if (isfield (fields, "contourmatrix")) | 337 if (isfield (fields, "contourmatrix")) |
339 ## contours | 338 ## contours |
340 xdata = hgS.properties.xdata; | 339 xdata = s.properties.xdata; |
341 ydata = hgS.properties.ydata; | 340 ydata = s.properties.ydata; |
342 zdata = hgS.properties.zdata; | 341 zdata = s.properties.zdata; |
343 levellist = hgS.properties.levellist; | 342 levellist = s.properties.levellist; |
344 textlist = hgS.properties.textlist; | 343 textlist = s.properties.textlist; |
345 | 344 |
346 ## contour creation | 345 ## contour creation |
347 if (isempty (hgS.children(1).properties.zdata)) | 346 if (isempty (s.children(1).properties.zdata)) |
348 if (strcmpi (hgS.properties.fill, "on")) | 347 if (strcmpi (s.properties.fill, "on")) |
349 [cm2, h] = contourf (xdata, ydata, zdata, levellist); | 348 [cm2, h] = contourf (xdata, ydata, zdata, levellist); |
350 else | 349 else |
351 [cm2, h] = contour (xdata, ydata, zdata, levellist); | 350 [cm2, h] = contour (xdata, ydata, zdata, levellist); |
352 endif | 351 endif |
353 | 352 |
354 ## labels | 353 ## labels |
355 if (strcmpi (hgS.properties.showtext, "on")) | 354 if (strcmpi (s.properties.showtext, "on")) |
356 clabel (cm2, h, textlist); | 355 clabel (cm2, h, textlist); |
357 endif | 356 endif |
358 else | 357 else |
359 [cm2, h] = contour3 (xdata, ydata, zdata, levellist); | 358 [cm2, h] = contour3 (xdata, ydata, zdata, levellist); |
360 endif | 359 endif |
361 | 360 |
362 ## delete already set properties and children | 361 ## delete already set properties and children |
363 hgS.properties = rmfield (hgS.properties, ... | 362 s.properties = rmfield (s.properties, ... |
364 {"xdata", "ydata", "zdata", ... | 363 {"xdata", "ydata", "zdata", ... |
365 "contourmatrix", "levellist", ... | 364 "contourmatrix", "levellist", ... |
366 "fill", "labelspacing", ... | 365 "fill", "labelspacing", ... |
367 "levellistmode", "levelstep", ... | 366 "levellistmode", "levelstep", ... |
368 "levelstepmode", "textlist"... | 367 "levelstepmode", "textlist"... |
370 "textstepmode", "zlevel", ... | 369 "textstepmode", "zlevel", ... |
371 "zlevelmode"}); | 370 "zlevelmode"}); |
372 | 371 |
373 elseif (isfield (fields, "udata") && isfield (fields, "vdata")) | 372 elseif (isfield (fields, "udata") && isfield (fields, "vdata")) |
374 ## quiver | 373 ## quiver |
375 xdata = hgS.properties.xdata; | 374 xdata = s.properties.xdata; |
376 ydata = hgS.properties.ydata; | 375 ydata = s.properties.ydata; |
377 | 376 |
378 udata = hgS.properties.udata; | 377 udata = s.properties.udata; |
379 vdata = hgS.properties.vdata; | 378 vdata = s.properties.vdata; |
380 | 379 |
381 h = quiver (xdata, ydata, udata, vdata); | 380 h = quiver (xdata, ydata, udata, vdata); |
382 | 381 |
383 ## delete already set properties and children | 382 ## delete already set properties and children |
384 hgS.properties = rmfield (hgS.properties, ... | 383 s.properties = rmfield (s.properties, ... |
385 {"xdata", "ydata", "zdata", ... | 384 {"xdata", "ydata", "zdata", ... |
386 "xdatasource", "ydatasource", "zdatasource", ... | 385 "xdatasource", "ydatasource", "zdatasource", ... |
387 "udata", "vdata", "wdata", ... | 386 "udata", "vdata", "wdata", ... |
388 "udatasource", "vdatasource", "wdatasource"}); | 387 "udatasource", "vdatasource", "wdatasource"}); |
389 | 388 |
390 elseif (isfield (fields, "format")) | 389 elseif (isfield (fields, "format")) |
391 ##errorbar | 390 ##errorbar |
392 form = hgS.properties.format; | 391 form = s.properties.format; |
393 xdata = hgS.properties.xdata; | 392 xdata = s.properties.xdata; |
394 ydata = hgS.properties.ydata; | 393 ydata = s.properties.ydata; |
395 xldata = hgS.properties.xldata; | 394 xldata = s.properties.xldata; |
396 ldata = hgS.properties.ldata; | 395 ldata = s.properties.ldata; |
397 xudata = hgS.properties.xudata; | 396 xudata = s.properties.xudata; |
398 udata = hgS.properties.udata; | 397 udata = s.properties.udata; |
399 | 398 |
400 switch form | 399 switch form |
401 case "xerr" | 400 case "xerr" |
402 h = errorbar (xdata, ydata, xldata, xudata, ">"); | 401 h = errorbar (xdata, ydata, xldata, xudata, ">"); |
403 case "yerr" | 402 case "yerr" |
409 case "boxy" | 408 case "boxy" |
410 h = errorbar (xdata, ydata, ldata, udata, "#~"); | 409 h = errorbar (xdata, ydata, ldata, udata, "#~"); |
411 case "boxxy" | 410 case "boxxy" |
412 h = errorbar (xdata, ydata, xldata, xudata, ldata, udata, "#~>"); | 411 h = errorbar (xdata, ydata, xldata, xudata, ldata, udata, "#~>"); |
413 otherwise | 412 otherwise |
414 error ("struct2hdl: couldn't guess the errorbar format") | 413 error ("struct2hdl: couldn't guess the errorbar format"); |
415 endswitch | 414 endswitch |
416 ## delete already set properties | 415 ## delete already set properties |
417 hgS.properties = rmfield (hgS.properties, ... | 416 s.properties = rmfield (s.properties, ... |
418 {"xdata", "ydata", ... | 417 {"xdata", "ydata", ... |
419 "xldata", "ldata", ... | 418 "xldata", "ldata", ... |
420 "xudata", "udata", ... | 419 "xudata", "udata", ... |
421 "xldatasource", "ldatasource", ... | 420 "xldatasource", "ldatasource", ... |
422 "xudatasource", "udatasource", ... | 421 "xudatasource", "udatasource", ... |
427 ## FIXME - here we don't have access to brothers so we first create all | 426 ## FIXME - here we don't have access to brothers so we first create all |
428 ## the barseries of the bargroup (but the last), then retrieve information, | 427 ## the barseries of the bargroup (but the last), then retrieve information, |
429 ## and rebuild the whole bargroup. | 428 ## and rebuild the whole bargroup. |
430 ## The duplicate are deleted after calling "setprops" | 429 ## The duplicate are deleted after calling "setprops" |
431 | 430 |
432 bargroup = hgS.properties.bargroup; | 431 bargroup = s.properties.bargroup; |
433 oldh = hgS.handle; | 432 oldh = s.handle; |
434 | 433 |
435 temp = arrayfun (@(x) any(x == bargroup), [matchin(1:2:end) oldh]); | 434 temp = arrayfun (@(x) any(x == bargroup), [p(1:2:end) oldh]); |
436 tst = sum (temp) == length (bargroup); | 435 tst = sum (temp) == length (bargroup); |
437 | 436 |
438 if (isscalar (bargroup) || !tst) | 437 if (isscalar (bargroup) || !tst) |
439 xdata = hgS.properties.xdata; | 438 xdata = s.properties.xdata; |
440 ydata = hgS.properties.ydata; | 439 ydata = s.properties.ydata; |
441 | 440 |
442 h = bar (xdata, ydata); | 441 h = bar (xdata, ydata); |
443 | 442 |
444 ## delete already set properties, | 443 ## delete already set properties, |
445 hgS.properties = rmfield (hgS.properties, ... | 444 s.properties = rmfield (s.properties, ... |
446 {"xdata", "ydata", ... | 445 {"xdata", "ydata", ... |
447 "xdatasource", "ydatasource", ... | 446 "xdatasource", "ydatasource", ... |
448 "bargroup", ... | 447 "bargroup", ... |
449 "barwidth", "baseline"}); | 448 "barwidth", "baseline"}); |
450 else | 449 else |
451 xdata = []; | 450 xdata = []; |
452 ydata = []; | 451 ydata = []; |
453 | 452 |
454 ##build x/y matrix | 453 ##build x/y matrix |
455 nbar = length (bargroup); | 454 nbar = length (bargroup); |
456 tmp = struct ("handle", NaN,"type", "", "children", [], "special", []); | 455 tmp = struct ("handle", NaN, "type", "", "children", [], "special", []); |
457 for ii = 1:(nbar - 1) | 456 for ii = 1:(nbar - 1) |
458 idx = find (matchin(1:2:end) == bargroup(ii)) * 2; | 457 idx = find (p(1:2:end) == bargroup(ii)) * 2; |
459 hdl = matchin (idx); | 458 hdl = p (idx); |
460 xdata = [xdata get(hdl).xdata]; | 459 xdata = [xdata get(hdl).xdata]; |
461 ydata = [ydata get(hdl).ydata]; | 460 ydata = [ydata get(hdl).ydata]; |
462 tmp.children(ii) = hdl2struct (hdl); | 461 tmp.children(ii) = hdl2struct (hdl); |
463 endfor | 462 endfor |
464 | 463 |
465 xdata = [xdata hgS.properties.xdata]; | 464 xdata = [xdata s.properties.xdata]; |
466 ydata = [ydata hgS.properties.ydata]; | 465 ydata = [ydata s.properties.ydata]; |
467 width = hgS.properties.barwidth; | 466 width = s.properties.barwidth; |
468 h = bar (ydata, width); | 467 h = bar (ydata, width); |
469 | 468 |
470 ## replace previous handles in "match", copy props and delete redundant | 469 ## replace previous handles in "match", copy props and delete redundant |
471 for ii = 1:(nbar - 1) | 470 for ii = 1:(nbar - 1) |
472 props = tmp.children(ii).properties; | 471 props = tmp.children(ii).properties; |
473 bl = props.baseline; | 472 bl = props.baseline; |
474 tmp.children(ii).properties = rmfield (props, {"baseline", "bargroup"}); | 473 tmp.children(ii).properties = rmfield (props, {"baseline", "bargroup"}); |
475 setprops (tmp.children(ii), h(ii), matchin, 1); | 474 setprops (tmp.children(ii), h(ii), p, 1); |
476 delete (tmp.children(ii).handle); | 475 delete (tmp.children(ii).handle); |
477 delete (bl); | 476 delete (bl); |
478 idxpar = find (matchin == tmp.children(ii).handle); | 477 idxpar = find (p == tmp.children(ii).handle); |
479 matchin (idxpar) = h(ii); | 478 p(idxpar) = h(ii); |
480 idxkid = idxpar - 2; | 479 idxkid = idxpar - 2; |
481 matchin (idxkid) = get (h(ii), "children"); | 480 p(idxkid) = get (h(ii), "children"); |
482 endfor | 481 endfor |
483 matchin (2,((end-nbar+2):end)) = h (1:(end-1)); | 482 p(2,((end-nbar+2):end)) = h(1:(end-1)); |
484 h = h (end); | 483 h = h(end); |
485 | 484 |
486 ## delete already set properties , | 485 ## delete already set properties , |
487 hgS.properties = rmfield (hgS.properties, ... | 486 s.properties = rmfield (s.properties, ... |
488 {"xdata", "ydata", "bargroup"... | 487 {"xdata", "ydata", "bargroup"... |
489 "barwidth", "baseline"}); | 488 "barwidth", "baseline"}); |
490 endif | 489 endif |
491 elseif (isfield (fields, "baseline")) | 490 elseif (isfield (fields, "baseline")) |
492 ## stem plot | 491 ## stem plot |
493 xdata = hgS.properties.xdata; | 492 xdata = s.properties.xdata; |
494 ydata = hgS.properties.ydata; | 493 ydata = s.properties.ydata; |
495 | 494 |
496 h = stem (xdata, ydata); | 495 h = stem (xdata, ydata); |
497 | 496 |
498 ## delete already set properties, | 497 ## delete already set properties, |
499 hgS.properties = rmfield (hgS.properties, ... | 498 s.properties = rmfield (s.properties, ... |
500 {"xdata", "ydata", ... | 499 {"xdata", "ydata", ... |
501 "xdatasource", "ydatasource", ... | 500 "xdatasource", "ydatasource", ... |
502 "baseline"}); | 501 "baseline"}); |
503 elseif (isfield (fields, "basevalue")) | 502 elseif (isfield (fields, "basevalue")) |
504 ## area plot | 503 ## area plot |
505 xdata = hgS.properties.xdata; | 504 xdata = s.properties.xdata; |
506 ydata = hgS.properties.ydata; | 505 ydata = s.properties.ydata; |
507 level = hgS.properties.basevalue; | 506 level = s.properties.basevalue; |
508 | 507 |
509 h = area (xdata, ydata, level); | 508 h = area (xdata, ydata, level); |
510 | 509 |
511 ## delete already set properties, | 510 ## delete already set properties, |
512 hgS.properties = rmfield (hgS.properties, ... | 511 s.properties = rmfield (s.properties, ... |
513 {"xdata", "ydata", ... | 512 {"xdata", "ydata", ... |
514 "xdatasource", "ydatasource"}); | 513 "xdatasource", "ydatasource"}); |
515 else | 514 else |
516 warning ("struct2hdl: couldn't infer the hggroup type. Will build objects but listener/callback functions will be lost"); | 515 warning ("struct2hdl: could not infer the hggroup type. Will build objects but listener/callback functions will be lost"); |
517 h = hggroup ("parent", par); | 516 h = hggroup ("parent", par); |
518 addmissingprops (h, hgS.properties); | 517 addmissingprops (h, s.properties); |
519 hgS.special = []; # children will be treated as normal children | 518 s.special = []; # children will be treated as normal children |
520 endif | 519 endif |
521 hgSout = hgS; | 520 sout = s; |
522 matchout = matchin; | 521 pout = p; |
523 endfunction | 522 endfunction |
524 | 523 |
525 function setprops (hgS, h, matchin, hilev) | 524 function setprops (s, h, p, hilev) |
526 more off | 525 more off; |
527 if (strcmpi (hgS.properties.tag, "")) | 526 if (strcmpi (s.properties.tag, "")) |
528 specs = hgS.children(hgS.special); | 527 specs = s.children(s.special); |
529 hdls = arrayfun (@(x) x.handle, specs); | 528 hdls = arrayfun (@(x) x.handle, specs); |
530 nh = length(hdls); | 529 nh = length (hdls); |
531 msg = ""; | 530 msg = ""; |
532 if (! nh) | 531 if (! nh) |
533 set (h, hgS.properties); | 532 set (h, s.properties); |
534 else | 533 else |
535 ## Specials are objects that where automatically constructed with | 534 ## Specials are objects that where automatically constructed with |
536 ## current object. Among them are "x(yz)labels", "title", high | 535 ## current object. Among them are "x(yz)labels", "title", high |
537 ## level hggroup children | 536 ## level hggroup children |
538 fields = fieldnames (hgS.properties); | 537 fields = fieldnames (s.properties); |
539 vals = struct2cell (hgS.properties); | 538 vals = struct2cell (s.properties); |
540 idx = find (cellfun (@(x) valcomp(x, hdls) , vals)); | 539 idx = find (cellfun (@(x) valcomp(x, hdls) , vals)); |
541 hgS.properties = rmfield (hgS.properties, fields(idx)); | 540 s.properties = rmfield (s.properties, fields(idx)); |
542 | 541 |
543 ## set all properties but special handles | 542 ## set all properties but special handles |
544 set (h, hgS.properties); | 543 set (h, s.properties); |
545 | 544 |
546 ## find props with val == (one of special handles) | 545 ## find props with val == (one of special handles) |
547 nf = length (idx); | 546 nf = length (idx); |
548 fields = fields(idx); | 547 fields = fields(idx); |
549 vals = vals(idx); | 548 vals = vals(idx); |
550 while nf | 549 while (nf) |
551 field = fields{nf}; | 550 field = fields{nf}; |
552 idx = find (hdls == vals{nf}); | 551 idx = find (hdls == vals{nf}); |
553 spec = specs(idx); | 552 spec = specs(idx); |
554 if (isprop (h, field)) | 553 if (isprop (h, field)) |
555 h2 = get (h , field); | 554 h2 = get (h , field); |
559 endwhile | 558 endwhile |
560 | 559 |
561 ## If hggroup children were created by high level functions, | 560 ## If hggroup children were created by high level functions, |
562 ## copy only usefull properties. | 561 ## copy only usefull properties. |
563 if (hilev) | 562 if (hilev) |
564 if (strcmpi (hgS.type, "hggroup")) | 563 if (strcmp (s.type, "hggroup")) |
565 nold = numel (hgS.children); | 564 nold = numel (s.children); |
566 nnew = numel (get(h).children); | 565 nnew = numel (get (h).children); |
567 | 566 |
568 if (nold == nnew) | 567 if (nold == nnew) |
569 hnew = get(h).children; | 568 hnew = get (h).children; |
570 ii = 1; | 569 ii = 1; |
571 while ii <= nnew | 570 while (ii <= nnew) |
572 try | 571 try |
573 set (hnew (ii), "displayname", ... | 572 set (hnew (ii), "displayname", ... |
574 hgS.children(ii).properties.displayname); | 573 s.children(ii).properties.displayname); |
575 catch | 574 catch |
576 sprintf ("struct2hdl: couldn't set hggroup children #%d props.", ii) | 575 sprintf ("struct2hdl: couldn't set hggroup children #%d props.", ii); |
577 end_try_catch | 576 end_try_catch |
578 ii ++; | 577 ii ++; |
579 endwhile | 578 endwhile |
580 | 579 |
581 else | 580 else |
582 error ("struct2hdl: non-conformant number of children in hgggroup") | 581 error ("struct2hdl: non-conformant number of children in hgggroup"); |
583 endif | 582 endif |
584 endif | 583 endif |
585 endif | 584 endif |
586 endif | 585 endif |
587 | 586 |
588 elseif (strcmpi (hgS.properties.tag, "legend") | 587 elseif (strcmpi (s.properties.tag, "legend") |
589 || strcmpi (hgS.properties.tag, "colorbar")) | 588 || strcmpi (s.properties.tag, "colorbar")) |
590 set (h, hgS.properties); | 589 set (h, s.properties); |
591 endif | 590 endif |
592 | 591 |
593 endfunction | 592 endfunction |
594 | 593 |
595 function out = valcomp (x, hdls) | 594 function out = valcomp (x, hdls) |
596 if (isfloat(x) && isscalar(x)) | 595 if (isfloat (x) && isscalar (x)) |
597 out = any (x == hdls); | 596 out = any (x == hdls); |
598 else | 597 else |
599 out = 0; | 598 out = 0; |
600 endif | 599 endif |
601 endfunction | 600 endfunction |
604 hid = {"autopos_tag", "looseinset"}; | 603 hid = {"autopos_tag", "looseinset"}; |
605 oldfields = fieldnames (props); | 604 oldfields = fieldnames (props); |
606 curfields = fieldnames (get (h)); | 605 curfields = fieldnames (get (h)); |
607 missing = cellfun (@(x) !any (strcmp (x, curfields)), oldfields); | 606 missing = cellfun (@(x) !any (strcmp (x, curfields)), oldfields); |
608 idx = find (missing); | 607 idx = find (missing); |
609 for ii = 1:length(idx) | 608 for ii = 1:length (idx) |
610 prop = oldfields{idx(ii)}; | 609 prop = oldfields{idx(ii)}; |
611 if (! any (strcmp (prop, hid))) | 610 if (! any (strcmp (prop, hid))) |
612 addproperty (prop, h, "any"); | 611 addproperty (prop, h, "any"); |
613 endif | 612 endif |
614 endfor | 613 endfor |
615 endfunction | 614 endfunction |
615 | |
616 | |
617 ## FIXME: Need validation tests |