GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
graphics.h
Go to the documentation of this file.
1 // DO NOT EDIT! Generated automatically by genprops.awk.
2 
3 /*
4 
5 Copyright (C) 2007-2013 John W. Eaton
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if !defined (octave_graphics_h)
26 #define octave_graphics_h 1
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <cctype>
33 
34 #include <algorithm>
35 #include <list>
36 #include <map>
37 #include <set>
38 #include <sstream>
39 #include <string>
40 
41 #include "caseless-str.h"
42 
43 #include "gripes.h"
44 #include "oct-handle.h"
45 #include "oct-map.h"
46 #include "oct-mutex.h"
47 #include "oct-refcount.h"
48 #include "ov.h"
49 #include "txt-eng-ft.h"
50 
51 // FIXME: maybe this should be a configure option?
52 // Matlab defaults to "Helvetica", but that causes problems for many
53 // gnuplot users.
54 #if !defined (OCTAVE_DEFAULT_FONTNAME)
55 #define OCTAVE_DEFAULT_FONTNAME "*"
56 #endif
57 
59 
60 // ---------------------------------------------------------------------
61 
63 {
64 public:
65  base_scaler (void) { }
66 
67  virtual ~base_scaler (void) { }
68 
69  virtual Matrix scale (const Matrix& m) const
70  {
71  error ("invalid axis scale");
72  return m;
73  }
74 
75  virtual NDArray scale (const NDArray& m) const
76  {
77  error ("invalid axis scale");
78  return m;
79  }
80 
81  virtual double scale (double d) const
82  {
83  error ("invalid axis scale");
84  return d;
85  }
86 
87  virtual double unscale (double d) const
88  {
89  error ("invalid axis scale");
90  return d;
91  }
92 
93  virtual base_scaler* clone () const
94  { return new base_scaler (); }
95 
96  virtual bool is_linear (void) const
97  { return false; }
98 };
99 
100 class lin_scaler : public base_scaler
101 {
102 public:
103  lin_scaler (void) { }
104 
105  Matrix scale (const Matrix& m) const { return m; }
106 
107  NDArray scale (const NDArray& m) const { return m; }
108 
109  double scale (double d) const { return d; }
110 
111  double unscale (double d) const { return d; }
112 
113  base_scaler* clone (void) const { return new lin_scaler (); }
114 
115  bool is_linear (void) const { return true; }
116 };
117 
118 class log_scaler : public base_scaler
119 {
120 public:
121  log_scaler (void) { }
122 
123  Matrix scale (const Matrix& m) const
124  {
125  Matrix retval (m.rows (), m.cols ());
126 
127  do_scale (m.data (), retval.fortran_vec (), m.numel ());
128 
129  return retval;
130  }
131 
132  NDArray scale (const NDArray& m) const
133  {
134  NDArray retval (m.dims ());
135 
136  do_scale (m.data (), retval.fortran_vec (), m.numel ());
137 
138  return retval;
139  }
140 
141  double scale (double d) const
142  { return log10 (d); }
143 
144  double unscale (double d) const
145  { return pow (10.0, d); }
146 
147  base_scaler* clone (void) const
148  { return new log_scaler (); }
149 
150 private:
151  void do_scale (const double *src, double *dest, int n) const
152  {
153  for (int i = 0; i < n; i++)
154  dest[i] = log10 (src[i]);
155  }
156 };
157 
159 {
160 public:
161  neg_log_scaler (void) { }
162 
163  Matrix scale (const Matrix& m) const
164  {
165  Matrix retval (m.rows (), m.cols ());
166 
167  do_scale (m.data (), retval.fortran_vec (), m.numel ());
168 
169  return retval;
170  }
171 
172  NDArray scale (const NDArray& m) const
173  {
174  NDArray retval (m.dims ());
175 
176  do_scale (m.data (), retval.fortran_vec (), m.numel ());
177 
178  return retval;
179  }
180 
181  double scale (double d) const
182  { return -log10 (-d); }
183 
184  double unscale (double d) const
185  { return -pow (10.0, -d); }
186 
187  base_scaler* clone (void) const
188  { return new neg_log_scaler (); }
189 
190 private:
191  void do_scale (const double *src, double *dest, int n) const
192  {
193  for (int i = 0; i < n; i++)
194  dest[i] = -log10 (-src[i]);
195  }
196 };
197 
198 class scaler
199 {
200 public:
201  scaler (void) : rep (new base_scaler ()) { }
202 
203  scaler (const scaler& s) : rep (s.rep->clone ()) { }
204 
205  scaler (const std::string& s)
206  : rep (s == "log"
207  ? new log_scaler ()
208  : (s == "neglog" ? new neg_log_scaler ()
209  : (s == "linear" ? new lin_scaler () : new base_scaler ())))
210  { }
211 
212  ~scaler (void) { delete rep; }
213 
214  Matrix scale (const Matrix& m) const
215  { return rep->scale (m); }
216 
217  NDArray scale (const NDArray& m) const
218  { return rep->scale (m); }
219 
220  double scale (double d) const
221  { return rep->scale (d); }
222 
223  double unscale (double d) const
224  { return rep->unscale (d); }
225 
226  bool is_linear (void) const
227  { return rep->is_linear (); }
228 
230  {
231  if (rep)
232  {
233  delete rep;
234  rep = 0;
235  }
236 
237  rep = s.rep->clone ();
238 
239  return *this;
240  }
241 
242  scaler& operator = (const std::string& s)
243  {
244  if (rep)
245  {
246  delete rep;
247  rep = 0;
248  }
249 
250  if (s == "log")
251  rep = new log_scaler ();
252  else if (s == "neglog")
253  rep = new neg_log_scaler ();
254  else if (s == "linear")
255  rep = new lin_scaler ();
256  else
257  rep = new base_scaler ();
258 
259  return *this;
260  }
261 
262 private:
264 };
265 
266 // ---------------------------------------------------------------------
267 
268 class property;
269 
271 
273 {
274 public:
275  friend class property;
276 
277 public:
279  : id (-1), count (1), name (), parent (), hidden (), listeners ()
280  { }
281 
282  base_property (const std::string& s, const graphics_handle& h)
283  : id (-1), count (1), name (s), parent (h), hidden (false), listeners ()
284  { }
285 
287  : id (-1), count (1), name (p.name), parent (p.parent),
288  hidden (p.hidden), listeners ()
289  { }
290 
291  virtual ~base_property (void) { }
292 
293  bool ok (void) const { return parent.ok (); }
294 
295  std::string get_name (void) const { return name; }
296 
297  void set_name (const std::string& s) { name = s; }
298 
299  graphics_handle get_parent (void) const { return parent; }
300 
301  void set_parent (const graphics_handle &h) { parent = h; }
302 
303  bool is_hidden (void) const { return hidden; }
304 
305  void set_hidden (bool flag) { hidden = flag; }
306 
307  virtual bool is_radio (void) const { return false; }
308 
309  int get_id (void) const { return id; }
310 
311  void set_id (int d) { id = d; }
312 
313  // Sets property value, notifies graphics toolkit.
314  // If do_run is true, runs associated listeners.
315  OCTINTERP_API bool set (const octave_value& v, bool do_run = true,
316  bool do_notify_toolkit = true);
317 
318  virtual octave_value get (void) const
319  {
320  error ("get: invalid property \"%s\"", name.c_str ());
321  return octave_value ();
322  }
323 
324 
325  virtual std::string values_as_string (void) const
326  {
327  error ("values_as_string: invalid property \"%s\"", name.c_str ());
328  return std::string ();
329  }
330 
331  virtual Cell values_as_cell (void) const
332  {
333  error ("values_as_cell: invalid property \"%s\"", name.c_str ());
334  return Cell ();
335  }
336 
338  {
339  set (val);
340  return *this;
341  }
342 
344  {
345  octave_value_list& l = listeners[mode];
346  l.resize (l.length () + 1, v);
347  }
348 
350  listener_mode mode = POSTSET)
351  {
352  octave_value_list& l = listeners[mode];
353 
354  if (v.is_defined ())
355  {
356  bool found = false;
357  int i;
358 
359  for (i = 0; i < l.length (); i++)
360  {
361  if (v.internal_rep () == l(i).internal_rep ())
362  {
363  found = true;
364  break;
365  }
366  }
367  if (found)
368  {
369  for (int j = i; j < l.length () - 1; j++)
370  l(j) = l(j + 1);
371 
372  l.resize (l.length () - 1);
373  }
374  }
375  else
376  {
377  if (mode == PERSISTENT)
378  l.resize (0);
379  else
380  {
381  octave_value_list lnew (0);
383  for (int i = l.length () - 1; i >= 0 ; i--)
384  {
385  for (int j = 0; j < lp.length (); j++)
386  {
387  if (l(i).internal_rep () == lp(j).internal_rep ())
388  {
389  lnew.resize (lnew.length () + 1, l(i));
390  break;
391  }
392  }
393  }
394  l = lnew;
395  }
396  }
397 
398  }
399 
401 
402  virtual base_property* clone (void) const
403  { return new base_property (*this); }
404 
405 protected:
406  virtual bool do_set (const octave_value&)
407  {
408  error ("set: invalid property \"%s\"", name.c_str ());
409  return false;
410  }
411 
412 private:
413  typedef std::map<listener_mode, octave_value_list> listener_map;
414  typedef std::map<listener_mode, octave_value_list>::iterator
416  typedef std::map<listener_mode, octave_value_list>::const_iterator
418 
419 private:
420  int id;
422  std::string name;
424  bool hidden;
426 };
427 
428 // ---------------------------------------------------------------------
429 
431 {
432 public:
433  string_property (const std::string& s, const graphics_handle& h,
434  const std::string& val = "")
435  : base_property (s, h), str (val) { }
436 
438  : base_property (p), str (p.str) { }
439 
440  octave_value get (void) const
441  { return octave_value (str); }
442 
443  std::string string_value (void) const { return str; }
444 
446  {
447  set (val);
448  return *this;
449  }
450 
451  base_property* clone (void) const { return new string_property (*this); }
452 
453 protected:
454  bool do_set (const octave_value& val)
455  {
456  if (val.is_string ())
457  {
458  std::string new_str = val.string_value ();
459 
460  if (new_str != str)
461  {
462  str = new_str;
463  return true;
464  }
465  }
466  else
467  error ("set: invalid string property value for \"%s\"",
468  get_name ().c_str ());
469  return false;
470  }
471 
472 private:
473  std::string str;
474 };
475 
476 // ---------------------------------------------------------------------
477 
479 {
480 public:
482 
483  string_array_property (const std::string& s, const graphics_handle& h,
484  const std::string& val = "", const char& sep = '|',
485  const desired_enum& typ = string_t)
486  : base_property (s, h), desired_type (typ), separator (sep), str ()
487  {
488  size_t pos = 0;
489 
490  while (true)
491  {
492  size_t new_pos = val.find_first_of (separator, pos);
493 
494  if (new_pos == std::string::npos)
495  {
496  str.append (val.substr (pos));
497  break;
498  }
499  else
500  str.append (val.substr (pos, new_pos - pos));
501 
502  pos = new_pos + 1;
503  }
504  }
505 
506  string_array_property (const std::string& s, const graphics_handle& h,
507  const Cell& c, const char& sep = '|',
508  const desired_enum& typ = string_t)
509  : base_property (s, h), desired_type (typ), separator (sep), str ()
510  {
511  if (c.is_cellstr ())
512  {
513  string_vector strings (c.numel ());
514 
515  for (octave_idx_type i = 0; i < c.numel (); i++)
516  strings[i] = c(i).string_value ();
517 
518  str = strings;
519  }
520  else
521  error ("set: invalid order property value for \"%s\"",
522  get_name ().c_str ());
523  }
524 
527  separator (p.separator), str (p.str) { }
528 
529  octave_value get (void) const
530  {
531  if (desired_type == string_t)
532  return octave_value (string_value ());
533  else
534  return octave_value (cell_value ());
535  }
536 
537  std::string string_value (void) const
538  {
539  std::string s;
540 
541  for (octave_idx_type i = 0; i < str.length (); i++)
542  {
543  s += str[i];
544  if (i != str.length () - 1)
545  s += separator;
546  }
547 
548  return s;
549  }
550 
551  Cell cell_value (void) const {return Cell (str);}
552 
553  string_vector string_vector_value (void) const { return str; }
554 
556  {
557  set (val);
558  return *this;
559  }
560 
561  base_property* clone (void) const
562  { return new string_array_property (*this); }
563 
564 protected:
565  bool do_set (const octave_value& val)
566  {
567  if (val.is_string () && val.rows () == 1)
568  {
569  bool replace = false;
570  std::string new_str = val.string_value ();
571  string_vector strings;
572  size_t pos = 0;
573 
574  // Split single string on delimiter (usually '|')
575  while (pos != std::string::npos)
576  {
577  size_t new_pos = new_str.find_first_of (separator, pos);
578 
579  if (new_pos == std::string::npos)
580  {
581  strings.append (new_str.substr (pos));
582  break;
583  }
584  else
585  strings.append (new_str.substr (pos, new_pos - pos));
586 
587  pos = new_pos + 1;
588  }
589 
590  if (str.numel () == strings.numel ())
591  {
592  for (octave_idx_type i = 0; i < str.numel (); i++)
593  if (strings[i] != str[i])
594  {
595  replace = true;
596  break;
597  }
598  }
599  else
600  replace = true;
601 
603 
604  if (replace)
605  {
606  str = strings;
607  return true;
608  }
609  }
610  else if (val.is_string ()) // multi-row character matrix
611  {
612  bool replace = false;
613  charMatrix chm = val.char_matrix_value ();
614  octave_idx_type nel = chm.rows ();
615  string_vector strings (nel);
616 
617  if (nel != str.numel ())
618  replace = true;
619  for (octave_idx_type i = 0; i < nel; i++)
620  {
621  strings[i] = chm.row_as_string (i);
622  if (!replace && strings[i] != str[i])
623  replace = true;
624  }
625 
627 
628  if (replace)
629  {
630  str = strings;
631  return true;
632  }
633  }
634  else if (val.is_cellstr ())
635  {
636  bool replace = false;
637  Cell new_cell = val.cell_value ();
638 
639  string_vector strings = new_cell.cellstr_value ();
640 
641  octave_idx_type nel = strings.length ();
642 
643  if (nel != str.length ())
644  replace = true;
645  else
646  {
647  for (octave_idx_type i = 0; i < nel; i++)
648  {
649  if (strings[i] != str[i])
650  {
651  replace = true;
652  break;
653  }
654  }
655  }
656 
658 
659  if (replace)
660  {
661  str = strings;
662  return true;
663  }
664  }
665  else
666  error ("set: invalid string property value for \"%s\"",
667  get_name ().c_str ());
668  return false;
669  }
670 
671 private:
673  char separator;
675 };
676 
677 // ---------------------------------------------------------------------
678 
680 {
681 public:
682  enum type { char_t, cellstr_t };
683 
684  text_label_property (const std::string& s, const graphics_handle& h,
685  const std::string& val = "")
686  : base_property (s, h), value (val), stored_type (char_t)
687  { }
688 
689  text_label_property (const std::string& s, const graphics_handle& h,
690  const NDArray& nda)
691  : base_property (s, h), stored_type (char_t)
692  {
693  octave_idx_type nel = nda.numel ();
694 
695  value.resize (nel);
696 
697  for (octave_idx_type i = 0; i < nel; i++)
698  {
699  std::ostringstream buf;
700  buf << nda(i);
701  value[i] = buf.str ();
702  }
703  }
704 
705  text_label_property (const std::string& s, const graphics_handle& h,
706  const Cell& c)
708  {
709  octave_idx_type nel = c.numel ();
710 
711  value.resize (nel);
712 
713  for (octave_idx_type i = 0; i < nel; i++)
714  {
715  octave_value tmp = c(i);
716 
717  if (tmp.is_string ())
718  value[i] = c(i).string_value ();
719  else
720  {
721  double d = c(i).double_value ();
722 
723  if (! error_state)
724  {
725  std::ostringstream buf;
726  buf << d;
727  value[i] = buf.str ();
728  }
729  else
730  break;
731  }
732  }
733  }
734 
737  { }
738 
739  bool empty (void) const
740  {
741  octave_value tmp = get ();
742  return tmp.is_empty ();
743  }
744 
745  octave_value get (void) const
746  {
747  if (stored_type == char_t)
748  return octave_value (char_value ());
749  else
750  return octave_value (cell_value ());
751  }
752 
753  std::string string_value (void) const
754  {
755  return value.empty () ? std::string () : value[0];
756  }
757 
758  string_vector string_vector_value (void) const { return value; }
759 
760  charMatrix char_value (void) const { return charMatrix (value, ' '); }
761 
762  Cell cell_value (void) const {return Cell (value); }
763 
765  {
766  set (val);
767  return *this;
768  }
769 
770  base_property* clone (void) const { return new text_label_property (*this); }
771 
772 protected:
773 
774  bool do_set (const octave_value& val)
775  {
776  if (val.is_string ())
777  {
778  value = val.all_strings ();
779 
781  }
782  else if (val.is_cell ())
783  {
784  Cell c = val.cell_value ();
785 
786  octave_idx_type nel = c.numel ();
787 
788  value.resize (nel);
789 
790  for (octave_idx_type i = 0; i < nel; i++)
791  {
792  octave_value tmp = c(i);
793 
794  if (tmp.is_string ())
795  value[i] = c(i).string_value ();
796  else
797  {
798  double d = c(i).double_value ();
799 
800  if (! error_state)
801  {
802  std::ostringstream buf;
803  buf << d;
804  value[i] = buf.str ();
805  }
806  else
807  return false;
808  }
809  }
810 
812  }
813  else
814  {
815  NDArray nda = val.array_value ();
816 
817  if (! error_state)
818  {
819  octave_idx_type nel = nda.numel ();
820 
821  value.resize (nel);
822 
823  for (octave_idx_type i = 0; i < nel; i++)
824  {
825  std::ostringstream buf;
826  buf << nda(i);
827  value[i] = buf.str ();
828  }
829 
831  }
832  else
833  {
834  error ("set: invalid string property value for \"%s\"",
835  get_name ().c_str ());
836 
837  return false;
838  }
839  }
840 
841  return true;
842  }
843 
844 private:
847 };
848 
849 // ---------------------------------------------------------------------
850 
852 {
853 public:
854  OCTINTERP_API radio_values (const std::string& opt_string = std::string ());
855 
856  radio_values (const radio_values& a)
858 
859  radio_values& operator = (const radio_values& a)
860  {
861  if (&a != this)
862  {
865  }
866 
867  return *this;
868  }
869 
870  std::string default_value (void) const { return default_val; }
871 
872  bool validate (const std::string& val, std::string& match)
873  {
874  bool retval = true;
875 
876  if (! contains (val, match))
877  {
878  error ("invalid value = %s", val.c_str ());
879  retval = false;
880  }
881 
882  return retval;
883  }
884 
885  bool contains (const std::string& val, std::string& match)
886  {
887  size_t k = 0;
888 
889  size_t len = val.length ();
890 
891  std::string first_match;
892 
893  for (std::set<caseless_str>::const_iterator p = possible_vals.begin ();
894  p != possible_vals.end (); p++)
895  {
896  if (p->compare (val, len))
897  {
898  if (len == p->length ())
899  {
900  // We found a full match (consider the case of val ==
901  // "replace" with possible values "replace" and
902  // "replacechildren"). Any other matches are
903  // irrelevant, so set match and return now.
904 
905  match = *p;
906  return true;
907  }
908  else
909  {
910  if (k == 0)
911  first_match = *p;
912 
913  k++;
914  }
915  }
916  }
917 
918  if (k == 1)
919  {
920  match = first_match;
921  return true;
922  }
923  else
924  return false;
925  }
926 
927  std::string values_as_string (void) const;
928 
929  Cell values_as_cell (void) const;
930 
931  octave_idx_type nelem (void) const { return possible_vals.size (); }
932 
933 private:
934  // Might also want to cache
935  std::string default_val;
936  std::set<caseless_str> possible_vals;
937 };
938 
940 {
941 public:
942  radio_property (const std::string& nm, const graphics_handle& h,
943  const radio_values& v = radio_values ())
944  : base_property (nm, h),
945  vals (v), current_val (v.default_value ()) { }
946 
947  radio_property (const std::string& nm, const graphics_handle& h,
948  const std::string& v)
949  : base_property (nm, h),
950  vals (v), current_val (vals.default_value ()) { }
951 
952  radio_property (const std::string& nm, const graphics_handle& h,
953  const radio_values& v, const std::string& def)
954  : base_property (nm, h),
955  vals (v), current_val (def) { }
956 
958  : base_property (p), vals (p.vals), current_val (p.current_val) { }
959 
960  octave_value get (void) const { return octave_value (current_val); }
961 
962  const std::string& current_value (void) const { return current_val; }
963 
964  std::string values_as_string (void) const { return vals.values_as_string (); }
965 
966  Cell values_as_cell (void) const { return vals.values_as_cell (); }
967 
968  bool is (const caseless_str& v) const
969  { return v.compare (current_val); }
970 
971  bool is_radio (void) const { return true; }
972 
974  {
975  set (val);
976  return *this;
977  }
978 
979  base_property* clone (void) const { return new radio_property (*this); }
980 
981 protected:
982  bool do_set (const octave_value& newval)
983  {
984  if (newval.is_string ())
985  {
986  std::string s = newval.string_value ();
987 
988  std::string match;
989 
990  if (vals.validate (s, match))
991  {
992  if (match != current_val)
993  {
994  if (s.length () != match.length ())
995  warning_with_id ("Octave:abbreviated-property-match",
996  "%s: allowing %s to match %s value %s",
997  "set", s.c_str (), get_name ().c_str (),
998  match.c_str ());
999  current_val = match;
1000  return true;
1001  }
1002  }
1003  else
1004  error ("set: invalid value for radio property \"%s\" (value = %s)",
1005  get_name ().c_str (), s.c_str ());
1006  }
1007  else
1008  error ("set: invalid value for radio property \"%s\"",
1009  get_name ().c_str ());
1010  return false;
1011  }
1012 
1013 private:
1015  std::string current_val;
1016 };
1017 
1018 // ---------------------------------------------------------------------
1019 
1021 {
1022 public:
1023  color_values (double r = 0, double g = 0, double b = 1)
1024  : xrgb (1, 3)
1025  {
1026  xrgb(0) = r;
1027  xrgb(1) = g;
1028  xrgb(2) = b;
1029 
1030  validate ();
1031  }
1032 
1033  color_values (std::string str)
1034  : xrgb (1, 3)
1035  {
1036  if (! str2rgb (str))
1037  error ("invalid color specification: %s", str.c_str ());
1038  }
1039 
1041  : xrgb (c.xrgb)
1042  { }
1043 
1045  {
1046  if (&c != this)
1047  xrgb = c.xrgb;
1048 
1049  return *this;
1050  }
1051 
1052  bool operator == (const color_values& c) const
1053  {
1054  return (xrgb(0) == c.xrgb(0)
1055  && xrgb(1) == c.xrgb(1)
1056  && xrgb(2) == c.xrgb(2));
1057  }
1058 
1059  bool operator != (const color_values& c) const
1060  { return ! (*this == c); }
1061 
1062  Matrix rgb (void) const { return xrgb; }
1063 
1064  operator octave_value (void) const { return xrgb; }
1065 
1066  void validate (void) const
1067  {
1068  for (int i = 0; i < 3; i++)
1069  {
1070  if (xrgb(i) < 0 || xrgb(i) > 1)
1071  {
1072  error ("invalid RGB color specification");
1073  break;
1074  }
1075  }
1076  }
1077 
1078 private:
1080 
1081  OCTINTERP_API bool str2rgb (std::string str);
1082 };
1083 
1085 {
1086 public:
1088  : base_property ("", graphics_handle ()),
1090  current_val (v.default_value ())
1091  { }
1092 
1094  : base_property ("", graphics_handle ()),
1096  current_val (v.default_value ())
1097  { }
1098 
1099  color_property (const std::string& nm, const graphics_handle& h,
1100  const color_values& c = color_values (),
1101  const radio_values& v = radio_values ())
1102  : base_property (nm, h),
1104  current_val (v.default_value ())
1105  { }
1106 
1107  color_property (const std::string& nm, const graphics_handle& h,
1108  const radio_values& v)
1109  : base_property (nm, h),
1111  current_val (v.default_value ())
1112  { }
1113 
1114  color_property (const std::string& nm, const graphics_handle& h,
1115  const std::string& v)
1116  : base_property (nm, h),
1118  current_val (radio_val.default_value ())
1119  { }
1120 
1121  color_property (const std::string& nm, const graphics_handle& h,
1122  const color_property& v)
1123  : base_property (nm, h),
1126  { }
1127 
1131  current_val (p.current_val) { }
1132 
1133  octave_value get (void) const
1134  {
1135  if (current_type == color_t)
1136  return color_val.rgb ();
1137 
1138  return current_val;
1139  }
1140 
1141  bool is_rgb (void) const { return (current_type == color_t); }
1142 
1143  bool is_radio (void) const { return (current_type == radio_t); }
1144 
1145  bool is (const std::string& v) const
1146  { return (is_radio () && current_val == v); }
1147 
1148  Matrix rgb (void) const
1149  {
1150  if (current_type != color_t)
1151  error ("color has no rgb value");
1152 
1153  return color_val.rgb ();
1154  }
1155 
1156  const std::string& current_value (void) const
1157  {
1158  if (current_type != radio_t)
1159  error ("color has no radio value");
1160 
1161  return current_val;
1162  }
1163 
1165  {
1166  set (val);
1167  return *this;
1168  }
1169 
1170  operator octave_value (void) const { return get (); }
1171 
1172  base_property* clone (void) const { return new color_property (*this); }
1173 
1174  std::string values_as_string (void) const
1175  { return radio_val.values_as_string (); }
1176 
1177  Cell values_as_cell (void) const { return radio_val.values_as_cell (); }
1178 
1179 protected:
1180  OCTINTERP_API bool do_set (const octave_value& newval);
1181 
1182 private:
1186  std::string current_val;
1187 };
1188 
1189 // ---------------------------------------------------------------------
1190 
1192 {
1193 public:
1194  double_property (const std::string& nm, const graphics_handle& h,
1195  double d = 0)
1196  : base_property (nm, h),
1197  current_val (d) { }
1198 
1200  : base_property (p), current_val (p.current_val) { }
1201 
1202  octave_value get (void) const { return octave_value (current_val); }
1203 
1204  double double_value (void) const { return current_val; }
1205 
1207  {
1208  set (val);
1209  return *this;
1210  }
1211 
1212  base_property* clone (void) const { return new double_property (*this); }
1213 
1214 protected:
1215  bool do_set (const octave_value& v)
1216  {
1217  if (v.is_scalar_type () && v.is_real_type ())
1218  {
1219  double new_val = v.double_value ();
1220 
1221  if (new_val != current_val)
1222  {
1223  current_val = new_val;
1224  return true;
1225  }
1226  }
1227  else
1228  error ("set: invalid value for double property \"%s\"",
1229  get_name ().c_str ());
1230  return false;
1231  }
1232 
1233 private:
1234  double current_val;
1235 };
1236 
1237 // ---------------------------------------------------------------------
1238 
1240 {
1241 public:
1243  : base_property ("", graphics_handle ()),
1244  current_type (double_t), dval (d), radio_val (v),
1245  current_val (v.default_value ())
1246  { }
1247 
1248  double_radio_property (const std::string& nm, const graphics_handle& h,
1249  const std::string& v)
1250  : base_property (nm, h),
1251  current_type (radio_t), dval (0), radio_val (v),
1252  current_val (radio_val.default_value ())
1253  { }
1254 
1255  double_radio_property (const std::string& nm, const graphics_handle& h,
1256  const double_radio_property& v)
1257  : base_property (nm, h),
1260  { }
1261 
1264  dval (p.dval), radio_val (p.radio_val),
1265  current_val (p.current_val) { }
1266 
1267  octave_value get (void) const
1268  {
1269  if (current_type == double_t)
1270  return dval;
1271 
1272  return current_val;
1273  }
1274 
1275  bool is_double (void) const { return (current_type == double_t); }
1276 
1277  bool is_radio (void) const { return (current_type == radio_t); }
1278 
1279  bool is (const std::string& v) const
1280  { return (is_radio () && current_val == v); }
1281 
1282  double double_value (void) const
1283  {
1284  if (current_type != double_t)
1285  error ("%s: property has no double", get_name ().c_str ());
1286 
1287  return dval;
1288  }
1289 
1290  const std::string& current_value (void) const
1291  {
1292  if (current_type != radio_t)
1293  error ("%s: property has no radio value");
1294 
1295  return current_val;
1296  }
1297 
1299  {
1300  set (val);
1301  return *this;
1302  }
1303 
1304  operator octave_value (void) const { return get (); }
1305 
1306  base_property* clone (void) const
1307  { return new double_radio_property (*this); }
1308 
1309 protected:
1310  OCTINTERP_API bool do_set (const octave_value& v);
1311 
1312 private:
1314  double dval;
1316  std::string current_val;
1317 };
1318 
1319 // ---------------------------------------------------------------------
1320 
1322 {
1323 public:
1325  : base_property ("", graphics_handle ()), data (Matrix ()),
1326  xmin (), xmax (), xminp (), xmaxp (),
1328  {
1329  get_data_limits ();
1330  }
1331 
1332  array_property (const std::string& nm, const graphics_handle& h,
1333  const octave_value& m)
1334  : base_property (nm, h), data (m.is_sparse_type () ? m.full_value () : m),
1335  xmin (), xmax (), xminp (), xmaxp (),
1337  {
1338  get_data_limits ();
1339  }
1340 
1341  // This copy constructor is only intended to be used
1342  // internally to access min/max values; no need to
1343  // copy constraints.
1345  : base_property (p), data (p.data),
1346  xmin (p.xmin), xmax (p.xmax), xminp (p.xminp), xmaxp (p.xmaxp),
1348  { }
1349 
1350  octave_value get (void) const { return data; }
1351 
1352  void add_constraint (const std::string& type)
1353  { type_constraints.insert (type); }
1354 
1355  void add_constraint (const dim_vector& dims)
1356  { size_constraints.push_back (dims); }
1357 
1358  double min_val (void) const { return xmin; }
1359  double max_val (void) const { return xmax; }
1360  double min_pos (void) const { return xminp; }
1361  double max_neg (void) const { return xmaxp; }
1362 
1363  Matrix get_limits (void) const
1364  {
1365  Matrix m (1, 4);
1366 
1367  m(0) = min_val ();
1368  m(1) = max_val ();
1369  m(2) = min_pos ();
1370  m(3) = max_neg ();
1371 
1372  return m;
1373  }
1374 
1376  {
1377  set (val);
1378  return *this;
1379  }
1380 
1381  base_property* clone (void) const
1382  {
1383  array_property *p = new array_property (*this);
1384 
1387 
1388  return p;
1389  }
1390 
1391 protected:
1392  bool do_set (const octave_value& v)
1393  {
1394  octave_value tmp = v.is_sparse_type () ? v.full_value () : v;
1395 
1396  if (validate (tmp))
1397  {
1398  // FIXME: should we check for actual data change?
1399  if (! is_equal (tmp))
1400  {
1401  data = tmp;
1402 
1403  get_data_limits ();
1404 
1405  return true;
1406  }
1407  }
1408  else
1409  error ("invalid value for array property \"%s\"",
1410  get_name ().c_str ());
1411 
1412  return false;
1413  }
1414 
1415 private:
1416  OCTINTERP_API bool validate (const octave_value& v);
1417 
1418  OCTINTERP_API bool is_equal (const octave_value& v) const;
1419 
1420  OCTINTERP_API void get_data_limits (void);
1421 
1422 protected:
1424  double xmin;
1425  double xmax;
1426  double xminp;
1427  double xmaxp;
1428  std::set<std::string> type_constraints;
1429  std::list<dim_vector> size_constraints;
1430 };
1431 
1433 {
1434 public:
1435  row_vector_property (const std::string& nm, const graphics_handle& h,
1436  const octave_value& m)
1437  : array_property (nm, h, m)
1438  {
1439  add_constraint (dim_vector (-1, 1));
1440  add_constraint (dim_vector (1, -1));
1441  add_constraint (dim_vector (0, 0));
1442  }
1443 
1445  : array_property (p)
1446  {
1447  add_constraint (dim_vector (-1, 1));
1448  add_constraint (dim_vector (1, -1));
1449  add_constraint (dim_vector (0, 0));
1450  }
1451 
1452  void add_constraint (const std::string& type)
1453  {
1455  }
1456 
1457  void add_constraint (const dim_vector& dims)
1458  {
1460  }
1461 
1463  {
1464  size_constraints.remove (dim_vector (1, -1));
1465  size_constraints.remove (dim_vector (-1, 1));
1466 
1467  add_constraint (dim_vector (1, len));
1468  add_constraint (dim_vector (len, 1));
1469  }
1470 
1472  {
1473  set (val);
1474  return *this;
1475  }
1476 
1477  base_property* clone (void) const
1478  {
1479  row_vector_property *p = new row_vector_property (*this);
1480 
1483 
1484  return p;
1485  }
1486 
1487 protected:
1488  bool do_set (const octave_value& v)
1489  {
1490  bool retval = array_property::do_set (v);
1491 
1492  if (! error_state)
1493  {
1494  dim_vector dv = data.dims ();
1495 
1496  if (dv(0) > 1 && dv(1) == 1)
1497  {
1498  int tmp = dv(0);
1499  dv(0) = dv(1);
1500  dv(1) = tmp;
1501 
1502  data = data.reshape (dv);
1503  }
1504 
1505  return retval;
1506  }
1507 
1508  return false;
1509  }
1510 
1511 private:
1512  OCTINTERP_API bool validate (const octave_value& v);
1513 };
1514 
1515 // ---------------------------------------------------------------------
1516 
1518 {
1519 public:
1520  bool_property (const std::string& nm, const graphics_handle& h,
1521  bool val)
1522  : radio_property (nm, h, radio_values (val ? "{on}|off" : "on|{off}"))
1523  { }
1524 
1525  bool_property (const std::string& nm, const graphics_handle& h,
1526  const char* val)
1527  : radio_property (nm, h, radio_values ("on|off"), val)
1528  { }
1529 
1531  : radio_property (p) { }
1532 
1533  bool is_on (void) const { return is ("on"); }
1534 
1536  {
1537  set (val);
1538  return *this;
1539  }
1540 
1541  base_property* clone (void) const { return new bool_property (*this); }
1542 
1543 protected:
1544  bool do_set (const octave_value& val)
1545  {
1546  if (val.is_bool_scalar ())
1547  return radio_property::do_set (val.bool_value () ? "on" : "off");
1548  else
1549  return radio_property::do_set (val);
1550  }
1551 };
1552 
1553 // ---------------------------------------------------------------------
1554 
1556 {
1557 public:
1558  handle_property (const std::string& nm, const graphics_handle& h,
1559  const graphics_handle& val = graphics_handle ())
1560  : base_property (nm, h),
1561  current_val (val) { }
1562 
1564  : base_property (p), current_val (p.current_val) { }
1565 
1566  octave_value get (void) const { return current_val.as_octave_value (); }
1567 
1568  graphics_handle handle_value (void) const { return current_val; }
1569 
1571  {
1572  set (val);
1573  return *this;
1574  }
1575 
1577  {
1578  set (octave_value (h.value ()));
1579  return *this;
1580  }
1581 
1582  base_property* clone (void) const { return new handle_property (*this); }
1583 
1584 protected:
1585  OCTINTERP_API bool do_set (const octave_value& v);
1586 
1587 private:
1589 };
1590 
1591 // ---------------------------------------------------------------------
1592 
1594 {
1595 public:
1596  any_property (const std::string& nm, const graphics_handle& h,
1597  const octave_value& m = Matrix ())
1598  : base_property (nm, h), data (m) { }
1599 
1601  : base_property (p), data (p.data) { }
1602 
1603  octave_value get (void) const { return data; }
1604 
1606  {
1607  set (val);
1608  return *this;
1609  }
1610 
1611  base_property* clone (void) const { return new any_property (*this); }
1612 
1613 protected:
1614  bool do_set (const octave_value& v)
1615  {
1616  data = v;
1617  return true;
1618  }
1619 
1620 private:
1622 };
1623 
1624 // ---------------------------------------------------------------------
1625 
1627 {
1628 public:
1631  {
1632  do_init_children (Matrix ());
1633  }
1634 
1635  children_property (const std::string& nm, const graphics_handle& h,
1636  const Matrix &val)
1637  : base_property (nm, h), children_list ()
1638  {
1639  do_init_children (val);
1640  }
1641 
1643  : base_property (p), children_list ()
1644  {
1646  }
1647 
1649  {
1650  set (val);
1651  return *this;
1652  }
1653 
1654  base_property* clone (void) const { return new children_property (*this); }
1655 
1656  bool remove_child (const double &val)
1657  {
1658  return do_remove_child (val);
1659  }
1660 
1661  void adopt (const double &val)
1662  {
1663  do_adopt_child (val);
1664  }
1665 
1666  Matrix get_children (void) const
1667  {
1668  return do_get_children (false);
1669  }
1670 
1671  Matrix get_hidden (void) const
1672  {
1673  return do_get_children (true);
1674  }
1675 
1676  Matrix get_all (void) const
1677  {
1678  return do_get_all_children ();
1679  }
1680 
1681  octave_value get (void) const
1682  {
1683  return octave_value (get_children ());
1684  }
1685 
1686  void delete_children (bool clear = false)
1687  {
1689  }
1690 
1692  {
1693  for (children_list_iterator p = children_list.begin ();
1694  p != children_list.end (); p++)
1695  {
1696  if (*p == old_gh)
1697  {
1698  *p = new_gh.value ();
1699  return;
1700  }
1701  }
1702 
1703  error ("children_list::renumber: child not found!");
1704  }
1705 
1706 private:
1707  typedef std::list<double>::iterator children_list_iterator;
1708  typedef std::list<double>::const_iterator const_children_list_iterator;
1709  std::list<double> children_list;
1710 
1711 protected:
1712  bool do_set (const octave_value& val)
1713  {
1714  const Matrix new_kids = val.matrix_value ();
1715 
1716  octave_idx_type nel = new_kids.numel ();
1717 
1718  const Matrix new_kids_column = new_kids.reshape (dim_vector (nel, 1));
1719 
1720  bool is_ok = true;
1721 
1722  if (! error_state)
1723  {
1724  const Matrix visible_kids = do_get_children (false);
1725 
1726  if (visible_kids.numel () == new_kids.numel ())
1727  {
1728  Matrix t1 = visible_kids.sort ();
1729  Matrix t2 = new_kids_column.sort ();
1730 
1731  if (t1 != t2)
1732  is_ok = false;
1733  }
1734  else
1735  is_ok = false;
1736 
1737  if (! is_ok)
1738  error ("set: new children must be a permutation of existing children");
1739  }
1740  else
1741  {
1742  is_ok = false;
1743  error ("set: expecting children to be array of graphics handles");
1744  }
1745 
1746  if (is_ok)
1747  {
1748  Matrix tmp = new_kids_column.stack (get_hidden ());
1749 
1750  children_list.clear ();
1751 
1752  // Don't use do_init_children here, as that reverses the
1753  // order of the list, and we don't want to do that if setting
1754  // the child list directly.
1755 
1756  for (octave_idx_type i = 0; i < tmp.numel (); i++)
1757  children_list.push_back (tmp.xelem (i));
1758  }
1759 
1760  return is_ok;
1761  }
1762 
1763 private:
1764  void do_init_children (const Matrix &val)
1765  {
1766  children_list.clear ();
1767  for (octave_idx_type i = 0; i < val.numel (); i++)
1768  children_list.push_front (val.xelem (i));
1769  }
1770 
1771  void do_init_children (const std::list<double> &val)
1772  {
1773  children_list.clear ();
1774  for (const_children_list_iterator p = val.begin (); p != val.end (); p++)
1775  children_list.push_front (*p);
1776  }
1777 
1778  Matrix do_get_children (bool return_hidden) const;
1779 
1781  {
1782  Matrix retval (children_list.size (), 1);
1783  octave_idx_type i = 0;
1784 
1785  for (const_children_list_iterator p = children_list.begin ();
1786  p != children_list.end (); p++)
1787  retval(i++) = *p;
1788  return retval;
1789  }
1790 
1791  bool do_remove_child (double child)
1792  {
1793  for (children_list_iterator p = children_list.begin ();
1794  p != children_list.end (); p++)
1795  {
1796  if (*p == child)
1797  {
1798  children_list.erase (p);
1799  return true;
1800  }
1801  }
1802  return false;
1803  }
1804 
1805  void do_adopt_child (const double &val)
1806  {
1807  children_list.push_front (val);
1808  }
1809 
1810  void do_delete_children (bool clear);
1811 };
1812 
1813 
1814 
1815 // ---------------------------------------------------------------------
1816 
1818 {
1819 public:
1820  callback_property (const std::string& nm, const graphics_handle& h,
1821  const octave_value& m)
1822  : base_property (nm, h), callback (m), executing (false) { }
1823 
1825  : base_property (p), callback (p.callback), executing (false) { }
1826 
1827  octave_value get (void) const { return callback; }
1828 
1829  OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
1830 
1831  bool is_defined (void) const
1832  {
1833  return (callback.is_defined () && ! callback.is_empty ());
1834  }
1835 
1837  {
1838  set (val);
1839  return *this;
1840  }
1841 
1842  base_property* clone (void) const { return new callback_property (*this); }
1843 
1844 protected:
1845  bool do_set (const octave_value& v)
1846  {
1847  if (validate (v))
1848  {
1849  callback = v;
1850  return true;
1851  }
1852  else
1853  error ("invalid value for callback property \"%s\"",
1854  get_name ().c_str ());
1855  return false;
1856  }
1857 
1858 private:
1859  OCTINTERP_API bool validate (const octave_value& v) const;
1860 
1861 private:
1863 
1864  // If TRUE, we are executing this callback.
1865  mutable bool executing;
1866 };
1867 
1868 // ---------------------------------------------------------------------
1869 
1871 {
1872 public:
1873  property (void) : rep (new base_property ("", graphics_handle ()))
1874  { }
1875 
1876  property (base_property *bp, bool persist = false) : rep (bp)
1877  { if (persist) rep->count++; }
1878 
1879  property (const property& p) : rep (p.rep)
1880  {
1881  rep->count++;
1882  }
1883 
1884  ~property (void)
1885  {
1886  if (--rep->count == 0)
1887  delete rep;
1888  }
1889 
1890  bool ok (void) const
1891  { return rep->ok (); }
1892 
1893  std::string get_name (void) const
1894  { return rep->get_name (); }
1895 
1896  void set_name (const std::string& name)
1897  { rep->set_name (name); }
1898 
1900  { return rep->get_parent (); }
1901 
1902  void set_parent (const graphics_handle& h)
1903  { rep->set_parent (h); }
1904 
1905  bool is_hidden (void) const
1906  { return rep->is_hidden (); }
1907 
1908  void set_hidden (bool flag)
1909  { rep->set_hidden (flag); }
1910 
1911  bool is_radio (void) const
1912  { return rep->is_radio (); }
1913 
1914  int get_id (void) const
1915  { return rep->get_id (); }
1916 
1917  void set_id (int d)
1918  { rep->set_id (d); }
1919 
1920  octave_value get (void) const
1921  { return rep->get (); }
1922 
1923  bool set (const octave_value& val, bool do_run = true,
1924  bool do_notify_toolkit = true)
1925  { return rep->set (val, do_run, do_notify_toolkit); }
1926 
1927  std::string values_as_string (void) const
1928  { return rep->values_as_string (); }
1929 
1930  Cell values_as_cell (void) const
1931  { return rep->values_as_cell (); }
1932 
1933  property& operator = (const octave_value& val)
1934  {
1935  *rep = val;
1936  return *this;
1937  }
1938 
1939  property& operator = (const property& p)
1940  {
1941  if (rep && --rep->count == 0)
1942  delete rep;
1943 
1944  rep = p.rep;
1945  rep->count++;
1946 
1947  return *this;
1948  }
1949 
1951  { rep->add_listener (v, mode); }
1952 
1954  listener_mode mode = POSTSET)
1955  { rep->delete_listener (v, mode); }
1956 
1958  { rep->run_listeners (mode); }
1959 
1960  OCTINTERP_API static
1961  property create (const std::string& name, const graphics_handle& parent,
1962  const caseless_str& type,
1963  const octave_value_list& args);
1964 
1965  property clone (void) const
1966  { return property (rep->clone ()); }
1967 
1968  /*
1969  const string_property& as_string_property (void) const
1970  { return *(dynamic_cast<string_property*> (rep)); }
1971 
1972  const radio_property& as_radio_property (void) const
1973  { return *(dynamic_cast<radio_property*> (rep)); }
1974 
1975  const color_property& as_color_property (void) const
1976  { return *(dynamic_cast<color_property*> (rep)); }
1977 
1978  const double_property& as_double_property (void) const
1979  { return *(dynamic_cast<double_property*> (rep)); }
1980 
1981  const bool_property& as_bool_property (void) const
1982  { return *(dynamic_cast<bool_property*> (rep)); }
1983 
1984  const handle_property& as_handle_property (void) const
1985  { return *(dynamic_cast<handle_property*> (rep)); }
1986  */
1987 
1988 private:
1990 };
1991 
1992 // ---------------------------------------------------------------------
1993 
1995 {
1996 public:
1997  typedef std::map<std::string, octave_value> pval_map_type;
1998  typedef std::map<std::string, pval_map_type> plist_map_type;
1999 
2000  typedef pval_map_type::iterator pval_map_iterator;
2001  typedef pval_map_type::const_iterator pval_map_const_iterator;
2002 
2003  typedef plist_map_type::iterator plist_map_iterator;
2004  typedef plist_map_type::const_iterator plist_map_const_iterator;
2005 
2007  : plist_map (m) { }
2008 
2009  ~property_list (void) { }
2010 
2011  void set (const caseless_str& name, const octave_value& val);
2012 
2013  octave_value lookup (const caseless_str& name) const;
2014 
2015  plist_map_iterator begin (void) { return plist_map.begin (); }
2016  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
2017 
2018  plist_map_iterator end (void) { return plist_map.end (); }
2019  plist_map_const_iterator end (void) const { return plist_map.end (); }
2020 
2021  plist_map_iterator find (const std::string& go_name)
2022  {
2023  return plist_map.find (go_name);
2024  }
2025 
2026  plist_map_const_iterator find (const std::string& go_name) const
2027  {
2028  return plist_map.find (go_name);
2029  }
2030 
2031  octave_scalar_map as_struct (const std::string& prefix_arg) const;
2032 
2033 private:
2035 };
2036 
2037 // ---------------------------------------------------------------------
2038 
2039 class graphics_toolkit;
2040 class graphics_object;
2041 
2043 {
2044 public:
2045  friend class graphics_toolkit;
2046 
2047 public:
2048  base_graphics_toolkit (const std::string& nm)
2049  : name (nm), count (0) { }
2050 
2051  virtual ~base_graphics_toolkit (void) { }
2052 
2053  std::string get_name (void) const { return name; }
2054 
2055  virtual bool is_valid (void) const { return false; }
2056 
2057  virtual void redraw_figure (const graphics_object&) const
2058  { gripe_invalid ("redraw_figure"); }
2059 
2060  virtual void print_figure (const graphics_object&, const std::string&,
2061  const std::string&, bool,
2062  const std::string& = "") const
2063  { gripe_invalid ("print_figure"); }
2064 
2065  virtual Matrix get_canvas_size (const graphics_handle&) const
2066  {
2067  gripe_invalid ("get_canvas_size");
2068  return Matrix (1, 2, 0.0);
2069  }
2070 
2071  virtual double get_screen_resolution (void) const
2072  {
2073  gripe_invalid ("get_screen_resolution");
2074  return 72.0;
2075  }
2076 
2077  virtual Matrix get_screen_size (void) const
2078  {
2079  gripe_invalid ("get_screen_size");
2080  return Matrix (1, 2, 0.0);
2081  }
2082 
2083  // Callback function executed when the given graphics object
2084  // changes. This allows the graphics toolkit to act on property
2085  // changes if needed.
2086  virtual void update (const graphics_object&, int)
2087  { gripe_invalid ("base_graphics_toolkit::update"); }
2088 
2089  void update (const graphics_handle&, int);
2090 
2091  // Callback function executed when the given graphics object is
2092  // created. This allows the graphics toolkit to do toolkit-specific
2093  // initializations for a newly created object.
2094  virtual bool initialize (const graphics_object&)
2095  { gripe_invalid ("base_graphics_toolkit::initialize"); return false; }
2096 
2097  bool initialize (const graphics_handle&);
2098 
2099  // Callback function executed just prior to deleting the given
2100  // graphics object. This allows the graphics toolkit to perform
2101  // toolkit-specific cleanup operations before an object is deleted.
2102  virtual void finalize (const graphics_object&)
2103  { gripe_invalid ("base_graphics_toolkit::finalize"); }
2104 
2105  void finalize (const graphics_handle&);
2106 
2107  // Close the graphics toolkit.
2108  virtual void close (void)
2109  { gripe_invalid ("base_graphics_toolkit::close"); }
2110 
2111 private:
2112  std::string name;
2114 
2115 private:
2116  void gripe_invalid (const std::string& fname) const
2117  {
2118  if (! is_valid ())
2119  error ("%s: invalid graphics toolkit", fname.c_str ());
2120  }
2121 };
2122 
2124 {
2125 public:
2127  : rep (new base_graphics_toolkit ("unknown"))
2128  {
2129  rep->count++;
2130  }
2131 
2133  : rep (b)
2134  {
2135  rep->count++;
2136  }
2137 
2139  : rep (b.rep)
2140  {
2141  rep->count++;
2142  }
2143 
2145  {
2146  if (--rep->count == 0)
2147  delete rep;
2148  }
2149 
2151  {
2152  if (rep != b.rep)
2153  {
2154  if (--rep->count == 0)
2155  delete rep;
2156 
2157  rep = b.rep;
2158  rep->count++;
2159  }
2160 
2161  return *this;
2162  }
2163 
2164  operator bool (void) const { return rep->is_valid (); }
2165 
2166  std::string get_name (void) const { return rep->get_name (); }
2167 
2168  void redraw_figure (const graphics_object& go) const
2169  { rep->redraw_figure (go); }
2170 
2171  void print_figure (const graphics_object& go, const std::string& term,
2172  const std::string& file, bool mono,
2173  const std::string& debug_file = "") const
2174  { rep->print_figure (go, term, file, mono, debug_file); }
2175 
2177  { return rep->get_canvas_size (fh); }
2178 
2179  double get_screen_resolution (void) const
2180  { return rep->get_screen_resolution (); }
2181 
2183  { return rep->get_screen_size (); }
2184 
2185  // Notifies graphics toolkit that object't property has changed.
2186  void update (const graphics_object& go, int id)
2187  { rep->update (go, id); }
2188 
2189  void update (const graphics_handle& h, int id)
2190  { rep->update (h, id); }
2191 
2192  // Notifies graphics toolkit that new object was created.
2193  bool initialize (const graphics_object& go)
2194  { return rep->initialize (go); }
2195 
2196  bool initialize (const graphics_handle& h)
2197  { return rep->initialize (h); }
2198 
2199  // Notifies graphics toolkit that object was destroyed.
2200  // This is called only for explicitly deleted object. Children are
2201  // deleted implicitly and graphics toolkit isn't notified.
2202  void finalize (const graphics_object& go)
2203  { rep->finalize (go); }
2204 
2205  void finalize (const graphics_handle& h)
2206  { rep->finalize (h); }
2207 
2208  // Close the graphics toolkit.
2209  void close (void) { rep->close (); }
2210 
2211 private:
2212 
2214 };
2215 
2217 {
2218 public:
2219 
2221  {
2222  return instance_ok () ? instance->do_get_toolkit () : graphics_toolkit ();
2223  }
2224 
2225  static void register_toolkit (const std::string& name)
2226  {
2227  if (instance_ok ())
2228  instance->do_register_toolkit (name);
2229  }
2230 
2231  static void unregister_toolkit (const std::string& name)
2232  {
2233  if (instance_ok ())
2235  }
2236 
2237  static void load_toolkit (const graphics_toolkit& tk)
2238  {
2239  if (instance_ok ())
2240  instance->do_load_toolkit (tk);
2241  }
2242 
2243  static void unload_toolkit (const std::string& name)
2244  {
2245  if (instance_ok ())
2246  instance->do_unload_toolkit (name);
2247  }
2248 
2249  static graphics_toolkit find_toolkit (const std::string& name)
2250  {
2251  return instance_ok ()
2252  ? instance->do_find_toolkit (name) : graphics_toolkit ();
2253  }
2254 
2256  {
2257  return instance_ok () ? instance->do_available_toolkits_list () : Cell ();
2258  }
2259 
2261  {
2262  return instance_ok () ? instance->do_loaded_toolkits_list () : Cell ();
2263  }
2264 
2265  static void unload_all_toolkits (void)
2266  {
2267  if (instance_ok ())
2269  }
2270 
2271  static std::string default_toolkit (void)
2272  {
2273  return instance_ok () ? instance->do_default_toolkit () : std::string ();
2274  }
2275 
2276 private:
2277 
2278  gtk_manager (void);
2279 
2280  ~gtk_manager (void) { }
2281 
2282  OCTINTERP_API static void create_instance (void);
2283 
2284  static bool instance_ok (void)
2285  {
2286  bool retval = true;
2287 
2288  if (! instance)
2289  create_instance ();
2290 
2291  if (! instance)
2292  {
2293  ::error ("unable to create gh_manager!");
2294 
2295  retval = false;
2296  }
2297 
2298  return retval;
2299  }
2300 
2301  static void cleanup_instance (void) { delete instance; instance = 0; }
2302 
2304 
2305  // The name of the default toolkit.
2306  std::string dtk;
2307 
2308  // The list of toolkits that we know about.
2309  std::set<std::string> available_toolkits;
2310 
2311  // The list of toolkits we have actually loaded.
2312  std::map<std::string, graphics_toolkit> loaded_toolkits;
2313 
2314  typedef std::set<std::string>::iterator available_toolkits_iterator;
2315 
2316  typedef std::set<std::string>::const_iterator
2318 
2319  typedef std::map<std::string, graphics_toolkit>::iterator
2321 
2322  typedef std::map<std::string, graphics_toolkit>::const_iterator
2324 
2325  graphics_toolkit do_get_toolkit (void) const;
2326 
2327  void do_register_toolkit (const std::string& name)
2328  {
2329  available_toolkits.insert (name);
2330  }
2331 
2332  void do_unregister_toolkit (const std::string& name)
2333  {
2334  available_toolkits.erase (name);
2335  }
2336 
2338  {
2339  loaded_toolkits[tk.get_name ()] = tk;
2340  }
2341 
2342  void do_unload_toolkit (const std::string& name)
2343  {
2344  loaded_toolkits.erase (name);
2345  }
2346 
2347  graphics_toolkit do_find_toolkit (const std::string& name) const
2348  {
2350 
2351  if (p != loaded_toolkits.end ())
2352  return p->second;
2353  else
2354  return graphics_toolkit ();
2355  }
2356 
2358  {
2359  Cell m (1 , available_toolkits.size ());
2360 
2361  octave_idx_type i = 0;
2363  p != available_toolkits.end (); p++)
2364  m(i++) = *p;
2365 
2366  return m;
2367  }
2368 
2370  {
2371  Cell m (1 , loaded_toolkits.size ());
2372 
2373  octave_idx_type i = 0;
2375  p != loaded_toolkits.end (); p++)
2376  m(i++) = p->first;
2377 
2378  return m;
2379  }
2380 
2382  {
2383  while (! loaded_toolkits.empty ())
2384  {
2386 
2387  std::string name = p->first;
2388 
2389  p->second.close ();
2390 
2391  // The toolkit may have unloaded itself. If not, we'll do
2392  // it here.
2393  if (loaded_toolkits.find (name) != loaded_toolkits.end ())
2394  unload_toolkit (name);
2395  }
2396  }
2397 
2398  std::string do_default_toolkit (void) { return dtk; }
2399 };
2400 
2401 // ---------------------------------------------------------------------
2402 
2403 class base_graphics_object;
2404 class graphics_object;
2405 
2407 {
2408 public:
2409  base_properties (const std::string& ty = "unknown",
2410  const graphics_handle& mh = graphics_handle (),
2411  const graphics_handle& p = graphics_handle ());
2412 
2413  virtual ~base_properties (void) { }
2414 
2415  virtual std::string graphics_object_name (void) const { return "unknown"; }
2416 
2417  void mark_modified (void);
2418 
2419  void override_defaults (base_graphics_object& obj);
2420 
2421  virtual void init_integerhandle (const octave_value&)
2422  {
2423  panic_impossible ();
2424  }
2425 
2426  // Look through DEFAULTS for properties with given CLASS_NAME, and
2427  // apply them to the current object with set (virtual method).
2428 
2429  void set_from_list (base_graphics_object& obj, property_list& defaults);
2430 
2431  void insert_property (const std::string& name, property p)
2432  {
2433  p.set_name (name);
2434  p.set_parent (__myhandle__);
2435  all_props[name] = p;
2436  }
2437 
2438  virtual void set (const caseless_str&, const octave_value&);
2439 
2440  virtual octave_value get (const caseless_str& pname) const;
2441 
2442  virtual octave_value get (const std::string& pname) const
2443  {
2444  return get (caseless_str (pname));
2445  }
2446 
2447  virtual octave_value get (const char *pname) const
2448  {
2449  return get (caseless_str (pname));
2450  }
2451 
2452  virtual octave_value get (bool all = false) const;
2453 
2454  virtual property get_property (const caseless_str& pname);
2455 
2456  virtual bool has_property (const caseless_str&) const
2457  {
2458  panic_impossible ();
2459  return false;
2460  }
2461 
2462  bool is_modified (void) const { return is___modified__ (); }
2463 
2464  virtual void remove_child (const graphics_handle& h)
2465  {
2466  if (children.remove_child (h.value ()))
2467  mark_modified ();
2468  }
2469 
2470  virtual void adopt (const graphics_handle& h)
2471  {
2472  children.adopt (h.value ());
2473  mark_modified ();
2474  }
2475 
2476  virtual graphics_toolkit get_toolkit (void) const;
2477 
2478  virtual Matrix
2479  get_boundingbox (bool /*internal*/ = false,
2480  const Matrix& /*parent_pix_size*/ = Matrix ()) const
2481  { return Matrix (1, 4, 0.0); }
2482 
2483  virtual void update_boundingbox (void);
2484 
2485  virtual void update_autopos (const std::string& elem_type);
2486 
2487  virtual void add_listener (const caseless_str&, const octave_value&,
2489 
2490  virtual void delete_listener (const caseless_str&, const octave_value&,
2492 
2493  void set_tag (const octave_value& val) { tag = val; }
2494 
2495  void set_parent (const octave_value& val);
2496 
2497  Matrix get_children (void) const
2498  {
2499  return children.get_children ();
2500  }
2501 
2502  Matrix get_all_children (void) const
2503  {
2504  return children.get_all ();
2505  }
2506 
2507  Matrix get_hidden_children (void) const
2508  {
2509  return children.get_hidden ();
2510  }
2511 
2512  void set_modified (const octave_value& val) { set___modified__ (val); }
2513 
2514  void set___modified__ (const octave_value& val) { __modified__ = val; }
2515 
2516  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
2517 
2518  // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent
2519  // axes object.
2520 
2521  virtual void update_axis_limits (const std::string& axis_type) const;
2522 
2523  virtual void update_axis_limits (const std::string& axis_type,
2524  const graphics_handle& h) const;
2525 
2526  virtual void delete_children (bool clear = false)
2527  {
2528  children.delete_children (clear);
2529  }
2530 
2531  void renumber_child (graphics_handle old_gh, graphics_handle new_gh)
2532  {
2533  children.renumber (old_gh, new_gh);
2534  }
2535 
2536  void renumber_parent (graphics_handle new_gh)
2537  {
2538  parent = new_gh;
2539  }
2540 
2541  static property_list::pval_map_type factory_defaults (void);
2542 
2543  // FIXME: these functions should be generated automatically by the
2544  // genprops.awk script.
2545  //
2546  // EMIT_BASE_PROPERTIES_GET_FUNCTIONS
2547 
2548  virtual octave_value get_alim (void) const { return octave_value (); }
2549  virtual octave_value get_clim (void) const { return octave_value (); }
2550  virtual octave_value get_xlim (void) const { return octave_value (); }
2551  virtual octave_value get_ylim (void) const { return octave_value (); }
2552  virtual octave_value get_zlim (void) const { return octave_value (); }
2553 
2554  virtual bool is_aliminclude (void) const { return false; }
2555  virtual bool is_climinclude (void) const { return false; }
2556  virtual bool is_xliminclude (void) const { return false; }
2557  virtual bool is_yliminclude (void) const { return false; }
2558  virtual bool is_zliminclude (void) const { return false; }
2559 
2560  bool is_handle_visible (void) const;
2561 
2562  std::set<std::string> dynamic_property_names (void) const;
2563 
2564  bool has_dynamic_property (const std::string& pname);
2565 
2566 protected:
2567  std::set<std::string> dynamic_properties;
2568 
2569  void set_dynamic (const caseless_str& pname, const octave_value& val);
2570 
2571  octave_value get_dynamic (const caseless_str& pname) const;
2572 
2573  octave_value get_dynamic (bool all = false) const;
2574 
2575  property get_property_dynamic (const caseless_str& pname);
2576 
2577 public:
2578 
2579 
2580  static std::set<std::string> core_property_names (void);
2581 
2582  static bool has_core_property (const caseless_str& pname);
2583 
2584  std::set<std::string> all_property_names (void) const;
2585 
2586 protected:
2587 
2608 
2609 public:
2610 
2611  enum
2612  {
2613  ID_BEINGDELETED = 0,
2614  ID_BUSYACTION = 1,
2615  ID_BUTTONDOWNFCN = 2,
2616  ID_CHILDREN = 3,
2617  ID_CLIPPING = 4,
2618  ID_CREATEFCN = 5,
2619  ID_DELETEFCN = 6,
2620  ID_HANDLEVISIBILITY = 7,
2621  ID_HITTEST = 8,
2622  ID_INTERRUPTIBLE = 9,
2623  ID_PARENT = 10,
2624  ID_SELECTED = 11,
2625  ID_SELECTIONHIGHLIGHT = 12,
2626  ID_TAG = 13,
2627  ID_TYPE = 14,
2628  ID_UICONTEXTMENU = 15,
2629  ID_USERDATA = 16,
2630  ID_VISIBLE = 17,
2631  ID___MODIFIED__ = 18,
2632  ID___MYHANDLE__ = 19
2633  };
2634 
2635  bool is_beingdeleted (void) const { return beingdeleted.is_on (); }
2636  std::string get_beingdeleted (void) const { return beingdeleted.current_value (); }
2637 
2638  bool busyaction_is (const std::string& v) const { return busyaction.is (v); }
2639  std::string get_busyaction (void) const { return busyaction.current_value (); }
2640 
2641  void execute_buttondownfcn (const octave_value& data = octave_value ()) const { buttondownfcn.execute (data); }
2642  octave_value get_buttondownfcn (void) const { return buttondownfcn.get (); }
2643 
2644  bool is_clipping (void) const { return clipping.is_on (); }
2645  std::string get_clipping (void) const { return clipping.current_value (); }
2646 
2647  void execute_createfcn (const octave_value& data = octave_value ()) const { createfcn.execute (data); }
2648  octave_value get_createfcn (void) const { return createfcn.get (); }
2649 
2650  void execute_deletefcn (const octave_value& data = octave_value ()) const { deletefcn.execute (data); }
2651  octave_value get_deletefcn (void) const { return deletefcn.get (); }
2652 
2653  bool handlevisibility_is (const std::string& v) const { return handlevisibility.is (v); }
2654  std::string get_handlevisibility (void) const { return handlevisibility.current_value (); }
2655 
2656  bool is_hittest (void) const { return hittest.is_on (); }
2657  std::string get_hittest (void) const { return hittest.current_value (); }
2658 
2659  bool is_interruptible (void) const { return interruptible.is_on (); }
2660  std::string get_interruptible (void) const { return interruptible.current_value (); }
2661 
2662  graphics_handle get_parent (void) const { return parent.handle_value (); }
2663 
2664  bool is_selected (void) const { return selected.is_on (); }
2665  std::string get_selected (void) const { return selected.current_value (); }
2666 
2667  bool is_selectionhighlight (void) const { return selectionhighlight.is_on (); }
2668  std::string get_selectionhighlight (void) const { return selectionhighlight.current_value (); }
2669 
2670  std::string get_tag (void) const { return tag.string_value (); }
2671 
2672  std::string get_type (void) const { return type.string_value (); }
2673 
2674  graphics_handle get_uicontextmenu (void) const { return uicontextmenu.handle_value (); }
2675 
2676  octave_value get_userdata (void) const { return userdata.get (); }
2677 
2678  bool is_visible (void) const { return visible.is_on (); }
2679  std::string get_visible (void) const { return visible.current_value (); }
2680 
2681  bool is___modified__ (void) const { return __modified__.is_on (); }
2682  std::string get___modified__ (void) const { return __modified__.current_value (); }
2683 
2684  graphics_handle get___myhandle__ (void) const { return __myhandle__; }
2685 
2686 
2687  void set_beingdeleted (const octave_value& val)
2688  {
2689  if (! error_state)
2690  {
2691  if (beingdeleted.set (val, true))
2692  {
2693  mark_modified ();
2694  }
2695  }
2696  }
2697 
2698  void set_busyaction (const octave_value& val)
2699  {
2700  if (! error_state)
2701  {
2702  if (busyaction.set (val, true))
2703  {
2704  mark_modified ();
2705  }
2706  }
2707  }
2708 
2709  void set_buttondownfcn (const octave_value& val)
2710  {
2711  if (! error_state)
2712  {
2713  if (buttondownfcn.set (val, true))
2714  {
2715  mark_modified ();
2716  }
2717  }
2718  }
2719 
2720  void set_children (const octave_value& val)
2721  {
2722  if (! error_state)
2723  {
2724  if (children.set (val, true))
2725  {
2726  mark_modified ();
2727  }
2728  }
2729  }
2730 
2731  void set_clipping (const octave_value& val)
2732  {
2733  if (! error_state)
2734  {
2735  if (clipping.set (val, true))
2736  {
2737  mark_modified ();
2738  }
2739  }
2740  }
2741 
2742  void set_createfcn (const octave_value& val)
2743  {
2744  if (! error_state)
2745  {
2746  if (createfcn.set (val, true))
2747  {
2748  mark_modified ();
2749  }
2750  }
2751  }
2752 
2753  void set_deletefcn (const octave_value& val)
2754  {
2755  if (! error_state)
2756  {
2757  if (deletefcn.set (val, true))
2758  {
2759  mark_modified ();
2760  }
2761  }
2762  }
2763 
2764  void set_handlevisibility (const octave_value& val)
2765  {
2766  if (! error_state)
2767  {
2768  if (handlevisibility.set (val, true))
2769  {
2770  mark_modified ();
2771  }
2772  }
2773  }
2774 
2775  void set_hittest (const octave_value& val)
2776  {
2777  if (! error_state)
2778  {
2779  if (hittest.set (val, true))
2780  {
2781  mark_modified ();
2782  }
2783  }
2784  }
2785 
2786  void set_interruptible (const octave_value& val)
2787  {
2788  if (! error_state)
2789  {
2790  if (interruptible.set (val, true))
2791  {
2792  mark_modified ();
2793  }
2794  }
2795  }
2796 
2797  void set_selected (const octave_value& val)
2798  {
2799  if (! error_state)
2800  {
2801  if (selected.set (val, true))
2802  {
2803  mark_modified ();
2804  }
2805  }
2806  }
2807 
2808  void set_selectionhighlight (const octave_value& val)
2809  {
2810  if (! error_state)
2811  {
2812  if (selectionhighlight.set (val, true))
2813  {
2814  mark_modified ();
2815  }
2816  }
2817  }
2818 
2819  void set_uicontextmenu (const octave_value& val)
2820  {
2821  if (! error_state)
2822  {
2823  if (uicontextmenu.set (val, true))
2824  {
2825  mark_modified ();
2826  }
2827  }
2828  }
2829 
2830  void set_userdata (const octave_value& val)
2831  {
2832  if (! error_state)
2833  {
2834  if (userdata.set (val, true))
2835  {
2836  mark_modified ();
2837  }
2838  }
2839  }
2840 
2841  void set_visible (const octave_value& val)
2842  {
2843  if (! error_state)
2844  {
2845  if (visible.set (val, true))
2846  {
2847  mark_modified ();
2848  }
2849  }
2850  }
2851 
2852 
2853 protected:
2855  {
2856  bool operator () (const caseless_str &a, const caseless_str &b) const
2857  {
2858  std::string a1 = a;
2859  std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
2860  std::string b1 = b;
2861  std::transform (b1.begin (), b1.end (), b1.begin (), tolower);
2862 
2863  return a1 < b1;
2864  }
2865  };
2866 
2867  std::map<caseless_str, property, cmp_caseless_str> all_props;
2868 
2869 protected:
2870  void insert_static_property (const std::string& name, base_property& p)
2871  { insert_property (name, property (&p, true)); }
2872 
2873  virtual void init (void) { }
2874 };
2875 
2877 {
2878 public:
2879  friend class graphics_object;
2880 
2881  base_graphics_object (void) : count (1), toolkit_flag (false) { }
2882 
2883  virtual ~base_graphics_object (void) { }
2884 
2885  virtual void mark_modified (void)
2886  {
2887  if (valid_object ())
2889  else
2890  error ("base_graphics_object::mark_modified: invalid graphics object");
2891  }
2892 
2894  {
2895  if (valid_object ())
2897  else
2898  error ("base_graphics_object::override_defaults: invalid graphics object");
2899  }
2900 
2901  virtual void set_from_list (property_list& plist)
2902  {
2903  if (valid_object ())
2904  get_properties ().set_from_list (*this, plist);
2905  else
2906  error ("base_graphics_object::set_from_list: invalid graphics object");
2907  }
2908 
2909  virtual void set (const caseless_str& pname, const octave_value& pval)
2910  {
2911  if (valid_object ())
2912  get_properties ().set (pname, pval);
2913  else
2914  error ("base_graphics_object::set: invalid graphics object");
2915  }
2916 
2917  virtual void set_defaults (const std::string&)
2918  {
2919  error ("base_graphics_object::set_defaults: invalid graphics object");
2920  }
2921 
2922  virtual octave_value get (bool all = false) const
2923  {
2924  if (valid_object ())
2925  return get_properties ().get (all);
2926  else
2927  {
2928  error ("base_graphics_object::get: invalid graphics object");
2929  return octave_value ();
2930  }
2931  }
2932 
2933  virtual octave_value get (const caseless_str& pname) const
2934  {
2935  if (valid_object ())
2936  return get_properties ().get (pname);
2937  else
2938  {
2939  error ("base_graphics_object::get: invalid graphics object");
2940  return octave_value ();
2941  }
2942  }
2943 
2944  virtual octave_value get_default (const caseless_str&) const;
2945 
2946  virtual octave_value get_factory_default (const caseless_str&) const;
2947 
2948  virtual octave_value get_defaults (void) const
2949  {
2950  error ("base_graphics_object::get_defaults: invalid graphics object");
2951  return octave_value ();
2952  }
2953 
2954  virtual octave_value get_factory_defaults (void) const
2955  {
2956  error ("base_graphics_object::get_factory_defaults: invalid graphics object");
2957  return octave_value ();
2958  }
2959 
2960  virtual std::string values_as_string (void);
2961 
2962  virtual octave_scalar_map values_as_struct (void);
2963 
2964  virtual graphics_handle get_parent (void) const
2965  {
2966  if (valid_object ())
2967  return get_properties ().get_parent ();
2968  else
2969  {
2970  error ("base_graphics_object::get_parent: invalid graphics object");
2971  return graphics_handle ();
2972  }
2973  }
2974 
2976  {
2977  if (valid_object ())
2978  return get_properties ().get___myhandle__ ();
2979  else
2980  {
2981  error ("base_graphics_object::get_handle: invalid graphics object");
2982  return graphics_handle ();
2983  }
2984  }
2985 
2986  virtual void remove_child (const graphics_handle& h)
2987  {
2988  if (valid_object ())
2990  else
2991  error ("base_graphics_object::remove_child: invalid graphics object");
2992  }
2993 
2994  virtual void adopt (const graphics_handle& h)
2995  {
2996  if (valid_object ())
2997  get_properties ().adopt (h);
2998  else
2999  error ("base_graphics_object::adopt: invalid graphics object");
3000  }
3001 
3002  virtual void reparent (const graphics_handle& np)
3003  {
3004  if (valid_object ())
3005  get_properties ().reparent (np);
3006  else
3007  error ("base_graphics_object::reparent: invalid graphics object");
3008  }
3009 
3010  virtual void defaults (void) const
3011  {
3012  if (valid_object ())
3013  {
3014  std::string msg = (type () + "::defaults");
3015  gripe_not_implemented (msg.c_str ());
3016  }
3017  else
3018  error ("base_graphics_object::default: invalid graphics object");
3019  }
3020 
3022  {
3023  static base_properties properties;
3024  error ("base_graphics_object::get_properties: invalid graphics object");
3025  return properties;
3026  }
3027 
3028  virtual const base_properties& get_properties (void) const
3029  {
3030  static base_properties properties;
3031  error ("base_graphics_object::get_properties: invalid graphics object");
3032  return properties;
3033  }
3034 
3035  virtual void update_axis_limits (const std::string& axis_type);
3036 
3037  virtual void update_axis_limits (const std::string& axis_type,
3038  const graphics_handle& h);
3039 
3040  virtual bool valid_object (void) const { return false; }
3041 
3042  bool valid_toolkit_object (void) const { return toolkit_flag; }
3043 
3044  virtual std::string type (void) const
3045  {
3046  return (valid_object () ? get_properties ().graphics_object_name ()
3047  : "unknown");
3048  }
3049 
3050  bool isa (const std::string& go_name) const
3051  {
3052  return type () == go_name;
3053  }
3054 
3055  virtual graphics_toolkit get_toolkit (void) const
3056  {
3057  if (valid_object ())
3058  return get_properties ().get_toolkit ();
3059  else
3060  {
3061  error ("base_graphics_object::get_toolkit: invalid graphics object");
3062  return graphics_toolkit ();
3063  }
3064  }
3065 
3066  virtual void add_property_listener (const std::string& nm,
3067  const octave_value& v,
3068  listener_mode mode = POSTSET)
3069  {
3070  if (valid_object ())
3071  get_properties ().add_listener (nm, v, mode);
3072  }
3073 
3074  virtual void delete_property_listener (const std::string& nm,
3075  const octave_value& v,
3076  listener_mode mode = POSTSET)
3077  {
3078  if (valid_object ())
3079  get_properties ().delete_listener (nm, v, mode);
3080  }
3081 
3082  virtual void remove_all_listeners (void);
3083 
3084  virtual void reset_default_properties (void)
3085  {
3086  if (valid_object ())
3087  {
3088  std::string msg = (type () + "::reset_default_properties");
3089  gripe_not_implemented (msg.c_str ());
3090  }
3091  else
3092  error ("base_graphics_object::default: invalid graphics object");
3093  }
3094 
3095 protected:
3096  virtual void initialize (const graphics_object& go)
3097  {
3098  if (! toolkit_flag)
3099  toolkit_flag = get_toolkit ().initialize (go);
3100  }
3101 
3102  virtual void finalize (const graphics_object& go)
3103  {
3104  if (toolkit_flag)
3105  {
3106  get_toolkit ().finalize (go);
3107  toolkit_flag = false;
3108  }
3109  }
3110 
3111  virtual void update (const graphics_object& go, int id)
3112  {
3113  if (toolkit_flag)
3114  get_toolkit ().update (go, id);
3115  }
3116 
3117 protected:
3118  // A reference count.
3120 
3121  // A flag telling whether this object is a valid object
3122  // in the backend context.
3124 
3125  // No copying!
3126 
3128 
3130  {
3131  return *this;
3132  }
3133 };
3134 
3136 {
3137 public:
3138  graphics_object (void) : rep (new base_graphics_object ()) { }
3139 
3141  : rep (new_rep) { }
3142 
3143  graphics_object (const graphics_object& obj) : rep (obj.rep)
3144  {
3145  rep->count++;
3146  }
3147 
3148  graphics_object& operator = (const graphics_object& obj)
3149  {
3150  if (rep != obj.rep)
3151  {
3152  if (--rep->count == 0)
3153  delete rep;
3154 
3155  rep = obj.rep;
3156  rep->count++;
3157  }
3158 
3159  return *this;
3160  }
3161 
3163  {
3164  if (--rep->count == 0)
3165  delete rep;
3166  }
3167 
3168  void mark_modified (void) { rep->mark_modified (); }
3169 
3170  void override_defaults (base_graphics_object& obj)
3171  {
3172  rep->override_defaults (obj);
3173  }
3174 
3175  void set_from_list (property_list& plist) { rep->set_from_list (plist); }
3176 
3177  void set (const caseless_str& name, const octave_value& val)
3178  {
3179  rep->set (name, val);
3180  }
3181 
3182  void set (const octave_value_list& args);
3183 
3184  void set (const Array<std::string>& names, const Cell& values,
3185  octave_idx_type row);
3186 
3187  void set (const octave_map& m);
3188 
3189  void set_value_or_default (const caseless_str& name,
3190  const octave_value& val);
3191 
3192  void set_defaults (const std::string& mode) { rep->set_defaults (mode); }
3193 
3194  octave_value get (bool all = false) const { return rep->get (all); }
3195 
3196  octave_value get (const caseless_str& name) const
3197  {
3198  return name.compare ("default")
3199  ? get_defaults ()
3200  : (name.compare ("factory")
3201  ? get_factory_defaults () : rep->get (name));
3202  }
3203 
3204  octave_value get (const std::string& name) const
3205  {
3206  return get (caseless_str (name));
3207  }
3208 
3209  octave_value get (const char *name) const
3210  {
3211  return get (caseless_str (name));
3212  }
3213 
3214  octave_value get_default (const caseless_str& name) const
3215  {
3216  return rep->get_default (name);
3217  }
3218 
3219  octave_value get_factory_default (const caseless_str& name) const
3220  {
3221  return rep->get_factory_default (name);
3222  }
3223 
3224  octave_value get_defaults (void) const { return rep->get_defaults (); }
3225 
3226  octave_value get_factory_defaults (void) const
3227  {
3228  return rep->get_factory_defaults ();
3229  }
3230 
3231  std::string values_as_string (void) { return rep->values_as_string (); }
3232 
3233  octave_map values_as_struct (void) { return rep->values_as_struct (); }
3234 
3235  graphics_handle get_parent (void) const { return rep->get_parent (); }
3236 
3237  graphics_handle get_handle (void) const { return rep->get_handle (); }
3238 
3239  graphics_object get_ancestor (const std::string& type) const;
3240 
3241  void remove_child (const graphics_handle& h) { rep->remove_child (h); }
3242 
3243  void adopt (const graphics_handle& h) { rep->adopt (h); }
3244 
3245  void reparent (const graphics_handle& h) { rep->reparent (h); }
3246 
3247  void defaults (void) const { rep->defaults (); }
3248 
3249  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
3250 
3251  base_properties& get_properties (void) { return rep->get_properties (); }
3252 
3253  const base_properties& get_properties (void) const
3254  {
3255  return rep->get_properties ();
3256  }
3257 
3258  void update_axis_limits (const std::string& axis_type)
3259  {
3260  rep->update_axis_limits (axis_type);
3261  }
3262 
3263  void update_axis_limits (const std::string& axis_type,
3264  const graphics_handle& h)
3265  {
3266  rep->update_axis_limits (axis_type, h);
3267  }
3268 
3269  bool valid_object (void) const { return rep->valid_object (); }
3270 
3271  std::string type (void) const { return rep->type (); }
3272 
3273  operator bool (void) const { return rep->valid_object (); }
3274 
3275  // FIXME: these functions should be generated automatically by the
3276  // genprops.awk script.
3277  //
3278  // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS
3279 
3280  octave_value get_alim (void) const
3281  { return get_properties ().get_alim (); }
3282 
3283  octave_value get_clim (void) const
3284  { return get_properties ().get_clim (); }
3285 
3286  octave_value get_xlim (void) const
3287  { return get_properties ().get_xlim (); }
3288 
3289  octave_value get_ylim (void) const
3290  { return get_properties ().get_ylim (); }
3291 
3292  octave_value get_zlim (void) const
3293  { return get_properties ().get_zlim (); }
3294 
3295  bool is_aliminclude (void) const
3296  { return get_properties ().is_aliminclude (); }
3297 
3298  bool is_climinclude (void) const
3299  { return get_properties ().is_climinclude (); }
3300 
3301  bool is_xliminclude (void) const
3302  { return get_properties ().is_xliminclude (); }
3303 
3304  bool is_yliminclude (void) const
3305  { return get_properties ().is_yliminclude (); }
3306 
3307  bool is_zliminclude (void) const
3308  { return get_properties ().is_zliminclude (); }
3309 
3310  bool is_handle_visible (void) const
3311  { return get_properties ().is_handle_visible (); }
3312 
3313  graphics_toolkit get_toolkit (void) const { return rep->get_toolkit (); }
3314 
3315  void add_property_listener (const std::string& nm, const octave_value& v,
3316  listener_mode mode = POSTSET)
3317  { rep->add_property_listener (nm, v, mode); }
3318 
3319  void delete_property_listener (const std::string& nm, const octave_value& v,
3320  listener_mode mode = POSTSET)
3321  { rep->delete_property_listener (nm, v, mode); }
3322 
3323  void initialize (void) { rep->initialize (*this); }
3324 
3325  void finalize (void) { rep->finalize (*this); }
3326 
3327  void update (int id) { rep->update (*this, id); }
3328 
3330  { rep->reset_default_properties (); }
3331 
3332 private:
3334 };
3335 
3336 // ---------------------------------------------------------------------
3337 
3339 {
3340 public:
3342  {
3343  public:
3344  void remove_child (const graphics_handle& h);
3345 
3346  Matrix get_boundingbox (bool internal = false,
3347  const Matrix& parent_pix_size = Matrix ()) const;
3348 
3349  // See the genprops.awk script for an explanation of the
3350  // properties declarations.
3351 
3352  // FIXME: it seems strange to me that the diary, diaryfile,
3353  // echo, errormessage, format, formatspacing, language, and
3354  // recursionlimit properties are here.
3355  // WTF do they have to do with graphics?
3356  // Also note that these properties (and the monitorpositions,
3357  // pointerlocation, and pointerwindow properties) are not yet used
3358  // by Octave, so setting them will have no effect, and changes
3359  // made elswhere (say, the diary or format functions) will not
3360  // cause these properties to be updated.
3361  // ANSWER: Matlab defines these properties and uses them in
3362  // the same way that Octave uses an internal static variable to
3363  // keep track of state. set (0, "echo", "on") is equivalent
3364  // to Octave's echo ("on"). Maybe someday we can connect callbacks
3365  // that actually call Octave's own functions for this.
3366 
3367  // Programming note: Keep property list sorted if new ones are added.
3368 
3369 public:
3370  properties (const graphics_handle& mh, const graphics_handle& p);
3371 
3372  ~properties (void) { }
3373 
3374  void set (const caseless_str& pname, const octave_value& val);
3375 
3376  octave_value get (bool all = false) const;
3377 
3378  octave_value get (const caseless_str& pname) const;
3379 
3380  octave_value get (const std::string& pname) const
3381  {
3382  return get (caseless_str (pname));
3383  }
3384 
3385  octave_value get (const char *pname) const
3386  {
3387  return get (caseless_str (pname));
3388  }
3389 
3390  property get_property (const caseless_str& pname);
3391 
3392  std::string graphics_object_name (void) const { return go_name; }
3393 
3394  static property_list::pval_map_type factory_defaults (void);
3395 
3396 private:
3397  static std::string go_name;
3398 
3399 public:
3400 
3401 
3402  static std::set<std::string> core_property_names (void);
3403 
3404  static bool has_core_property (const caseless_str& pname);
3405 
3406  std::set<std::string> all_property_names (void) const;
3407 
3408  bool has_property (const caseless_str& pname) const;
3409 
3410 private:
3411 
3432 
3433 public:
3434 
3435  enum
3436  {
3437  ID_CALLBACKOBJECT = 1000,
3438  ID_COMMANDWINDOWSIZE = 1001,
3439  ID_CURRENTFIGURE = 1002,
3440  ID_DIARY = 1003,
3441  ID_DIARYFILE = 1004,
3442  ID_ECHO = 1005,
3443  ID_ERRORMESSAGE = 1006,
3444  ID_FIXEDWIDTHFONTNAME = 1007,
3445  ID_FORMAT = 1008,
3446  ID_FORMATSPACING = 1009,
3447  ID_LANGUAGE = 1010,
3448  ID_MONITORPOSITIONS = 1011,
3449  ID_POINTERLOCATION = 1012,
3450  ID_POINTERWINDOW = 1013,
3451  ID_RECURSIONLIMIT = 1014,
3452  ID_SCREENDEPTH = 1015,
3453  ID_SCREENPIXELSPERINCH = 1016,
3454  ID_SCREENSIZE = 1017,
3455  ID_SHOWHIDDENHANDLES = 1018,
3456  ID_UNITS = 1019
3457  };
3458 
3459  graphics_handle get_callbackobject (void) const { return callbackobject.handle_value (); }
3460 
3461  octave_value get_commandwindowsize (void) const { return commandwindowsize.get (); }
3462 
3463  graphics_handle get_currentfigure (void) const { return currentfigure.handle_value (); }
3464 
3465  bool is_diary (void) const { return diary.is_on (); }
3466  std::string get_diary (void) const { return diary.current_value (); }
3467 
3468  std::string get_diaryfile (void) const { return diaryfile.string_value (); }
3469 
3470  bool is_echo (void) const { return echo.is_on (); }
3471  std::string get_echo (void) const { return echo.current_value (); }
3472 
3473  std::string get_errormessage (void) const { return errormessage.string_value (); }
3474 
3475  std::string get_fixedwidthfontname (void) const { return fixedwidthfontname.string_value (); }
3476 
3477  bool format_is (const std::string& v) const { return format.is (v); }
3478  std::string get_format (void) const { return format.current_value (); }
3479 
3480  bool formatspacing_is (const std::string& v) const { return formatspacing.is (v); }
3481  std::string get_formatspacing (void) const { return formatspacing.current_value (); }
3482 
3483  std::string get_language (void) const { return language.string_value (); }
3484 
3485  octave_value get_monitorpositions (void) const { return monitorpositions.get (); }
3486 
3487  octave_value get_pointerlocation (void) const { return pointerlocation.get (); }
3488 
3489  double get_pointerwindow (void) const { return pointerwindow.double_value (); }
3490 
3491  double get_recursionlimit (void) const { return recursionlimit.double_value (); }
3492 
3493  double get_screendepth (void) const { return screendepth.double_value (); }
3494 
3495  double get_screenpixelsperinch (void) const { return screenpixelsperinch.double_value (); }
3496 
3497  octave_value get_screensize (void) const { return screensize.get (); }
3498 
3499  bool is_showhiddenhandles (void) const { return showhiddenhandles.is_on (); }
3500  std::string get_showhiddenhandles (void) const { return showhiddenhandles.current_value (); }
3501 
3502  bool units_is (const std::string& v) const { return units.is (v); }
3503  std::string get_units (void) const { return units.current_value (); }
3504 
3505 
3506  void set_callbackobject (const octave_value& val);
3507 
3508  void set_commandwindowsize (const octave_value& val)
3509  {
3510  if (! error_state)
3511  {
3512  if (commandwindowsize.set (val, true))
3513  {
3514  mark_modified ();
3515  }
3516  }
3517  }
3518 
3519  void set_currentfigure (const octave_value& val);
3520 
3521  void set_diary (const octave_value& val)
3522  {
3523  if (! error_state)
3524  {
3525  if (diary.set (val, true))
3526  {
3527  mark_modified ();
3528  }
3529  }
3530  }
3531 
3532  void set_diaryfile (const octave_value& val)
3533  {
3534  if (! error_state)
3535  {
3536  if (diaryfile.set (val, true))
3537  {
3538  mark_modified ();
3539  }
3540  }
3541  }
3542 
3543  void set_echo (const octave_value& val)
3544  {
3545  if (! error_state)
3546  {
3547  if (echo.set (val, true))
3548  {
3549  mark_modified ();
3550  }
3551  }
3552  }
3553 
3554  void set_errormessage (const octave_value& val)
3555  {
3556  if (! error_state)
3557  {
3558  if (errormessage.set (val, true))
3559  {
3560  mark_modified ();
3561  }
3562  }
3563  }
3564 
3565  void set_fixedwidthfontname (const octave_value& val)
3566  {
3567  if (! error_state)
3568  {
3569  if (fixedwidthfontname.set (val, true))
3570  {
3571  mark_modified ();
3572  }
3573  }
3574  }
3575 
3576  void set_format (const octave_value& val)
3577  {
3578  if (! error_state)
3579  {
3580  if (format.set (val, true))
3581  {
3582  mark_modified ();
3583  }
3584  }
3585  }
3586 
3587  void set_formatspacing (const octave_value& val)
3588  {
3589  if (! error_state)
3590  {
3591  if (formatspacing.set (val, true))
3592  {
3593  mark_modified ();
3594  }
3595  }
3596  }
3597 
3598  void set_language (const octave_value& val)
3599  {
3600  if (! error_state)
3601  {
3602  if (language.set (val, true))
3603  {
3604  mark_modified ();
3605  }
3606  }
3607  }
3608 
3609  void set_monitorpositions (const octave_value& val)
3610  {
3611  if (! error_state)
3612  {
3613  if (monitorpositions.set (val, true))
3614  {
3615  mark_modified ();
3616  }
3617  }
3618  }
3619 
3620  void set_pointerlocation (const octave_value& val)
3621  {
3622  if (! error_state)
3623  {
3624  if (pointerlocation.set (val, true))
3625  {
3626  mark_modified ();
3627  }
3628  }
3629  }
3630 
3631  void set_pointerwindow (const octave_value& val)
3632  {
3633  if (! error_state)
3634  {
3635  if (pointerwindow.set (val, true))
3636  {
3637  mark_modified ();
3638  }
3639  }
3640  }
3641 
3642  void set_recursionlimit (const octave_value& val)
3643  {
3644  if (! error_state)
3645  {
3646  if (recursionlimit.set (val, true))
3647  {
3648  mark_modified ();
3649  }
3650  }
3651  }
3652 
3653  void set_screendepth (const octave_value& val)
3654  {
3655  if (! error_state)
3656  {
3657  if (screendepth.set (val, true))
3658  {
3659  mark_modified ();
3660  }
3661  }
3662  }
3663 
3664  void set_screenpixelsperinch (const octave_value& val)
3665  {
3666  if (! error_state)
3667  {
3668  if (screenpixelsperinch.set (val, true))
3669  {
3670  mark_modified ();
3671  }
3672  }
3673  }
3674 
3675  void set_screensize (const octave_value& val)
3676  {
3677  if (! error_state)
3678  {
3679  if (screensize.set (val, true))
3680  {
3681  mark_modified ();
3682  }
3683  }
3684  }
3685 
3686  void set_showhiddenhandles (const octave_value& val)
3687  {
3688  if (! error_state)
3689  {
3690  if (showhiddenhandles.set (val, true))
3691  {
3692  mark_modified ();
3693  }
3694  }
3695  }
3696 
3697  void set_units (const octave_value& val)
3698  {
3699  if (! error_state)
3700  {
3701  if (units.set (val, true))
3702  {
3703  update_units ();
3704  mark_modified ();
3705  }
3706  }
3707  }
3708 
3709  void update_units (void);
3710 
3711 
3712  private:
3713  std::list<graphics_handle> cbo_stack;
3714  };
3715 
3716 private:
3718 
3719 public:
3720 
3722  : xproperties (0, graphics_handle ()), default_properties () { }
3723 
3724  ~root_figure (void) { }
3725 
3726  void mark_modified (void) { }
3727 
3729  {
3730  // Now override with our defaults. If the default_properties
3731  // list includes the properties for all defaults (line,
3732  // surface, etc.) then we don't have to know the type of OBJ
3733  // here, we just call its set function and let it decide which
3734  // properties from the list to use.
3735  obj.set_from_list (default_properties);
3736  }
3737 
3738  void set (const caseless_str& name, const octave_value& value)
3739  {
3740  if (name.compare ("default", 7))
3741  // strip "default", pass rest to function that will
3742  // parse the remainder and add the element to the
3743  // default_properties map.
3744  default_properties.set (name.substr (7), value);
3745  else
3746  xproperties.set (name, value);
3747  }
3748 
3749  octave_value get (const caseless_str& name) const
3750  {
3751  octave_value retval;
3752 
3753  if (name.compare ("default", 7))
3754  return get_default (name.substr (7));
3755  else if (name.compare ("factory", 7))
3756  return get_factory_default (name.substr (7));
3757  else
3758  retval = xproperties.get (name);
3759 
3760  return retval;
3761  }
3762 
3763  octave_value get_default (const caseless_str& name) const
3764  {
3765  octave_value retval = default_properties.lookup (name);
3766 
3767  if (retval.is_undefined ())
3768  {
3769  // no default property found, use factory default
3770  retval = factory_properties.lookup (name);
3771 
3772  if (retval.is_undefined ())
3773  error ("get: invalid default property '%s'", name.c_str ());
3774  }
3775 
3776  return retval;
3777  }
3778 
3779  octave_value get_factory_default (const caseless_str& name) const
3780  {
3781  octave_value retval = factory_properties.lookup (name);
3782 
3783  if (retval.is_undefined ())
3784  error ("get: invalid factory default property '%s'", name.c_str ());
3785 
3786  return retval;
3787  }
3788 
3789  octave_value get_defaults (void) const
3790  {
3791  return default_properties.as_struct ("default");
3792  }
3793 
3794  octave_value get_factory_defaults (void) const
3795  {
3796  return factory_properties.as_struct ("factory");
3797  }
3798 
3799  base_properties& get_properties (void) { return xproperties; }
3800 
3801  const base_properties& get_properties (void) const { return xproperties; }
3802 
3803  bool valid_object (void) const { return true; }
3804 
3805  void reset_default_properties (void);
3806 
3807 private:
3809 
3811 
3812  static property_list::plist_map_type init_factory_properties (void);
3813 };
3814 
3815 // ---------------------------------------------------------------------
3816 
3818 {
3819 public:
3821  {
3822  public:
3823  void init_integerhandle (const octave_value& val)
3824  {
3825  integerhandle = val;
3826  }
3827 
3828  void remove_child (const graphics_handle& h);
3829 
3830  void set_visible (const octave_value& val);
3831 
3832  graphics_toolkit get_toolkit (void) const
3833  {
3834  if (! toolkit)
3835  toolkit = gtk_manager::get_toolkit ();
3836 
3837  return toolkit;
3838  }
3839 
3840  void set_toolkit (const graphics_toolkit& b);
3841 
3842  void set___graphics_toolkit__ (const octave_value& val)
3843  {
3844  if (! error_state)
3845  {
3846  if (val.is_string ())
3847  {
3848  std::string nm = val.string_value ();
3850  if (b.get_name () != nm)
3851  {
3852  error ("set___graphics_toolkit__: invalid graphics toolkit");
3853  }
3854  else
3855  {
3856  set_toolkit (b);
3857  mark_modified ();
3858  }
3859  }
3860  else
3861  error ("set___graphics_toolkit__ must be a string");
3862  }
3863  }
3864 
3865  void set_position (const octave_value& val,
3866  bool do_notify_toolkit = true);
3867 
3868  void set_outerposition (const octave_value& val,
3869  bool do_notify_toolkit = true);
3870 
3871  Matrix get_boundingbox (bool internal = false,
3872  const Matrix& parent_pix_size = Matrix ()) const;
3873 
3874  void set_boundingbox (const Matrix& bb, bool internal = false,
3875  bool do_notify_toolkit = true);
3876 
3877  Matrix map_from_boundingbox (double x, double y) const;
3878 
3879  Matrix map_to_boundingbox (double x, double y) const;
3880 
3881  void update_units (const caseless_str& old_units);
3882 
3883  void update_paperunits (const caseless_str& old_paperunits);
3884 
3885  std::string get_title (void) const;
3886 
3887  // See the genprops.awk script for an explanation of the
3888  // properties declarations.
3889  // Programming note: Keep property list sorted if new ones are added.
3890 
3891 public:
3892  properties (const graphics_handle& mh, const graphics_handle& p);
3893 
3894  ~properties (void) { }
3895 
3896  void set (const caseless_str& pname, const octave_value& val);
3897 
3898  octave_value get (bool all = false) const;
3899 
3900  octave_value get (const caseless_str& pname) const;
3901 
3902  octave_value get (const std::string& pname) const
3903  {
3904  return get (caseless_str (pname));
3905  }
3906 
3907  octave_value get (const char *pname) const
3908  {
3909  return get (caseless_str (pname));
3910  }
3911 
3912  property get_property (const caseless_str& pname);
3913 
3914  std::string graphics_object_name (void) const { return go_name; }
3915 
3916  static property_list::pval_map_type factory_defaults (void);
3917 
3918 private:
3919  static std::string go_name;
3920 
3921 public:
3922 
3923 
3924  static std::set<std::string> core_property_names (void);
3925 
3926  static bool has_core_property (const caseless_str& pname);
3927 
3928  std::set<std::string> all_property_names (void) const;
3929 
3930  bool has_property (const caseless_str& pname) const;
3931 
3932 private:
3933 
3989 
3990 public:
3991 
3992  enum
3993  {
3994  ID_ALPHAMAP = 2000,
3995  ID_BUTTONDOWNFCN = 2001,
3996  ID_CLOSEREQUESTFCN = 2002,
3997  ID_COLOR = 2003,
3998  ID_COLORMAP = 2004,
3999  ID_CURRENTAXES = 2005,
4000  ID_CURRENTCHARACTER = 2006,
4001  ID_CURRENTOBJECT = 2007,
4002  ID_CURRENTPOINT = 2008,
4003  ID_DOCKCONTROLS = 2009,
4004  ID_DOUBLEBUFFER = 2010,
4005  ID_FILENAME = 2011,
4006  ID_INTEGERHANDLE = 2012,
4007  ID_INVERTHARDCOPY = 2013,
4008  ID_KEYPRESSFCN = 2014,
4009  ID_KEYRELEASEFCN = 2015,
4010  ID_MENUBAR = 2016,
4011  ID_MINCOLORMAP = 2017,
4012  ID_NAME = 2018,
4013  ID_NEXTPLOT = 2019,
4014  ID_NUMBERTITLE = 2020,
4015  ID_OUTERPOSITION = 2021,
4016  ID_PAPERORIENTATION = 2022,
4017  ID_PAPERPOSITION = 2023,
4018  ID_PAPERPOSITIONMODE = 2024,
4019  ID_PAPERSIZE = 2025,
4020  ID_PAPERTYPE = 2026,
4021  ID_PAPERUNITS = 2027,
4022  ID_POINTER = 2028,
4023  ID_POINTERSHAPECDATA = 2029,
4024  ID_POINTERSHAPEHOTSPOT = 2030,
4025  ID_POSITION = 2031,
4026  ID_RENDERER = 2032,
4027  ID_RENDERERMODE = 2033,
4028  ID_RESIZE = 2034,
4029  ID_RESIZEFCN = 2035,
4030  ID_SELECTIONTYPE = 2036,
4031  ID_TOOLBAR = 2037,
4032  ID_UNITS = 2038,
4033  ID_WINDOWBUTTONDOWNFCN = 2039,
4034  ID_WINDOWBUTTONMOTIONFCN = 2040,
4035  ID_WINDOWBUTTONUPFCN = 2041,
4036  ID_WINDOWKEYPRESSFCN = 2042,
4037  ID_WINDOWKEYRELEASEFCN = 2043,
4038  ID_WINDOWSCROLLWHEELFCN = 2044,
4039  ID_WINDOWSTYLE = 2045,
4040  ID_WVISUAL = 2046,
4041  ID_WVISUALMODE = 2047,
4042  ID_XDISPLAY = 2048,
4043  ID_XVISUAL = 2049,
4044  ID_XVISUALMODE = 2050,
4045  ID___ENHANCED__ = 2051,
4046  ID___GRAPHICS_TOOLKIT__ = 2052,
4047  ID___GUIDATA__ = 2053,
4048  ID___PLOT_STREAM__ = 2054
4049  };
4050 
4051  octave_value get_alphamap (void) const { return alphamap.get (); }
4052 
4053  void execute_buttondownfcn (const octave_value& data = octave_value ()) const { buttondownfcn.execute (data); }
4054  octave_value get_buttondownfcn (void) const { return buttondownfcn.get (); }
4055 
4056  void execute_closerequestfcn (const octave_value& data = octave_value ()) const { closerequestfcn.execute (data); }
4057  octave_value get_closerequestfcn (void) const { return closerequestfcn.get (); }
4058 
4059  bool color_is_rgb (void) const { return color.is_rgb (); }
4060  bool color_is (const std::string& v) const { return color.is (v); }
4061  Matrix get_color_rgb (void) const { return (color.is_rgb () ? color.rgb () : Matrix ()); }
4062  octave_value get_color (void) const { return color.get (); }
4063 
4064  octave_value get_colormap (void) const { return colormap.get (); }
4065 
4066  graphics_handle get_currentaxes (void) const { return currentaxes.handle_value (); }
4067 
4068  std::string get_currentcharacter (void) const { return currentcharacter.string_value (); }
4069 
4070  graphics_handle get_currentobject (void) const { return currentobject.handle_value (); }
4071 
4072  octave_value get_currentpoint (void) const { return currentpoint.get (); }
4073 
4074  bool is_dockcontrols (void) const { return dockcontrols.is_on (); }
4075  std::string get_dockcontrols (void) const { return dockcontrols.current_value (); }
4076 
4077  bool is_doublebuffer (void) const { return doublebuffer.is_on (); }
4078  std::string get_doublebuffer (void) const { return doublebuffer.current_value (); }
4079 
4080  std::string get_filename (void) const { return filename.string_value (); }
4081 
4082  bool is_integerhandle (void) const { return integerhandle.is_on (); }
4083  std::string get_integerhandle (void) const { return integerhandle.current_value (); }
4084 
4085  bool is_inverthardcopy (void) const { return inverthardcopy.is_on (); }
4086  std::string get_inverthardcopy (void) const { return inverthardcopy.current_value (); }
4087 
4088  void execute_keypressfcn (const octave_value& data = octave_value ()) const { keypressfcn.execute (data); }
4089  octave_value get_keypressfcn (void) const { return keypressfcn.get (); }
4090 
4091  void execute_keyreleasefcn (const octave_value& data = octave_value ()) const { keyreleasefcn.execute (data); }
4092  octave_value get_keyreleasefcn (void) const { return keyreleasefcn.get (); }
4093 
4094  bool menubar_is (const std::string& v) const { return menubar.is (v); }
4095  std::string get_menubar (void) const { return menubar.current_value (); }
4096 
4097  double get_mincolormap (void) const { return mincolormap.double_value (); }
4098 
4099  std::string get_name (void) const { return name.string_value (); }
4100 
4101  bool nextplot_is (const std::string& v) const { return nextplot.is (v); }
4102  std::string get_nextplot (void) const { return nextplot.current_value (); }
4103 
4104  bool is_numbertitle (void) const { return numbertitle.is_on (); }
4105  std::string get_numbertitle (void) const { return numbertitle.current_value (); }
4106 
4107  octave_value get_outerposition (void) const { return outerposition.get (); }
4108 
4109  bool paperorientation_is (const std::string& v) const { return paperorientation.is (v); }
4110  std::string get_paperorientation (void) const { return paperorientation.current_value (); }
4111 
4112  octave_value get_paperposition (void) const { return paperposition.get (); }
4113 
4114  bool paperpositionmode_is (const std::string& v) const { return paperpositionmode.is (v); }
4115  std::string get_paperpositionmode (void) const { return paperpositionmode.current_value (); }
4116 
4117  octave_value get_papersize (void) const { return papersize.get (); }
4118 
4119  bool papertype_is (const std::string& v) const { return papertype.is (v); }
4120  std::string get_papertype (void) const { return papertype.current_value (); }
4121 
4122  bool paperunits_is (const std::string& v) const { return paperunits.is (v); }
4123  std::string get_paperunits (void) const { return paperunits.current_value (); }
4124 
4125  bool pointer_is (const std::string& v) const { return pointer.is (v); }
4126  std::string get_pointer (void) const { return pointer.current_value (); }
4127 
4128  octave_value get_pointershapecdata (void) const { return pointershapecdata.get (); }
4129 
4130  octave_value get_pointershapehotspot (void) const { return pointershapehotspot.get (); }
4131 
4132  octave_value get_position (void) const { return position.get (); }
4133 
4134  bool renderer_is (const std::string& v) const { return renderer.is (v); }
4135  std::string get_renderer (void) const { return renderer.current_value (); }
4136 
4137  bool renderermode_is (const std::string& v) const { return renderermode.is (v); }
4138  std::string get_renderermode (void) const { return renderermode.current_value (); }
4139 
4140  bool is_resize (void) const { return resize.is_on (); }
4141  std::string get_resize (void) const { return resize.current_value (); }
4142 
4143  void execute_resizefcn (const octave_value& data = octave_value ()) const { resizefcn.execute (data); }
4144  octave_value get_resizefcn (void) const { return resizefcn.get (); }
4145 
4146  bool selectiontype_is (const std::string& v) const { return selectiontype.is (v); }
4147  std::string get_selectiontype (void) const { return selectiontype.current_value (); }
4148 
4149  bool toolbar_is (const std::string& v) const { return toolbar.is (v); }
4150  std::string get_toolbar (void) const { return toolbar.current_value (); }
4151 
4152  bool units_is (const std::string& v) const { return units.is (v); }
4153  std::string get_units (void) const { return units.current_value (); }
4154 
4155  void execute_windowbuttondownfcn (const octave_value& data = octave_value ()) const { windowbuttondownfcn.execute (data); }
4156  octave_value get_windowbuttondownfcn (void) const { return windowbuttondownfcn.get (); }
4157 
4158  void execute_windowbuttonmotionfcn (const octave_value& data = octave_value ()) const { windowbuttonmotionfcn.execute (data); }
4159  octave_value get_windowbuttonmotionfcn (void) const { return windowbuttonmotionfcn.get (); }
4160 
4161  void execute_windowbuttonupfcn (const octave_value& data = octave_value ()) const { windowbuttonupfcn.execute (data); }
4162  octave_value get_windowbuttonupfcn (void) const { return windowbuttonupfcn.get (); }
4163 
4164  void execute_windowkeypressfcn (const octave_value& data = octave_value ()) const { windowkeypressfcn.execute (data); }
4165  octave_value get_windowkeypressfcn (void) const { return windowkeypressfcn.get (); }
4166 
4167  void execute_windowkeyreleasefcn (const octave_value& data = octave_value ()) const { windowkeyreleasefcn.execute (data); }
4168  octave_value get_windowkeyreleasefcn (void) const { return windowkeyreleasefcn.get (); }
4169 
4170  void execute_windowscrollwheelfcn (const octave_value& data = octave_value ()) const { windowscrollwheelfcn.execute (data); }
4171  octave_value get_windowscrollwheelfcn (void) const { return windowscrollwheelfcn.get (); }
4172 
4173  bool windowstyle_is (const std::string& v) const { return windowstyle.is (v); }
4174  std::string get_windowstyle (void) const { return windowstyle.current_value (); }
4175 
4176  std::string get_wvisual (void) const { return wvisual.string_value (); }
4177 
4178  bool wvisualmode_is (const std::string& v) const { return wvisualmode.is (v); }
4179  std::string get_wvisualmode (void) const { return wvisualmode.current_value (); }
4180 
4181  std::string get_xdisplay (void) const { return xdisplay.string_value (); }
4182 
4183  std::string get_xvisual (void) const { return xvisual.string_value (); }
4184 
4185  bool xvisualmode_is (const std::string& v) const { return xvisualmode.is (v); }
4186  std::string get_xvisualmode (void) const { return xvisualmode.current_value (); }
4187 
4188  bool is___enhanced__ (void) const { return __enhanced__.is_on (); }
4189  std::string get___enhanced__ (void) const { return __enhanced__.current_value (); }
4190 
4191  std::string get___graphics_toolkit__ (void) const { return __graphics_toolkit__.string_value (); }
4192 
4193  octave_value get___guidata__ (void) const { return __guidata__.get (); }
4194 
4195  octave_value get___plot_stream__ (void) const { return __plot_stream__.get (); }
4196 
4197 
4198  void set_alphamap (const octave_value& val)
4199  {
4200  if (! error_state)
4201  {
4202  if (alphamap.set (val, true))
4203  {
4204  mark_modified ();
4205  }
4206  }
4207  }
4208 
4209  void set_buttondownfcn (const octave_value& val)
4210  {
4211  if (! error_state)
4212  {
4213  if (buttondownfcn.set (val, true))
4214  {
4215  mark_modified ();
4216  }
4217  }
4218  }
4219 
4220  void set_closerequestfcn (const octave_value& val)
4221  {
4222  if (! error_state)
4223  {
4224  if (closerequestfcn.set (val, true))
4225  {
4226  mark_modified ();
4227  }
4228  }
4229  }
4230 
4231  void set_color (const octave_value& val)
4232  {
4233  if (! error_state)
4234  {
4235  if (color.set (val, true))
4236  {
4237  mark_modified ();
4238  }
4239  }
4240  }
4241 
4242  void set_colormap (const octave_value& val)
4243  {
4244  if (! error_state)
4245  {
4246  if (colormap.set (val, true))
4247  {
4248  mark_modified ();
4249  }
4250  }
4251  }
4252 
4253  void set_currentaxes (const octave_value& val);
4254 
4255  void set_currentcharacter (const octave_value& val)
4256  {
4257  if (! error_state)
4258  {
4259  if (currentcharacter.set (val, true))
4260  {
4261  mark_modified ();
4262  }
4263  }
4264  }
4265 
4266  void set_currentobject (const octave_value& val)
4267  {
4268  if (! error_state)
4269  {
4270  if (currentobject.set (val, true))
4271  {
4272  mark_modified ();
4273  }
4274  }
4275  }
4276 
4277  void set_currentpoint (const octave_value& val)
4278  {
4279  if (! error_state)
4280  {
4281  if (currentpoint.set (val, true))
4282  {
4283  mark_modified ();
4284  }
4285  }
4286  }
4287 
4288  void set_dockcontrols (const octave_value& val)
4289  {
4290  if (! error_state)
4291  {
4292  if (dockcontrols.set (val, true))
4293  {
4294  mark_modified ();
4295  }
4296  }
4297  }
4298 
4299  void set_doublebuffer (const octave_value& val)
4300  {
4301  if (! error_state)
4302  {
4303  if (doublebuffer.set (val, true))
4304  {
4305  mark_modified ();
4306  }
4307  }
4308  }
4309 
4310  void set_filename (const octave_value& val)
4311  {
4312  if (! error_state)
4313  {
4314  if (filename.set (val, true))
4315  {
4316  mark_modified ();
4317  }
4318  }
4319  }
4320 
4321  void set_integerhandle (const octave_value& val);
4322 
4323  void set_inverthardcopy (const octave_value& val)
4324  {
4325  if (! error_state)
4326  {
4327  if (inverthardcopy.set (val, true))
4328  {
4329  mark_modified ();
4330  }
4331  }
4332  }
4333 
4334  void set_keypressfcn (const octave_value& val)
4335  {
4336  if (! error_state)
4337  {
4338  if (keypressfcn.set (val, true))
4339  {
4340  mark_modified ();
4341  }
4342  }
4343  }
4344 
4345  void set_keyreleasefcn (const octave_value& val)
4346  {
4347  if (! error_state)
4348  {
4349  if (keyreleasefcn.set (val, true))
4350  {
4351  mark_modified ();
4352  }
4353  }
4354  }
4355 
4356  void set_menubar (const octave_value& val)
4357  {
4358  if (! error_state)
4359  {
4360  if (menubar.set (val, true))
4361  {
4362  mark_modified ();
4363  }
4364  }
4365  }
4366 
4367  void set_mincolormap (const octave_value& val)
4368  {
4369  if (! error_state)
4370  {
4371  if (mincolormap.set (val, true))
4372  {
4373  mark_modified ();
4374  }
4375  }
4376  }
4377 
4378  void set_name (const octave_value& val)
4379  {
4380  if (! error_state)
4381  {
4382  if (name.set (val, true))
4383  {
4384  mark_modified ();
4385  }
4386  }
4387  }
4388 
4389  void set_nextplot (const octave_value& val)
4390  {
4391  if (! error_state)
4392  {
4393  if (nextplot.set (val, true))
4394  {
4395  mark_modified ();
4396  }
4397  }
4398  }
4399 
4400  void set_numbertitle (const octave_value& val)
4401  {
4402  if (! error_state)
4403  {
4404  if (numbertitle.set (val, true))
4405  {
4406  mark_modified ();
4407  }
4408  }
4409  }
4410 
4411  void set_paperorientation (const octave_value& val)
4412  {
4413  if (! error_state)
4414  {
4415  if (paperorientation.set (val, true))
4416  {
4417  update_paperorientation ();
4418  mark_modified ();
4419  }
4420  }
4421  }
4422 
4423  void update_paperorientation (void);
4424 
4425  void set_paperposition (const octave_value& val)
4426  {
4427  if (! error_state)
4428  {
4429  if (paperposition.set (val, true))
4430  {
4431  mark_modified ();
4432  }
4433  }
4434  }
4435 
4436  void set_paperpositionmode (const octave_value& val)
4437  {
4438  if (! error_state)
4439  {
4440  if (paperpositionmode.set (val, true))
4441  {
4442  mark_modified ();
4443  }
4444  }
4445  }
4446 
4447  void set_papersize (const octave_value& val)
4448  {
4449  if (! error_state)
4450  {
4451  if (papersize.set (val, true))
4452  {
4453  update_papersize ();
4454  mark_modified ();
4455  }
4456  }
4457  }
4458 
4459  void update_papersize (void);
4460 
4461  void set_papertype (const octave_value& val);
4462 
4463  void update_papertype (void);
4464 
4465  void set_paperunits (const octave_value& val);
4466 
4467  void set_pointer (const octave_value& val)
4468  {
4469  if (! error_state)
4470  {
4471  if (pointer.set (val, true))
4472  {
4473  mark_modified ();
4474  }
4475  }
4476  }
4477 
4478  void set_pointershapecdata (const octave_value& val)
4479  {
4480  if (! error_state)
4481  {
4482  if (pointershapecdata.set (val, true))
4483  {
4484  mark_modified ();
4485  }
4486  }
4487  }
4488 
4489  void set_pointershapehotspot (const octave_value& val)
4490  {
4491  if (! error_state)
4492  {
4493  if (pointershapehotspot.set (val, true))
4494  {
4495  mark_modified ();
4496  }
4497  }
4498  }
4499 
4500  void set_renderer (const octave_value& val)
4501  {
4502  if (! error_state)
4503  {
4504  if (renderer.set (val, true))
4505  {
4506  mark_modified ();
4507  }
4508  }
4509  }
4510 
4511  void set_renderermode (const octave_value& val)
4512  {
4513  if (! error_state)
4514  {
4515  if (renderermode.set (val, true))
4516  {
4517  mark_modified ();
4518  }
4519  }
4520  }
4521 
4522  void set_resize (const octave_value& val)
4523  {
4524  if (! error_state)
4525  {
4526  if (resize.set (val, true))
4527  {
4528  mark_modified ();
4529  }
4530  }
4531  }
4532 
4533  void set_resizefcn (const octave_value& val)
4534  {
4535  if (! error_state)
4536  {
4537  if (resizefcn.set (val, true))
4538  {
4539  mark_modified ();
4540  }
4541  }
4542  }
4543 
4544  void set_selectiontype (const octave_value& val)
4545  {
4546  if (! error_state)
4547  {
4548  if (selectiontype.set (val, true))
4549  {
4550  mark_modified ();
4551  }
4552  }
4553  }
4554 
4555  void set_toolbar (const octave_value& val)
4556  {
4557  if (! error_state)
4558  {
4559  if (toolbar.set (val, true))
4560  {
4561  mark_modified ();
4562  }
4563  }
4564  }
4565 
4566  void set_units (const octave_value& val);
4567 
4568  void set_windowbuttondownfcn (const octave_value& val)
4569  {
4570  if (! error_state)
4571  {
4572  if (windowbuttondownfcn.set (val, true))
4573  {
4574  mark_modified ();
4575  }
4576  }
4577  }
4578 
4579  void set_windowbuttonmotionfcn (const octave_value& val)
4580  {
4581  if (! error_state)
4582  {
4583  if (windowbuttonmotionfcn.set (val, true))
4584  {
4585  mark_modified ();
4586  }
4587  }
4588  }
4589 
4590  void set_windowbuttonupfcn (const octave_value& val)
4591  {
4592  if (! error_state)
4593  {
4594  if (windowbuttonupfcn.set (val, true))
4595  {
4596  mark_modified ();
4597  }
4598  }
4599  }
4600 
4601  void set_windowkeypressfcn (const octave_value& val)
4602  {
4603  if (! error_state)
4604  {
4605  if (windowkeypressfcn.set (val, true))
4606  {
4607  mark_modified ();
4608  }
4609  }
4610  }
4611 
4612  void set_windowkeyreleasefcn (const octave_value& val)
4613  {
4614  if (! error_state)
4615  {
4616  if (windowkeyreleasefcn.set (val, true))
4617  {
4618  mark_modified ();
4619  }
4620  }
4621  }
4622 
4623  void set_windowscrollwheelfcn (const octave_value& val)
4624  {
4625  if (! error_state)
4626  {
4627  if (windowscrollwheelfcn.set (val, true))
4628  {
4629  mark_modified ();
4630  }
4631  }
4632  }
4633 
4634  void set_windowstyle (const octave_value& val)
4635  {
4636  if (! error_state)
4637  {
4638  if (windowstyle.set (val, true))
4639  {
4640  mark_modified ();
4641  }
4642  }
4643  }
4644 
4645  void set_wvisual (const octave_value& val)
4646  {
4647  if (! error_state)
4648  {
4649  if (wvisual.set (val, true))
4650  {
4651  mark_modified ();
4652  }
4653  }
4654  }
4655 
4656  void set_wvisualmode (const octave_value& val)
4657  {
4658  if (! error_state)
4659  {
4660  if (wvisualmode.set (val, true))
4661  {
4662  mark_modified ();
4663  }
4664  }
4665  }
4666 
4667  void set_xdisplay (const octave_value& val)
4668  {
4669  if (! error_state)
4670  {
4671  if (xdisplay.set (val, true))
4672  {
4673  mark_modified ();
4674  }
4675  }
4676  }
4677 
4678  void set_xvisual (const octave_value& val)
4679  {
4680  if (! error_state)
4681  {
4682  if (xvisual.set (val, true))
4683  {
4684  mark_modified ();
4685  }
4686  }
4687  }
4688 
4689  void set_xvisualmode (const octave_value& val)
4690  {
4691  if (! error_state)
4692  {
4693  if (xvisualmode.set (val, true))
4694  {
4695  mark_modified ();
4696  }
4697  }
4698  }
4699 
4700  void set___enhanced__ (const octave_value& val)
4701  {
4702  if (! error_state)
4703  {
4704  if (__enhanced__.set (val, true))
4705  {
4706  mark_modified ();
4707  }
4708  }
4709  }
4710 
4711  void set___guidata__ (const octave_value& val)
4712  {
4713  if (! error_state)
4714  {
4715  if (__guidata__.set (val, true))
4716  {
4717  mark_modified ();
4718  }
4719  }
4720  }
4721 
4722  void set___plot_stream__ (const octave_value& val)
4723  {
4724  if (! error_state)
4725  {
4726  if (__plot_stream__.set (val, true))
4727  {
4728  mark_modified ();
4729  }
4730  }
4731  }
4732 
4733 
4734  protected:
4735  void init (void)
4736  {
4737  alphamap.add_constraint (dim_vector (-1, 1));
4738  colormap.add_constraint (dim_vector (-1, 3));
4739  outerposition.add_constraint (dim_vector (1, 4));
4740  paperposition.add_constraint (dim_vector (1, 4));
4741  papersize.add_constraint (dim_vector (1, 2));
4742  pointershapecdata.add_constraint (dim_vector (16, 16));
4743  pointershapehotspot.add_constraint (dim_vector (1, 2));
4744  position.add_constraint (dim_vector (1, 4));
4745  }
4746 
4747  private:
4749  };
4750 
4751 private:
4753 
4754 public:
4756  : base_graphics_object (), xproperties (mh, p), default_properties ()
4757  {
4758  xproperties.override_defaults (*this);
4759  }
4760 
4761  ~figure (void) { }
4762 
4764  {
4765  // Allow parent (root figure) to override first (properties knows how
4766  // to find the parent object).
4767  xproperties.override_defaults (obj);
4768 
4769  // Now override with our defaults. If the default_properties
4770  // list includes the properties for all defaults (line,
4771  // surface, etc.) then we don't have to know the type of OBJ
4772  // here, we just call its set function and let it decide which
4773  // properties from the list to use.
4774  obj.set_from_list (default_properties);
4775  }
4776 
4777  void set (const caseless_str& name, const octave_value& value)
4778  {
4779  if (name.compare ("default", 7))
4780  // strip "default", pass rest to function that will
4781  // parse the remainder and add the element to the
4782  // default_properties map.
4783  default_properties.set (name.substr (7), value);
4784  else
4785  xproperties.set (name, value);
4786  }
4787 
4788  octave_value get (const caseless_str& name) const
4789  {
4790  octave_value retval;
4791 
4792  if (name.compare ("default", 7))
4793  retval = get_default (name.substr (7));
4794  else
4795  retval = xproperties.get (name);
4796 
4797  return retval;
4798  }
4799 
4800  octave_value get_default (const caseless_str& name) const;
4801 
4802  octave_value get_defaults (void) const
4803  {
4804  return default_properties.as_struct ("default");
4805  }
4806 
4807  base_properties& get_properties (void) { return xproperties; }
4808 
4809  const base_properties& get_properties (void) const { return xproperties; }
4810 
4811  bool valid_object (void) const { return true; }
4812 
4813  void reset_default_properties (void);
4814 
4815 private:
4817 };
4818 
4819 // ---------------------------------------------------------------------
4820 
4822 {
4823 public:
4825  : xform (xform_eye ()), xform_inv (xform_eye ()),
4826  sx ("linear"), sy ("linear"), sz ("linear"), zlim (1, 2, 0.0)
4827  {
4828  zlim(1) = 1.0;
4829  }
4830 
4831  graphics_xform (const Matrix& xm, const Matrix& xim,
4832  const scaler& x, const scaler& y, const scaler& z,
4833  const Matrix& zl)
4834  : xform (xm), xform_inv (xim), sx (x), sy (y), sz (z), zlim (zl) { }
4835 
4837  : xform (g.xform), xform_inv (g.xform_inv), sx (g.sx),
4838  sy (g.sy), sz (g.sz), zlim (g.zlim) { }
4839 
4840  ~graphics_xform (void) { }
4841 
4842  graphics_xform& operator = (const graphics_xform& g)
4843  {
4844  xform = g.xform;
4845  xform_inv = g.xform_inv;
4846  sx = g.sx;
4847  sy = g.sy;
4848  sz = g.sz;
4849  zlim = g.zlim;
4850 
4851  return *this;
4852  }
4853 
4854  static ColumnVector xform_vector (double x, double y, double z);
4855 
4856  static Matrix xform_eye (void);
4857 
4858  ColumnVector transform (double x, double y, double z,
4859  bool use_scale = true) const;
4860 
4861  ColumnVector untransform (double x, double y, double z,
4862  bool use_scale = true) const;
4863 
4864  ColumnVector untransform (double x, double y, bool use_scale = true) const
4865  { return untransform (x, y, (zlim(0)+zlim(1))/2, use_scale); }
4866 
4867  Matrix xscale (const Matrix& m) const { return sx.scale (m); }
4868  Matrix yscale (const Matrix& m) const { return sy.scale (m); }
4869  Matrix zscale (const Matrix& m) const { return sz.scale (m); }
4870 
4871  Matrix scale (const Matrix& m) const
4872  {
4873  bool has_z = (m.columns () > 2);
4874 
4875  if (sx.is_linear () && sy.is_linear ()
4876  && (! has_z || sz.is_linear ()))
4877  return m;
4878 
4879  Matrix retval (m.dims ());
4880 
4881  int r = m.rows ();
4882 
4883  for (int i = 0; i < r; i++)
4884  {
4885  retval(i,0) = sx.scale (m(i,0));
4886  retval(i,1) = sy.scale (m(i,1));
4887  if (has_z)
4888  retval(i,2) = sz.scale (m(i,2));
4889  }
4890 
4891  return retval;
4892  }
4893 
4894 private:
4897  scaler sx, sy, sz;
4899 };
4900 
4901 enum
4902 {
4907 };
4908 
4910 {
4911 public:
4913  {
4914  public:
4915  void set_defaults (base_graphics_object& obj, const std::string& mode);
4916 
4917  void remove_child (const graphics_handle& h);
4918 
4919  const scaler& get_x_scaler (void) const { return sx; }
4920  const scaler& get_y_scaler (void) const { return sy; }
4921  const scaler& get_z_scaler (void) const { return sz; }
4922 
4923  Matrix get_boundingbox (bool internal = false,
4924  const Matrix& parent_pix_size = Matrix ()) const;
4925  Matrix get_extent (bool with_text = false,
4926  bool only_text_height=false) const;
4927 
4928  double get_fontsize_points (double box_pix_height = 0) const;
4929 
4930  void update_boundingbox (void)
4931  {
4932  if (units_is ("normalized"))
4933  {
4934  sync_positions ();
4936  }
4937  }
4938 
4939  void update_camera (void);
4940  void update_axes_layout (void);
4941  void update_aspectratios (void);
4942  void update_transform (void)
4943  {
4944  update_aspectratios ();
4945  update_camera ();
4946  update_axes_layout ();
4947  }
4948 
4949  void sync_positions (void);
4950 
4951  void update_autopos (const std::string& elem_type);
4952  void update_xlabel_position (void);
4953  void update_ylabel_position (void);
4954  void update_zlabel_position (void);
4955  void update_title_position (void);
4956 
4957  graphics_xform get_transform (void) const
4958  { return graphics_xform (x_render, x_render_inv, sx, sy, sz, x_zlim); }
4959 
4960  Matrix get_transform_matrix (void) const { return x_render; }
4961  Matrix get_inverse_transform_matrix (void) const { return x_render_inv; }
4962  Matrix get_opengl_matrix_1 (void) const { return x_gl_mat1; }
4963  Matrix get_opengl_matrix_2 (void) const { return x_gl_mat2; }
4964  Matrix get_transform_zlim (void) const { return x_zlim; }
4965 
4966  int get_xstate (void) const { return xstate; }
4967  int get_ystate (void) const { return ystate; }
4968  int get_zstate (void) const { return zstate; }
4969  double get_xPlane (void) const { return xPlane; }
4970  double get_xPlaneN (void) const { return xPlaneN; }
4971  double get_yPlane (void) const { return yPlane; }
4972  double get_yPlaneN (void) const { return yPlaneN; }
4973  double get_zPlane (void) const { return zPlane; }
4974  double get_zPlaneN (void) const { return zPlaneN; }
4975  double get_xpTick (void) const { return xpTick; }
4976  double get_xpTickN (void) const { return xpTickN; }
4977  double get_ypTick (void) const { return ypTick; }
4978  double get_ypTickN (void) const { return ypTickN; }
4979  double get_zpTick (void) const { return zpTick; }
4980  double get_zpTickN (void) const { return zpTickN; }
4981  double get_x_min (void) const { return std::min (xPlane, xPlaneN); }
4982  double get_x_max (void) const { return std::max (xPlane, xPlaneN); }
4983  double get_y_min (void) const { return