comparison src/graphics.cc @ 6705:0ee6bda23b87

[project @ 2007-06-13 05:42:24 by jwe]
author jwe
date Wed, 13 Jun 2007 05:42:25 +0000
parents 39e34c15f222
children 388747e3d96b
comparison
equal deleted inserted replaced
6704:781777998927 6705:0ee6bda23b87
31 #include <list> 31 #include <list>
32 #include <map> 32 #include <map>
33 #include <set> 33 #include <set>
34 #include <string> 34 #include <string>
35 35
36 #include <defun.h> 36 #include "defun.h"
37 #include <ov.h> 37 #include "error.h"
38 #include <oct-obj.h>
39 #include <oct-map.h>
40 #include <ov-fcn-handle.h>
41 #include <parse.h>
42
43 #include "graphics.h" 38 #include "graphics.h"
39 #include "ov.h"
40 #include "oct-obj.h"
41 #include "oct-map.h"
42 #include "ov-fcn-handle.h"
43 #include "parse.h"
44 44
45 static void 45 static void
46 gripe_set_invalid (const std::string& pname) 46 gripe_set_invalid (const std::string& pname)
47 { 47 {
48 error ("set: invalid value for %s property", pname.c_str ()); 48 error ("set: invalid value for %s property", pname.c_str ());
60 return val.is_empty () ? octave_value (octave_NaN) : val; 60 return val.is_empty () ? octave_value (octave_NaN) : val;
61 } 61 }
62 62
63 // --------------------------------------------------------------------- 63 // ---------------------------------------------------------------------
64 64
65 class 65 radio_values::radio_values (const std::string& opt_string)
66 radio_values 66 {
67 { 67 size_t beg = 0;
68 public: 68 size_t len = opt_string.length ();
69 radio_values (const std::string& opt_string = std::string ()) 69 bool done = len == 0;
70 { 70
71 size_t beg = 0; 71 while (! done)
72 size_t len = opt_string.length (); 72 {
73 bool done = len == 0; 73 size_t end = opt_string.find ('|', beg);
74 74
75 while (! done) 75 if (end == std::string::npos)
76 { 76 {
77 size_t end = opt_string.find ('|', beg); 77 end = len;
78 78 done = true;
79 if (end == std::string::npos) 79 }
80 { 80
81 end = len; 81 std::string t = opt_string.substr (beg, end-beg);
82 done = true; 82
83 } 83 // Might want more error checking here...
84 84 if (t[0] == '{')
85 std::string t = opt_string.substr (beg, end-beg); 85 {
86 86 t = t.substr (1, t.length () - 2);
87 // Might want more error checking here...
88 if (t[0] == '{')
89 {
90 t = t.substr (1, t.length () - 2);
91 default_val = t;
92 }
93 else if (beg == 0) // ensure default value
94 default_val = t; 87 default_val = t;
95 88 }
96 possible_vals.insert (t); 89 else if (beg == 0) // ensure default value
97 90 default_val = t;
98 beg = end + 1; 91
99 } 92 possible_vals.insert (t);
100 }; 93
101 94 beg = end + 1;
102 radio_values (const radio_values& a) 95 }
103 : default_val (a.default_val), possible_vals (a.possible_vals) { } 96 }
104 97
105 radio_values& operator = (const radio_values& a) 98 bool
106 { 99 color_values::c2rgb (char c)
107 if (&a != this) 100 {
108 { 101 double tmp_rgb[3] = {0, 0, 0};
109 default_val = a.default_val; 102 bool retval = true;
110 possible_vals = a.possible_vals; 103
111 } 104 switch(c)
112 105 {
113 return *this; 106 case 'r':
114 } 107 tmp_rgb[0] = 1;
115 108 break;
116 std::string default_value (void) const { return default_val; } 109
117 110 case 'g':
118 std::set<std::string> possible_values (void) const { return possible_vals; } 111 tmp_rgb[1] = 1;
119 112 break;
120 bool validate (const std::string& val) 113
121 { 114 case 'b':
122 bool retval = true; 115 tmp_rgb[2] = 1;
123 116 break;
124 if (possible_vals.find (val) == possible_vals.end ()) 117
125 { 118 case 'c':
126 error ("invalid value = %s", val.c_str ()); 119 tmp_rgb[1] = tmp_rgb[2] = 1;
127 retval = false; 120 break;
128 } 121
129 122 case 'm':
130 return retval; 123 tmp_rgb[0] = tmp_rgb[2] = 1;
131 } 124 break;
132 125
133 private: 126 case 'y':
134 // Might also want to cache 127 tmp_rgb[0] = tmp_rgb[1] = 1;
135 std::string default_val; 128 break;
136 std::set<std::string> possible_vals; 129
137 }; 130 case 'w':
138 131 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1;
139 class 132 break;
140 radio_property 133
141 { 134 default:
142 public: 135 retval = false;
143 radio_property (const radio_values& v) 136 }
144 : vals (v), current_val (v.default_value ()) { } 137
145 138 if (retval)
146 radio_property (const radio_values& v, const std::string& initial_value) 139 {
147 : vals (v), current_val (initial_value) { } 140 for (int i = 0; i < 3; i++)
148 141 xrgb[i] = tmp_rgb[i];
149 radio_property (const radio_property& a) 142 }
150 : vals (a.vals), current_val (a.current_val) { } 143
151 144 return retval;
152 radio_property& operator = (const radio_property& a) 145 }
153 { 146
154 if (&a != this) 147
155 { 148 color_property::color_property (const octave_value& val)
156 vals = a.vals; 149 : radio_val (), current_val ()
157 current_val = a.current_val; 150 {
158 } 151 // FIXME -- need some error checking here.
159 152
160 return *this; 153 if (val.is_string ())
161 } 154 {
162 155 std::string s = val.string_value ();
163 radio_property& operator = (const std::string& newval) 156
164 { 157 if (! s.empty ())
165 if (vals.validate (newval)) 158 {
166 current_val = newval; 159 color_values col (s[0]);
167 160 if (! error_state)
168 return *this; 161 {
169 } 162 color_val = col;
170 163 current_type = color_t;
171 const std::string& current_value (void) const { return current_val; } 164 }
172 165 }
173 private: 166 else
174 radio_values vals; 167 error ("invalid color specification");
175 std::string current_val; 168 }
176 }; 169 else if (val.is_real_matrix ())
177 170 {
178 class 171 Matrix m = val.matrix_value ();
179 color_values 172
180 { 173 if (m.numel () == 3)
181 public: 174 {
182 color_values (double r = 0, double g = 0, double b = 1) 175 color_values col (m (0), m (1), m(2));
183 { 176 if (! error_state)
184 xrgb[0] = r; 177 {
185 xrgb[1] = g; 178 color_val = col;
186 xrgb[2] = b; 179 current_type = color_t;
187 180 }
188 validate (); 181 }
189 } 182 else
190 183 error ("invalid color specification");
191 color_values (const char c) 184 }
192 { 185 else
193 if (! c2rgb (c)) 186 error ("invalid color specification");
194 error ("invalid color specification"); 187 }
195 } 188
196 189
197 color_values (const color_values& c) 190 void
198 { 191 property_list::set (const property_name& name, const octave_value& val)
199 xrgb[0] = c.xrgb[0]; 192 {
200 xrgb[1] = c.xrgb[1]; 193 size_t offset = 0;
201 xrgb[2] = c.xrgb[2]; 194
202 } 195 size_t len = name.length ();
203 196
204 color_values& operator = (const color_values& c) 197 if (len > 4)
205 { 198 {
206 if (&c != this) 199 property_name pfx = name.substr (0, 4);
207 { 200
208 xrgb[0] = c.xrgb[0]; 201 if (pfx.compare ("axes") || pfx.compare ("line")
209 xrgb[1] = c.xrgb[1]; 202 || pfx.compare ("text"))
210 xrgb[2] = c.xrgb[2]; 203 offset = 4;
211 204 else if (len > 5)
212 } 205 {
213 206 pfx = name.substr (0, 5);
214 return *this; 207
215 } 208 if (pfx.compare ("image"))
216 209 offset = 5;
217 const double* rgb (void) const { return xrgb; } 210 else if (len > 6)
218 211 {
219 void validate (void) const 212 pfx = name.substr (0, 6);
220 { 213
221 for (int i = 0; i < 3; i++) 214 if (pfx.compare ("figure"))
222 { 215 offset = 6;
223 if (xrgb[i] < 0 || xrgb[i] > 1) 216 else if (len > 7)
224 { 217 {
225 error ("invalid RGB color specification"); 218 pfx = name.substr (0, 7);
226 break; 219
227 } 220 if (pfx.compare ("surface"))
228 } 221 offset = 7;
229 } 222 }
230 223 }
231 private: 224 }
232 double xrgb[3]; 225
233 226 if (offset > 0)
234 bool c2rgb (char c) 227 {
235 { 228 // FIXME -- should we validate property names and values here?
236 double tmp_rgb[3] = {0, 0, 0}; 229
237 bool retval = true; 230 std::string pname = name.substr (offset);
238 231
239 switch(c) 232 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
240 { 233 std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
241 case 'r': 234
242 tmp_rgb[0] = 1; 235 bool remove = false;
243 break; 236 if (val.is_string ())
244 237 {
245 case 'g': 238 property_name tval = val.string_value ();
246 tmp_rgb[1] = 1; 239
247 break; 240 remove = tval.compare ("remove");
248 241 }
249 case 'b': 242
250 tmp_rgb[2] = 1; 243 pval_map_type& pval_map = plist_map[pfx];
251 break; 244
252 245 if (remove)
253 case 'c': 246 {
254 tmp_rgb[1] = tmp_rgb[2] = 1; 247 pval_map_iterator p = pval_map.find (pname);
255 break; 248
256 249 if (p != pval_map.end ())
257 case 'm': 250 pval_map.erase (p);
258 tmp_rgb[0] = tmp_rgb[2] = 1; 251 }
259 break; 252 else
260 253 pval_map[pname] = val;
261 case 'y': 254 }
262 tmp_rgb[0] = tmp_rgb[1] = 1; 255 }
263 break; 256
264 257 if (offset == 0)
265 case 'w': 258 error ("invalid default property specification");
266 tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1; 259 }
267 break; 260
268 261 octave_value
269 default: 262 property_list::lookup (const property_name& name) const
270 retval = false; 263 {
271 } 264 octave_value retval;
272 265
273 if (retval) 266 size_t offset = 0;
274 { 267
275 for (int i = 0; i < 3; i++) 268 size_t len = name.length ();
276 xrgb[i] = tmp_rgb[i]; 269
277 } 270 if (len > 4)
278 271 {
279 return retval; 272 property_name pfx = name.substr (0, 4);
280 } 273
281 }; 274 if (pfx.compare ("axes") || pfx.compare ("line")
282 275 || pfx.compare ("text"))
283 276 offset = 4;
284 class 277 else if (len > 5)
285 color_property 278 {
286 { 279 pfx = name.substr (0, 5);
287 public: 280
288 color_property (const color_values& c = color_values (), 281 if (pfx.compare ("image"))
289 const radio_values& v = radio_values ()) 282 offset = 5;
290 : current_type (color_t), color_val (c), radio_val (v), 283 else if (len > 6)
291 current_val (v.default_value ()) 284 {
292 { } 285 pfx = name.substr (0, 6);
293 286
294 color_property (const radio_values& v) 287 if (pfx.compare ("figure"))
295 : current_type (radio_t), color_val (color_values ()), radio_val (v), 288 offset = 6;
296 current_val (v.default_value ()) 289 else if (len > 7)
297 { } 290 {
298 291 pfx = name.substr (0, 7);
299 color_property (const radio_values& v, const std::string& initial_value) 292
300 : current_type (radio_t), color_val (color_values ()), radio_val (v), 293 if (pfx.compare ("surface"))
301 current_val (initial_value) 294 offset = 7;
302 { } 295 }
303 296 }
304 color_property (const octave_value& val) 297 }
305 : radio_val (), current_val () 298
306 { 299 if (offset > 0)
307 // FIXME -- need some error checking here. 300 {
308 301 std::string pname = name.substr (offset);
309 if (val.is_string ()) 302
310 { 303 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
311 std::string s = val.string_value (); 304 std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
312 305
313 if (! s.empty ()) 306 plist_map_const_iterator p = find (pfx);
314 { 307
315 color_values col (s[0]); 308 if (p != end ())
316 if (! error_state) 309 {
317 { 310 const pval_map_type& pval_map = p->second;
318 color_val = col; 311
319 current_type = color_t; 312 pval_map_const_iterator q = pval_map.find (pname);
320 } 313
321 } 314 if (q != pval_map.end ())
322 else 315 retval = q->second;
323 error ("invalid color specification"); 316 }
324 } 317 }
325 else if (val.is_real_matrix ()) 318 }
326 { 319
327 Matrix m = val.matrix_value (); 320 return retval;
328 321 }
329 if (m.numel () == 3) 322
330 { 323 Octave_map
331 color_values col (m (0), m (1), m(2)); 324 property_list::as_struct (const std::string& prefix_arg) const
332 if (! error_state) 325 {
333 { 326 Octave_map m;
334 color_val = col; 327
335 current_type = color_t; 328 for (plist_map_const_iterator p = begin (); p != end (); p++)
336 } 329 {
337 } 330 std::string prefix = prefix_arg + p->first;
338 else 331
339 error ("invalid color specification"); 332 const pval_map_type pval_map = p->second;
340 } 333
341 else 334 for (pval_map_const_iterator q = pval_map.begin ();
342 error ("invalid color specification"); 335 q != pval_map.end ();
343 } 336 q++)
344 337 m.assign (prefix + q->first, q->second);
345 operator octave_value (void) const 338 }
346 { 339
347 if (current_type == color_t) 340 return m;
348 { 341 }
349 Matrix retval (1, 3); 342
350 const double *xrgb = color_val.rgb (); 343 void
351 344 graphics_object::set (const octave_value_list& args)
352 for (int i = 0; i < 3 ; i++) 345 {
353 retval(i) = xrgb[i]; 346 int nargin = args.length ();
354 347
355 return retval; 348 if (nargin == 0)
356 } 349 rep->defaults ();
357 350 else if (nargin % 2 == 0)
358 return current_val; 351 {
359 } 352 for (int i = 0; i < nargin; i += 2)
360 353 {
361 color_property& operator = (const color_property& a) 354 property_name name = args(i).string_value ();
362 { 355
363 if (&a != this) 356 if (! error_state)
364 { 357 {
365 current_type = a.current_type; 358 octave_value val = args(i+1);
366 color_val = a.color_val; 359
367 radio_val = a.radio_val; 360 if (val.is_string ())
368 current_val = a.current_val; 361 {
369 } 362 property_name tval = val.string_value ();
370 363
371 return *this; 364 if (tval.compare ("default"))
372 } 365 val = get_default (name);
373 366 else if (tval.compare ("factory"))
374 color_property& operator = (const std::string& newval) 367 val = get_factory_default (name);
375 { 368 }
376 if (radio_val.validate (newval)) 369
377 { 370 if (error_state)
378 current_val = newval; 371 break;
379 current_type = radio_t; 372
380 } 373 rep->set (name, val);
381 374 }
382 return *this; 375 else
383 } 376 error ("set: expecting argument %d to be a property name", i);
384 377 }
385 color_property& operator = (const color_values& newval) 378 }
386 { 379 else
387 color_val = newval; 380 error ("set: invalid number of arguments");
388 current_type = color_t; 381 }
389 382
390 return *this; 383
391 } 384 graphics_handle
392 385 gh_manager::get_handle (const std::string& go_name)
393 bool is_rgb (void) const { return (current_type == color_t); } 386 {
394 387 graphics_handle retval;
395 bool is_radio (void) const { return (current_type == radio_t); } 388
396 389 if (go_name == "figure")
397 const double* rgb (void) const 390 {
398 { 391 // We always want the lowest unused figure number.
399 if (current_type != color_t) 392
400 error ("color has no rgb value"); 393 retval = 1;
401 394
402 return color_val.rgb (); 395 while (handle_map.find (retval) != handle_map.end ())
403 } 396 retval++;
404 397 }
405 const std::string& current_value (void) const 398 else
406 { 399 {
407 if (current_type != radio_t) 400 free_list_iterator p = handle_free_list.begin ();
408 error ("color has no radio value"); 401
409 402 if (p != handle_free_list.end ())
410 return current_val; 403 {
411 } 404 retval = *p;
412 405 handle_free_list.erase (p);
413 private: 406 }
414 enum current_enum { color_t, radio_t } current_type; 407 else
415 color_values color_val; 408 retval = next_handle--;
416 radio_values radio_val; 409 }
417 std::string current_val; 410
418 }; 411 return retval;
419 412 }
420 class 413
421 colormap_property 414 void
422 { 415 gh_manager::do_free (const graphics_handle& h)
423 public: 416 {
424 colormap_property (const Matrix& m = Matrix ()) 417 if (h != 0)
425 : cmap (m) 418 {
426 { 419 iterator p = handle_map.find (h);
427 if (cmap.is_empty ()) 420
428 { 421 if (p != handle_map.end ())
429 cmap = Matrix (64, 3); 422 {
430 423 handle_map.erase (p);
431 for (octave_idx_type i = 0; i < 64; i++) 424
432 cmap(i,0) = cmap(i,1) = cmap(i,2) = i / 64.0; 425 if (h < 0)
433 } 426 handle_free_list.insert (h);
434 427 }
435 validate (); 428 else
436 } 429 error ("graphics_handle::free: invalid object %g", h);
437 430 }
438 colormap_property (const octave_value& val) 431 else
439 { 432 error ("graphics_handle::free: can't delete root figure");
440 cmap = val.matrix_value (); 433 }
441 434
442 validate ();
443 }
444
445 void validate (void) const
446 {
447 if (error_state || cmap.columns () != 3)
448 error ("invalid colormap specification");
449 }
450
451 operator octave_value (void) const { return cmap; }
452
453 private:
454 Matrix cmap;
455 };
456
457 // ---------------------------------------------------------------------
458
459 class property_name : public std::string
460 {
461 public:
462 typedef std::string::iterator iterator;
463 typedef std::string::const_iterator const_iterator;
464
465 property_name (void) : std::string () { }
466 property_name (const std::string& s) : std::string (s) { }
467 property_name (const char *s) : std::string (s) { }
468
469 property_name (const property_name& name) : std::string (name) { }
470
471 property_name& operator = (const property_name& pname)
472 {
473 std::string::operator = (pname);
474 return *this;
475 }
476
477 operator std::string (void) const { return *this; }
478
479 // Case-insensitive comparison.
480 bool compare (const std::string& s, size_t limit = NPOS) const
481 {
482 const_iterator p1 = begin ();
483 const_iterator p2 = s.begin ();
484
485 size_t k = 0;
486
487 while (p1 != end () && p2 != s.end () && k++ < limit)
488 {
489 if (std::tolower (*p1) != std::tolower (*p2))
490 return false;
491
492 *p1++;
493 *p2++;
494 }
495
496 return (limit == NPOS) ? size () == s.size () : k == limit;
497 }
498 };
499
500 // ---------------------------------------------------------------------
501
502 class property_list
503 {
504 public:
505 typedef std::map<std::string, octave_value> pval_map_type;
506 typedef std::map<std::string, pval_map_type> plist_map_type;
507
508 typedef pval_map_type::iterator pval_map_iterator;
509 typedef pval_map_type::const_iterator pval_map_const_iterator;
510
511 typedef plist_map_type::iterator plist_map_iterator;
512 typedef plist_map_type::const_iterator plist_map_const_iterator;
513
514 property_list (const plist_map_type& m = plist_map_type ())
515 : plist_map (m) { }
516
517 ~property_list (void) { }
518
519 void set (const property_name& name, const octave_value& val)
520 {
521 size_t offset = 0;
522
523 size_t len = name.length ();
524
525 if (len > 4)
526 {
527 property_name pfx = name.substr (0, 4);
528
529 if (pfx.compare ("axes") || pfx.compare ("line")
530 || pfx.compare ("text"))
531 offset = 4;
532 else if (len > 5)
533 {
534 pfx = name.substr (0, 5);
535
536 if (pfx.compare ("image"))
537 offset = 5;
538 else if (len > 6)
539 {
540 pfx = name.substr (0, 6);
541
542 if (pfx.compare ("figure"))
543 offset = 6;
544 else if (len > 7)
545 {
546 pfx = name.substr (0, 7);
547
548 if (pfx.compare ("surface"))
549 offset = 7;
550 }
551 }
552 }
553
554 if (offset > 0)
555 {
556 // FIXME -- should we validate property names and values here?
557
558 std::string pname = name.substr (offset);
559
560 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
561 std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
562
563 bool remove = false;
564 if (val.is_string ())
565 {
566 property_name tval = val.string_value ();
567
568 remove = tval.compare ("remove");
569 }
570
571 pval_map_type& pval_map = plist_map[pfx];
572
573 if (remove)
574 {
575 pval_map_iterator p = pval_map.find (pname);
576
577 if (p != pval_map.end ())
578 pval_map.erase (p);
579 }
580 else
581 pval_map[pname] = val;
582 }
583 }
584
585 if (offset == 0)
586 error ("invalid default property specification");
587 }
588
589 octave_value lookup (const property_name& name) const
590 {
591 octave_value retval;
592
593 size_t offset = 0;
594
595 size_t len = name.length ();
596
597 if (len > 4)
598 {
599 property_name pfx = name.substr (0, 4);
600
601 if (pfx.compare ("axes") || pfx.compare ("line")
602 || pfx.compare ("text"))
603 offset = 4;
604 else if (len > 5)
605 {
606 pfx = name.substr (0, 5);
607
608 if (pfx.compare ("image"))
609 offset = 5;
610 else if (len > 6)
611 {
612 pfx = name.substr (0, 6);
613
614 if (pfx.compare ("figure"))
615 offset = 6;
616 else if (len > 7)
617 {
618 pfx = name.substr (0, 7);
619
620 if (pfx.compare ("surface"))
621 offset = 7;
622 }
623 }
624 }
625
626 if (offset > 0)
627 {
628 std::string pname = name.substr (offset);
629
630 std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower);
631 std::transform (pname.begin (), pname.end (), pname.begin (), tolower);
632
633 plist_map_const_iterator p = find (pfx);
634
635 if (p != end ())
636 {
637 const pval_map_type& pval_map = p->second;
638
639 pval_map_const_iterator q = pval_map.find (pname);
640
641 if (q != pval_map.end ())
642 retval = q->second;
643 }
644 }
645 }
646
647 return retval;
648 }
649
650 plist_map_iterator begin (void) { return plist_map.begin (); }
651 plist_map_const_iterator begin (void) const { return plist_map.begin (); }
652
653 plist_map_iterator end (void) { return plist_map.end (); }
654 plist_map_const_iterator end (void) const { return plist_map.end (); }
655
656 plist_map_iterator find (const std::string& go_name)
657 {
658 return plist_map.find (go_name);
659 }
660
661 plist_map_const_iterator find (const std::string& go_name) const
662 {
663 return plist_map.find (go_name);
664 }
665
666 Octave_map as_struct (const std::string& prefix_arg) const
667 {
668 Octave_map m;
669
670 for (plist_map_const_iterator p = begin (); p != end (); p++)
671 {
672 std::string prefix = prefix_arg + p->first;
673
674 const pval_map_type pval_map = p->second;
675
676 for (pval_map_const_iterator q = pval_map.begin ();
677 q != pval_map.end ();
678 q++)
679 m.assign (prefix + q->first, q->second);
680 }
681
682 return m;
683 }
684
685 private:
686 plist_map_type plist_map;
687 };
688
689 // ---------------------------------------------------------------------
690
691 typedef double graphics_handle;
692
693 // ---------------------------------------------------------------------
694
695 class base_graphics_object
696 {
697 public:
698 friend class graphics_object;
699
700 base_graphics_object (void) : count (1) { }
701
702 base_graphics_object (const base_graphics_object&) { }
703
704 virtual ~base_graphics_object (void) { }
705
706 virtual void mark_modified (void)
707 {
708 error ("base_graphics_object::mark_modified: invalid graphics object");
709 }
710
711 virtual void override_defaults (base_graphics_object&)
712 {
713 error ("base_graphics_object::override_defaults: invalid graphics object");
714 }
715
716 virtual void set_from_list (property_list&)
717 {
718 error ("base_graphics_object::set_from_list: invalid graphics object");
719 }
720
721 virtual void set (const property_name&, const octave_value&)
722 {
723 error ("base_graphics_object::set: invalid graphics object");
724 }
725
726 virtual void set_defaults (const std::string&)
727 {
728 error ("base_graphics_object::set_defaults: invalid graphics object");
729 }
730
731 virtual octave_value get (void) const
732 {
733 error ("base_graphics_object::get: invalid graphics object");
734 return octave_value ();
735 }
736
737 virtual octave_value get (const property_name&) const
738 {
739 error ("base_graphics_object::get: invalid graphics object");
740 return octave_value ();
741 }
742
743 virtual octave_value get_default (const property_name&) const;
744
745 virtual octave_value get_factory_default (const property_name&) const;
746
747 virtual octave_value get_defaults (void) const
748 {
749 error ("base_graphics_object::get_defaults: invalid graphics object");
750 return octave_value ();
751 }
752
753 virtual octave_value get_factory_defaults (void) const
754 {
755 error ("base_graphics_object::get_factory_defaults: invalid graphics object");
756 return octave_value ();
757 }
758
759 virtual graphics_handle get_parent (void) const
760 {
761 error ("base_graphics_object::get_parent: invalid graphics object");
762 return octave_NaN;
763 }
764
765 virtual void remove_child (const graphics_handle&)
766 {
767 error ("base_graphics_object::remove_child: invalid graphics object");
768 }
769
770 virtual void adopt (const graphics_handle&)
771 {
772 error ("base_graphics_object::adopt: invalid graphics object");
773 }
774
775 virtual void reparent (const graphics_handle&)
776 {
777 error ("base_graphics_object::reparent: invalid graphics object");
778 }
779
780 virtual void defaults (void) const
781 {
782 error ("base_graphics_object::default: invalid graphics object");
783 }
784
785 virtual bool valid_object (void) const { return false; }
786
787 virtual std::string type (void) const { return "unknown"; }
788
789 bool isa (const std::string& go_name) const
790 {
791 return type () == go_name;
792 }
793
794 protected:
795 // A reference count.
796 int count;
797 };
798
799 class graphics_object
800 {
801 public:
802 graphics_object (void) : rep (new base_graphics_object ()) { }
803
804 graphics_object (base_graphics_object *new_rep)
805 : rep (new_rep) { }
806
807 graphics_object (const graphics_object& obj)
808 {
809 rep = obj.rep;
810 rep->count++;
811 }
812
813 graphics_object& operator = (const graphics_object& obj)
814 {
815 if (rep != obj.rep)
816 {
817 if (--rep->count == 0)
818 delete rep;
819
820 rep = obj.rep;
821 rep->count++;
822 }
823
824 return *this;
825 }
826
827 ~graphics_object (void)
828 {
829 if (--rep->count == 0)
830 delete rep;
831 }
832
833 void mark_modified (void) { rep->mark_modified (); }
834
835 void override_defaults (base_graphics_object& obj)
836 {
837 rep->override_defaults (obj);
838 }
839
840 void set_from_list (property_list& plist)
841 {
842 rep->set_from_list (plist);
843 }
844
845 void set (const property_name& name, const octave_value& val)
846 {
847 rep->set (name, val);
848 }
849
850 void set (const octave_value_list& args)
851 {
852 int nargin = args.length ();
853
854 if (nargin == 0)
855 rep->defaults ();
856 else if (nargin % 2 == 0)
857 {
858 for (int i = 0; i < nargin; i += 2)
859 {
860 property_name name = args(i).string_value ();
861
862 if (! error_state)
863 {
864 octave_value val = args(i+1);
865
866 if (val.is_string ())
867 {
868 property_name tval = val.string_value ();
869
870 if (tval.compare ("default"))
871 val = get_default (name);
872 else if (tval.compare ("factory"))
873 val = get_factory_default (name);
874 }
875
876 if (error_state)
877 break;
878
879 rep->set (name, val);
880 }
881 else
882 error ("set: expecting argument %d to be a property name", i);
883 }
884 }
885 else
886 error ("set: invalid number of arguments");
887 }
888
889 void set_defaults (const std::string& mode)
890 {
891 rep->set_defaults (mode);
892 }
893
894 octave_value get (void) const
895 {
896 return rep->get ();
897 }
898
899 octave_value get (const property_name& name) const
900 {
901 return name.compare ("default")
902 ? get_defaults ()
903 : (name.compare ("factory")
904 ? get_factory_defaults () : rep->get (name));
905 }
906
907 octave_value get_default (const property_name& name) const
908 {
909 return rep->get_default (name);
910 }
911
912 octave_value get_factory_default (const property_name& name) const
913 {
914 return rep->get_factory_default (name);
915 }
916
917 octave_value get_defaults (void) const { return rep->get_defaults (); }
918
919 octave_value get_factory_defaults (void) const
920 {
921 return rep->get_factory_defaults ();
922 }
923
924 graphics_handle get_parent (void) const { return rep->get_parent (); }
925
926 void remove_child (const graphics_handle& h) { return rep->remove_child (h); }
927
928 void adopt (const graphics_handle& h) { return rep->adopt (h); }
929
930 void reparent (const graphics_handle& h) { return rep->reparent (h); }
931
932 void defaults (void) const { rep->defaults (); }
933
934 bool isa (const std::string& go_name) const { return rep->isa (go_name); }
935
936 bool valid_object (void) const { return rep->valid_object (); }
937
938 operator bool (void) const { return rep->valid_object (); }
939
940 private:
941 base_graphics_object *rep;
942 };
943
944 // ---------------------------------------------------------------------
945
946 class gh_manager
947 {
948 protected:
949
950 gh_manager (void);
951
952 public:
953
954 static bool instance_ok (void)
955 {
956 bool retval = true;
957
958 if (! instance)
959 instance = new gh_manager ();
960
961 if (! instance)
962 {
963 ::error ("unable to create gh_manager!");
964
965 retval = false;
966 }
967
968 return retval;
969 }
970
971 static void free (const graphics_handle& h)
972 {
973 if (instance_ok ())
974 instance->do_free (h);
975 }
976
977 static graphics_handle lookup (double val)
978 {
979 return instance_ok () ? instance->do_lookup (val) : graphics_handle ();
980 }
981
982 static graphics_object get_object (const graphics_handle& h)
983 {
984 return instance_ok () ? instance->do_get_object (h) : graphics_object ();
985 }
986
987 static graphics_handle
988 make_graphics_handle (const std::string& go_name,
989 const graphics_handle& parent)
990 {
991 return instance_ok ()
992 ? instance->do_make_graphics_handle (go_name, parent) : octave_NaN;
993 }
994
995 static graphics_handle make_figure_handle (double val)
996 {
997 return instance_ok ()
998 ? instance->do_make_figure_handle (val) : octave_NaN;
999 }
1000
1001 static void push_figure (const graphics_handle& h)
1002 {
1003 if (instance_ok ())
1004 instance->do_push_figure (h);
1005 }
1006
1007 static void pop_figure (const graphics_handle& h)
1008 {
1009 if (instance_ok ())
1010 instance->do_pop_figure (h);
1011 }
1012
1013 static graphics_handle current_figure (void)
1014 {
1015 return instance_ok () ? instance->do_current_figure () : octave_NaN;
1016 }
1017
1018 static Matrix handle_list (void)
1019 {
1020 return instance_ok () ? instance->do_handle_list () : Matrix ();
1021 }
1022
1023 static Matrix figure_handle_list (void)
1024 {
1025 return instance_ok () ? instance->do_figure_handle_list () : Matrix ();
1026 }
1027
1028 private:
1029
1030 static gh_manager *instance;
1031
1032 typedef std::map<graphics_handle, graphics_object>::iterator iterator;
1033 typedef std::map<graphics_handle, graphics_object>::const_iterator const_iterator;
1034
1035 typedef std::set<graphics_handle>::iterator free_list_iterator;
1036 typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
1037
1038 typedef std::list<graphics_handle>::iterator figure_list_iterator;
1039 typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
1040
1041 // A map of handles to graphics objects.
1042 std::map<graphics_handle, graphics_object> handle_map;
1043
1044 // The available graphics handles.
1045 std::set<graphics_handle> handle_free_list;
1046
1047 // The next handle available if handle_free_list is empty.
1048 graphics_handle next_handle;
1049
1050 // The allocated figure handles. Top of the stack is most recently
1051 // created.
1052 std::list<graphics_handle> figure_list;
1053
1054 graphics_handle get_handle (const std::string& go_name)
1055 {
1056 graphics_handle retval;
1057
1058 if (go_name == "figure")
1059 {
1060 // We always want the lowest unused figure number.
1061
1062 retval = 1;
1063
1064 while (handle_map.find (retval) != handle_map.end ())
1065 retval++;
1066 }
1067 else
1068 {
1069 free_list_iterator p = handle_free_list.begin ();
1070
1071 if (p != handle_free_list.end ())
1072 {
1073 retval = *p;
1074 handle_free_list.erase (p);
1075 }
1076 else
1077 retval = next_handle--;
1078 }
1079
1080 return retval;
1081 }
1082
1083 void do_free (const graphics_handle& h)
1084 {
1085 if (h != 0)
1086 {
1087 iterator p = handle_map.find (h);
1088
1089 if (p != handle_map.end ())
1090 {
1091 handle_map.erase (p);
1092
1093 if (h < 0)
1094 handle_free_list.insert (h);
1095 }
1096 else
1097 error ("graphics_handle::free: invalid object %g", h);
1098 }
1099 else
1100 error ("graphics_handle::free: can't delete root figure");
1101 }
1102
1103 graphics_handle do_lookup (double val)
1104 {
1105 iterator p = handle_map.find (val);
1106
1107 return (p != handle_map.end ()) ? p->first : octave_NaN;
1108 }
1109
1110 graphics_object do_get_object (const graphics_handle& h)
1111 {
1112 iterator p = handle_map.find (h);
1113
1114 return (p != handle_map.end ()) ? p->second : graphics_object ();
1115 }
1116
1117 graphics_handle do_make_graphics_handle (const std::string& go_name,
1118 const graphics_handle& p);
1119
1120 graphics_handle do_make_figure_handle (double val);
1121
1122 Matrix do_handle_list (void)
1123 {
1124 Matrix retval (1, handle_map.size ());
1125 octave_idx_type i = 0;
1126 for (const_iterator p = handle_map.begin (); p != handle_map.end (); p++)
1127 retval(i++) = p->first;
1128 return retval;
1129 }
1130
1131 Matrix do_figure_handle_list (void)
1132 {
1133 Matrix retval (1, figure_list.size ());
1134 octave_idx_type i = 0;
1135 for (const_figure_list_iterator p = figure_list.begin ();
1136 p != figure_list.end ();
1137 p++)
1138 retval(i++) = *p;
1139 return retval;
1140 }
1141
1142 void do_push_figure (const graphics_handle& h);
1143
1144 void do_pop_figure (const graphics_handle& h);
1145
1146 graphics_handle do_current_figure (void) const
1147 {
1148 return figure_list.empty () ? octave_NaN : figure_list.front ();
1149 }
1150 };
1151 435
1152 gh_manager *gh_manager::instance = 0; 436 gh_manager *gh_manager::instance = 0;
1153
1154 // ---------------------------------------------------------------------
1155 437
1156 static void 438 static void
1157 xset (const graphics_handle& h, const property_name& name, 439 xset (const graphics_handle& h, const property_name& name,
1158 const octave_value& val) 440 const octave_value& val)
1159 { 441 {
1307 } 589 }
1308 590
1309 return ok ? new_kids : kids; 591 return ok ? new_kids : kids;
1310 } 592 }
1311 593
1312 class base_properties 594 void
1313 { 595 base_properties::set_from_list (base_graphics_object& obj,
1314 public: 596 property_list& defaults)
1315 base_properties (const std::string& t = "unknown", 597 {
1316 const graphics_handle& mh = octave_NaN, 598 std::string go_name = graphics_object_name ();
1317 const graphics_handle& p = octave_NaN) 599
1318 : type (t), __modified__ (true), __myhandle__ (mh), parent (p), 600 property_list::plist_map_const_iterator p = defaults.find (go_name);
1319 children () { } 601
1320 602 if (p != defaults.end ())
1321 virtual ~base_properties (void) { } 603 {
1322 604 const property_list::pval_map_type pval_map = p->second;
1323 virtual std::string graphics_object_name (void) const = 0; 605
1324 606 for (property_list::pval_map_const_iterator q = pval_map.begin ();
1325 void mark_modified (void) 607 q != pval_map.end ();
1326 { 608 q++)
1327 __modified__ = true; 609 {
1328 graphics_object parent_obj = gh_manager::get_object (parent); 610 std::string pname = q->first;
1329 parent_obj.mark_modified (); 611
1330 } 612 obj.set (pname, q->second);
1331 613
1332 void override_defaults (base_graphics_object& obj) 614 if (error_state)
1333 {
1334 graphics_object parent_obj = gh_manager::get_object (parent);
1335 parent_obj.override_defaults (obj);
1336 }
1337
1338 // Look through DEFAULTS for properties with given CLASS_NAME, and
1339 // apply them to the current object with set (virtual method).
1340
1341 void set_from_list (base_graphics_object& obj, property_list& defaults)
1342 {
1343 std::string go_name = graphics_object_name ();
1344
1345 property_list::plist_map_const_iterator p = defaults.find (go_name);
1346
1347 if (p != defaults.end ())
1348 {
1349 const property_list::pval_map_type pval_map = p->second;
1350
1351 for (property_list::pval_map_const_iterator q = pval_map.begin ();
1352 q != pval_map.end ();
1353 q++)
1354 {
1355 std::string pname = q->first;
1356
1357 obj.set (pname, q->second);
1358
1359 if (error_state)
1360 {
1361 error ("error setting default property %s", pname.c_str ());
1362 break;
1363 }
1364 }
1365 }
1366 }
1367
1368 virtual void set (const property_name& name, const octave_value& val) = 0;
1369
1370 graphics_handle get_parent (void) const { return parent; }
1371
1372 void remove_child (const graphics_handle& h)
1373 {
1374 octave_idx_type k = -1;
1375 octave_idx_type n = children.numel ();
1376 for (octave_idx_type i = 0; i < n; i++)
1377 {
1378 if (h == children(i))
1379 {
1380 k = i;
1381 break;
1382 }
1383 }
1384
1385 if (k >= 0)
1386 {
1387 Matrix new_kids (1, n-1);
1388 octave_idx_type j = 0;
1389 for (octave_idx_type i = 0; i < n; i++)
1390 {
1391 if (i != k)
1392 new_kids(j++) = children(i);
1393 }
1394 children = new_kids;
1395 }
1396 }
1397
1398 void adopt (const graphics_handle& h)
1399 {
1400 octave_idx_type n = children.numel ();
1401 children.resize (1, n+1);
1402 children(n) = h;
1403 }
1404
1405 void set_parent (const octave_value& val)
1406 {
1407 double tmp = val.double_value ();
1408
1409 graphics_handle new_parent = octave_NaN;
1410
1411 if (! error_state)
1412 {
1413 new_parent = gh_manager::lookup (tmp);
1414
1415 if (! xisnan (new_parent))
1416 {
1417 graphics_object parent_obj = gh_manager::get_object (parent);
1418
1419 parent_obj.remove_child (__myhandle__);
1420
1421 parent = new_parent;
1422
1423 ::adopt (parent, __myhandle__);
1424 }
1425 else
1426 error ("set: invalid graphics handle (= %g) for parent", tmp);
1427 }
1428 else
1429 error ("set: expecting parent to be a graphics handle");
1430 }
1431
1432 void reparent (const graphics_handle& new_parent) { parent = new_parent; }
1433
1434 virtual void delete_children (void)
1435 {
1436 octave_idx_type n = children.numel ();
1437
1438 for (octave_idx_type i = 0; i < n; i++)
1439 gh_manager::free (children(i));
1440 }
1441
1442 protected:
1443 std::string type;
1444 bool __modified__;
1445 graphics_handle __myhandle__;
1446 graphics_handle parent;
1447 Matrix children;
1448 };
1449
1450 // ---------------------------------------------------------------------
1451
1452 class root_figure : public base_graphics_object
1453 {
1454 public:
1455 class root_figure_properties : public base_properties
1456 {
1457 public:
1458 root_figure_properties (void)
1459 : base_properties ("root figure", 0, octave_NaN),
1460 currentfigure (octave_NaN),
1461 visible ("on")
1462 { }
1463
1464 ~root_figure_properties (void) { }
1465
1466 void set (const property_name& name, const octave_value& val)
1467 {
1468 if (name.compare ("currentfigure"))
1469 {
1470 octave_value tval = empty_to_nan (val);
1471
1472 if (is_handle (tval))
1473 { 615 {
1474 currentfigure = tval.double_value (); 616 error ("error setting default property %s", pname.c_str ());
1475 617 break;
1476 gh_manager::push_figure (currentfigure);
1477 } 618 }
1478 else 619 }
1479 gripe_set_invalid ("currentfigure"); 620 }
1480 } 621 }
1481 else if (name.compare ("children")) 622
1482 children = maybe_set_children (children, val); 623 void
1483 else if (name.compare ("visible")) 624 base_properties::remove_child (const graphics_handle& h)
1484 visible = val; 625 {
626 octave_idx_type k = -1;
627 octave_idx_type n = children.numel ();
628 for (octave_idx_type i = 0; i < n; i++)
629 {
630 if (h == children(i))
631 {
632 k = i;
633 break;
634 }
635 }
636
637 if (k >= 0)
638 {
639 Matrix new_kids (1, n-1);
640 octave_idx_type j = 0;
641 for (octave_idx_type i = 0; i < n; i++)
642 {
643 if (i != k)
644 new_kids(j++) = children(i);
645 }
646 children = new_kids;
647 }
648 }
649
650 void base_properties::set_parent (const octave_value& val)
651 {
652 double tmp = val.double_value ();
653
654 graphics_handle new_parent = octave_NaN;
655
656 if (! error_state)
657 {
658 new_parent = gh_manager::lookup (tmp);
659
660 if (! xisnan (new_parent))
661 {
662 graphics_object parent_obj = gh_manager::get_object (parent);
663
664 parent_obj.remove_child (__myhandle__);
665
666 parent = new_parent;
667
668 ::adopt (parent, __myhandle__);
669 }
1485 else 670 else
1486 warning ("set: invalid property `%s'", name.c_str ()); 671 error ("set: invalid graphics handle (= %g) for parent", tmp);
1487 } 672 }
1488 673 else
1489 octave_value get (void) const 674 error ("set: expecting parent to be a graphics handle");
1490 { 675 }
1491 Octave_map m; 676
1492 677 void
1493 m.assign ("type", type); 678 root_figure::root_figure_properties::set (const property_name& name,
1494 m.assign ("currentfigure", nan_to_empty (currentfigure)); 679 const octave_value& val)
1495 m.assign ("children", children); 680 {
1496 m.assign ("visible", visible); 681 if (name.compare ("currentfigure"))
1497 682 {
1498 return m; 683 octave_value tval = empty_to_nan (val);
1499 } 684
1500 685 if (is_handle (tval))
1501 octave_value get (const property_name& name) const 686 {
1502 { 687 currentfigure = tval.double_value ();
1503 octave_value retval; 688
1504 689 gh_manager::push_figure (currentfigure);
1505 if (name.compare ("type")) 690 }
1506 retval = type;
1507 else if (name.compare ("currentfigure"))
1508 retval = nan_to_empty (currentfigure);
1509 else if (name.compare ("children"))
1510 retval = children;
1511 else if (name.compare ("visible"))
1512 retval = visible;
1513 else 691 else
1514 warning ("get: invalid property `%s'", name.c_str ()); 692 gripe_set_invalid ("currentfigure");
1515 693 }
1516 return retval; 694 else if (name.compare ("children"))
1517 } 695 children = maybe_set_children (children, val);
1518 696 else if (name.compare ("visible"))
1519 std::string graphics_object_name (void) const { return go_name; } 697 visible = val;
1520 698 else
1521 private: 699 warning ("set: invalid property `%s'", name.c_str ());
1522 graphics_handle currentfigure; 700 }
1523 octave_value visible; 701
1524 702 octave_value root_figure::root_figure_properties::get (void) const
1525 static std::string go_name; 703 {
1526 }; 704 Octave_map m;
1527 705
1528 root_figure_properties properties; 706 m.assign ("type", type);
1529 707 m.assign ("currentfigure", nan_to_empty (currentfigure));
1530 public: 708 m.assign ("children", children);
1531 709 m.assign ("visible", visible);
1532 root_figure (void) : properties (), default_properties () { } 710
1533 711 return m;
1534 ~root_figure (void) { properties.delete_children (); } 712 }
1535 713
1536 std::string type (void) const { return properties.graphics_object_name (); } 714 octave_value
1537 715 root_figure::root_figure_properties::get (const property_name& name) const
1538 void mark_modified (void) { } 716 {
1539 717 octave_value retval;
1540 void override_defaults (base_graphics_object& obj) 718
1541 { 719 if (name.compare ("type"))
1542 // Now override with our defaults. If the default_properties 720 retval = type;
1543 // list includes the properties for all defaults (line, 721 else if (name.compare ("currentfigure"))
1544 // surface, etc.) then we don't have to know the type of OBJ 722 retval = nan_to_empty (currentfigure);
1545 // here, we just call its set function and let it decide which 723 else if (name.compare ("children"))
1546 // properties from the list to use. 724 retval = children;
1547 obj.set_from_list (default_properties); 725 else if (name.compare ("visible"))
1548 } 726 retval = visible;
1549 727 else
1550 void set_from_list (property_list& plist) 728 warning ("get: invalid property `%s'", name.c_str ());
1551 { 729
1552 properties.set_from_list (*this, plist); 730 return retval;
1553 } 731 }
1554
1555 void set (const property_name& name, const octave_value& value)
1556 {
1557 if (name.compare ("default", 7))
1558 // strip "default", pass rest to function that will
1559 // parse the remainder and add the element to the
1560 // default_properties map.
1561 default_properties.set (name.substr (7), value);
1562 else
1563 properties.set (name, value);
1564 }
1565
1566 octave_value get (void) const
1567 {
1568 return properties.get ();
1569 }
1570
1571 octave_value get (const property_name& name) const
1572 {
1573 octave_value retval;
1574
1575 if (name.compare ("default", 7))
1576 return get_default (name.substr (7));
1577 else if (name.compare ("factory", 7))
1578 return get_factory_default (name.substr (7));
1579 else
1580 retval = properties.get (name);
1581
1582 return retval;
1583 }
1584
1585 octave_value get_default (const property_name& name) const
1586 {
1587 octave_value retval = default_properties.lookup (name);
1588
1589 if (retval.is_undefined ())
1590 error ("get: invalid default property `%s'", name.c_str ());
1591
1592 return retval;
1593 }
1594
1595 octave_value get_factory_default (const property_name& name) const
1596 {
1597 octave_value retval = factory_properties.lookup (name);
1598
1599 if (retval.is_undefined ())
1600 error ("get: invalid factory default property `%s'", name.c_str ());
1601
1602 return retval;
1603 }
1604
1605 octave_value get_defaults (void) const
1606 {
1607 return default_properties.as_struct ("default");
1608 }
1609
1610 octave_value get_factory_defaults (void) const
1611 {
1612 return factory_properties.as_struct ("factory");
1613 }
1614
1615 graphics_handle get_parent (void) const { return properties.get_parent (); }
1616
1617 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
1618
1619 void adopt (const graphics_handle& h) { properties.adopt (h); }
1620
1621 void reparent (const graphics_handle& np) { properties.reparent (np); }
1622
1623 bool valid_object (void) const { return true; }
1624
1625 private:
1626 property_list default_properties;
1627
1628 static property_list factory_properties;
1629
1630 static property_list::plist_map_type init_factory_properties (void);
1631 };
1632 732
1633 property_list 733 property_list
1634 root_figure::factory_properties = root_figure::init_factory_properties (); 734 root_figure::factory_properties = root_figure::init_factory_properties ();
1635 735
1636 std::string root_figure::root_figure_properties::go_name ("root figure"); 736 std::string root_figure::root_figure_properties::go_name ("root figure");
1637 737
1638 // --------------------------------------------------------------------- 738 // ---------------------------------------------------------------------
1639 739
1640 class figure : public base_graphics_object 740 figure::figure_properties::figure_properties (const graphics_handle& mh,
1641 { 741 const graphics_handle& p)
1642 public: 742 : base_properties (go_name, mh, p),
1643 class figure_properties : public base_properties 743 __plot_stream__ (Matrix ()),
1644 { 744 nextplot ("replace"),
1645 public: 745 closerequestfcn (make_fcn_handle ("closereq")),
1646 figure_properties (const graphics_handle& mh, const graphics_handle& p) 746 currentaxes (octave_NaN),
1647 : base_properties (go_name, mh, p), 747 colormap (),
1648 __plot_stream__ (Matrix ()), 748 visible ("on"),
1649 nextplot ("replace"), 749 paperorientation ("portrait")
1650 closerequestfcn (make_fcn_handle ("closereq")), 750 { }
1651 currentaxes (octave_NaN), 751
1652 colormap (), 752 void
1653 visible ("on"), 753 figure::figure_properties::set (const property_name& name,
1654 paperorientation ("portrait") 754 const octave_value& val)
1655 { } 755 {
1656 756 bool modified = true;
1657 ~figure_properties (void) { } 757
1658 758 if (name.compare ("children"))
1659 void set (const property_name& name, const octave_value& val) 759 children = maybe_set_children (children, val);
1660 { 760 else if (name.compare ("__modified__"))
1661 bool modified = true; 761 {
1662 762 __modified__ = val.bool_value ();
1663 if (name.compare ("children")) 763 modified = false;
1664 children = maybe_set_children (children, val); 764 }
1665 else if (name.compare ("__modified__")) 765 else if (name.compare ("__plot_stream__"))
1666 { 766 __plot_stream__ = val;
1667 __modified__ = val.bool_value (); 767 else if (name.compare ("nextplot"))
1668 modified = false; 768 nextplot = val;
1669 } 769 else if (name.compare ("closerequestfcn"))
1670 else if (name.compare ("__plot_stream__")) 770 closerequestfcn = val;
1671 __plot_stream__ = val; 771 else if (name.compare ("currentaxes"))
1672 else if (name.compare ("nextplot")) 772 {
1673 nextplot = val; 773 octave_value tval = empty_to_nan (val);
1674 else if (name.compare ("closerequestfcn")) 774
1675 closerequestfcn = val; 775 if (is_handle (tval))
1676 else if (name.compare ("currentaxes")) 776 currentaxes = tval.double_value ();
1677 {
1678 octave_value tval = empty_to_nan (val);
1679
1680 if (is_handle (tval))
1681 currentaxes = tval.double_value ();
1682 else
1683 gripe_set_invalid ("currentaxes");
1684 }
1685 else if (name.compare ("colormap"))
1686 colormap = colormap_property (val);
1687 else if (name.compare ("visible"))
1688 {
1689 std::string s = val.string_value ();
1690
1691 if (! error_state)
1692 {
1693 if (s == "on")
1694 xset (0, "currentfigure", __myhandle__);
1695
1696 visible = val;
1697 }
1698 }
1699 else if (name.compare ("paperorientation"))
1700 paperorientation = val;
1701 else 777 else
1702 { 778 gripe_set_invalid ("currentaxes");
1703 modified = false; 779 }
1704 warning ("set: invalid property `%s'", name.c_str ()); 780 else if (name.compare ("colormap"))
1705 } 781 colormap = colormap_property (val);
1706 782 else if (name.compare ("visible"))
1707 if (modified) 783 {
1708 mark_modified (); 784 std::string s = val.string_value ();
1709 } 785
1710 786 if (! error_state)
1711 octave_value get (void) const 787 {
1712 { 788 if (s == "on")
1713 Octave_map m; 789 xset (0, "currentfigure", __myhandle__);
1714 790
1715 m.assign ("type", type); 791 visible = val;
1716 m.assign ("parent", parent); 792 }
1717 m.assign ("children", children); 793 }
1718 m.assign ("__modified__", __modified__); 794 else if (name.compare ("paperorientation"))
1719 m.assign ("__plot_stream__", __plot_stream__); 795 paperorientation = val;
1720 m.assign ("nextplot", nextplot); 796 else
1721 m.assign ("closerequestfcn", closerequestfcn); 797 {
1722 m.assign ("currentaxes", nan_to_empty (currentaxes)); 798 modified = false;
1723 m.assign ("colormap", colormap); 799 warning ("set: invalid property `%s'", name.c_str ());
1724 m.assign ("visible", visible); 800 }
1725 m.assign ("paperorientation", paperorientation); 801
1726 802 if (modified)
1727 return m; 803 mark_modified ();
1728 } 804 }
1729 805
1730 octave_value get (const property_name& name) const 806 octave_value
1731 { 807 figure::figure_properties::get (void) const
1732 octave_value retval; 808 {
1733 809 Octave_map m;
1734 if (name.compare ("type")) 810
1735 retval = type; 811 m.assign ("type", type);
1736 else if (name.compare ("parent")) 812 m.assign ("parent", parent);
1737 retval = parent; 813 m.assign ("children", children);
1738 else if (name.compare ("children")) 814 m.assign ("__modified__", __modified__);
1739 retval = children; 815 m.assign ("__plot_stream__", __plot_stream__);
1740 else if (name.compare ("__modified__")) 816 m.assign ("nextplot", nextplot);
1741 retval = __modified__; 817 m.assign ("closerequestfcn", closerequestfcn);
1742 else if (name.compare ("__plot_stream__")) 818 m.assign ("currentaxes", nan_to_empty (currentaxes));
1743 retval = __plot_stream__; 819 m.assign ("colormap", colormap);
1744 else if (name.compare ("nextplot")) 820 m.assign ("visible", visible);
1745 retval = nextplot; 821 m.assign ("paperorientation", paperorientation);
1746 else if (name.compare ("closerequestfcn")) 822
1747 retval = closerequestfcn; 823 return m;
1748 else if (name.compare ("currentaxes")) 824 }
1749 retval = nan_to_empty (currentaxes); 825
1750 else if (name.compare ("colormap")) 826 octave_value
1751 retval = colormap; 827 figure::figure_properties::get (const property_name& name) const
1752 else if (name.compare ("visible")) 828 {
1753 retval = visible; 829 octave_value retval;
1754 else if (name.compare ("paperorientation")) 830
1755 retval = paperorientation; 831 if (name.compare ("type"))
1756 else 832 retval = type;
1757 warning ("get: invalid property `%s'", name.c_str ()); 833 else if (name.compare ("parent"))
1758 834 retval = parent;
1759 return retval; 835 else if (name.compare ("children"))
1760 } 836 retval = children;
1761 837 else if (name.compare ("__modified__"))
1762 void close (void) 838 retval = __modified__;
1763 { 839 else if (name.compare ("__plot_stream__"))
1764 if (! __plot_stream__.is_empty ()) 840 retval = __plot_stream__;
1765 { 841 else if (name.compare ("nextplot"))
1766 octave_value_list args; 842 retval = nextplot;
1767 args(1) = "\nquit;\n"; 843 else if (name.compare ("closerequestfcn"))
1768 args(0) = __plot_stream__; 844 retval = closerequestfcn;
1769 feval ("fputs", args); 845 else if (name.compare ("currentaxes"))
1770 args.resize (1); 846 retval = nan_to_empty (currentaxes);
1771 feval ("fflush", args); 847 else if (name.compare ("colormap"))
1772 feval ("pclose", args); 848 retval = colormap;
1773 } 849 else if (name.compare ("visible"))
1774 850 retval = visible;
1775 gh_manager::pop_figure (__myhandle__); 851 else if (name.compare ("paperorientation"))
1776 852 retval = paperorientation;
1777 xset (0, "currentfigure", gh_manager::current_figure ()); 853 else
1778 } 854 warning ("get: invalid property `%s'", name.c_str ());
1779 855
1780 std::string graphics_object_name (void) const { return go_name; } 856 return retval;
1781 857 }
1782 static property_list::pval_map_type factory_defaults (void) 858
1783 { 859 void figure::figure_properties::close (void)
1784 property_list::pval_map_type m; 860 {
1785 861 if (! __plot_stream__.is_empty ())
1786 m["nextplot"] = "replace"; 862 {
1787 // m["closerequestfcn"] = make_fcn_handle ("closereq"); 863 octave_value_list args;
1788 m["colormap"] = colormap_property (); 864 args(1) = "\nquit;\n";
1789 m["visible"] = "on"; 865 args(0) = __plot_stream__;
1790 m["paperorientation"] = "portrait"; 866 feval ("fputs", args);
1791 867 args.resize (1);
1792 return m; 868 feval ("fflush", args);
1793 } 869 feval ("pclose", args);
1794 870 }
1795 private: 871
1796 octave_value __plot_stream__; 872 gh_manager::pop_figure (__myhandle__);
1797 octave_value nextplot; 873
1798 octave_value closerequestfcn; 874 xset (0, "currentfigure", gh_manager::current_figure ());
1799 graphics_handle currentaxes; 875 }
1800 colormap_property colormap; 876
1801 octave_value visible; 877 property_list::pval_map_type figure::figure_properties::factory_defaults (void)
1802 octave_value paperorientation; 878 {
1803 879 property_list::pval_map_type m;
1804 static std::string go_name; 880
1805 }; 881 m["nextplot"] = "replace";
1806 882 // m["closerequestfcn"] = make_fcn_handle ("closereq");
1807 figure_properties properties; 883 m["colormap"] = colormap_property ();
1808 884 m["visible"] = "on";
1809 public: 885 m["paperorientation"] = "portrait";
1810 figure (const graphics_handle& mh, const graphics_handle& p) 886
1811 : base_graphics_object (), properties (mh, p), default_properties () 887 return m;
1812 { 888 }
1813 properties.override_defaults (*this);
1814 }
1815
1816 ~figure (void)
1817 {
1818 properties.delete_children ();
1819 properties.close ();
1820 }
1821
1822 std::string type (void) const { return properties.graphics_object_name (); }
1823
1824 void mark_modified (void) { properties.mark_modified (); }
1825
1826 void override_defaults (base_graphics_object& obj)
1827 {
1828 // Allow parent (root figure) to override first (properties knows how
1829 // to find the parent object).
1830 properties.override_defaults (obj);
1831
1832 // Now override with our defaults. If the default_properties
1833 // list includes the properties for all defaults (line,
1834 // surface, etc.) then we don't have to know the type of OBJ
1835 // here, we just call its set function and let it decide which
1836 // properties from the list to use.
1837 obj.set_from_list (default_properties);
1838 }
1839
1840 void set_from_list (property_list& plist)
1841 {
1842 properties.set_from_list (*this, plist);
1843 }
1844
1845 void set (const property_name& name, const octave_value& value)
1846 {
1847 if (name.compare ("default", 7))
1848 // strip "default", pass rest to function that will
1849 // parse the remainder and add the element to the
1850 // default_properties map.
1851 default_properties.set (name.substr (7), value);
1852 else
1853 properties.set (name, value);
1854 }
1855
1856 octave_value get (void) const
1857 {
1858 return properties.get ();
1859 }
1860
1861 octave_value get (const property_name& name) const
1862 {
1863 octave_value retval;
1864
1865 if (name.compare ("default", 7))
1866 retval = get_default (name.substr (7));
1867 else
1868 retval = properties.get (name);
1869
1870 return retval;
1871 }
1872
1873 octave_value get_default (const property_name& name) const
1874 {
1875 octave_value retval = default_properties.lookup (name);
1876
1877 if (retval.is_undefined ())
1878 {
1879 graphics_handle parent = get_parent ();
1880 graphics_object parent_obj = gh_manager::get_object (parent);
1881
1882 retval = parent_obj.get_default (name);
1883 }
1884
1885 return retval;
1886 }
1887
1888 octave_value get_defaults (void) const
1889 {
1890 return default_properties.as_struct ("default");
1891 }
1892
1893 graphics_handle get_parent (void) const { return properties.get_parent (); }
1894
1895 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
1896
1897 void adopt (const graphics_handle& h) { properties.adopt (h); }
1898
1899 void reparent (const graphics_handle& np) { properties.reparent (np); }
1900
1901 bool valid_object (void) const { return true; }
1902
1903 private:
1904 property_list default_properties;
1905 };
1906 889
1907 std::string figure::figure_properties::go_name ("figure"); 890 std::string figure::figure_properties::go_name ("figure");
1908 891
1909 // --------------------------------------------------------------------- 892 // ---------------------------------------------------------------------
1910 893
1911 class axes : public base_graphics_object 894 axes::axes_properties::axes_properties (const graphics_handle& mh,
1912 { 895 const graphics_handle& p)
1913 public: 896 : base_properties (go_name, mh, p),
1914 class axes_properties : public base_properties 897 position (Matrix ()),
1915 { 898 title (octave_NaN),
1916 public: 899 box ("on"),
1917 axes_properties (const graphics_handle& mh, const graphics_handle& p) 900 key ("off"),
1918 : base_properties (go_name, mh, p), 901 keybox ("off"),
1919 position (Matrix ()), 902 keypos (1),
1920 title (octave_NaN), 903 dataaspectratio (Matrix (1, 3, 1.0)),
1921 box ("on"), 904 dataaspectratiomode ("auto"),
1922 key ("off"), 905 xlim (),
1923 keybox ("off"), 906 ylim (),
1924 keypos (1), 907 zlim (),
1925 dataaspectratio (Matrix (1, 3, 1.0)), 908 xlimmode ("auto"),
1926 dataaspectratiomode ("auto"), 909 ylimmode ("auto"),
1927 xlim (), 910 zlimmode ("auto"),
1928 ylim (), 911 xlabel (octave_NaN),
1929 zlim (), 912 ylabel (octave_NaN),
1930 xlimmode ("auto"), 913 zlabel (octave_NaN),
1931 ylimmode ("auto"), 914 xgrid ("off"),
1932 zlimmode ("auto"), 915 ygrid ("off"),
1933 xlabel (octave_NaN), 916 zgrid ("off"),
1934 ylabel (octave_NaN), 917 xminorgrid ("off"),
1935 zlabel (octave_NaN), 918 yminorgrid ("off"),
1936 xgrid ("off"), 919 zminorgrid ("off"),
1937 ygrid ("off"), 920 xtick (Matrix ()),
1938 zgrid ("off"), 921 ytick (Matrix ()),
1939 xminorgrid ("off"), 922 ztick (Matrix ()),
1940 yminorgrid ("off"), 923 xtickmode ("auto"),
1941 zminorgrid ("off"), 924 ytickmode ("auto"),
1942 xtick (Matrix ()), 925 ztickmode ("auto"),
1943 ytick (Matrix ()), 926 xticklabel (""),
1944 ztick (Matrix ()), 927 yticklabel (""),
1945 xtickmode ("auto"), 928 zticklabel (""),
1946 ytickmode ("auto"), 929 xticklabelmode ("auto"),
1947 ztickmode ("auto"), 930 yticklabelmode ("auto"),
1948 xticklabel (""), 931 zticklabelmode ("auto"),
1949 yticklabel (""), 932 xscale ("linear"),
1950 zticklabel (""), 933 yscale ("linear"),
1951 xticklabelmode ("auto"), 934 zscale ("linear"),
1952 yticklabelmode ("auto"), 935 xdir ("normal"),
1953 zticklabelmode ("auto"), 936 ydir ("normal"),
1954 xscale ("linear"), 937 zdir ("normal"),
1955 yscale ("linear"), 938 view (),
1956 zscale ("linear"), 939 nextplot ("replace"),
1957 xdir ("normal"), 940 outerposition ()
1958 ydir ("normal"), 941 {
1959 zdir ("normal"), 942 Matrix tlim (1, 2, 0.0);
1960 view (), 943 tlim(1) = 1;
1961 nextplot ("replace"), 944 xlim = tlim;
1962 outerposition () 945 ylim = tlim;
1963 { 946 zlim = tlim;
1964 Matrix tlim (1, 2, 0.0); 947
1965 tlim(1) = 1; 948 Matrix tview (1, 2, 0.0);
1966 xlim = tlim; 949 tview(1) = 90;
1967 ylim = tlim; 950 view = tview;
1968 zlim = tlim; 951
1969 952 Matrix touterposition (1, 4, 0.0);
1970 Matrix tview (1, 2, 0.0); 953 touterposition(2) = 1;
1971 tview(1) = 90; 954 touterposition(3) = 1;
1972 view = tview; 955 outerposition = touterposition;
1973 956 }
957
958 void
959 axes::axes_properties::set (const property_name& name, const octave_value& val)
960 {
961 bool modified = true;
962
963 if (name.compare ("parent"))
964 set_parent (val);
965 else if (name.compare ("children"))
966 children = maybe_set_children (children, val);
967 else if (name.compare ("__modified__"))
968 {
969 __modified__ = val.bool_value ();
970 modified = false;
971 }
972 else if (name.compare ("position"))
973 position = val;
974 else if (name.compare ("title"))
975 {
976 graphics_handle h = ::reparent (val, "set", "title",
977 __myhandle__, false);
978 if (! error_state)
979 {
980 if (! xisnan (title))
981 gh_manager::free (title);
982
983 title = h;
984 }
985 }
986 else if (name.compare ("box"))
987 box = val;
988 else if (name.compare ("key"))
989 key = val;
990 else if (name.compare ("keybox"))
991 keybox = val;
992 else if (name.compare ("keypos"))
993 keypos = val;
994 else if (name.compare ("dataaspectratio"))
995 {
996 dataaspectratio = val;
997 dataaspectratiomode = "manual";
998 }
999 else if (name.compare ("dataaspectratiomode"))
1000 dataaspectratiomode = val;
1001 else if (name.compare ("xlim"))
1002 {
1003 xlim = val;
1004 xlimmode = "manual";
1005 }
1006 else if (name.compare ("ylim"))
1007 {
1008 ylim = val;
1009 ylimmode = "manual";
1010 }
1011 else if (name.compare ("zlim"))
1012 {
1013 zlim = val;
1014 zlimmode = "manual";
1015 }
1016 else if (name.compare ("xlimmode"))
1017 xlimmode = val;
1018 else if (name.compare ("ylimmode"))
1019 ylimmode = val;
1020 else if (name.compare ("zlimmode"))
1021 zlimmode = val;
1022 else if (name.compare ("xlabel"))
1023 {
1024 graphics_handle h = ::reparent (val, "set", "xlabel",
1025 __myhandle__, false);
1026 if (! error_state)
1027 {
1028 if (! xisnan (xlabel))
1029 gh_manager::free (xlabel);
1030
1031 xlabel = h;
1032 }
1033 }
1034 else if (name.compare ("ylabel"))
1035 {
1036 graphics_handle h = ::reparent (val, "set", "ylabel",
1037 __myhandle__, false);
1038 if (! error_state)
1039 {
1040 if (! xisnan (ylabel))
1041 gh_manager::free (ylabel);
1042
1043 ylabel = h;
1044 }
1045 }
1046 else if (name.compare ("zlabel"))
1047 {
1048 graphics_handle h = ::reparent (val, "set", "zlabel",
1049 __myhandle__, false);
1050 if (! error_state)
1051 {
1052 if (! xisnan (zlabel))
1053 gh_manager::free (zlabel);
1054
1055 zlabel = h;
1056 }
1057 }
1058 else if (name.compare ("xgrid"))
1059 xgrid = val;
1060 else if (name.compare ("ygrid"))
1061 ygrid = val;
1062 else if (name.compare ("zgrid"))
1063 zgrid = val;
1064 else if (name.compare ("xminorgrid"))
1065 xminorgrid = val;
1066 else if (name.compare ("yminorgrid"))
1067 yminorgrid = val;
1068 else if (name.compare ("zminorgrid"))
1069 zminorgrid = val;
1070 else if (name.compare ("xtick"))
1071 {
1072 xtick = val;
1073 xtickmode = "manual";
1074 }
1075 else if (name.compare ("ytick"))
1076 {
1077 ytick = val;
1078 ytickmode = "manual";
1079 }
1080 else if (name.compare ("ztick"))
1081 {
1082 ztick = val;
1083 ztickmode = "manual";
1084 }
1085 else if (name.compare ("xtickmode"))
1086 xtickmode = val;
1087 else if (name.compare ("ytickmode"))
1088 ytickmode = val;
1089 else if (name.compare ("ztickmode"))
1090 ztickmode = val;
1091 else if (name.compare ("xticklabel"))
1092 {
1093 xticklabel = val;
1094 xticklabelmode = "manual";
1095 }
1096 else if (name.compare ("yticklabel"))
1097 {
1098 yticklabel = val;
1099 yticklabelmode = "manual";
1100 }
1101 else if (name.compare ("zticklabel"))
1102 {
1103 zticklabel = val;
1104 zticklabelmode = "manual";
1105 }
1106 else if (name.compare ("xticklabelmode"))
1107 xticklabelmode = val;
1108 else if (name.compare ("yticklabelmode"))
1109 yticklabelmode = val;
1110 else if (name.compare ("zticklabelmode"))
1111 zticklabelmode = val;
1112 else if (name.compare ("xscale"))
1113 xscale = val;
1114 else if (name.compare ("yscale"))
1115 yscale = val;
1116 else if (name.compare ("zscale"))
1117 zscale = val;
1118 else if (name.compare ("xdir"))
1119 xdir = val;
1120 else if (name.compare ("ydir"))
1121 ydir = val;
1122 else if (name.compare ("zdir"))
1123 zdir = val;
1124 else if (name.compare ("view"))
1125 view = val;
1126 else if (name.compare ("nextplot"))
1127 nextplot = val;
1128 else if (name.compare ("outerposition"))
1129 outerposition = val;
1130 else
1131 {
1132 modified = false;
1133 warning ("set: invalid property `%s'", name.c_str ());
1134 }
1135
1136 if (modified)
1137 mark_modified ();
1138 }
1139
1140 void
1141 axes::axes_properties::set_defaults (base_graphics_object& obj,
1142 const std::string& mode)
1143 {
1144 position = Matrix ();
1145 title = octave_NaN;
1146 box = "on";
1147 key = "off";
1148 keybox = "off";
1149 keypos = 1;
1150 dataaspectratio = Matrix (1, 3, 1.0);
1151 dataaspectratiomode = "auto";
1152
1153 Matrix tlim (1, 2, 0.0);
1154 tlim(1) = 1;
1155 xlim = tlim;
1156 ylim = tlim;
1157 zlim = tlim;
1158
1159 xlimmode = "auto";
1160 ylimmode = "auto";
1161 zlimmode = "auto";
1162 xlabel = octave_NaN;
1163 ylabel = octave_NaN;
1164 zlabel = octave_NaN;
1165 xgrid = "off";
1166 ygrid = "off";
1167 zgrid = "off";
1168 xminorgrid = "off";
1169 yminorgrid = "off";
1170 zminorgrid = "off";
1171 xtick = Matrix ();
1172 ytick = Matrix ();
1173 ztick = Matrix ();
1174 xtickmode = "auto";
1175 ytickmode = "auto";
1176 ztickmode = "auto";
1177 xticklabel = "";
1178 yticklabel = "";
1179 zticklabel = "";
1180 xticklabelmode = "auto";
1181 yticklabelmode = "auto";
1182 zticklabelmode = "auto";
1183 xscale = "linear";
1184 yscale = "linear";
1185 zscale = "linear";
1186 xdir = "normal";
1187 ydir = "normal";
1188 zdir = "normal";
1189
1190 Matrix tview (1, 2, 0.0);
1191 tview(1) = 90;
1192 view = tview;
1193
1194 nextplot = "replace";
1195
1196 // FIXME -- this is not quite right; we should preserve
1197 // "position" and "units".
1198
1199 if (mode != "replace")
1200 {
1974 Matrix touterposition (1, 4, 0.0); 1201 Matrix touterposition (1, 4, 0.0);
1975 touterposition(2) = 1; 1202 touterposition(2) = 1;
1976 touterposition(3) = 1; 1203 touterposition(3) = 1;
1977 outerposition = touterposition; 1204 outerposition = touterposition;
1978 } 1205 }
1979 1206
1980 ~axes_properties (void) { } 1207 delete_children ();
1981 1208
1982 void set (const property_name& name, const octave_value& val) 1209 children = Matrix ();
1983 { 1210
1984 bool modified = true; 1211 override_defaults (obj);
1985 1212 }
1986 if (name.compare ("parent")) 1213
1987 set_parent (val); 1214 octave_value
1988 else if (name.compare ("children")) 1215 axes::axes_properties::get (void) const
1989 children = maybe_set_children (children, val); 1216 {
1990 else if (name.compare ("__modified__")) 1217 Octave_map m;
1991 { 1218
1992 __modified__ = val.bool_value (); 1219 if (xisnan (title))
1993 modified = false; 1220 title = gh_manager::make_graphics_handle ("text", __myhandle__);
1994 } 1221
1995 else if (name.compare ("position")) 1222 if (xisnan (xlabel))
1996 position = val; 1223 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
1997 else if (name.compare ("title")) 1224
1998 { 1225 if (xisnan (ylabel))
1999 graphics_handle h = ::reparent (val, "set", "title", 1226 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2000 __myhandle__, false); 1227
2001 if (! error_state) 1228 if (xisnan (zlabel))
2002 { 1229 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2003 if (! xisnan (title)) 1230
2004 gh_manager::free (title); 1231 m.assign ("type", type);
2005 1232 m.assign ("parent", parent);
2006 title = h; 1233 m.assign ("children", children);
2007 } 1234 m.assign ("__modified__", __modified__);
2008 } 1235 m.assign ("position", position);
2009 else if (name.compare ("box")) 1236 m.assign ("title", title);
2010 box = val; 1237 m.assign ("box", box);
2011 else if (name.compare ("key")) 1238 m.assign ("key", key);
2012 key = val; 1239 m.assign ("keybox", keybox);
2013 else if (name.compare ("keybox")) 1240 m.assign ("keypos", keypos);
2014 keybox = val; 1241 m.assign ("dataaspectratio", dataaspectratio);
2015 else if (name.compare ("keypos")) 1242 m.assign ("dataaspectratiomode", dataaspectratiomode);
2016 keypos = val; 1243 m.assign ("xlim", xlim);
2017 else if (name.compare ("dataaspectratio")) 1244 m.assign ("ylim", ylim);
2018 { 1245 m.assign ("zlim", zlim);
2019 dataaspectratio = val; 1246 m.assign ("xlimmode", xlimmode);
2020 dataaspectratiomode = "manual"; 1247 m.assign ("ylimmode", ylimmode);
2021 } 1248 m.assign ("zlimmode", zlimmode);
2022 else if (name.compare ("dataaspectratiomode")) 1249 m.assign ("xlabel", xlabel);
2023 dataaspectratiomode = val; 1250 m.assign ("ylabel", ylabel);
2024 else if (name.compare ("xlim")) 1251 m.assign ("zlabel", zlabel);
2025 { 1252 m.assign ("xgrid", xgrid);
2026 xlim = val; 1253 m.assign ("ygrid", ygrid);
2027 xlimmode = "manual"; 1254 m.assign ("zgrid", zgrid);
2028 } 1255 m.assign ("xminorgrid", xminorgrid);
2029 else if (name.compare ("ylim")) 1256 m.assign ("yminorgrid", yminorgrid);
2030 { 1257 m.assign ("zminorgrid", zminorgrid);
2031 ylim = val; 1258 m.assign ("xtick", xtick);
2032 ylimmode = "manual"; 1259 m.assign ("ytick", ytick);
2033 } 1260 m.assign ("ztick", ztick);
2034 else if (name.compare ("zlim")) 1261 m.assign ("xtickmode", xtickmode);
2035 { 1262 m.assign ("ytickmode", ytickmode);
2036 zlim = val; 1263 m.assign ("ztickmode", ztickmode);
2037 zlimmode = "manual"; 1264 m.assign ("xticklabel", xticklabel);
2038 } 1265 m.assign ("yticklabel", yticklabel);
2039 else if (name.compare ("xlimmode")) 1266 m.assign ("zticklabel", zticklabel);
2040 xlimmode = val; 1267 m.assign ("xticklabelmode", xticklabelmode);
2041 else if (name.compare ("ylimmode")) 1268 m.assign ("yticklabelmode", yticklabelmode);
2042 ylimmode = val; 1269 m.assign ("zticklabelmode", zticklabelmode);
2043 else if (name.compare ("zlimmode")) 1270 m.assign ("xscale", xscale);
2044 zlimmode = val; 1271 m.assign ("yscale", yscale);
2045 else if (name.compare ("xlabel")) 1272 m.assign ("zscale", zscale);
2046 { 1273 m.assign ("xdir", xdir);
2047 graphics_handle h = ::reparent (val, "set", "xlabel", 1274 m.assign ("ydir", ydir);
2048 __myhandle__, false); 1275 m.assign ("zdir", zdir);
2049 if (! error_state) 1276 m.assign ("view", view);
2050 { 1277 m.assign ("nextplot", nextplot);
2051 if (! xisnan (xlabel)) 1278 m.assign ("outerposition", outerposition);
2052 gh_manager::free (xlabel); 1279
2053 1280 return m;
2054 xlabel = h; 1281 }
2055 } 1282
2056 } 1283 octave_value
2057 else if (name.compare ("ylabel")) 1284 axes::axes_properties::get (const property_name& name) const
2058 { 1285 {
2059 graphics_handle h = ::reparent (val, "set", "ylabel", 1286 octave_value retval;
2060 __myhandle__, false); 1287
2061 if (! error_state) 1288 if (name.compare ("type"))
2062 { 1289 retval = type;
2063 if (! xisnan (ylabel)) 1290 else if (name.compare ("parent"))
2064 gh_manager::free (ylabel); 1291 retval = parent;
2065 1292 else if (name.compare ("children"))
2066 ylabel = h; 1293 retval = children;
2067 } 1294 else if (name.compare ("__modified__"))
2068 } 1295 retval = __modified__;
2069 else if (name.compare ("zlabel")) 1296 else if (name.compare ("position"))
2070 { 1297 retval = position;
2071 graphics_handle h = ::reparent (val, "set", "zlabel", 1298 else if (name.compare ("title"))
2072 __myhandle__, false); 1299 {
2073 if (! error_state)
2074 {
2075 if (! xisnan (zlabel))
2076 gh_manager::free (zlabel);
2077
2078 zlabel = h;
2079 }
2080 }
2081 else if (name.compare ("xgrid"))
2082 xgrid = val;
2083 else if (name.compare ("ygrid"))
2084 ygrid = val;
2085 else if (name.compare ("zgrid"))
2086 zgrid = val;
2087 else if (name.compare ("xminorgrid"))
2088 xminorgrid = val;
2089 else if (name.compare ("yminorgrid"))
2090 yminorgrid = val;
2091 else if (name.compare ("zminorgrid"))
2092 zminorgrid = val;
2093 else if (name.compare ("xtick"))
2094 {
2095 xtick = val;
2096 xtickmode = "manual";
2097 }
2098 else if (name.compare ("ytick"))
2099 {
2100 ytick = val;
2101 ytickmode = "manual";
2102 }
2103 else if (name.compare ("ztick"))
2104 {
2105 ztick = val;
2106 ztickmode = "manual";
2107 }
2108 else if (name.compare ("xtickmode"))
2109 xtickmode = val;
2110 else if (name.compare ("ytickmode"))
2111 ytickmode = val;
2112 else if (name.compare ("ztickmode"))
2113 ztickmode = val;
2114 else if (name.compare ("xticklabel"))
2115 {
2116 xticklabel = val;
2117 xticklabelmode = "manual";
2118 }
2119 else if (name.compare ("yticklabel"))
2120 {
2121 yticklabel = val;
2122 yticklabelmode = "manual";
2123 }
2124 else if (name.compare ("zticklabel"))
2125 {
2126 zticklabel = val;
2127 zticklabelmode = "manual";
2128 }
2129 else if (name.compare ("xticklabelmode"))
2130 xticklabelmode = val;
2131 else if (name.compare ("yticklabelmode"))
2132 yticklabelmode = val;
2133 else if (name.compare ("zticklabelmode"))
2134 zticklabelmode = val;
2135 else if (name.compare ("xscale"))
2136 xscale = val;
2137 else if (name.compare ("yscale"))
2138 yscale = val;
2139 else if (name.compare ("zscale"))
2140 zscale = val;
2141 else if (name.compare ("xdir"))
2142 xdir = val;
2143 else if (name.compare ("ydir"))
2144 ydir = val;
2145 else if (name.compare ("zdir"))
2146 zdir = val;
2147 else if (name.compare ("view"))
2148 view = val;
2149 else if (name.compare ("nextplot"))
2150 nextplot = val;
2151 else if (name.compare ("outerposition"))
2152 outerposition = val;
2153 else
2154 {
2155 modified = false;
2156 warning ("set: invalid property `%s'", name.c_str ());
2157 }
2158
2159 if (modified)
2160 mark_modified ();
2161 }
2162
2163 void set_defaults (base_graphics_object& obj, const std::string& mode)
2164 {
2165 position = Matrix ();
2166 title = octave_NaN;
2167 box = "on";
2168 key = "off";
2169 keybox = "off";
2170 keypos = 1;
2171 dataaspectratio = Matrix (1, 3, 1.0);
2172 dataaspectratiomode = "auto";
2173
2174 Matrix tlim (1, 2, 0.0);
2175 tlim(1) = 1;
2176 xlim = tlim;
2177 ylim = tlim;
2178 zlim = tlim;
2179
2180 xlimmode = "auto";
2181 ylimmode = "auto";
2182 zlimmode = "auto";
2183 xlabel = octave_NaN;
2184 ylabel = octave_NaN;
2185 zlabel = octave_NaN;
2186 xgrid = "off";
2187 ygrid = "off";
2188 zgrid = "off";
2189 xminorgrid = "off";
2190 yminorgrid = "off";
2191 zminorgrid = "off";
2192 xtick = Matrix ();
2193 ytick = Matrix ();
2194 ztick = Matrix ();
2195 xtickmode = "auto";
2196 ytickmode = "auto";
2197 ztickmode = "auto";
2198 xticklabel = "";
2199 yticklabel = "";
2200 zticklabel = "";
2201 xticklabelmode = "auto";
2202 yticklabelmode = "auto";
2203 zticklabelmode = "auto";
2204 xscale = "linear";
2205 yscale = "linear";
2206 zscale = "linear";
2207 xdir = "normal";
2208 ydir = "normal";
2209 zdir = "normal";
2210
2211 Matrix tview (1, 2, 0.0);
2212 tview(1) = 90;
2213 view = tview;
2214
2215 nextplot = "replace";
2216
2217 // FIXME -- this is not quite right; we should preserve
2218 // "position" and "units".
2219
2220 if (mode != "replace")
2221 {
2222 Matrix touterposition (1, 4, 0.0);
2223 touterposition(2) = 1;
2224 touterposition(3) = 1;
2225 outerposition = touterposition;
2226 }
2227
2228 delete_children ();
2229
2230 children = Matrix ();
2231
2232 override_defaults (obj);
2233 }
2234
2235 octave_value get (void) const
2236 {
2237 Octave_map m;
2238
2239 if (xisnan (title)) 1300 if (xisnan (title))
2240 title = gh_manager::make_graphics_handle ("text", __myhandle__); 1301 title = gh_manager::make_graphics_handle ("text", __myhandle__);
2241 1302
1303 retval = title;
1304 }
1305 else if (name.compare ("box"))
1306 retval = box;
1307 else if (name.compare ("key"))
1308 retval = key;
1309 else if (name.compare ("keybox"))
1310 retval = keybox;
1311 else if (name.compare ("keypos"))
1312 retval = keypos;
1313 else if (name.compare ("dataaspectratio"))
1314 retval = dataaspectratio;
1315 else if (name.compare ("dataaspectratiomode"))
1316 retval = dataaspectratiomode;
1317 else if (name.compare ("xlim"))
1318 retval = xlim;
1319 else if (name.compare ("ylim"))
1320 retval = ylim;
1321 else if (name.compare ("zlim"))
1322 retval = zlim;
1323 else if (name.compare ("xlimmode"))
1324 retval = xlimmode;
1325 else if (name.compare ("ylimmode"))
1326 retval = ylimmode;
1327 else if (name.compare ("zlimmode"))
1328 retval = zlimmode;
1329 else if (name.compare ("xlabel"))
1330 {
2242 if (xisnan (xlabel)) 1331 if (xisnan (xlabel))
2243 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1332 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2244 1333
1334 retval = xlabel;
1335 }
1336 else if (name.compare ("ylabel"))
1337 {
2245 if (xisnan (ylabel)) 1338 if (xisnan (ylabel))
2246 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1339 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2247 1340
1341 retval = ylabel;
1342 }
1343 else if (name.compare ("zlabel"))
1344 {
2248 if (xisnan (zlabel)) 1345 if (xisnan (zlabel))
2249 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1346 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2250 1347
2251 m.assign ("type", type); 1348 retval = zlabel;
2252 m.assign ("parent", parent); 1349 }
2253 m.assign ("children", children); 1350 else if (name.compare ("xgrid"))
2254 m.assign ("__modified__", __modified__); 1351 retval = xgrid;
2255 m.assign ("position", position); 1352 else if (name.compare ("ygrid"))
2256 m.assign ("title", title); 1353 retval = ygrid;
2257 m.assign ("box", box); 1354 else if (name.compare ("zgrid"))
2258 m.assign ("key", key); 1355 retval = zgrid;
2259 m.assign ("keybox", keybox); 1356 else if (name.compare ("xminorgrid"))
2260 m.assign ("keypos", keypos); 1357 retval = xminorgrid;
2261 m.assign ("dataaspectratio", dataaspectratio); 1358 else if (name.compare ("yminorgrid"))
2262 m.assign ("dataaspectratiomode", dataaspectratiomode); 1359 retval = yminorgrid;
2263 m.assign ("xlim", xlim); 1360 else if (name.compare ("zminorgrid"))
2264 m.assign ("ylim", ylim); 1361 retval = zminorgrid;
2265 m.assign ("zlim", zlim); 1362 else if (name.compare ("xtick"))
2266 m.assign ("xlimmode", xlimmode); 1363 retval = xtick;
2267 m.assign ("ylimmode", ylimmode); 1364 else if (name.compare ("ytick"))
2268 m.assign ("zlimmode", zlimmode); 1365 retval = ytick;
2269 m.assign ("xlabel", xlabel); 1366 else if (name.compare ("ztick"))
2270 m.assign ("ylabel", ylabel); 1367 retval = ztick;
2271 m.assign ("zlabel", zlabel); 1368 else if (name.compare ("xtickmode"))
2272 m.assign ("xgrid", xgrid); 1369 retval = xtickmode;
2273 m.assign ("ygrid", ygrid); 1370 else if (name.compare ("ytickmode"))
2274 m.assign ("zgrid", zgrid); 1371 retval = ytickmode;
2275 m.assign ("xminorgrid", xminorgrid); 1372 else if (name.compare ("ztickmode"))
2276 m.assign ("yminorgrid", yminorgrid); 1373 retval = ztickmode;
2277 m.assign ("zminorgrid", zminorgrid); 1374 else if (name.compare ("xticklabel"))
2278 m.assign ("xtick", xtick); 1375 retval = xticklabel;
2279 m.assign ("ytick", ytick); 1376 else if (name.compare ("yticklabel"))
2280 m.assign ("ztick", ztick); 1377 retval = yticklabel;
2281 m.assign ("xtickmode", xtickmode); 1378 else if (name.compare ("zticklabel"))
2282 m.assign ("ytickmode", ytickmode); 1379 retval = zticklabel;
2283 m.assign ("ztickmode", ztickmode); 1380 else if (name.compare ("xticklabelmode"))
2284 m.assign ("xticklabel", xticklabel); 1381 retval = xticklabelmode;
2285 m.assign ("yticklabel", yticklabel); 1382 else if (name.compare ("yticklabelmode"))
2286 m.assign ("zticklabel", zticklabel); 1383 retval = yticklabelmode;
2287 m.assign ("xticklabelmode", xticklabelmode); 1384 else if (name.compare ("zticklabelmode"))
2288 m.assign ("yticklabelmode", yticklabelmode); 1385 retval = zticklabelmode;
2289 m.assign ("zticklabelmode", zticklabelmode); 1386 else if (name.compare ("xscale"))
2290 m.assign ("xscale", xscale); 1387 retval = xscale;
2291 m.assign ("yscale", yscale); 1388 else if (name.compare ("yscale"))
2292 m.assign ("zscale", zscale); 1389 retval = yscale;
2293 m.assign ("xdir", xdir); 1390 else if (name.compare ("zscale"))
2294 m.assign ("ydir", ydir); 1391 retval = zscale;
2295 m.assign ("zdir", zdir); 1392 else if (name.compare ("xdir"))
2296 m.assign ("view", view); 1393 retval = xdir;
2297 m.assign ("nextplot", nextplot); 1394 else if (name.compare ("ydir"))
2298 m.assign ("outerposition", outerposition); 1395 retval = ydir;
2299 1396 else if (name.compare ("zdir"))
2300 return m; 1397 retval = zdir;
2301 } 1398 else if (name.compare ("view"))
2302 1399 retval = view;
2303 octave_value get (const property_name& name) const 1400 else if (name.compare ("nextplot"))
2304 { 1401 retval = nextplot;
2305 octave_value retval; 1402 else if (name.compare ("outerposition"))
2306 1403 retval = outerposition;
2307 if (name.compare ("type")) 1404 else
2308 retval = type; 1405 warning ("get: invalid property `%s'", name.c_str ());
2309 else if (name.compare ("parent")) 1406
2310 retval = parent; 1407 return retval;
2311 else if (name.compare ("children")) 1408 }
2312 retval = children; 1409
2313 else if (name.compare ("__modified__")) 1410 void
2314 retval = __modified__; 1411 axes::axes_properties::remove_child (const graphics_handle& h)
2315 else if (name.compare ("position")) 1412 {
2316 retval = position; 1413 if (! xisnan (title) && h == title)
2317 else if (name.compare ("title")) 1414 title = gh_manager::make_graphics_handle ("text", __myhandle__);
2318 { 1415 else if (! xisnan (xlabel) && h == xlabel)
2319 if (xisnan (title)) 1416 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2320 title = gh_manager::make_graphics_handle ("text", __myhandle__); 1417 else if (! xisnan (ylabel) && h == ylabel)
2321 1418 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2322 retval = title; 1419 else if (! xisnan (zlabel) && h == zlabel)
2323 } 1420 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2324 else if (name.compare ("box")) 1421 else
2325 retval = box; 1422 base_properties::remove_child (h);
2326 else if (name.compare ("key")) 1423 }
2327 retval = key; 1424
2328 else if (name.compare ("keybox")) 1425 void
2329 retval = keybox; 1426 axes::axes_properties::delete_children (void)
2330 else if (name.compare ("keypos")) 1427 {
2331 retval = keypos; 1428 base_properties::delete_children ();
2332 else if (name.compare ("dataaspectratio")) 1429
2333 retval = dataaspectratio; 1430 if (! xisnan (title))
2334 else if (name.compare ("dataaspectratiomode")) 1431 gh_manager::free (title);
2335 retval = dataaspectratiomode; 1432
2336 else if (name.compare ("xlim")) 1433 if (! xisnan (xlabel))
2337 retval = xlim; 1434 gh_manager::free (xlabel);
2338 else if (name.compare ("ylim")) 1435
2339 retval = ylim; 1436 if (! xisnan (ylabel))
2340 else if (name.compare ("zlim")) 1437 gh_manager::free (ylabel);
2341 retval = zlim; 1438
2342 else if (name.compare ("xlimmode")) 1439 if (! xisnan (zlabel))
2343 retval = xlimmode; 1440 gh_manager::free (zlabel);
2344 else if (name.compare ("ylimmode")) 1441 }
2345 retval = ylimmode; 1442
2346 else if (name.compare ("zlimmode")) 1443 property_list::pval_map_type axes::axes_properties::factory_defaults (void)
2347 retval = zlimmode; 1444 {
2348 else if (name.compare ("xlabel")) 1445 property_list::pval_map_type m;
2349 { 1446
2350 if (xisnan (xlabel)) 1447 m["position"] = Matrix ();
2351 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1448 m["title"] = octave_NaN;
2352 1449 m["box"] = "on";
2353 retval = xlabel; 1450 m["key"] = "off";
2354 } 1451 m["keybox"] = "off";
2355 else if (name.compare ("ylabel")) 1452 m["keypos"] = 1;
2356 { 1453 m["dataaspectratio"] = Matrix (1, 3, 1.0);
2357 if (xisnan (ylabel)) 1454 m["dataaspectratiomode"] = "auto";
2358 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1455
2359 1456 Matrix tlim (1, 2, 0.0);
2360 retval = ylabel; 1457 tlim(1) = 1;
2361 } 1458
2362 else if (name.compare ("zlabel")) 1459 m["xlim"] = tlim;
2363 { 1460 m["ylim"] = tlim;
2364 if (xisnan (zlabel)) 1461 m["zlim"] = tlim;
2365 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__); 1462
2366 1463 m["xlimmode"] = "auto";
2367 retval = zlabel; 1464 m["ylimmode"] = "auto";
2368 } 1465 m["zlimmode"] = "auto";
2369 else if (name.compare ("xgrid")) 1466 m["xlabel"] = octave_NaN;
2370 retval = xgrid; 1467 m["ylabel"] = octave_NaN;
2371 else if (name.compare ("ygrid")) 1468 m["zlabel"] = octave_NaN;
2372 retval = ygrid; 1469 m["xgrid"] = "off";
2373 else if (name.compare ("zgrid")) 1470 m["ygrid"] = "off";
2374 retval = zgrid; 1471 m["zgrid"] = "off";
2375 else if (name.compare ("xminorgrid")) 1472 m["xminorgrid"] = "off";
2376 retval = xminorgrid; 1473 m["yminorgrid"] = "off";
2377 else if (name.compare ("yminorgrid")) 1474 m["zminorgrid"] = "off";
2378 retval = yminorgrid; 1475 m["xtick"] = Matrix ();
2379 else if (name.compare ("zminorgrid")) 1476 m["ytick"] = Matrix ();
2380 retval = zminorgrid; 1477 m["ztick"] = Matrix ();
2381 else if (name.compare ("xtick")) 1478 m["xtickmode"] = "auto";
2382 retval = xtick; 1479 m["ytickmode"] = "auto";
2383 else if (name.compare ("ytick")) 1480 m["ztickmode"] = "auto";
2384 retval = ytick; 1481 m["xticklabel"] = "";
2385 else if (name.compare ("ztick")) 1482 m["yticklabel"] = "";
2386 retval = ztick; 1483 m["zticklabel"] = "";
2387 else if (name.compare ("xtickmode")) 1484 m["xticklabelmode"] = "auto";
2388 retval = xtickmode; 1485 m["yticklabelmode"] = "auto";
2389 else if (name.compare ("ytickmode")) 1486 m["zticklabelmode"] = "auto";
2390 retval = ytickmode; 1487 m["xscale"] = "linear";
2391 else if (name.compare ("ztickmode")) 1488 m["yscale"] = "linear";
2392 retval = ztickmode; 1489 m["zscale"] = "linear";
2393 else if (name.compare ("xticklabel")) 1490 m["xdir"] = "normal";
2394 retval = xticklabel; 1491 m["ydir"] = "normal";
2395 else if (name.compare ("yticklabel")) 1492 m["zdir"] = "normal";
2396 retval = yticklabel; 1493
2397 else if (name.compare ("zticklabel")) 1494 Matrix tview (1, 2, 0.0);
2398 retval = zticklabel; 1495 tview(1) = 90;
2399 else if (name.compare ("xticklabelmode")) 1496
2400 retval = xticklabelmode; 1497 m["view"] = tview;
2401 else if (name.compare ("yticklabelmode")) 1498
2402 retval = yticklabelmode; 1499 m["nextplot"] = "replace";
2403 else if (name.compare ("zticklabelmode")) 1500
2404 retval = zticklabelmode; 1501 Matrix touterposition (1, 4, 0.0);
2405 else if (name.compare ("xscale")) 1502 touterposition(2) = 1;
2406 retval = xscale; 1503 touterposition(3) = 1;
2407 else if (name.compare ("yscale")) 1504
2408 retval = yscale; 1505 m["outerposition"] = touterposition;
2409 else if (name.compare ("zscale")) 1506
2410 retval = zscale; 1507 return m;
2411 else if (name.compare ("xdir")) 1508 }
2412 retval = xdir;
2413 else if (name.compare ("ydir"))
2414 retval = ydir;
2415 else if (name.compare ("zdir"))
2416 retval = zdir;
2417 else if (name.compare ("view"))
2418 retval = view;
2419 else if (name.compare ("nextplot"))
2420 retval = nextplot;
2421 else if (name.compare ("outerposition"))
2422 retval = outerposition;
2423 else
2424 warning ("get: invalid property `%s'", name.c_str ());
2425
2426 return retval;
2427 }
2428
2429 void remove_child (const graphics_handle& h)
2430 {
2431 if (! xisnan (title) && h == title)
2432 title = gh_manager::make_graphics_handle ("text", __myhandle__);
2433 else if (! xisnan (xlabel) && h == xlabel)
2434 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2435 else if (! xisnan (ylabel) && h == ylabel)
2436 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2437 else if (! xisnan (zlabel) && h == zlabel)
2438 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
2439 else
2440 base_properties::remove_child (h);
2441 }
2442
2443 void delete_children (void)
2444 {
2445 base_properties::delete_children ();
2446
2447 if (! xisnan (title))
2448 gh_manager::free (title);
2449
2450 if (! xisnan (xlabel))
2451 gh_manager::free (xlabel);
2452
2453 if (! xisnan (ylabel))
2454 gh_manager::free (ylabel);
2455
2456 if (! xisnan (zlabel))
2457 gh_manager::free (zlabel);
2458 }
2459
2460 std::string graphics_object_name (void) const { return go_name; }
2461
2462 static property_list::pval_map_type factory_defaults (void)
2463 {
2464 property_list::pval_map_type m;
2465
2466 m["position"] = Matrix ();
2467 m["title"] = octave_NaN;
2468 m["box"] = "on";
2469 m["key"] = "off";
2470 m["keybox"] = "off";
2471 m["keypos"] = 1;
2472 m["dataaspectratio"] = Matrix (1, 3, 1.0);
2473 m["dataaspectratiomode"] = "auto";
2474
2475 Matrix tlim (1, 2, 0.0);
2476 tlim(1) = 1;
2477
2478 m["xlim"] = tlim;
2479 m["ylim"] = tlim;
2480 m["zlim"] = tlim;
2481
2482 m["xlimmode"] = "auto";
2483 m["ylimmode"] = "auto";
2484 m["zlimmode"] = "auto";
2485 m["xlabel"] = octave_NaN;
2486 m["ylabel"] = octave_NaN;
2487 m["zlabel"] = octave_NaN;
2488 m["xgrid"] = "off";
2489 m["ygrid"] = "off";
2490 m["zgrid"] = "off";
2491 m["xminorgrid"] = "off";
2492 m["yminorgrid"] = "off";
2493 m["zminorgrid"] = "off";
2494 m["xtick"] = Matrix ();
2495 m["ytick"] = Matrix ();
2496 m["ztick"] = Matrix ();
2497 m["xtickmode"] = "auto";
2498 m["ytickmode"] = "auto";
2499 m["ztickmode"] = "auto";
2500 m["xticklabel"] = "";
2501 m["yticklabel"] = "";
2502 m["zticklabel"] = "";
2503 m["xticklabelmode"] = "auto";
2504 m["yticklabelmode"] = "auto";
2505 m["zticklabelmode"] = "auto";
2506 m["xscale"] = "linear";
2507 m["yscale"] = "linear";
2508 m["zscale"] = "linear";
2509 m["xdir"] = "normal";
2510 m["ydir"] = "normal";
2511 m["zdir"] = "normal";
2512
2513 Matrix tview (1, 2, 0.0);
2514 tview(1) = 90;
2515
2516 m["view"] = tview;
2517
2518 m["nextplot"] = "replace";
2519
2520 Matrix touterposition (1, 4, 0.0);
2521 touterposition(2) = 1;
2522 touterposition(3) = 1;
2523
2524 m["outerposition"] = touterposition;
2525
2526 return m;
2527 }
2528
2529 private:
2530 octave_value position;
2531 mutable graphics_handle title;
2532 octave_value box;
2533 octave_value key;
2534 octave_value keybox;
2535 octave_value keypos;
2536 octave_value dataaspectratio;
2537 octave_value dataaspectratiomode;
2538 octave_value xlim;
2539 octave_value ylim;
2540 octave_value zlim;
2541 octave_value xlimmode;
2542 octave_value ylimmode;
2543 octave_value zlimmode;
2544 mutable graphics_handle xlabel;
2545 mutable graphics_handle ylabel;
2546 mutable graphics_handle zlabel;
2547 octave_value xgrid;
2548 octave_value ygrid;
2549 octave_value zgrid;
2550 octave_value xminorgrid;
2551 octave_value yminorgrid;
2552 octave_value zminorgrid;
2553 octave_value xtick;
2554 octave_value ytick;
2555 octave_value ztick;
2556 octave_value xtickmode;
2557 octave_value ytickmode;
2558 octave_value ztickmode;
2559 octave_value xticklabel;
2560 octave_value yticklabel;
2561 octave_value zticklabel;
2562 octave_value xticklabelmode;
2563 octave_value yticklabelmode;
2564 octave_value zticklabelmode;
2565 octave_value xscale;
2566 octave_value yscale;
2567 octave_value zscale;
2568 octave_value xdir;
2569 octave_value ydir;
2570 octave_value zdir;
2571 octave_value view;
2572 octave_value nextplot;
2573 octave_value outerposition;
2574
2575 static std::string go_name;
2576 };
2577
2578 axes_properties properties;
2579
2580 public:
2581 axes (const graphics_handle& mh, const graphics_handle& p)
2582 : base_graphics_object (), properties (mh, p), default_properties ()
2583 {
2584 properties.override_defaults (*this);
2585 }
2586
2587 ~axes (void) { properties.delete_children (); }
2588
2589 std::string type (void) const { return properties.graphics_object_name (); }
2590
2591 void mark_modified (void) { properties.mark_modified (); }
2592
2593 void override_defaults (base_graphics_object& obj)
2594 {
2595 // Allow parent (figure) to override first (properties knows how
2596 // to find the parent object).
2597 properties.override_defaults (obj);
2598
2599 // Now override with our defaults. If the default_properties
2600 // list includes the properties for all defaults (line,
2601 // surface, etc.) then we don't have to know the type of OBJ
2602 // here, we just call its set function and let it decide which
2603 // properties from the list to use.
2604 obj.set_from_list (default_properties);
2605 }
2606
2607 void set_from_list (property_list& plist)
2608 {
2609 properties.set_from_list (*this, plist);
2610 }
2611
2612 void set (const property_name& name, const octave_value& value)
2613 {
2614 if (name.compare ("default", 7))
2615 // strip "default", pass rest to function that will
2616 // parse the remainder and add the element to the
2617 // default_properties map.
2618 default_properties.set (name.substr (7), value);
2619 else
2620 properties.set (name, value);
2621 }
2622
2623 void set_defaults (const std::string& mode)
2624 {
2625 properties.set_defaults (*this, mode);
2626 }
2627
2628 octave_value get (void) const
2629 {
2630 return properties.get ();
2631 }
2632
2633 octave_value get (const property_name& name) const
2634 {
2635 octave_value retval;
2636
2637 // FIXME -- finish this.
2638 if (name.compare ("default", 7))
2639 retval = get_default (name.substr (7));
2640 else
2641 retval = properties.get (name);
2642
2643 return retval;
2644 }
2645
2646 octave_value get_default (const property_name& name) const
2647 {
2648 octave_value retval = default_properties.lookup (name);
2649
2650 if (retval.is_undefined ())
2651 {
2652 graphics_handle parent = get_parent ();
2653 graphics_object parent_obj = gh_manager::get_object (parent);
2654
2655 retval = parent_obj.get_default (name);
2656 }
2657
2658 return retval;
2659 }
2660
2661 octave_value get_defaults (void) const
2662 {
2663 return default_properties.as_struct ("default");
2664 }
2665
2666 graphics_handle get_parent (void) const { return properties.get_parent (); }
2667
2668 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
2669
2670 void adopt (const graphics_handle& h) { properties.adopt (h); }
2671
2672 void reparent (const graphics_handle& np) { properties.reparent (np); }
2673
2674 bool valid_object (void) const { return true; }
2675
2676 private:
2677 property_list default_properties;
2678 };
2679 1509
2680 std::string axes::axes_properties::go_name ("axes"); 1510 std::string axes::axes_properties::go_name ("axes");
2681 1511
2682 // --------------------------------------------------------------------- 1512 // ---------------------------------------------------------------------
2683 1513
2690 retval(1) = 1; 1520 retval(1) = 1;
2691 1521
2692 return retval; 1522 return retval;
2693 } 1523 }
2694 1524
2695 class line : public base_graphics_object 1525 line::line_properties::line_properties (const graphics_handle& mh,
2696 { 1526 const graphics_handle& p)
2697 public: 1527 : base_properties (go_name, mh, p),
2698 class line_properties : public base_properties 1528 xdata (default_data ()),
2699 { 1529 ydata (default_data ()),
2700 public: 1530 zdata (Matrix ()),
2701 line_properties (const graphics_handle& mh, const graphics_handle& p) 1531 ldata (Matrix ()),
2702 : base_properties (go_name, mh, p), 1532 udata (Matrix ()),
2703 xdata (default_data ()), 1533 xldata (Matrix ()),
2704 ydata (default_data ()), 1534 xudata (Matrix ()),
2705 zdata (Matrix ()), 1535 color (),
2706 ldata (Matrix ()), 1536 linestyle ("-"),
2707 udata (Matrix ()), 1537 linewidth (0.5),
2708 xldata (Matrix ()), 1538 marker ("none"),
2709 xudata (Matrix ()), 1539 markeredgecolor ("auto"),
2710 color (), 1540 markerfacecolor ("none"),
2711 linestyle ("-"), 1541 markersize (1),
2712 linewidth (0.5), 1542 keylabel ("")
2713 marker ("none"), 1543 { }
2714 markeredgecolor ("auto"), 1544
2715 markerfacecolor ("none"), 1545 void
2716 markersize (1), 1546 line::line_properties::set (const property_name& name, const octave_value& val)
2717 keylabel ("") { } 1547 {
2718 1548 bool modified = true;
2719 ~line_properties (void) { } 1549
2720 1550 if (name.compare ("parent"))
2721 void set (const property_name& name, const octave_value& val) 1551 set_parent (val);
2722 { 1552 else if (name.compare ("children"))
2723 bool modified = true; 1553 children = maybe_set_children (children, val);
2724 1554 else if (name.compare ("__modified__"))
2725 if (name.compare ("parent")) 1555 {
2726 set_parent (val); 1556 __modified__ = val.bool_value ();
2727 else if (name.compare ("children")) 1557 modified = false;
2728 children = maybe_set_children (children, val); 1558 }
2729 else if (name.compare ("__modified__")) 1559 else if (name.compare ("xdata"))
2730 { 1560 xdata = val;
2731 __modified__ = val.bool_value (); 1561 else if (name.compare ("ydata"))
2732 modified = false; 1562 ydata = val;
2733 } 1563 else if (name.compare ("zdata"))
2734 else if (name.compare ("xdata")) 1564 zdata = val;
2735 xdata = val; 1565 else if (name.compare ("ldata"))
2736 else if (name.compare ("ydata")) 1566 ldata = val;
2737 ydata = val; 1567 else if (name.compare ("udata"))
2738 else if (name.compare ("zdata")) 1568 udata = val;
2739 zdata = val; 1569 else if (name.compare ("xldata"))
2740 else if (name.compare ("ldata")) 1570 xldata = val;
2741 ldata = val; 1571 else if (name.compare ("xudata"))
2742 else if (name.compare ("udata")) 1572 xudata = val;
2743 udata = val; 1573 else if (name.compare ("color"))
2744 else if (name.compare ("xldata")) 1574 color = color_property (val);
2745 xldata = val; 1575 else if (name.compare ("linestyle"))
2746 else if (name.compare ("xudata")) 1576 linestyle = val;
2747 xudata = val; 1577 else if (name.compare ("linewidth"))
2748 else if (name.compare ("color")) 1578 linewidth = val;
2749 color = color_property (val); 1579 else if (name.compare ("marker"))
2750 else if (name.compare ("linestyle")) 1580 marker = val;
2751 linestyle = val; 1581 else if (name.compare ("markeredgecolor"))
2752 else if (name.compare ("linewidth")) 1582 markeredgecolor = val;
2753 linewidth = val; 1583 else if (name.compare ("markerfacecolor"))
2754 else if (name.compare ("marker")) 1584 markerfacecolor = val;
2755 marker = val; 1585 else if (name.compare ("markersize"))
2756 else if (name.compare ("markeredgecolor")) 1586 markersize = val;
2757 markeredgecolor = val; 1587 else if (name.compare ("keylabel"))
2758 else if (name.compare ("markerfacecolor")) 1588 keylabel = val;
2759 markerfacecolor = val; 1589 else
2760 else if (name.compare ("markersize")) 1590 {
2761 markersize = val; 1591 modified = false;
2762 else if (name.compare ("keylabel")) 1592 warning ("set: invalid property `%s'", name.c_str ());
2763 keylabel = val; 1593 }
2764 else 1594
2765 { 1595 if (modified)
2766 modified = false; 1596 mark_modified ();
2767 warning ("set: invalid property `%s'", name.c_str ()); 1597 }
2768 } 1598
2769 1599 octave_value
2770 if (modified) 1600 line::line_properties::get (void) const
2771 mark_modified (); 1601 {
2772 } 1602 Octave_map m;
2773 1603
2774 octave_value get (void) const 1604 m.assign ("type", type);
2775 { 1605 m.assign ("parent", parent);
2776 Octave_map m; 1606 m.assign ("children", children);
2777 1607 m.assign ("__modified__", __modified__);
2778 m.assign ("type", type); 1608 m.assign ("xdata", xdata);
2779 m.assign ("parent", parent); 1609 m.assign ("ydata", ydata);
2780 m.assign ("children", children); 1610 m.assign ("zdata", zdata);
2781 m.assign ("__modified__", __modified__); 1611 m.assign ("ldata", ldata);
2782 m.assign ("xdata", xdata); 1612 m.assign ("udata", udata);
2783 m.assign ("ydata", ydata); 1613 m.assign ("xldata", xldata);
2784 m.assign ("zdata", zdata); 1614 m.assign ("xudata", xudata);
2785 m.assign ("ldata", ldata); 1615 m.assign ("color", color);
2786 m.assign ("udata", udata); 1616 m.assign ("linestyle", linestyle);
2787 m.assign ("xldata", xldata); 1617 m.assign ("linewidth", linewidth);
2788 m.assign ("xudata", xudata); 1618 m.assign ("marker", marker);
2789 m.assign ("color", color); 1619 m.assign ("markeredgecolor", markeredgecolor);
2790 m.assign ("linestyle", linestyle); 1620 m.assign ("markerface", markerfacecolor);
2791 m.assign ("linewidth", linewidth); 1621 m.assign ("markersize", markersize);
2792 m.assign ("marker", marker); 1622 m.assign ("keylabel", keylabel);
2793 m.assign ("markeredgecolor", markeredgecolor); 1623
2794 m.assign ("markerface", markerfacecolor); 1624 return m;
2795 m.assign ("markersize", markersize); 1625 }
2796 m.assign ("keylabel", keylabel); 1626
2797 1627 octave_value
2798 return m; 1628 line::line_properties::get (const property_name& name) const
2799 } 1629 {
2800 1630 octave_value retval;
2801 octave_value get (const property_name& name) const 1631
2802 { 1632 if (name.compare ("type"))
2803 octave_value retval; 1633 retval = type;
2804 1634 else if (name.compare ("parent"))
2805 if (name.compare ("type")) 1635 retval = parent;
2806 retval = type; 1636 else if (name.compare ("children"))
2807 else if (name.compare ("parent")) 1637 retval = children;
2808 retval = parent; 1638 else if (name.compare ("__modified__"))
2809 else if (name.compare ("children")) 1639 retval = __modified__;
2810 retval = children; 1640 else if (name.compare ("xdata"))
2811 else if (name.compare ("__modified__")) 1641 retval = xdata;
2812 retval = __modified__; 1642 else if (name.compare ("ydata"))
2813 else if (name.compare ("xdata")) 1643 retval = ydata;
2814 retval = xdata; 1644 else if (name.compare ("zdata"))
2815 else if (name.compare ("ydata")) 1645 retval = zdata;
2816 retval = ydata; 1646 else if (name.compare ("ldata"))
2817 else if (name.compare ("zdata")) 1647 retval = ldata;
2818 retval = zdata; 1648 else if (name.compare ("udata"))
2819 else if (name.compare ("ldata")) 1649 retval = udata;
2820 retval = ldata; 1650 else if (name.compare ("xldata"))
2821 else if (name.compare ("udata")) 1651 retval = xldata;
2822 retval = udata; 1652 else if (name.compare ("xudata"))
2823 else if (name.compare ("xldata")) 1653 retval = xudata;
2824 retval = xldata; 1654 else if (name.compare ("color"))
2825 else if (name.compare ("xudata")) 1655 retval = color;
2826 retval = xudata; 1656 else if (name.compare ("linestyle"))
2827 else if (name.compare ("color")) 1657 retval = linestyle;
2828 retval = color; 1658 else if (name.compare ("linewidth"))
2829 else if (name.compare ("linestyle")) 1659 retval = linewidth;
2830 retval = linestyle; 1660 else if (name.compare ("marker"))
2831 else if (name.compare ("linewidth")) 1661 retval = marker;
2832 retval = linewidth; 1662 else if (name.compare ("markeredgecolor"))
2833 else if (name.compare ("marker")) 1663 retval = markeredgecolor;
2834 retval = marker; 1664 else if (name.compare ("markerfacecolor"))
2835 else if (name.compare ("markeredgecolor")) 1665 retval = markerfacecolor;
2836 retval = markeredgecolor; 1666 else if (name.compare ("markersize"))
2837 else if (name.compare ("markerfacecolor")) 1667 retval = markersize;
2838 retval = markerfacecolor; 1668 else if (name.compare ("keylabel"))
2839 else if (name.compare ("markersize")) 1669 retval = keylabel;
2840 retval = markersize; 1670 else
2841 else if (name.compare ("keylabel")) 1671 warning ("get: invalid property `%s'", name.c_str ());
2842 retval = keylabel; 1672
2843 else 1673 return retval;
2844 warning ("get: invalid property `%s'", name.c_str ()); 1674 }
2845 1675
2846 return retval; 1676 property_list::pval_map_type line::line_properties::factory_defaults (void)
2847 } 1677 {
2848 1678 property_list::pval_map_type m;
2849 std::string graphics_object_name (void) const { return go_name; } 1679
2850 1680 m["xdata"] = default_data ();
2851 static property_list::pval_map_type factory_defaults (void) 1681 m["ydata"] = default_data ();
2852 { 1682 m["zdata"] = Matrix ();
2853 property_list::pval_map_type m; 1683 m["ldata"] = Matrix ();
2854 1684 m["udata"] = Matrix ();
2855 m["xdata"] = default_data (); 1685 m["xldata"] = Matrix ();
2856 m["ydata"] = default_data (); 1686 m["xudata"] = Matrix ();
2857 m["zdata"] = Matrix (); 1687 m["color"] = color_property ();
2858 m["ldata"] = Matrix (); 1688 m["linestyle"] = "-";
2859 m["udata"] = Matrix (); 1689 m["linewidth"] = 0.5;
2860 m["xldata"] = Matrix (); 1690 m["marker"] = "none";
2861 m["xudata"] = Matrix (); 1691 m["markeredgecolor"] = "auto";
2862 m["color"] = color_property (); 1692 m["markerfacecolor"] = "none";
2863 m["linestyle"] = "-"; 1693 m["markersize"] = 1;
2864 m["linewidth"] = 0.5; 1694 m["keylabel"] = "";
2865 m["marker"] = "none"; 1695
2866 m["markeredgecolor"] = "auto"; 1696 return m;
2867 m["markerfacecolor"] = "none"; 1697 }
2868 m["markersize"] = 1;
2869 m["keylabel"] = "";
2870
2871 return m;
2872 }
2873
2874 private:
2875 octave_value xdata;
2876 octave_value ydata;
2877 octave_value zdata;
2878 octave_value ldata;
2879 octave_value udata;
2880 octave_value xldata;
2881 octave_value xudata;
2882 color_property color;
2883 octave_value linestyle;
2884 octave_value linewidth;
2885 octave_value marker;
2886 octave_value markeredgecolor;
2887 octave_value markerfacecolor;
2888 octave_value markersize;
2889 octave_value keylabel;
2890
2891 static std::string go_name;
2892 };
2893
2894 line_properties properties;
2895
2896 public:
2897 line (const graphics_handle& mh, const graphics_handle& p)
2898 : base_graphics_object (), properties (mh, p)
2899 {
2900 properties.override_defaults (*this);
2901 }
2902
2903 ~line (void) { properties.delete_children (); }
2904
2905 std::string type (void) const { return properties.graphics_object_name (); }
2906
2907 void mark_modified (void) { properties.mark_modified (); }
2908
2909 void override_defaults (base_graphics_object& obj)
2910 {
2911 // Allow parent (figure) to override first (properties knows how
2912 // to find the parent object).
2913 properties.override_defaults (obj);
2914 }
2915
2916 void set_from_list (property_list& plist)
2917 {
2918 properties.set_from_list (*this, plist);
2919 }
2920
2921 void set (const property_name& name, const octave_value& val)
2922 {
2923 properties.set (name, val);
2924 }
2925
2926 octave_value get (void) const
2927 {
2928 return properties.get ();
2929 }
2930
2931 octave_value get (const property_name& name) const
2932 {
2933 return properties.get (name);
2934 }
2935
2936 graphics_handle get_parent (void) const { return properties.get_parent (); }
2937
2938 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
2939
2940 void adopt (const graphics_handle& h) { properties.adopt (h); }
2941
2942 void reparent (const graphics_handle& h) { properties.reparent (h); }
2943
2944 bool valid_object (void) const { return true; }
2945 };
2946 1698
2947 std::string line::line_properties::go_name ("line"); 1699 std::string line::line_properties::go_name ("line");
2948 1700
2949 // --------------------------------------------------------------------- 1701 // ---------------------------------------------------------------------
2950 1702
2951 class text : public base_graphics_object 1703 text::text_properties::text_properties (const graphics_handle& mh,
2952 { 1704 const graphics_handle& p)
2953 public: 1705 : base_properties (go_name, mh, p),
2954 class text_properties : public base_properties 1706 string (""),
2955 { 1707 units ("data"),
2956 public: 1708 position (Matrix (1, 3, 0.0)),
2957 text_properties (const graphics_handle& mh, const graphics_handle& p) 1709 horizontalalignment ("left")
2958 : base_properties (go_name, mh, p), 1710 { }
2959 string (""), 1711
2960 units ("data"), 1712 void
2961 position (Matrix (1, 3, 0.0)), 1713 text::text_properties::set (const property_name& name, const octave_value& val)
2962 horizontalalignment ("left") 1714 {
2963 { } 1715 bool modified = true;
2964 1716
2965 ~text_properties (void) { } 1717 if (name.compare ("parent"))
2966 1718 set_parent (val);
2967 void set (const property_name& name, const octave_value& val) 1719 else if (name.compare ("children"))
2968 { 1720 children = maybe_set_children (children, val);
2969 bool modified = true; 1721 else if (name.compare ("__modified__"))
2970 1722 {
2971 if (name.compare ("parent")) 1723 __modified__ = val.bool_value ();
2972 set_parent (val); 1724 modified = false;
2973 else if (name.compare ("children")) 1725 }
2974 children = maybe_set_children (children, val); 1726 else if (name.compare ("string"))
2975 else if (name.compare ("__modified__")) 1727 string = val;
2976 { 1728 else if (name.compare ("units"))
2977 __modified__ = val.bool_value (); 1729 units = val;
2978 modified = false; 1730 else if (name.compare ("position"))
2979 } 1731 position = val;
2980 else if (name.compare ("string")) 1732 else if (name.compare ("horizontalalignment"))
2981 string = val; 1733 horizontalalignment = val;
2982 else if (name.compare ("units")) 1734 else
2983 units = val; 1735 {
2984 else if (name.compare ("position")) 1736 modified = false;
2985 position = val; 1737 warning ("set: invalid property `%s'", name.c_str ());
2986 else if (name.compare ("horizontalalignment")) 1738 }
2987 horizontalalignment = val; 1739
2988 else 1740 if (modified)
2989 { 1741 mark_modified ();
2990 modified = false; 1742 }
2991 warning ("set: invalid property `%s'", name.c_str ()); 1743
2992 } 1744 octave_value
2993 1745 text::text_properties::get (void) const
2994 if (modified) 1746 {
2995 mark_modified (); 1747 Octave_map m;
2996 } 1748
2997 1749 m.assign ("type", type);
2998 octave_value get (void) const 1750 m.assign ("parent", parent);
2999 { 1751 m.assign ("children", children);
3000 Octave_map m; 1752 m.assign ("__modified__", __modified__);
3001 1753 m.assign ("string", string);
3002 m.assign ("type", type); 1754 m.assign ("units", units);
3003 m.assign ("parent", parent); 1755 m.assign ("position", position);
3004 m.assign ("children", children); 1756 m.assign ("horizontalalignment", horizontalalignment);
3005 m.assign ("__modified__", __modified__); 1757
3006 m.assign ("string", string); 1758 return m;
3007 m.assign ("units", units); 1759 }
3008 m.assign ("position", position); 1760
3009 m.assign ("horizontalalignment", horizontalalignment); 1761 octave_value
3010 1762 text::text_properties::get (const property_name& name) const
3011 return m; 1763 {
3012 } 1764 octave_value retval;
3013 1765
3014 octave_value get (const property_name& name) const 1766 if (name.compare ("type"))
3015 { 1767 retval = type;
3016 octave_value retval; 1768 else if (name.compare ("parent"))
3017 1769 retval = parent;
3018 if (name.compare ("type")) 1770 else if (name.compare ("children"))
3019 retval = type; 1771 retval = children;
3020 else if (name.compare ("parent")) 1772 else if (name.compare ("__modified__"))
3021 retval = parent; 1773 retval = __modified__;
3022 else if (name.compare ("children")) 1774 else if (name.compare ("string"))
3023 retval = children; 1775 retval = string;
3024 else if (name.compare ("__modified__")) 1776 else if (name.compare ("units"))
3025 retval = __modified__; 1777 retval = units;
3026 else if (name.compare ("string")) 1778 else if (name.compare ("position"))
3027 retval = string; 1779 retval = position;
3028 else if (name.compare ("units")) 1780 else if (name.compare ("horizontalalignment"))
3029 retval = units; 1781 retval = horizontalalignment;
3030 else if (name.compare ("position")) 1782 else
3031 retval = position; 1783 warning ("get: invalid property `%s'", name.c_str ());
3032 else if (name.compare ("horizontalalignment")) 1784
3033 retval = horizontalalignment; 1785 return retval;
3034 else 1786 }
3035 warning ("get: invalid property `%s'", name.c_str ()); 1787
3036 1788 property_list::pval_map_type
3037 return retval; 1789 text::text_properties::factory_defaults (void)
3038 } 1790 {
3039 1791 property_list::pval_map_type m;
3040 std::string graphics_object_name (void) const { return go_name; } 1792
3041 1793 m["string"] = "";
3042 static property_list::pval_map_type factory_defaults (void) 1794 m["units"] = "data";
3043 { 1795 m["position"] = Matrix (1, 3, 0.0);
3044 property_list::pval_map_type m; 1796 m["horizontalalignment"] = "left";
3045 1797
3046 m["string"] = ""; 1798 return m;
3047 m["units"] = "data"; 1799 }
3048 m["position"] = Matrix (1, 3, 0.0);
3049 m["horizontalalignment"] = "left";
3050
3051 return m;
3052 }
3053
3054 private:
3055 octave_value string;
3056 octave_value units;
3057 octave_value position;
3058 octave_value horizontalalignment;
3059
3060 static std::string go_name;
3061 };
3062
3063 text_properties properties;
3064
3065 public:
3066 text (const graphics_handle& mh, const graphics_handle& p)
3067 : base_graphics_object (), properties (mh, p)
3068 {
3069 properties.override_defaults (*this);
3070 }
3071
3072 ~text (void) { properties.delete_children (); }
3073
3074 std::string type (void) const { return properties.graphics_object_name (); }
3075
3076 void mark_modified (void) { properties.mark_modified (); }
3077
3078 void override_defaults (base_graphics_object& obj)
3079 {
3080 // Allow parent (figure) to override first (properties knows how
3081 // to find the parent object).
3082 properties.override_defaults (obj);
3083 }
3084
3085 void set_from_list (property_list& plist)
3086 {
3087 properties.set_from_list (*this, plist);
3088 }
3089
3090 void set (const property_name& name, const octave_value& val)
3091 {
3092 properties.set (name, val);
3093 }
3094
3095 octave_value get (void) const
3096 {
3097 return properties.get ();
3098 }
3099
3100 octave_value get (const property_name& name) const
3101 {
3102 return properties.get (name);
3103 }
3104
3105 graphics_handle get_parent (void) const { return properties.get_parent (); }
3106
3107 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
3108
3109 void adopt (const graphics_handle& h) { properties.adopt (h); }
3110
3111 void reparent (const graphics_handle& h) { properties.reparent (h); }
3112
3113 bool valid_object (void) const { return true; }
3114 };
3115 1800
3116 std::string text::text_properties::go_name ("text"); 1801 std::string text::text_properties::go_name ("text");
3117 1802
3118 // --------------------------------------------------------------------- 1803 // ---------------------------------------------------------------------
3119 1804
3120 class image : public base_graphics_object 1805 image::image_properties::image_properties (const graphics_handle& mh,
3121 { 1806 const graphics_handle& p)
3122 public: 1807 : base_properties (go_name, mh, p),
3123 class image_properties : public base_properties 1808 cdata (Matrix ()),
3124 { 1809 xdata (Matrix ()),
3125 public: 1810 ydata (Matrix ())
3126 image_properties (const graphics_handle& mh, const graphics_handle& p) 1811 { }
3127 : base_properties (go_name, mh, p), 1812
3128 cdata (Matrix ()), 1813 void
3129 xdata (Matrix ()), 1814 image::image_properties::set (const property_name& name,
3130 ydata (Matrix ()) 1815 const octave_value& val)
3131 { } 1816 {
3132 1817 bool modified = true;
3133 ~image_properties (void) { } 1818
3134 1819 if (name.compare ("parent"))
3135 void set (const property_name& name, const octave_value& val) 1820 set_parent (val);
3136 { 1821 else if (name.compare ("children"))
3137 bool modified = true; 1822 children = maybe_set_children (children, val);
3138 1823 else if (name.compare ("__modified__"))
3139 if (name.compare ("parent")) 1824 {
3140 set_parent (val); 1825 __modified__ = val.bool_value ();
3141 else if (name.compare ("children")) 1826 modified = false;
3142 children = maybe_set_children (children, val); 1827 }
3143 else if (name.compare ("__modified__")) 1828 else if (name.compare ("cdata"))
3144 { 1829 cdata = val;
3145 __modified__ = val.bool_value (); 1830 else if (name.compare ("xdata"))
3146 modified = false; 1831 xdata = val;
3147 } 1832 else if (name.compare ("ydata"))
3148 else if (name.compare ("cdata")) 1833 ydata = val;
3149 cdata = val; 1834 else
3150 else if (name.compare ("xdata")) 1835 {
3151 xdata = val; 1836 modified = false;
3152 else if (name.compare ("ydata")) 1837 warning ("set: invalid property `%s'", name.c_str ());
3153 ydata = val; 1838 }
3154 else 1839
3155 { 1840 if (modified)
3156 modified = false; 1841 mark_modified ();
3157 warning ("set: invalid property `%s'", name.c_str ()); 1842 }
3158 } 1843
3159 1844 octave_value
3160 if (modified) 1845 image::image_properties::get (void) const
3161 mark_modified (); 1846 {
3162 } 1847 Octave_map m;
3163 1848
3164 octave_value get (void) const 1849 m.assign ("type", type);
3165 { 1850 m.assign ("parent", parent);
3166 Octave_map m; 1851 m.assign ("children", children);
3167 1852 m.assign ("__modified__", __modified__);
3168 m.assign ("type", type); 1853 m.assign ("cdata", cdata);
3169 m.assign ("parent", parent); 1854 m.assign ("xdata", xdata);
3170 m.assign ("children", children); 1855 m.assign ("ydata", ydata);
3171 m.assign ("__modified__", __modified__); 1856
3172 m.assign ("cdata", cdata); 1857 return m;
3173 m.assign ("xdata", xdata); 1858 }
3174 m.assign ("ydata", ydata); 1859
3175 1860 octave_value
3176 return m; 1861 image::image_properties::get (const property_name& name) const
3177 } 1862 {
3178 1863 octave_value retval;
3179 octave_value get (const property_name& name) const 1864
3180 { 1865 if (name.compare ("type"))
3181 octave_value retval; 1866 retval = type;
3182 1867 else if (name.compare ("parent"))
3183 if (name.compare ("type")) 1868 retval = parent;
3184 retval = type; 1869 else if (name.compare ("children"))
3185 else if (name.compare ("parent")) 1870 retval = children;
3186 retval = parent; 1871 else if (name.compare ("__modified__"))
3187 else if (name.compare ("children")) 1872 retval = __modified__;
3188 retval = children; 1873 else if (name.compare ("cdata"))
3189 else if (name.compare ("__modified__")) 1874 retval = cdata;
3190 retval = __modified__; 1875 else if (name.compare ("xdata"))
3191 else if (name.compare ("cdata")) 1876 retval = xdata;
3192 retval = cdata; 1877 else if (name.compare ("ydata"))
3193 else if (name.compare ("xdata")) 1878 retval = ydata;
3194 retval = xdata; 1879 else
3195 else if (name.compare ("ydata")) 1880 warning ("get: invalid property `%s'", name.c_str ());
3196 retval = ydata; 1881
3197 else 1882 return retval;
3198 warning ("get: invalid property `%s'", name.c_str ()); 1883 }
3199 1884
3200 return retval; 1885 property_list::pval_map_type image::image_properties::factory_defaults (void)
3201 } 1886 {
3202 1887 property_list::pval_map_type m;
3203 std::string graphics_object_name (void) const { return go_name; } 1888
3204 1889 m["cdata"] = Matrix ();
3205 static property_list::pval_map_type factory_defaults (void) 1890 m["xdata"] = Matrix ();
3206 { 1891 m["ydata"] = Matrix ();
3207 property_list::pval_map_type m; 1892
3208 1893 return m;
3209 m["cdata"] = Matrix (); 1894 }
3210 m["xdata"] = Matrix ();
3211 m["ydata"] = Matrix ();
3212
3213 return m;
3214 }
3215
3216 private:
3217 octave_value cdata;
3218 octave_value xdata;
3219 octave_value ydata;
3220
3221 static std::string go_name;
3222 };
3223
3224 image_properties properties;
3225
3226 public:
3227 image (const graphics_handle& mh, const graphics_handle& p)
3228 : base_graphics_object (), properties (mh, p)
3229 {
3230 properties.override_defaults (*this);
3231 }
3232
3233 ~image (void) { properties.delete_children (); }
3234
3235 std::string type (void) const { return properties.graphics_object_name (); }
3236
3237 void mark_modified (void) { properties.mark_modified (); }
3238
3239 void override_defaults (base_graphics_object& obj)
3240 {
3241 // Allow parent (figure) to override first (properties knows how
3242 // to find the parent object).
3243 properties.override_defaults (obj);
3244 }
3245
3246 void set_from_list (property_list& plist)
3247 {
3248 properties.set_from_list (*this, plist);
3249 }
3250
3251 void set (const property_name& name, const octave_value& val)
3252 {
3253 properties.set (name, val);
3254 }
3255
3256 octave_value get (void) const
3257 {
3258 return properties.get ();
3259 }
3260
3261 octave_value get (const property_name& name) const
3262 {
3263 return properties.get (name);
3264 }
3265
3266 graphics_handle get_parent (void) const { return properties.get_parent (); }
3267
3268 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
3269
3270 void adopt (const graphics_handle& h) { properties.adopt (h); }
3271
3272 void reparent (const graphics_handle& h) { properties.reparent (h); }
3273
3274 bool valid_object (void) const { return true; }
3275 };
3276 1895
3277 std::string image::image_properties::go_name ("image"); 1896 std::string image::image_properties::go_name ("image");
3278 1897
3279 // --------------------------------------------------------------------- 1898 // ---------------------------------------------------------------------
3280 1899
3281 class surface : public base_graphics_object 1900 surface::surface_properties::surface_properties (const graphics_handle& mh,
3282 { 1901 const graphics_handle& p)
3283 public: 1902 : base_properties (go_name, mh, p),
3284 class surface_properties : public base_properties 1903 xdata (Matrix ()),
3285 { 1904 ydata (Matrix ()),
3286 public: 1905 zdata (Matrix ()),
3287 surface_properties (const graphics_handle& mh, const graphics_handle& p) 1906 keylabel ("")
3288 : base_properties (go_name, mh, p), 1907 { }
3289 xdata (Matrix ()), 1908
3290 ydata (Matrix ()), 1909 void
3291 zdata (Matrix ()), 1910 surface::surface_properties::set (const property_name& name,
3292 keylabel ("") 1911 const octave_value& val)
3293 { } 1912 {
3294 1913 bool modified = true;
3295 ~surface_properties (void) { } 1914
3296 1915 if (name.compare ("parent"))
3297 void set (const property_name& name, const octave_value& val) 1916 set_parent (val);
3298 { 1917 else if (name.compare ("children"))
3299 bool modified = true; 1918 children = maybe_set_children (children, val);
3300 1919 else if (name.compare ("__modified__"))
3301 if (name.compare ("parent")) 1920 {
3302 set_parent (val); 1921 __modified__ = val.bool_value ();
3303 else if (name.compare ("children")) 1922 modified = false;
3304 children = maybe_set_children (children, val); 1923 }
3305 else if (name.compare ("__modified__")) 1924 else if (name.compare ("xdata"))
3306 { 1925 xdata = val;
3307 __modified__ = val.bool_value (); 1926 else if (name.compare ("ydata"))
3308 modified = false; 1927 ydata = val;
3309 } 1928 else if (name.compare ("zdata"))
3310 else if (name.compare ("xdata")) 1929 zdata = val;
3311 xdata = val; 1930 else if (name.compare ("keylabel"))
3312 else if (name.compare ("ydata")) 1931 keylabel = val;
3313 ydata = val; 1932 else
3314 else if (name.compare ("zdata")) 1933 {
3315 zdata = val; 1934 modified = false;
3316 else if (name.compare ("keylabel")) 1935 warning ("set: invalid property `%s'", name.c_str ());
3317 keylabel = val; 1936 }
3318 else 1937
3319 { 1938 if (modified)
3320 modified = false; 1939 mark_modified ();
3321 warning ("set: invalid property `%s'", name.c_str ()); 1940 }
3322 } 1941
3323 1942 octave_value
3324 if (modified) 1943 surface::surface_properties::get (void) const
3325 mark_modified (); 1944 {
3326 } 1945 Octave_map m;
3327 1946
3328 octave_value get (void) const 1947 m.assign ("type", type);
3329 { 1948 m.assign ("parent", parent);
3330 Octave_map m; 1949 m.assign ("children", children);
3331 1950 m.assign ("__modified__", __modified__);
3332 m.assign ("type", type); 1951 m.assign ("xdata", xdata);
3333 m.assign ("parent", parent); 1952 m.assign ("ydata", ydata);
3334 m.assign ("children", children); 1953 m.assign ("zdata", zdata);
3335 m.assign ("__modified__", __modified__); 1954 m.assign ("keylabel", keylabel);
3336 m.assign ("xdata", xdata); 1955
3337 m.assign ("ydata", ydata); 1956 return m;
3338 m.assign ("zdata", zdata); 1957 }
3339 m.assign ("keylabel", keylabel); 1958
3340 1959 octave_value
3341 return m; 1960 surface::surface_properties::get (const property_name& name) const
3342 } 1961 {
3343 1962 octave_value retval;
3344 octave_value get (const property_name& name) const 1963
3345 { 1964 if (name.compare ("type"))
3346 octave_value retval; 1965 retval = type;
3347 1966 else if (name.compare ("parent"))
3348 if (name.compare ("type")) 1967 retval = parent;
3349 retval = type; 1968 else if (name.compare ("children"))
3350 else if (name.compare ("parent")) 1969 retval = children;
3351 retval = parent; 1970 else if (name.compare ("__modified__"))
3352 else if (name.compare ("children")) 1971 retval = __modified__;
3353 retval = children; 1972 else if (name.compare ("xdata"))
3354 else if (name.compare ("__modified__")) 1973 retval = xdata;
3355 retval = __modified__; 1974 else if (name.compare ("ydata"))
3356 else if (name.compare ("xdata")) 1975 retval = ydata;
3357 retval = xdata; 1976 else if (name.compare ("zdata"))
3358 else if (name.compare ("ydata")) 1977 retval = zdata;
3359 retval = ydata; 1978 else if (name.compare ("keylabel"))
3360 else if (name.compare ("zdata")) 1979 retval = keylabel;
3361 retval = zdata; 1980 else
3362 else if (name.compare ("keylabel")) 1981 warning ("get: invalid property `%s'", name.c_str ());
3363 retval = keylabel; 1982
3364 else 1983 return retval;
3365 warning ("get: invalid property `%s'", name.c_str ()); 1984 }
3366 1985
3367 return retval; 1986 property_list::pval_map_type
3368 } 1987 surface::surface_properties::factory_defaults (void)
3369 1988 {
3370 std::string graphics_object_name (void) const { return go_name; } 1989 property_list::pval_map_type m;
3371 1990
3372 static property_list::pval_map_type factory_defaults (void) 1991 m["xdata"] = Matrix ();
3373 { 1992 m["ydata"] = Matrix ();
3374 property_list::pval_map_type m; 1993 m["zdata"] = Matrix ();
3375 1994 m["keylabel"] = "";
3376 m["xdata"] = Matrix (); 1995
3377 m["ydata"] = Matrix (); 1996 return m;
3378 m["zdata"] = Matrix (); 1997 }
3379 m["keylabel"] = "";
3380
3381 return m;
3382 }
3383
3384 private:
3385 octave_value xdata;
3386 octave_value ydata;
3387 octave_value zdata;
3388 octave_value keylabel;
3389
3390 static std::string go_name;
3391 };
3392
3393 surface_properties properties;
3394
3395 public:
3396 surface (const graphics_handle& mh, const graphics_handle& p)
3397 : base_graphics_object (), properties (mh, p)
3398 {
3399 properties.override_defaults (*this);
3400 }
3401
3402 ~surface (void) { properties.delete_children (); }
3403
3404 std::string type (void) const { return properties.graphics_object_name (); }
3405
3406 void mark_modified (void) { properties.mark_modified (); }
3407
3408 void override_defaults (base_graphics_object& obj)
3409 {
3410 // Allow parent (figure) to override first (properties knows how
3411 // to find the parent object).
3412 properties.override_defaults (obj);
3413 }
3414
3415 void set_from_list (property_list& plist)
3416 {
3417 properties.set_from_list (*this, plist);
3418 }
3419
3420 void set (const property_name& name, const octave_value& val)
3421 {
3422 properties.set (name, val);
3423 }
3424
3425 octave_value get (void) const
3426 {
3427 return properties.get ();
3428 }
3429
3430 octave_value get (const property_name& name) const
3431 {
3432 return properties.get (name);
3433 }
3434
3435 graphics_handle get_parent (void) const { return properties.get_parent (); }
3436
3437 void remove_child (const graphics_handle& h) { properties.remove_child (h); }
3438
3439 void adopt (const graphics_handle& h) { properties.adopt (h); }
3440
3441 void reparent (const graphics_handle& h) { properties.reparent (h); }
3442
3443 bool valid_object (void) const { return true; }
3444 };
3445 1998
3446 std::string surface::surface_properties::go_name ("surface"); 1999 std::string surface::surface_properties::go_name ("surface");
3447 2000
3448 // --------------------------------------------------------------------- 2001 // ---------------------------------------------------------------------
3449 2002