GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
graphics.in.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2007-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_graphics_h)
27 #define octave_graphics_h 1
28 
29 #include "octave-config.h"
30 
31 #include <cctype>
32 #include <cmath>
33 
34 #include <algorithm>
35 #include <list>
36 #include <map>
37 #include <memory>
38 #include <set>
39 #include <sstream>
40 #include <string>
41 #include <vector>
42 
43 #include "caseless-str.h"
44 
45 #include "errwarn.h"
46 #include "graphics-handle.h"
47 #include "graphics-toolkit.h"
48 #include "oct-map.h"
49 #include "oct-mutex.h"
50 #include "oct-refcount.h"
51 #include "ov.h"
52 #include "text-renderer.h"
53 
54 // FIXME: maybe this should be a configure option?
55 // Matlab defaults to "Helvetica", but that causes problems for many
56 // gnuplot users.
57 #if ! defined (OCTAVE_DEFAULT_FONTNAME)
58 #define OCTAVE_DEFAULT_FONTNAME "*"
59 #endif
60 
61 // ---------------------------------------------------------------------
62 
64 {
65 public:
66  base_scaler (void) { }
67 
68  virtual ~base_scaler (void) = default;
69 
70  virtual Matrix scale (const Matrix&) const
71  {
72  error ("invalid axis scale");
73  }
74 
75  virtual NDArray scale (const NDArray&) const
76  {
77  error ("invalid axis scale");
78  }
79 
80  virtual double scale (double) const
81  {
82  error ("invalid axis scale");
83  }
84 
85  virtual double unscale (double) const
86  {
87  error ("invalid axis scale");
88  }
89 
90  virtual base_scaler * clone () const
91  { return new base_scaler (); }
92 
93  virtual bool is_linear (void) const
94  { return false; }
95 };
96 
97 class lin_scaler : public base_scaler
98 {
99 public:
100  lin_scaler (void) { }
101 
102  Matrix scale (const Matrix& m) const { return m; }
103 
104  NDArray scale (const NDArray& m) const { return m; }
105 
106  double scale (double d) const { return d; }
107 
108  double unscale (double d) const { return d; }
109 
110  base_scaler * clone (void) const { return new lin_scaler (); }
111 
112  bool is_linear (void) const { return true; }
113 };
114 
115 class log_scaler : public base_scaler
116 {
117 public:
118  log_scaler (void) { }
119 
120  Matrix scale (const Matrix& m) const
121  {
122  Matrix retval (m.rows (), m.cols ());
123 
124  do_scale (m.data (), retval.fortran_vec (), m.numel ());
125 
126  return retval;
127  }
128 
129  NDArray scale (const NDArray& m) const
130  {
131  NDArray retval (m.dims ());
132 
133  do_scale (m.data (), retval.fortran_vec (), m.numel ());
134 
135  return retval;
136  }
137 
138  double scale (double d) const
139  { return log10 (d); }
140 
141  double unscale (double d) const
142  { return std::pow (10.0, d); }
143 
144  base_scaler * clone (void) const
145  { return new log_scaler (); }
146 
147 private:
148  void do_scale (const double *src, double *dest, int n) const
149  {
150  for (int i = 0; i < n; i++)
151  dest[i] = log10 (src[i]);
152  }
153 };
154 
156 {
157 public:
158  neg_log_scaler (void) { }
159 
160  Matrix scale (const Matrix& m) const
161  {
162  Matrix retval (m.rows (), m.cols ());
163 
164  do_scale (m.data (), retval.fortran_vec (), m.numel ());
165 
166  return retval;
167  }
168 
169  NDArray scale (const NDArray& m) const
170  {
171  NDArray retval (m.dims ());
172 
173  do_scale (m.data (), retval.fortran_vec (), m.numel ());
174 
175  return retval;
176  }
177 
178  double scale (double d) const
179  { return -log10 (-d); }
180 
181  double unscale (double d) const
182  { return -std::pow (10.0, -d); }
183 
184  base_scaler * clone (void) const
185  { return new neg_log_scaler (); }
186 
187 private:
188  void do_scale (const double *src, double *dest, int n) const
189  {
190  for (int i = 0; i < n; i++)
191  dest[i] = -log10 (-src[i]);
192  }
193 };
194 
195 class scaler
196 {
197 public:
198  scaler (void) : rep (new base_scaler ()) { }
199 
200  scaler (const scaler& s) : rep (s.rep->clone ()) { }
201 
202  scaler (const std::string& s)
203  : rep (s == "log"
204  ? new log_scaler ()
205  : (s == "neglog"
206  ? new neg_log_scaler ()
207  : (s == "linear"
208  ? new lin_scaler ()
209  : 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 (&s != this)
232  {
233  if (rep)
234  {
235  delete rep;
236  rep = nullptr;
237  }
238 
239  rep = s.rep->clone ();
240  }
241 
242  return *this;
243  }
244 
245  scaler& operator = (const std::string& s)
246  {
247  if (rep)
248  {
249  delete rep;
250  rep = nullptr;
251  }
252 
253  if (s == "log")
254  rep = new log_scaler ();
255  else if (s == "neglog")
256  rep = new neg_log_scaler ();
257  else if (s == "linear")
258  rep = new lin_scaler ();
259  else
260  rep = new base_scaler ();
261 
262  return *this;
263  }
264 
265 private:
267 };
268 
269 // ---------------------------------------------------------------------
270 
271 class property;
272 
273 // FIXME: These values should probably be defined inside a namespace or
274 // class, but which one is most appropriate? For now, prefix with
275 // "GCB_" to avoid conflict with PERSISTENT token ID used in the lexer.
276 // The lexer token IDs should probably also be fixed...
277 
279 
281 {
282 public:
283  friend class property;
284 
285 public:
287  : id (-1), count (1), name (), parent (), hidden (), listeners ()
288  { }
289 
290  base_property (const std::string& s, const graphics_handle& h)
291  : id (-1), count (1), name (s), parent (h), hidden (false), listeners ()
292  { }
293 
295  : id (-1), count (1), name (p.name), parent (p.parent),
296  hidden (p.hidden), listeners ()
297  { }
298 
299  virtual ~base_property (void) = default;
300 
301  bool ok (void) const { return parent.ok (); }
302 
303  std::string get_name (void) const { return name; }
304 
305  void set_name (const std::string& s) { name = s; }
306 
307  graphics_handle get_parent (void) const { return parent; }
308 
309  void set_parent (const graphics_handle& h) { parent = h; }
310 
311  bool is_hidden (void) const { return hidden; }
312 
313  void set_hidden (bool flag) { hidden = flag; }
314 
315  virtual bool is_radio (void) const { return false; }
316 
317  int get_id (void) const { return id; }
318 
319  void set_id (int d) { id = d; }
320 
321  // Sets property value, notifies graphics toolkit.
322  // If do_run is true, runs associated listeners.
323  OCTINTERP_API bool set (const octave_value& v, bool do_run = true,
324  bool do_notify_toolkit = true);
325 
326  virtual octave_value get (void) const
327  {
328  error (R"(get: invalid property "%s")", name.c_str ());
329  }
330 
331  virtual std::string values_as_string (void) const
332  {
333  error (R"(values_as_string: invalid property "%s")", name.c_str ());
334  }
335 
336  virtual Cell values_as_cell (void) const
337  {
338  error (R"(values_as_cell: invalid property "%s")", name.c_str ());
339  }
340 
342  {
343  set (val);
344  return *this;
345  }
346 
348  {
349  octave_value_list& l = listeners[mode];
350  l.resize (l.length () + 1, v);
351  }
352 
354  listener_mode mode = GCB_POSTSET)
355  {
356  octave_value_list& l = listeners[mode];
357 
358  if (v.is_defined ())
359  {
360  bool found = false;
361  int i;
362 
363  for (i = 0; i < l.length (); i++)
364  {
365  if (v.internal_rep () == l(i).internal_rep ())
366  {
367  found = true;
368  break;
369  }
370  }
371  if (found)
372  {
373  for (int j = i; j < l.length () - 1; j++)
374  l(j) = l(j + 1);
375 
376  l.resize (l.length () - 1);
377  }
378  }
379  else
380  {
381  if (mode == GCB_PERSISTENT)
382  l.resize (0);
383  else
384  {
385  octave_value_list lnew (0);
387  for (int i = l.length () - 1; i >= 0 ; i--)
388  {
389  for (int j = 0; j < lp.length (); j++)
390  {
391  if (l(i).internal_rep () == lp(j).internal_rep ())
392  {
393  lnew.resize (lnew.length () + 1, l(i));
394  break;
395  }
396  }
397  }
398  l = lnew;
399  }
400  }
401 
402  }
403 
404  OCTINTERP_API void run_listeners (listener_mode mode = GCB_POSTSET);
405 
406  virtual base_property * clone (void) const
407  { return new base_property (*this); }
408 
409 protected:
410  virtual bool do_set (const octave_value&)
411  {
412  error (R"(set: invalid property "%s")", name.c_str ());
413  }
414 
415 private:
416  typedef std::map<listener_mode, octave_value_list> listener_map;
417  typedef std::map<listener_mode, octave_value_list>::iterator
419  typedef std::map<listener_mode, octave_value_list>::const_iterator
421 
422 private:
423  int id;
425  std::string name;
427  bool hidden;
429 };
430 
431 // ---------------------------------------------------------------------
432 
434 {
435 public:
436  string_property (const std::string& s, const graphics_handle& h,
437  const std::string& val = "")
438  : base_property (s, h), str (val) { }
439 
441  : base_property (p), str (p.str) { }
442 
443  octave_value get (void) const
444  { return octave_value (str); }
445 
446  std::string string_value (void) const { return str; }
447 
449  {
450  set (val);
451  return *this;
452  }
453 
454  base_property * clone (void) const { return new string_property (*this); }
455 
456 protected:
457  bool do_set (const octave_value& val)
458  {
459  if (! val.is_string ())
460  error (R"(set: invalid string property value for "%s")",
461  get_name ().c_str ());
462 
463  std::string new_str = val.string_value ();
464 
465  if (new_str != str)
466  {
467  str = new_str;
468  return true;
469  }
470  return false;
471  }
472 
473 private:
474  std::string str;
475 };
476 
477 // ---------------------------------------------------------------------
478 
480 {
481 public:
483 
484  string_array_property (const std::string& s, const graphics_handle& h,
485  const std::string& val = "", const char& sep = '|',
486  const desired_enum& typ = string_t)
487  : base_property (s, h), desired_type (typ), separator (sep), str ()
488  {
489  size_t pos = 0;
490 
491  while (true)
492  {
493  size_t new_pos = val.find_first_of (separator, pos);
494 
495  if (new_pos == std::string::npos)
496  {
497  str.append (val.substr (pos));
498  break;
499  }
500  else
501  str.append (val.substr (pos, new_pos - pos));
502 
503  pos = new_pos + 1;
504  }
505  }
506 
507  string_array_property (const std::string& s, const graphics_handle& h,
508  const Cell& c, const char& sep = '|',
509  const desired_enum& typ = string_t)
510  : base_property (s, h), desired_type (typ), separator (sep), str ()
511  {
512  if (! c.iscellstr ())
513  error (R"(set: invalid order property value for "%s")",
514  get_name ().c_str ());
515 
516  string_vector strings (c.numel ());
517 
518  for (octave_idx_type i = 0; i < c.numel (); i++)
519  strings[i] = c(i).string_value ();
520 
521  str = strings;
522  }
523 
526  separator (p.separator), str (p.str) { }
527 
528  octave_value get (void) const
529  {
530  if (desired_type == string_t)
531  return octave_value (string_value ());
532  else
533  return octave_value (cell_value ());
534  }
535 
536  std::string string_value (void) const
537  {
538  std::string s;
539 
540  for (octave_idx_type i = 0; i < str.numel (); i++)
541  {
542  s += str[i];
543  if (i != str.numel () - 1)
544  s += separator;
545  }
546 
547  return s;
548  }
549 
550  Cell cell_value (void) const {return Cell (str);}
551 
552  string_vector string_vector_value (void) const { return str; }
553 
555  {
556  set (val);
557  return *this;
558  }
559 
560  base_property * clone (void) const
561  { return new string_array_property (*this); }
562 
563 protected:
564  bool do_set (const octave_value& val)
565  {
566  if (val.is_string () && val.rows () == 1)
567  {
568  bool replace = false;
569  std::string new_str = val.string_value ();
570  string_vector strings;
571  size_t pos = 0;
572 
573  // Split single string on delimiter (usually '|')
574  while (pos != std::string::npos)
575  {
576  size_t new_pos = new_str.find_first_of (separator, pos);
577 
578  if (new_pos == std::string::npos)
579  {
580  strings.append (new_str.substr (pos));
581  break;
582  }
583  else
584  strings.append (new_str.substr (pos, new_pos - pos));
585 
586  pos = new_pos + 1;
587  }
588 
589  if (str.numel () == strings.numel ())
590  {
591  for (octave_idx_type i = 0; i < str.numel (); i++)
592  if (strings[i] != str[i])
593  {
594  replace = true;
595  break;
596  }
597  }
598  else
599  replace = true;
600 
602 
603  if (replace)
604  {
605  str = strings;
606  return true;
607  }
608  }
609  else if (val.is_string ()) // multi-row character matrix
610  {
611  bool replace = false;
612  charMatrix chm = val.char_matrix_value ();
613  octave_idx_type nel = chm.rows ();
614  string_vector strings (nel);
615 
616  if (nel != str.numel ())
617  replace = true;
618  for (octave_idx_type i = 0; i < nel; i++)
619  {
620  strings[i] = chm.row_as_string (i);
621  if (! replace && strings[i] != str[i])
622  replace = true;
623  }
624 
626 
627  if (replace)
628  {
629  str = strings;
630  return true;
631  }
632  }
633  else if (val.iscellstr ())
634  {
635  bool replace = false;
636  Cell new_cell = val.cell_value ();
637 
638  string_vector strings = new_cell.cellstr_value ();
639 
640  octave_idx_type nel = strings.numel ();
641 
642  if (nel != str.numel ())
643  replace = true;
644  else
645  {
646  for (octave_idx_type i = 0; i < nel; i++)
647  {
648  if (strings[i] != str[i])
649  {
650  replace = true;
651  break;
652  }
653  }
654  }
655 
657 
658  if (replace)
659  {
660  str = strings;
661  return true;
662  }
663  }
664  else
665  error (R"(set: invalid string property value for "%s")",
666  get_name ().c_str ());
667 
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  std::ostringstream buf;
724  buf << d;
725  value[i] = buf.str ();
726  }
727  }
728  }
729 
732  { }
733 
734  bool empty (void) const
735  {
736  octave_value tmp = get ();
737  return tmp.isempty ();
738  }
739 
740  octave_value get (void) const
741  {
742  if (stored_type == char_t)
743  return octave_value (char_value ());
744  else
745  return octave_value (cell_value ());
746  }
747 
748  std::string string_value (void) const
749  {
750  return value.empty () ? "" : value[0];
751  }
752 
753  string_vector string_vector_value (void) const { return value; }
754 
755  charMatrix char_value (void) const { return charMatrix (value, ' '); }
756 
757  Cell cell_value (void) const {return Cell (value); }
758 
760  {
761  set (val);
762  return *this;
763  }
764 
765  base_property * clone (void) const { return new text_label_property (*this); }
766 
767 protected:
768 
769  bool do_set (const octave_value& val)
770  {
771  if (val.is_string ())
772  {
773  value = val.string_vector_value ();
774 
776  }
777  else if (val.iscell ())
778  {
779  Cell c = val.cell_value ();
780 
781  octave_idx_type nel = c.numel ();
782 
783  value.resize (nel);
784 
785  for (octave_idx_type i = 0; i < nel; i++)
786  {
787  octave_value tmp = c(i);
788 
789  if (tmp.is_string ())
790  value[i] = c(i).string_value ();
791  else
792  {
793  double d = c(i).double_value ();
794 
795  std::ostringstream buf;
796  buf << d;
797  value[i] = buf.str ();
798  }
799  }
800 
802  }
803  else
804  {
805  NDArray nda;
806 
807  try
808  {
809  nda = val.array_value ();
810  }
811  catch (octave::execution_exception& e)
812  {
813  error (e, R"(set: invalid string property value for "%s")",
814  get_name ().c_str ());
815  }
816 
817  octave_idx_type nel = nda.numel ();
818 
819  value.resize (nel);
820 
821  for (octave_idx_type i = 0; i < nel; i++)
822  {
823  std::ostringstream buf;
824  buf << nda(i);
825  value[i] = buf.str ();
826  }
827 
829  }
830 
831  return true;
832  }
833 
834 private:
837 };
838 
839 // ---------------------------------------------------------------------
840 
842 {
843 public:
844  OCTINTERP_API radio_values (const std::string& opt_string = "");
845 
848 
850  {
851  if (&a != this)
852  {
855  }
856 
857  return *this;
858  }
859 
860  std::string default_value (void) const { return default_val; }
861 
862  bool validate (const std::string& val, std::string& match)
863  {
864  bool retval = true;
865 
866  if (! contains (val, match))
867  error ("invalid value = %s", val.c_str ());
868 
869  return retval;
870  }
871 
872  bool contains (const std::string& val, std::string& match)
873  {
874  size_t k = 0;
875 
876  size_t len = val.length ();
877 
878  std::string first_match;
879 
880  for (const auto& possible_val : possible_vals)
881  {
882  if (possible_val.compare (val, len))
883  {
884  if (len == possible_val.length ())
885  {
886  // We found a full match (consider the case of val == "replace"
887  // with possible values "replace" and "replacechildren"). Any
888  // other matches are irrelevant, so set match and return now.
889  match = possible_val;
890  return true;
891  }
892  else
893  {
894  if (k == 0)
895  first_match = possible_val;
896 
897  k++;
898  }
899  }
900  }
901 
902  if (k == 1)
903  {
904  match = first_match;
905  return true;
906  }
907  else
908  return false;
909  }
910 
911  std::string values_as_string (void) const;
912 
913  Cell values_as_cell (void) const;
914 
915  octave_idx_type nelem (void) const { return possible_vals.size (); }
916 
917 private:
918  // Might also want to cache
919  std::string default_val;
920  std::set<caseless_str> possible_vals;
921 };
922 
924 {
925 public:
926  radio_property (const std::string& nm, const graphics_handle& h,
927  const radio_values& v = radio_values ())
928  : base_property (nm, h),
929  vals (v), current_val (v.default_value ()) { }
930 
931  radio_property (const std::string& nm, const graphics_handle& h,
932  const std::string& v)
933  : base_property (nm, h),
934  vals (v), current_val (vals.default_value ()) { }
935 
936  radio_property (const std::string& nm, const graphics_handle& h,
937  const radio_values& v, const std::string& def)
938  : base_property (nm, h),
939  vals (v), current_val (def) { }
940 
942  : base_property (p), vals (p.vals), current_val (p.current_val) { }
943 
944  octave_value get (void) const { return octave_value (current_val); }
945 
946  const std::string& current_value (void) const { return current_val; }
947 
948  std::string values_as_string (void) const { return vals.values_as_string (); }
949 
950  Cell values_as_cell (void) const { return vals.values_as_cell (); }
951 
952  bool is (const caseless_str& v) const
953  { return v.compare (current_val); }
954 
955  bool is_radio (void) const { return true; }
956 
958  {
959  set (val);
960  return *this;
961  }
962 
963  base_property * clone (void) const { return new radio_property (*this); }
964 
965 protected:
966  bool do_set (const octave_value& newval)
967  {
968  if (! newval.is_string ())
969  error (R"(set: invalid value for radio property "%s")",
970  get_name ().c_str ());
971 
972  std::string s = newval.string_value ();
973 
974  std::string match;
975 
976  if (! vals.validate (s, match))
977  error (R"(set: invalid value for radio property "%s" (value = %s))",
978  get_name ().c_str (), s.c_str ());
979 
980  if (match != current_val)
981  {
982  if (s.length () != match.length ())
983  warning_with_id ("Octave:abbreviated-property-match",
984  "%s: allowing %s to match %s value %s",
985  "set", s.c_str (), get_name ().c_str (),
986  match.c_str ());
987  current_val = match;
988  return true;
989  }
990  return false;
991  }
992 
993 private:
995  std::string current_val;
996 };
997 
998 // ---------------------------------------------------------------------
999 
1001 {
1002 public:
1003  color_values (double r = 0, double g = 0, double b = 1)
1004  : xrgb (1, 3)
1005  {
1006  xrgb(0) = r;
1007  xrgb(1) = g;
1008  xrgb(2) = b;
1009 
1010  validate ();
1011  }
1012 
1013  color_values (const std::string& str)
1014  : xrgb (1, 3)
1015  {
1016  if (! str2rgb (str))
1017  error ("invalid color specification: %s", str.c_str ());
1018  }
1019 
1021  : xrgb (c.xrgb)
1022  { }
1023 
1025  {
1026  if (&c != this)
1027  xrgb = c.xrgb;
1028 
1029  return *this;
1030  }
1031 
1032  bool operator == (const color_values& c) const
1033  {
1034  return (xrgb(0) == c.xrgb(0)
1035  && xrgb(1) == c.xrgb(1)
1036  && xrgb(2) == c.xrgb(2));
1037  }
1038 
1039  bool operator != (const color_values& c) const
1040  { return ! (*this == c); }
1041 
1042  Matrix rgb (void) const { return xrgb; }
1043 
1044  operator octave_value (void) const { return xrgb; }
1045 
1046  void validate (void) const
1047  {
1048  for (int i = 0; i < 3; i++)
1049  {
1050  if (xrgb(i) < 0 || xrgb(i) > 1)
1051  error ("invalid RGB color specification");
1052  }
1053  }
1054 
1055 private:
1057 
1058  OCTINTERP_API bool str2rgb (const std::string& str);
1059 };
1060 
1062 {
1063 public:
1065  : base_property ("", graphics_handle ()),
1067  current_val (v.default_value ())
1068  { }
1069 
1071  : base_property ("", graphics_handle ()),
1073  current_val (v.default_value ())
1074  { }
1075 
1076  color_property (const std::string& nm, const graphics_handle& h,
1077  const color_values& c = color_values (),
1078  const radio_values& v = radio_values ())
1079  : base_property (nm, h),
1081  current_val (v.default_value ())
1082  { }
1083 
1084  color_property (const std::string& nm, const graphics_handle& h,
1085  const radio_values& v)
1086  : base_property (nm, h),
1088  current_val (v.default_value ())
1089  { }
1090 
1091  color_property (const std::string& nm, const graphics_handle& h,
1092  const std::string& v)
1093  : base_property (nm, h),
1095  current_val (radio_val.default_value ())
1096  { }
1097 
1098  color_property (const std::string& nm, const graphics_handle& h,
1099  const color_property& v)
1100  : base_property (nm, h),
1103  { }
1104 
1108  current_val (p.current_val) { }
1109 
1110  octave_value get (void) const
1111  {
1112  if (current_type == color_t)
1113  return color_val.rgb ();
1114 
1115  return current_val;
1116  }
1117 
1118  bool is_rgb (void) const { return (current_type == color_t); }
1119 
1120  bool is_radio (void) const { return (current_type == radio_t); }
1121 
1122  bool is (const std::string& v) const
1123  { return (is_radio () && current_val == v); }
1124 
1125  Matrix rgb (void) const
1126  {
1127  if (current_type != color_t)
1128  error ("color has no RGB value");
1129 
1130  return color_val.rgb ();
1131  }
1132 
1133  const std::string& current_value (void) const
1134  {
1135  if (current_type != radio_t)
1136  error ("color has no radio value");
1137 
1138  return current_val;
1139  }
1140 
1142  {
1143  set (val);
1144  return *this;
1145  }
1146 
1147  operator octave_value (void) const { return get (); }
1148 
1149  base_property * clone (void) const { return new color_property (*this); }
1150 
1151  std::string values_as_string (void) const
1152  { return radio_val.values_as_string (); }
1153 
1154  Cell values_as_cell (void) const { return radio_val.values_as_cell (); }
1155 
1156 protected:
1157  OCTINTERP_API bool do_set (const octave_value& newval);
1158 
1159 private:
1163  std::string current_val;
1164 };
1165 
1166 // ---------------------------------------------------------------------
1167 
1169 {
1173  NOT_INF
1174 };
1176 {
1177 public:
1178  double_property (const std::string& nm, const graphics_handle& h,
1179  double d = 0)
1180  : base_property (nm, h),
1182  minval (std::pair<double, bool> (octave_NaN, true)),
1183  maxval (std::pair<double, bool> (octave_NaN, true)) { }
1184 
1188  minval (std::pair<double, bool> (octave_NaN, true)),
1189  maxval (std::pair<double, bool> (octave_NaN, true)) { }
1190 
1191  octave_value get (void) const { return octave_value (current_val); }
1192 
1193  double double_value (void) const { return current_val; }
1194 
1196  {
1197  set (val);
1198  return *this;
1199  }
1200 
1201  base_property * clone (void) const
1202  {
1203  double_property *p = new double_property (*this);
1204 
1206  p->minval = minval;
1207  p->maxval = maxval;
1208 
1209  return p;
1210  }
1211 
1212  void add_constraint (const std::string& type, double val, bool inclusive)
1213  {
1214  if (type == "min")
1215  minval = std::pair<double, bool> (val, inclusive);
1216  else if (type == "max")
1217  maxval = std::pair<double, bool> (val, inclusive);
1218  }
1219 
1220  void add_constraint (const finite_type finite)
1221  { finite_constraint = finite; }
1222 
1223 protected:
1224  bool do_set (const octave_value& v)
1225  {
1226  if (! v.is_scalar_type () || ! v.isreal ())
1227  error (R"(set: invalid value for double property "%s")",
1228  get_name ().c_str ());
1229 
1230  double new_val = v.double_value ();
1231 
1232  // Check min and max
1233  if (! octave::math::isnan (minval.first))
1234  {
1235  if (minval.second && minval.first > new_val)
1236  error (R"(set: "%s" must be greater than or equal to %g)",
1237  get_name ().c_str (), minval.first);
1238  else if (! minval.second && minval.first >= new_val)
1239  error (R"(set: "%s" must be greater than %g)",
1240  get_name ().c_str (), minval.first);
1241  }
1242 
1243  if (! octave::math::isnan (maxval.first))
1244  {
1245  if (maxval.second && maxval.first < new_val)
1246  error (R"(set: "%s" must be less than or equal to %g)",
1247  get_name ().c_str (), maxval.first);
1248  else if (! maxval.second && maxval.first <= new_val)
1249  error (R"(set: "%s" must be less than %g)",
1250  get_name ().c_str (), maxval.first);
1251  }
1252 
1253  if (finite_constraint == NO_CHECK) { /* do nothing */ }
1254  else if (finite_constraint == FINITE)
1255  {
1256  if (! octave::math::isfinite (new_val))
1257  error (R"(set: "%s" must be finite)", get_name ().c_str ());
1258  }
1259  else if (finite_constraint == NOT_NAN)
1260  {
1261  if (octave::math::isnan (new_val))
1262  error (R"(set: "%s" must not be nan)", get_name ().c_str ());
1263  }
1264  else if (finite_constraint == NOT_INF)
1265  {
1266  if (octave::math::isinf (new_val))
1267  error (R"(set: "%s" must not be infinite)", get_name ().c_str ());
1268  }
1269 
1270  if (new_val != current_val)
1271  {
1272  current_val = new_val;
1273  return true;
1274  }
1275 
1276  return false;
1277  }
1278 
1279 private:
1280  double current_val;
1282  std::pair<double, bool> minval, maxval;
1283 };
1284 
1285 // ---------------------------------------------------------------------
1286 
1288 {
1289 public:
1291  : base_property ("", graphics_handle ()),
1292  current_type (double_t), dval (d), radio_val (v),
1293  current_val (v.default_value ())
1294  { }
1295 
1296  double_radio_property (const std::string& nm, const graphics_handle& h,
1297  const std::string& v)
1298  : base_property (nm, h),
1299  current_type (radio_t), dval (0), radio_val (v),
1300  current_val (radio_val.default_value ())
1301  { }
1302 
1303  double_radio_property (const std::string& nm, const graphics_handle& h,
1304  const double_radio_property& v)
1305  : base_property (nm, h),
1308  { }
1309 
1312  dval (p.dval), radio_val (p.radio_val),
1313  current_val (p.current_val) { }
1314 
1315  octave_value get (void) const
1316  {
1317  if (current_type == double_t)
1318  return dval;
1319 
1320  return current_val;
1321  }
1322 
1323  bool is_double (void) const { return (current_type == double_t); }
1324 
1325  bool is_radio (void) const { return (current_type == radio_t); }
1326 
1327  bool is (const std::string& v) const
1328  { return (is_radio () && current_val == v); }
1329 
1330  double double_value (void) const
1331  {
1332  if (current_type != double_t)
1333  error ("%s: property has no double", get_name ().c_str ());
1334 
1335  return dval;
1336  }
1337 
1338  const std::string& current_value (void) const
1339  {
1340  if (current_type != radio_t)
1341  error ("%s: property has no radio value", get_name ().c_str ());
1342 
1343  return current_val;
1344  }
1345 
1347  {
1348  set (val);
1349  return *this;
1350  }
1351 
1352  operator octave_value (void) const { return get (); }
1353 
1354  base_property * clone (void) const
1355  { return new double_radio_property (*this); }
1356 
1357 protected:
1358  OCTINTERP_API bool do_set (const octave_value& v);
1359 
1360 private:
1362  double dval;
1364  std::string current_val;
1365 };
1366 
1367 // ---------------------------------------------------------------------
1368 
1370 {
1371 public:
1373  : base_property ("", graphics_handle ()), data (Matrix ()),
1374  xmin (), xmax (), xminp (), xmaxp (),
1376  minval (std::pair<double, bool> (octave_NaN, true)),
1377  maxval (std::pair<double, bool> (octave_NaN, true))
1378  {
1379  get_data_limits ();
1380  }
1381 
1382  array_property (const std::string& nm, const graphics_handle& h,
1383  const octave_value& m)
1384  : base_property (nm, h), data (m.issparse () ? m.full_value () : m),
1385  xmin (), xmax (), xminp (), xmaxp (),
1387  minval (std::pair<double, bool> (octave_NaN, true)),
1388  maxval (std::pair<double, bool> (octave_NaN, true))
1389  {
1390  get_data_limits ();
1391  }
1392 
1393  // This copy constructor is only intended to be used
1394  // internally to access min/max values; no need to
1395  // copy constraints.
1397  : base_property (p), data (p.data),
1398  xmin (p.xmin), xmax (p.xmax), xminp (p.xminp), xmaxp (p.xmaxp),
1400  minval (std::pair<double, bool> (octave_NaN, true)),
1401  maxval (std::pair<double, bool> (octave_NaN, true))
1402  { }
1403 
1404  octave_value get (void) const { return data; }
1405 
1406  void add_constraint (const std::string& type)
1407  { type_constraints.insert (type); }
1408 
1409  void add_constraint (const dim_vector& dims)
1410  { size_constraints.push_back (dims); }
1411 
1412  void add_constraint (const finite_type finite)
1413  { finite_constraint = finite; }
1414 
1415  void add_constraint (const std::string& type, double val, bool inclusive)
1416  {
1417  if (type == "min")
1418  minval = std::pair<double, bool> (val, inclusive);
1419  else if (type == "max")
1420  maxval = std::pair<double, bool> (val, inclusive);
1421  }
1422 
1423  double min_val (void) const { return xmin; }
1424  double max_val (void) const { return xmax; }
1425  double min_pos (void) const { return xminp; }
1426  double max_neg (void) const { return xmaxp; }
1427 
1428  Matrix get_limits (void) const
1429  {
1430  Matrix m (1, 4);
1431 
1432  m(0) = min_val ();
1433  m(1) = max_val ();
1434  m(2) = min_pos ();
1435  m(3) = max_neg ();
1436 
1437  return m;
1438  }
1439 
1441  {
1442  set (val);
1443  return *this;
1444  }
1445 
1446  base_property * clone (void) const
1447  {
1448  array_property *p = new array_property (*this);
1449 
1453  p->minval = minval;
1454  p->maxval = maxval;
1455 
1456  return p;
1457  }
1458 
1459 protected:
1460  bool do_set (const octave_value& v)
1461  {
1462  octave_value tmp = (v.issparse () ? v.full_value () : v);
1463 
1464  if (! validate (tmp))
1465  error (R"(invalid value for array property "%s")",
1466  get_name ().c_str ());
1467 
1468  // FIXME: should we check for actual data change?
1469  if (! is_equal (tmp))
1470  {
1471  data = tmp;
1472 
1473  get_data_limits ();
1474 
1475  return true;
1476  }
1477 
1478  return false;
1479  }
1480 
1481 private:
1482  OCTINTERP_API bool validate (const octave_value& v);
1483 
1484  OCTINTERP_API bool is_equal (const octave_value& v) const;
1485 
1486  OCTINTERP_API void get_data_limits (void);
1487 
1488 protected:
1490  double xmin;
1491  double xmax;
1492  double xminp;
1493  double xmaxp;
1494  std::set<std::string> type_constraints;
1495  std::list<dim_vector> size_constraints;
1497  std::pair<double, bool> minval, maxval;
1498 };
1499 
1501 {
1502 public:
1503  row_vector_property (const std::string& nm, const graphics_handle& h,
1504  const octave_value& m)
1505  : array_property (nm, h, m)
1506  {
1507  add_constraint (dim_vector (-1, 1));
1508  add_constraint (dim_vector (1, -1));
1509  add_constraint (dim_vector (0, 0));
1510  }
1511 
1513  : array_property (p)
1514  {
1515  add_constraint (dim_vector (-1, 1));
1516  add_constraint (dim_vector (1, -1));
1517  add_constraint (dim_vector (0, 0));
1518  }
1519 
1520  void add_constraint (const std::string& type)
1521  {
1523  }
1524 
1525  void add_constraint (const dim_vector& dims)
1526  {
1528  }
1529 
1530  void add_constraint (const finite_type finite)
1531  {
1533  }
1534 
1535  void add_constraint (const std::string& type, double val, bool inclusive)
1536  {
1537  array_property::add_constraint (type, val, inclusive);
1538  }
1539 
1541  {
1542  size_constraints.remove (dim_vector (1, -1));
1543  size_constraints.remove (dim_vector (-1, 1));
1544  size_constraints.remove (dim_vector (0, 0));
1545 
1546  add_constraint (dim_vector (1, len));
1547  add_constraint (dim_vector (len, 1));
1548  }
1549 
1551  {
1552  set (val);
1553  return *this;
1554  }
1555 
1556  base_property * clone (void) const
1557  {
1558  row_vector_property *p = new row_vector_property (*this);
1559 
1563  p->minval = minval;
1564  p->maxval = maxval;
1565 
1566  return p;
1567  }
1568 
1569 protected:
1570  bool do_set (const octave_value& v)
1571  {
1572  bool retval = array_property::do_set (v);
1573 
1574  dim_vector dv = data.dims ();
1575 
1576  if (dv(0) > 1 && dv(1) == 1)
1577  {
1578  int tmp = dv(0);
1579  dv(0) = dv(1);
1580  dv(1) = tmp;
1581 
1582  data = data.reshape (dv);
1583  }
1584 
1585  return retval;
1586  }
1587 
1588 private:
1589  OCTINTERP_API bool validate (const octave_value& v);
1590 };
1591 
1592 // ---------------------------------------------------------------------
1593 
1595 {
1596 public:
1597  bool_property (const std::string& nm, const graphics_handle& h,
1598  bool val)
1599  : radio_property (nm, h, radio_values (val ? "{on}|off" : "on|{off}"))
1600  { }
1601 
1602  bool_property (const std::string& nm, const graphics_handle& h,
1603  const char *val)
1604  : radio_property (nm, h, radio_values (std::string (val) == "on" ?
1605  "{on}|off" : "on|{off}"), val)
1606  { }
1607 
1609  : radio_property (p) { }
1610 
1611  bool is_on (void) const { return is ("on"); }
1612 
1614  {
1615  set (val);
1616  return *this;
1617  }
1618 
1619  base_property * clone (void) const { return new bool_property (*this); }
1620 
1621 protected:
1622  bool do_set (const octave_value& val)
1623  {
1624  if (val.is_bool_scalar ())
1625  return radio_property::do_set (val.bool_value () ? "on" : "off");
1626  else
1627  return radio_property::do_set (val);
1628  }
1629 };
1630 
1631 // ---------------------------------------------------------------------
1632 
1634 {
1635 public:
1636  handle_property (const std::string& nm, const graphics_handle& h,
1637  const graphics_handle& val = graphics_handle ())
1638  : base_property (nm, h),
1639  current_val (val) { }
1640 
1642  : base_property (p), current_val (p.current_val) { }
1643 
1644  octave_value get (void) const { return current_val.as_octave_value (); }
1645 
1646  graphics_handle handle_value (void) const { return current_val; }
1647 
1649  {
1650  set (val);
1651  return *this;
1652  }
1653 
1655  {
1656  set (octave_value (h.value ()));
1657  return *this;
1658  }
1659 
1660  void invalidate (void)
1662 
1663  base_property * clone (void) const { return new handle_property (*this); }
1664 
1665  void add_constraint (const std::string& type)
1666  { type_constraints.insert (type); }
1667 
1668 protected:
1669  OCTINTERP_API bool do_set (const octave_value& v);
1670  std::set<std::string> type_constraints;
1671 
1672 private:
1674 };
1675 
1676 // ---------------------------------------------------------------------
1677 
1679 {
1680 public:
1681  any_property (const std::string& nm, const graphics_handle& h,
1682  const octave_value& m = Matrix ())
1683  : base_property (nm, h), data (m) { }
1684 
1686  : base_property (p), data (p.data) { }
1687 
1688  octave_value get (void) const { return data; }
1689 
1691  {
1692  set (val);
1693  return *this;
1694  }
1695 
1696  base_property * clone (void) const { return new any_property (*this); }
1697 
1698 protected:
1699  bool do_set (const octave_value& v)
1700  {
1701  data = v;
1702  return true;
1703  }
1704 
1705 private:
1707 };
1708 
1709 // ---------------------------------------------------------------------
1710 
1712 {
1713 public:
1716  {
1717  do_init_children (Matrix ());
1718  }
1719 
1720  children_property (const std::string& nm, const graphics_handle& h,
1721  const Matrix& val)
1722  : base_property (nm, h), children_list ()
1723  {
1724  do_init_children (val);
1725  }
1726 
1728  : base_property (p), children_list ()
1729  {
1731  }
1732 
1734  {
1735  set (val);
1736  return *this;
1737  }
1738 
1739  base_property * clone (void) const { return new children_property (*this); }
1740 
1741  bool remove_child (double val)
1742  {
1743  return do_remove_child (val);
1744  }
1745 
1746  void adopt (double val)
1747  {
1748  do_adopt_child (val);
1749  }
1750 
1751  Matrix get_children (void) const
1752  {
1753  return do_get_children (false);
1754  }
1755 
1756  Matrix get_hidden (void) const
1757  {
1758  return do_get_children (true);
1759  }
1760 
1761  Matrix get_all (void) const
1762  {
1763  return do_get_all_children ();
1764  }
1765 
1766  octave_value get (void) const
1767  {
1768  return octave_value (get_children ());
1769  }
1770 
1771  void delete_children (bool clear = false, bool from_root = false)
1772  {
1773  do_delete_children (clear, from_root);
1774  }
1775 
1777  {
1778  for (auto& hchild : children_list)
1779  {
1780  if (hchild == old_gh)
1781  {
1782  hchild = new_gh.value ();
1783  return;
1784  }
1785  }
1786 
1787  error ("children_list::renumber: child not found!");
1788  }
1789 
1790 private:
1791  typedef std::list<double>::iterator children_list_iterator;
1792  typedef std::list<double>::const_iterator const_children_list_iterator;
1793  std::list<double> children_list;
1794 
1795 protected:
1796  bool do_set (const octave_value& val)
1797  {
1798  Matrix new_kids;
1799 
1800  try
1801  {
1802  new_kids = val.matrix_value ();
1803  }
1804  catch (octave::execution_exception& e)
1805  {
1806  error (e, "set: children must be an array of graphics handles");
1807  }
1808 
1809  octave_idx_type nel = new_kids.numel ();
1810 
1811  const Matrix new_kids_column = new_kids.reshape (dim_vector (nel, 1));
1812 
1813  bool is_ok = true;
1814  bool add_hidden = true;
1815 
1816  const Matrix visible_kids = do_get_children (false);
1817 
1818  if (visible_kids.numel () == new_kids.numel ())
1819  {
1820  Matrix t1 = visible_kids.sort ();
1821  Matrix t2 = new_kids_column.sort ();
1822  Matrix t3 = get_hidden ().sort ();
1823 
1824  if (t1 != t2)
1825  is_ok = false;
1826 
1827  if (t1 == t3)
1828  add_hidden = false;
1829  }
1830  else
1831  is_ok = false;
1832 
1833  if (! is_ok)
1834  error ("set: new children must be a permutation of existing children");
1835 
1836  Matrix tmp = new_kids_column;
1837 
1838  if (add_hidden)
1839  tmp.stack (get_hidden ());
1840 
1841  children_list.clear ();
1842 
1843  // Don't use do_init_children here, as that reverses the
1844  // order of the list, and we don't want to do that if setting
1845  // the child list directly.
1846  for (octave_idx_type i = 0; i < tmp.numel (); i++)
1847  children_list.push_back (tmp.xelem (i));
1848 
1849  return is_ok;
1850  }
1851 
1852 private:
1853  void do_init_children (const Matrix& val)
1854  {
1855  children_list.clear ();
1856  for (octave_idx_type i = 0; i < val.numel (); i++)
1857  children_list.push_front (val.xelem (i));
1858  }
1859 
1860  void do_init_children (const std::list<double>& val)
1861  {
1862  children_list.clear ();
1863  children_list = val;
1864  }
1865 
1866  Matrix do_get_children (bool return_hidden) const;
1867 
1869  {
1870  Matrix retval (children_list.size (), 1);
1871  octave_idx_type i = 0;
1872 
1873  for (const auto& hchild : children_list)
1874  retval(i++) = hchild;
1875 
1876  return retval;
1877  }
1878 
1879  bool do_remove_child (double child)
1880  {
1881  for (auto it = children_list.begin (); it != children_list.end (); it++)
1882  {
1883  if (*it == child)
1884  {
1885  children_list.erase (it);
1886  return true;
1887  }
1888  }
1889  return false;
1890  }
1891 
1892  void do_adopt_child (double val)
1893  {
1894  children_list.push_front (val);
1895  }
1896 
1897  void do_delete_children (bool clear, bool from_root);
1898 };
1899 
1900 // ---------------------------------------------------------------------
1901 
1903 {
1904 public:
1905  callback_property (const std::string& nm, const graphics_handle& h,
1906  const octave_value& m)
1907  : base_property (nm, h), callback (m) { }
1908 
1910  : base_property (p), callback (p.callback) { }
1911 
1912  octave_value get (void) const { return callback; }
1913 
1914  OCTINTERP_API void execute (const octave_value& data = octave_value ()) const;
1915 
1916  bool is_defined (void) const
1917  {
1918  return (callback.is_defined () && ! callback.isempty ());
1919  }
1920 
1922  {
1923  set (val);
1924  return *this;
1925  }
1926 
1927  base_property * clone (void) const { return new callback_property (*this); }
1928 
1929 protected:
1930  bool do_set (const octave_value& v)
1931  {
1932  if (! validate (v))
1933  error (R"(invalid value for callback property "%s")",
1934  get_name ().c_str ());
1935 
1936  callback = v;
1937  return true;
1938  return false;
1939  }
1940 
1941 private:
1942  OCTINTERP_API bool validate (const octave_value& v) const;
1943 
1944 private:
1946 };
1947 
1948 // ---------------------------------------------------------------------
1949 
1951 {
1952 public:
1953  property (void) : rep (new base_property ("", graphics_handle ()))
1954  { }
1955 
1956  property (base_property *bp, bool persist = false) : rep (bp)
1957  { if (persist) rep->count++; }
1958 
1959  property (const property& p) : rep (p.rep)
1960  {
1961  rep->count++;
1962  }
1963 
1964  ~property (void)
1965  {
1966  if (--rep->count == 0)
1967  delete rep;
1968  }
1969 
1970  bool ok (void) const
1971  { return rep->ok (); }
1972 
1973  std::string get_name (void) const
1974  { return rep->get_name (); }
1975 
1976  void set_name (const std::string& name)
1977  { rep->set_name (name); }
1978 
1980  { return rep->get_parent (); }
1981 
1982  void set_parent (const graphics_handle& h)
1983  { rep->set_parent (h); }
1984 
1985  bool is_hidden (void) const
1986  { return rep->is_hidden (); }
1987 
1988  void set_hidden (bool flag)
1989  { rep->set_hidden (flag); }
1990 
1991  bool is_radio (void) const
1992  { return rep->is_radio (); }
1993 
1994  int get_id (void) const
1995  { return rep->get_id (); }
1996 
1997  void set_id (int d)
1998  { rep->set_id (d); }
1999 
2000  octave_value get (void) const
2001  { return rep->get (); }
2002 
2003  bool set (const octave_value& val, bool do_run = true,
2004  bool do_notify_toolkit = true)
2005  { return rep->set (val, do_run, do_notify_toolkit); }
2006 
2007  std::string values_as_string (void) const
2008  { return rep->values_as_string (); }
2009 
2010  Cell values_as_cell (void) const
2011  { return rep->values_as_cell (); }
2012 
2013  property& operator = (const octave_value& val)
2014  {
2015  *rep = val;
2016  return *this;
2017  }
2018 
2019  property& operator = (const property& p)
2020  {
2021  if (rep && --rep->count == 0)
2022  delete rep;
2023 
2024  rep = p.rep;
2025  rep->count++;
2026 
2027  return *this;
2028  }
2029 
2031  { rep->add_listener (v, mode); }
2032 
2034  listener_mode mode = GCB_POSTSET)
2035  { rep->delete_listener (v, mode); }
2036 
2038  { rep->run_listeners (mode); }
2039 
2040  OCTINTERP_API static
2041  property create (const std::string& name, const graphics_handle& parent,
2042  const caseless_str& type,
2043  const octave_value_list& args);
2044 
2045  property clone (void) const
2046  { return property (rep->clone ()); }
2047 
2048 #if 0
2049  const string_property& as_string_property (void) const
2050  { return *(dynamic_cast<string_property *> (rep)); }
2051 
2052  const radio_property& as_radio_property (void) const
2053  { return *(dynamic_cast<radio_property *> (rep)); }
2054 
2055  const color_property& as_color_property (void) const
2056  { return *(dynamic_cast<color_property *> (rep)); }
2057 
2058  const double_property& as_double_property (void) const
2059  { return *(dynamic_cast<double_property *> (rep)); }
2060 
2061  const bool_property& as_bool_property (void) const
2062  { return *(dynamic_cast<bool_property *> (rep)); }
2063 
2064  const handle_property& as_handle_property (void) const
2065  { return *(dynamic_cast<handle_property *> (rep)); }
2066 #endif
2067 
2068 private:
2070 };
2071 
2072 // ---------------------------------------------------------------------
2073 
2074 typedef std::pair<std::string, octave_value> pval_pair;
2075 
2076 class pval_vector : public std::vector<pval_pair>
2077 {
2078 public:
2079  const_iterator find (const std::string pname) const
2080  {
2081  const_iterator it;
2082 
2083  for (it = (*this).begin (); it != (*this).end (); it++)
2084  if (pname == (*it).first)
2085  return it;
2086 
2087  return (*this).end ();
2088  }
2089 
2090  iterator find (const std::string pname)
2091  {
2092  iterator it;
2093 
2094  for (it = (*this).begin (); it != (*this).end (); it++)
2095  if (pname == (*it).first)
2096  return it;
2097 
2098  return (*this).end ();
2099  }
2100 
2101  octave_value lookup (const std::string pname) const
2102  {
2104 
2105  const_iterator it = find (pname);
2106 
2107  if (it != (*this).end ())
2108  retval = (*it).second;
2109 
2110  return retval;
2111  }
2112 
2113  octave_value& operator [] (const std::string pname)
2114  {
2115  iterator it = find (pname);
2116 
2117  if (it == (*this).end ())
2118  {
2119  push_back (pval_pair (pname, octave_value ()));
2120  return (*this).back ().second;
2121  }
2122 
2123  return (*it).second;
2124  }
2125 
2126  void erase (const std::string pname)
2127  {
2128  iterator it = find (pname);
2129  if (it != (*this).end ())
2130  erase (it);
2131  }
2132 
2133  void erase (iterator it)
2134  {
2135  std::vector<pval_pair>::erase (it);
2136  }
2137 
2138 };
2139 
2141 {
2142 public:
2144  typedef std::map<std::string, pval_map_type> plist_map_type;
2145 
2146  typedef pval_map_type::iterator pval_map_iterator;
2147  typedef pval_map_type::const_iterator pval_map_const_iterator;
2148 
2149  typedef plist_map_type::iterator plist_map_iterator;
2150  typedef plist_map_type::const_iterator plist_map_const_iterator;
2151 
2153  : plist_map (m) { }
2154 
2155  ~property_list (void) = default;
2156 
2157  void set (const caseless_str& name, const octave_value& val);
2158 
2159  octave_value lookup (const caseless_str& name) const;
2160 
2161  plist_map_iterator begin (void) { return plist_map.begin (); }
2162  plist_map_const_iterator begin (void) const { return plist_map.begin (); }
2163 
2164  plist_map_iterator end (void) { return plist_map.end (); }
2165  plist_map_const_iterator end (void) const { return plist_map.end (); }
2166 
2167  plist_map_iterator find (const std::string& go_name)
2168  {
2169  return plist_map.find (go_name);
2170  }
2171 
2172  plist_map_const_iterator find (const std::string& go_name) const
2173  {
2174  return plist_map.find (go_name);
2175  }
2176 
2177  octave_scalar_map as_struct (const std::string& prefix_arg) const;
2178 
2179 private:
2181 };
2182 
2183 // ---------------------------------------------------------------------
2184 
2185 class base_graphics_object;
2186 class graphics_object;
2187 
2188 class OCTINTERP_API base_properties
2189 {
2190 public:
2191  base_properties (const std::string& ty = "unknown",
2192  const graphics_handle& mh = graphics_handle (),
2193  const graphics_handle& p = graphics_handle ());
2194 
2195  virtual ~base_properties (void) = default;
2196 
2197  virtual std::string graphics_object_name (void) const { return "unknown"; }
2198 
2199  void mark_modified (void);
2200 
2201  void override_defaults (base_graphics_object& obj);
2202 
2203  virtual void init_integerhandle (const octave_value&)
2204  {
2205  panic_impossible ();
2206  }
2207 
2208  // Look through DEFAULTS for properties with given CLASS_NAME, and
2209  // apply them to the current object with set (virtual method).
2210 
2211  void set_from_list (base_graphics_object& obj, property_list& defaults);
2212 
2213  void insert_property (const std::string& name, property p)
2214  {
2215  p.set_name (name);
2216  p.set_parent (__myhandle__);
2217  all_props[name] = p;
2218  }
2219 
2220  virtual void set (const caseless_str&, const octave_value&);
2221 
2222  virtual octave_value get (const caseless_str& pname) const;
2223 
2224  virtual octave_value get (const std::string& pname) const
2225  {
2226  return get (caseless_str (pname));
2227  }
2228 
2229  virtual octave_value get (const char *pname) const
2230  {
2231  return get (caseless_str (pname));
2232  }
2233 
2234  virtual octave_value get (bool all = false) const;
2235 
2236  // FIXME: It seems like this function should be const, but that is
2237  // currently not possible with the way that properties are stored as
2238  // specific types in the graphics_object classes.
2239  virtual property get_property (const caseless_str& pname);
2240 
2241  virtual bool has_property (const caseless_str&) const
2242  {
2243  panic_impossible ();
2244  return false;
2245  }
2246 
2247  bool is_modified (void) const { return is___modified__ (); }
2248 
2249  virtual void remove_child (const graphics_handle& h, bool = false)
2250  {
2251  if (children.remove_child (h.value ()))
2252  {
2253  children.run_listeners ();
2254  mark_modified ();
2255  }
2256  }
2257 
2258  virtual void adopt (const graphics_handle& h)
2259  {
2260  children.adopt (h.value ());
2261  children.run_listeners ();
2262  mark_modified ();
2263  }
2264 
2265  virtual octave::graphics_toolkit get_toolkit (void) const;
2266 
2267  virtual Matrix
2268  get_boundingbox (bool /* finternal */ = false,
2269  const Matrix& /* parent_pix_size */ = Matrix ()) const
2270  { return Matrix (1, 4, 0.0); }
2271 
2272  virtual void update_boundingbox (void);
2273 
2274  virtual void update_autopos (const std::string& elem_type);
2275 
2276  virtual void add_listener (const caseless_str&, const octave_value&,
2278 
2279  virtual void delete_listener (const caseless_str&, const octave_value&,
2281 
2282  void set_beingdeleted (const octave_value& val)
2283  {
2284  beingdeleted.set (val, true, false);
2285  update_beingdeleted ();
2286  }
2287 
2288  void set_tag (const octave_value& val) { tag = val; }
2289 
2290  void set_parent (const octave_value& val);
2291 
2292  Matrix get_children (void) const
2293  {
2294  return children.get_children ();
2295  }
2296 
2298  {
2299  return children.get_all ();
2300  }
2301 
2303  {
2304  return children.get_hidden ();
2305  }
2306 
2307  void get_children_of_type (const caseless_str& type, bool get_invisible,
2308  bool traverse,
2309  std::list<graphics_object> &children_list) const;
2310 
2311  void set_modified (const octave_value& val) { set___modified__ (val); }
2312 
2313  void set___modified__ (const octave_value& val) { __modified__ = val; }
2314 
2315  void reparent (const graphics_handle& new_parent) { parent = new_parent; }
2316 
2317  // Update data limits for AXIS_TYPE (xdata, ydata, etc.) in the parent
2318  // axes object.
2319 
2320  virtual void update_axis_limits (const std::string& axis_type) const;
2321 
2322  virtual void update_axis_limits (const std::string& axis_type,
2323  const graphics_handle& h) const;
2324 
2325  virtual void update_uicontextmenu (void) const;
2326 
2327  virtual void delete_children (bool clear = false, bool from_root = false)
2328  {
2329  children.delete_children (clear, from_root);
2330  }
2331 
2333  {
2334  children.renumber (old_gh, new_gh);
2335  }
2336 
2338  {
2339  parent = new_gh;
2340  }
2341 
2343 
2344  // FIXME: These functions should be generated automatically by the
2345  // genprops.awk script.
2346  //
2347  // EMIT_BASE_PROPERTIES_GET_FUNCTIONS
2348 
2349  virtual octave_value get_alim (void) const { return octave_value (); }
2350  virtual octave_value get_clim (void) const { return octave_value (); }
2351  virtual octave_value get_xlim (void) const { return octave_value (); }
2352  virtual octave_value get_ylim (void) const { return octave_value (); }
2353  virtual octave_value get_zlim (void) const { return octave_value (); }
2354 
2355  virtual bool is_aliminclude (void) const { return false; }
2356  virtual bool is_climinclude (void) const { return false; }
2357  virtual bool is_xliminclude (void) const { return false; }
2358  virtual bool is_yliminclude (void) const { return false; }
2359  virtual bool is_zliminclude (void) const { return false; }
2360 
2361  bool is_handle_visible (void) const;
2362 
2363  std::set<std::string> dynamic_property_names (void) const;
2364 
2365  bool has_dynamic_property (const std::string& pname) const;
2366 
2367 protected:
2368  std::set<std::string> dynamic_properties;
2369 
2370  void set_dynamic (const caseless_str& pname, const octave_value& val);
2371 
2372  octave_value get_dynamic (const caseless_str& pname) const;
2373 
2374  octave_value get_dynamic (bool all = false) const;
2375 
2376  property get_property_dynamic (const caseless_str& pname) const;
2377 
2378  BEGIN_BASE_PROPERTIES
2379  // properties common to all objects
2380  bool_property beingdeleted s , "off"
2381  radio_property busyaction , "{queue}|cancel"
2382  callback_property buttondownfcn , Matrix ()
2383  children_property children gf , Matrix ()
2384  bool_property clipping , "on"
2385  callback_property createfcn , Matrix ()
2386  callback_property deletefcn , Matrix ()
2387  radio_property handlevisibility u , "{on}|callback|off"
2388  bool_property hittest , "on"
2389  bool_property interruptible , "on"
2390  handle_property parent fs , p
2391  radio_property pickableparts , "{visible}|all|none"
2392  bool_property selected , "off"
2393  bool_property selectionhighlight , "on"
2394  string_property tag s , ""
2395  string_property type frs , ty
2396  handle_property uicontextmenu u , graphics_handle ()
2397  any_property userdata , Matrix ()
2398  bool_property visible u , "on"
2399 
2400  // Octave-specific properties
2401  any_property __appdata__ h , Matrix ()
2402  bool_property __modified__ hs , "on"
2403  graphics_handle __myhandle__ fhrs , mh
2404  END_PROPERTIES
2405 
2406  virtual void update_beingdeleted (void) { };
2407 
2408  virtual void update_handlevisibility (void);
2409 
2410  virtual void update_visible (void) { };
2411 
2412 protected:
2413  struct cmp_caseless_str
2414  {
2415  bool operator () (const caseless_str& a, const caseless_str& b) const
2416  {
2417  std::string a1 = a;
2418  std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
2419  std::string b1 = b;
2420  std::transform (b1.begin (), b1.end (), b1.begin (), tolower);
2421 
2422  return a1 < b1;
2423  }
2424  };
2425 
2426  std::map<caseless_str, property, cmp_caseless_str> all_props;
2427 
2428 protected:
2429  void insert_static_property (const std::string& name, base_property& p)
2430  { insert_property (name, property (&p, true)); }
2431 
2432  virtual void init (void)
2433  {
2434  uicontextmenu.add_constraint ("uicontextmenu");
2435  }
2436 };
2437 
2438 class OCTINTERP_API base_graphics_object
2439 {
2440 public:
2441  friend class graphics_object;
2442 
2443  base_graphics_object (void) : toolkit_flag (false) { }
2444 
2445  // No copying!
2446 
2447  base_graphics_object (const base_graphics_object&) = delete;
2448 
2449  base_graphics_object& operator = (const base_graphics_object&) = delete;
2450 
2451  virtual ~base_graphics_object (void) = default;
2452 
2453  virtual void mark_modified (void)
2454  {
2455  if (! valid_object ())
2456  error ("base_graphics_object::mark_modified: invalid graphics object");
2457 
2458  get_properties ().mark_modified ();
2459  }
2460 
2461  virtual void override_defaults (base_graphics_object& obj)
2462  {
2463  if (! valid_object ())
2464  error ("base_graphics_object::override_defaults: invalid graphics object");
2465  get_properties ().override_defaults (obj);
2466  }
2467 
2468  void build_user_defaults_map (property_list::pval_map_type& def,
2469  const std::string go_name) const;
2470 
2471  virtual void set_from_list (property_list& plist)
2472  {
2473  if (! valid_object ())
2474  error ("base_graphics_object::set_from_list: invalid graphics object");
2475 
2476  get_properties ().set_from_list (*this, plist);
2477  }
2478 
2479  virtual void set (const caseless_str& pname, const octave_value& pval)
2480  {
2481  if (! valid_object ())
2482  error ("base_graphics_object::set: invalid graphics object");
2483 
2484  get_properties ().set (pname, pval);
2485  }
2486 
2487  virtual void set_defaults (const std::string&)
2488  {
2489  error ("base_graphics_object::set_defaults: invalid graphics object");
2490  }
2491 
2492  // The following version of the get method is not declared virtual
2493  // because no derived class overrides it.
2494 
2495  octave_value get (bool all = false) const
2496  {
2497  if (! valid_object ())
2498  error ("base_graphics_object::get: invalid graphics object");
2499 
2500  return get_properties ().get (all);
2501  }
2502 
2503  virtual octave_value get (const caseless_str& pname) const
2504  {
2505  if (! valid_object ())
2506  error ("base_graphics_object::get: invalid graphics object");
2507 
2508  return get_properties ().get (pname);
2509  }
2510 
2511  virtual octave_value get_default (const caseless_str&) const;
2512 
2513  virtual octave_value get_factory_default (const caseless_str&) const;
2514 
2515  virtual octave_value get_defaults (void) const
2516  {
2517  error ("base_graphics_object::get_defaults: invalid graphics object");
2518  }
2519 
2520  virtual property_list get_defaults_list (void) const
2521  {
2522  if (! valid_object ())
2523  error ("base_graphics_object::get_defaults_list: invalid graphics object");
2524 
2525  return property_list ();
2526  }
2527 
2528  virtual octave_value get_factory_defaults (void) const
2529  {
2530  error ("base_graphics_object::get_factory_defaults: invalid graphics object");
2531  }
2532 
2533  virtual property_list get_factory_defaults_list (void) const
2534  {
2535  error ("base_graphics_object::get_factory_defaults_list: invalid graphics object");
2536  }
2537 
2538  virtual bool has_readonly_property (const caseless_str& pname) const
2539  {
2540  return base_properties::has_readonly_property (pname);
2541  }
2542 
2543  // FIXME: It seems like this function should be const, but that is
2544  // currently not possible.
2545  virtual std::string values_as_string (void);
2546 
2547  // FIXME: It seems like this function should be const, but that is
2548  // currently not possible.
2549  virtual std::string value_as_string (const std::string& prop);
2550 
2551  // FIXME: It seems like this function should be const, but that is
2552  // currently not possible.
2553  virtual octave_scalar_map values_as_struct (void);
2554 
2555  virtual graphics_handle get_parent (void) const
2556  {
2557  if (! valid_object ())
2558  error ("base_graphics_object::get_parent: invalid graphics object");
2559 
2560  return get_properties ().get_parent ();
2561  }
2562 
2563  graphics_handle get_handle (void) const
2564  {
2565  if (! valid_object ())
2566  error ("base_graphics_object::get_handle: invalid graphics object");
2567 
2568  return get_properties ().get___myhandle__ ();
2569  }
2570 
2571  virtual void remove_child (const graphics_handle& h, bool from_root = false)
2572  {
2573  if (! valid_object ())
2574  error ("base_graphics_object::remove_child: invalid graphics object");
2575 
2576  get_properties ().remove_child (h, from_root);
2577  }
2578 
2579  virtual void adopt (const graphics_handle& h)
2580  {
2581  if (! valid_object ())
2582  error ("base_graphics_object::adopt: invalid graphics object");
2583 
2584  get_properties ().adopt (h);
2585  }
2586 
2587  virtual void reparent (const graphics_handle& np)
2588  {
2589  if (! valid_object ())
2590  error ("base_graphics_object::reparent: invalid graphics object");
2591 
2592  get_properties ().reparent (np);
2593  }
2594 
2595  virtual void defaults (void) const
2596  {
2597  if (! valid_object ())
2598  error ("base_graphics_object::default: invalid graphics object");
2599 
2600  std::string msg = (type () + "::defaults");
2601  err_not_implemented (msg.c_str ());
2602  }
2603 
2604  virtual base_properties& get_properties (void)
2605  {
2606  static base_properties properties;
2607  warning ("base_graphics_object::get_properties: invalid graphics object");
2608  return properties;
2609  }
2610 
2611  virtual const base_properties& get_properties (void) const
2612  {
2613  static base_properties properties;
2614  warning ("base_graphics_object::get_properties: invalid graphics object");
2615  return properties;
2616  }
2617 
2618  virtual void update_axis_limits (const std::string& axis_type);
2619 
2620  virtual void update_axis_limits (const std::string& axis_type,
2621  const graphics_handle& h);
2622 
2623  virtual bool valid_object (void) const { return false; }
2624 
2625  bool valid_toolkit_object (void) const { return toolkit_flag; }
2626 
2627  virtual std::string type (void) const
2628  {
2629  return (valid_object () ? get_properties ().graphics_object_name ()
2630  : "unknown");
2631  }
2632 
2633  bool isa (const std::string& go_name) const
2634  {
2635  return type () == go_name;
2636  }
2637 
2638  virtual octave::graphics_toolkit get_toolkit (void) const
2639  {
2640  if (! valid_object ())
2641  error ("base_graphics_object::get_toolkit: invalid graphics object");
2642 
2643  return get_properties ().get_toolkit ();
2644  }
2645 
2646  virtual void add_property_listener (const std::string& nm,
2647  const octave_value& v,
2648  listener_mode mode = GCB_POSTSET)
2649  {
2650  if (valid_object ())
2651  get_properties ().add_listener (nm, v, mode);
2652  }
2653 
2654  virtual void delete_property_listener (const std::string& nm,
2655  const octave_value& v,
2656  listener_mode mode = GCB_POSTSET)
2657  {
2658  if (valid_object ())
2659  get_properties ().delete_listener (nm, v, mode);
2660  }
2661 
2662  virtual void remove_all_listeners (void);
2663 
2664  virtual void reset_default_properties (void);
2665 
2666 protected:
2667  virtual void initialize (const graphics_object& go)
2668  {
2669  if (! toolkit_flag)
2670  toolkit_flag = get_toolkit ().initialize (go);
2671  }
2672 
2673  virtual void finalize (const graphics_object& go)
2674  {
2675  if (toolkit_flag)
2676  {
2677  get_toolkit ().finalize (go);
2678  toolkit_flag = false;
2679  }
2680  }
2681 
2682  virtual void update (const graphics_object& go, int id)
2683  {
2684  if (toolkit_flag)
2685  get_toolkit ().update (go, id);
2686  }
2687 
2688 protected:
2689 
2690  // A flag telling whether this object is a valid object
2691  // in the backend context.
2692  bool toolkit_flag;
2693 };
2694 
2695 class OCTINTERP_API graphics_object
2696 {
2697 public:
2698 
2699  graphics_object (void) : rep (new base_graphics_object ()) { }
2700 
2701  graphics_object (base_graphics_object *new_rep) : rep (new_rep) { }
2702 
2703  graphics_object (const graphics_object&) = default;
2704 
2705  graphics_object& operator = (const graphics_object&) = default;
2706 
2707  ~graphics_object (void) = default;
2708 
2709  void mark_modified (void) { rep->mark_modified (); }
2710 
2711  void override_defaults (base_graphics_object& obj)
2712  {
2713  rep->override_defaults (obj);
2714  }
2715 
2716  void override_defaults (void)
2717  {
2718  rep->override_defaults (*rep);
2719  }
2720 
2721  void build_user_defaults_map (property_list::pval_map_type& def,
2722  const std::string go_name) const
2723  {
2724  rep->build_user_defaults_map (def, go_name);
2725  }
2726 
2727  void set_from_list (property_list& plist) { rep->set_from_list (plist); }
2728 
2729  void set (const caseless_str& name, const octave_value& val)
2730  {
2731  rep->set (name, val);
2732  }
2733 
2734  void set (const octave_value_list& args);
2735 
2736  void set (const Array<std::string>& names, const Cell& values,
2737  octave_idx_type row);
2738 
2739  void set (const octave_map& m);
2740 
2741  void set_value_or_default (const caseless_str& name,
2742  const octave_value& val);
2743 
2744  void set_defaults (const std::string& mode) { rep->set_defaults (mode); }
2745 
2746  octave_value get (bool all = false) const { return rep->get (all); }
2747 
2748  octave_value get (const caseless_str& name) const
2749  {
2750  return name.compare ("default")
2751  ? get_defaults ()
2752  : (name.compare ("factory")
2753  ? get_factory_defaults () : rep->get (name));
2754  }
2755 
2756  octave_value get (const std::string& name) const
2757  {
2758  return get (caseless_str (name));
2759  }
2760 
2761  octave_value get (const char *name) const
2762  {
2763  return get (caseless_str (name));
2764  }
2765 
2766  octave_value get_default (const caseless_str& name) const
2767  {
2768  return rep->get_default (name);
2769  }
2770 
2771  octave_value get_factory_default (const caseless_str& name) const
2772  {
2773  return rep->get_factory_default (name);
2774  }
2775 
2776  octave_value get_defaults (void) const { return rep->get_defaults (); }
2777 
2778  property_list get_defaults_list (void) const
2779  {
2780  return rep->get_defaults_list ();
2781  }
2782 
2783  octave_value get_factory_defaults (void) const
2784  {
2785  return rep->get_factory_defaults ();
2786  }
2787 
2788  property_list get_factory_defaults_list (void) const
2789  {
2790  return rep->get_factory_defaults_list ();
2791  }
2792 
2793  bool has_readonly_property (const caseless_str& pname) const
2794  {
2795  return rep->has_readonly_property (pname);
2796  }
2797 
2798  // FIXME: It seems like this function should be const, but that is
2799  // currently not possible.
2800  std::string values_as_string (void) { return rep->values_as_string (); }
2801 
2802  // FIXME: It seems like this function should be const, but that is
2803  // currently not possible.
2804  std::string value_as_string (const std::string& prop)
2805  {
2806  return rep->value_as_string (prop);
2807  }
2808 
2809  // FIXME: It seems like this function should be const, but that is
2810  // currently not possible.
2811  octave_map values_as_struct (void) { return rep->values_as_struct (); }
2812 
2813  graphics_handle get_parent (void) const { return rep->get_parent (); }
2814 
2815  graphics_handle get_handle (void) const { return rep->get_handle (); }
2816 
2817  graphics_object get_ancestor (const std::string& type) const;
2818 
2819  void remove_child (const graphics_handle& h) { rep->remove_child (h); }
2820 
2821  void adopt (const graphics_handle& h) { rep->adopt (h); }
2822 
2823  void reparent (const graphics_handle& h) { rep->reparent (h); }
2824 
2825  void defaults (void) const { rep->defaults (); }
2826 
2827  bool isa (const std::string& go_name) const { return rep->isa (go_name); }
2828 
2829  base_properties& get_properties (void) { return rep->get_properties (); }
2830 
2831  const base_properties& get_properties (void) const
2832  {
2833  return rep->get_properties ();
2834  }
2835 
2836  void update_axis_limits (const std::string& axis_type)
2837  {
2838  rep->update_axis_limits (axis_type);
2839  }
2840 
2841  void update_axis_limits (const std::string& axis_type,
2842  const graphics_handle& h)
2843  {
2844  rep->update_axis_limits (axis_type, h);
2845  }
2846 
2847  bool valid_object (void) const { return rep->valid_object (); }
2848 
2849  std::string type (void) const { return rep->type (); }
2850 
2851  operator bool (void) const { return rep->valid_object (); }
2852 
2853  // FIXME: These functions should be generated automatically by the
2854  // genprops.awk script.
2855  //
2856  // EMIT_GRAPHICS_OBJECT_GET_FUNCTIONS
2857 
2858  octave_value get_alim (void) const
2859  { return get_properties ().get_alim (); }
2860 
2861  octave_value get_clim (void) const
2862  { return get_properties ().get_clim (); }
2863 
2864  octave_value get_xlim (void) const
2865  { return get_properties ().get_xlim (); }
2866 
2867  octave_value get_ylim (void) const
2868  { return get_properties ().get_ylim (); }
2869 
2870  octave_value get_zlim (void) const
2871  { return get_properties ().get_zlim (); }
2872 
2873  bool is_aliminclude (void) const
2874  { return get_properties ().is_aliminclude (); }
2875 
2876  bool is_climinclude (void) const
2877  { return get_properties ().is_climinclude (); }
2878 
2879  bool is_xliminclude (void) const
2880  { return get_properties ().is_xliminclude (); }
2881 
2882  bool is_yliminclude (void) const
2883  { return get_properties ().is_yliminclude (); }
2884 
2885  bool is_zliminclude (void) const
2886  { return get_properties ().is_zliminclude (); }
2887 
2888  bool is_handle_visible (void) const
2889  { return get_properties ().is_handle_visible (); }
2890 
2891  octave::graphics_toolkit get_toolkit (void) const { return rep->get_toolkit (); }
2892 
2893  void add_property_listener (const std::string& nm, const octave_value& v,
2894  listener_mode mode = GCB_POSTSET)
2895  { rep->add_property_listener (nm, v, mode); }
2896 
2897  void delete_property_listener (const std::string& nm, const octave_value& v,
2898  listener_mode mode = GCB_POSTSET)
2899  { rep->delete_property_listener (nm, v, mode); }
2900 
2901  void remove_all_listeners (void) { rep->remove_all_listeners (); }
2902 
2903  void initialize (void) { rep->initialize (*this); }
2904 
2905  void finalize (void) { rep->finalize (*this); }
2906 
2907  void update (int id) { rep->update (*this, id); }
2908 
2909  void reset_default_properties (void)
2910  { rep->reset_default_properties (); }
2911 
2912 private:
2913 
2914  std::shared_ptr<base_graphics_object> rep;
2915 };
2916 
2917 // ---------------------------------------------------------------------
2918 
2919 class OCTINTERP_API root_figure : public base_graphics_object
2920 {
2921 public:
2922 
2923  // The gh_manager constructor creates the single instance of
2924  // the root_figure object.
2925 
2926  friend class gh_manager;
2927 
2928  class OCTINTERP_API properties : public base_properties
2929  {
2930  public:
2931  void remove_child (const graphics_handle& h, bool from_root = false);
2932 
2933  Matrix get_boundingbox (bool internal = false,
2934  const Matrix& parent_pix_size = Matrix ()) const;
2935 
2936  // See the genprops.awk script for an explanation of the
2937  // properties declarations.
2938 
2939  // FIXME: Properties that still don't have callbacks are:
2940  // monitorpositions, pointerlocation, pointerwindow.
2941  // Note that these properties are not yet used by Octave, so setting
2942  // them will have no effect.
2943 
2944  // FIXME: The commandwindowsize property has been deprecated in Matlab
2945  // and is now available through matlab.desktop.comandwindow.size.
2946  // Until Octave has something similar, keep this property in root.
2947 
2948  // Programming note: Keep property list sorted if new ones are added.
2949 
2950  BEGIN_PROPERTIES (root_figure, root)
2951  handle_property callbackobject Sr , graphics_handle ()
2952  array_property commandwindowsize r , Matrix (1, 2, 0)
2953  handle_property currentfigure S , graphics_handle ()
2954  string_property fixedwidthfontname , "Courier"
2955  array_property monitorpositions r , default_screensize ()
2956  array_property pointerlocation , Matrix (1, 2, 0)
2957  double_property pointerwindow r , 0.0
2958  double_property screendepth r , default_screendepth ()
2959  double_property screenpixelsperinch r , default_screenpixelsperinch ()
2960  array_property screensize r , default_screensize ()
2961  bool_property showhiddenhandles , "off"
2962  radio_property units U , "{pixels}|inches|centimeters|points|normalized|characters"
2963  // Hide base properties which don't make sense for root object
2964  //radio_property beingdeleted h , "{off}|on"
2965  END_PROPERTIES
2966  };
2967 
2968 private:
2969 
2970  properties xproperties;
2971 
2972 protected:
2973 
2974  root_figure (void)
2975  : xproperties (0, graphics_handle ()), default_properties (),
2976  factory_properties (init_factory_properties ())
2977  { }
2978 
2979 public:
2980 
2981  ~root_figure (void) = default;
2982 
2983  root_figure (const root_figure&) = delete;
2984 
2985  root_figure& operator = (const root_figure&) = delete;
2986 
2987  void mark_modified (void) { }
2988 
2989  void override_defaults (base_graphics_object& obj)
2990  {
2991  // Now override with our defaults. If the default_properties
2992  // list includes the properties for all defaults (line,
2993  // surface, etc.) then we don't have to know the type of OBJ
2994  // here, we just call its set function and let it decide which
2995  // properties from the list to use.
2996  obj.set_from_list (default_properties);
2997  }
2998 
2999  void set (const caseless_str& name, const octave_value& value)
3000  {
3001  if (name.compare ("default", 7))
3002  // strip "default", pass rest to function that will
3003  // parse the remainder and add the element to the
3004  // default_properties map.
3005  default_properties.set (name.substr (7), value);
3006  else
3007  xproperties.set (name, value);
3008  }
3009 
3010  octave_value get (const caseless_str& name) const
3011  {
3012  octave_value retval;
3013 
3014  if (name.compare ("default", 7))
3015  return get_default (name.substr (7));
3016  else if (name.compare ("factory", 7))
3017  return get_factory_default (name.substr (7));
3018  else
3019  retval = xproperties.get (name);
3020 
3021  return retval;
3022  }
3023 
3024  octave_value get_default (const caseless_str& name) const
3025  {
3026  octave_value retval = default_properties.lookup (name);
3027 
3028  if (retval.is_undefined ())
3029  {
3030  // no default property found, use factory default
3031  retval = factory_properties.lookup (name);
3032 
3033  if (retval.is_undefined ())
3034  error ("get: invalid default property '%s'", name.c_str ());
3035  }
3036 
3037  return retval;
3038  }
3039 
3040  octave_value get_factory_default (const caseless_str& name) const
3041  {
3042  octave_value retval = factory_properties.lookup (name);
3043 
3044  if (retval.is_undefined ())
3045  error ("get: invalid factory default property '%s'", name.c_str ());
3046 
3047  return retval;
3048  }
3049 
3050  octave_value get_defaults (void) const
3051  {
3052  return default_properties.as_struct ("default");
3053  }
3054 
3055  property_list get_defaults_list (void) const
3056  {
3057  return default_properties;
3058  }
3059 
3060  octave_value get_factory_defaults (void) const
3061  {
3062  return factory_properties.as_struct ("factory");
3063  }
3064 
3065  property_list get_factory_defaults_list (void) const
3066  {
3067  return factory_properties;
3068  }
3069 
3070  base_properties& get_properties (void) { return xproperties; }
3071 
3072  const base_properties& get_properties (void) const { return xproperties; }
3073 
3074  bool valid_object (void) const { return true; }
3075 
3076  void reset_default_properties (void);
3077 
3078  bool has_readonly_property (const caseless_str& pname) const
3079  {
3080  bool retval = xproperties.has_readonly_property (pname);
3081  if (! retval)
3082  retval = base_properties::has_readonly_property (pname);
3083  return retval;
3084  }
3085 
3086 private:
3087 
3088  property_list default_properties;
3089 
3090  property_list factory_properties;
3091 
3092  static property_list::plist_map_type init_factory_properties (void);
3093 };
3094 
3095 // ---------------------------------------------------------------------
3096 
3097 class OCTINTERP_API figure : public base_graphics_object
3098 {
3099 public:
3100  class OCTINTERP_API properties : public base_properties
3101  {
3102  public:
3103  void init_integerhandle (const octave_value& val)
3104  {
3105  integerhandle = val;
3106  }
3107 
3108  void remove_child (const graphics_handle& h, bool from_root = false);
3109 
3110  void set_visible (const octave_value& val);
3111 
3112  octave::graphics_toolkit get_toolkit (void) const;
3113 
3114  void set_toolkit (const octave::graphics_toolkit& b);
3115 
3116  void set___graphics_toolkit__ (const octave_value& val);
3117 
3118  void adopt (const graphics_handle& h);
3119 
3120  void set_position (const octave_value& val,
3121  bool do_notify_toolkit = true);
3122 
3123  void set_outerposition (const octave_value& val,
3124  bool do_notify_toolkit = true);
3125 
3126  Matrix bbox2position (const Matrix& bbox) const;
3127 
3128  Matrix get_boundingbox (bool internal = false,
3129  const Matrix& parent_pix_size = Matrix ()) const;
3130 
3131  void set_boundingbox (const Matrix& bb, bool internal = false,
3132  bool do_notify_toolkit = true);
3133 
3134  Matrix map_from_boundingbox (double x, double y) const;
3135 
3136  Matrix map_to_boundingbox (double x, double y) const;
3137 
3138  void update_units (const caseless_str& old_units);
3139 
3140  void update_paperunits (const caseless_str& old_paperunits);
3141 
3142  std::string get_title (void) const;
3143 
3144  // See the genprops.awk script for an explanation of the
3145  // properties declarations.
3146  // Programming note: Keep property list sorted if new ones are added.
3147 
3148  BEGIN_PROPERTIES (figure)
3149  array_property alphamap , Matrix (64, 1, 1)
3150  callback_property buttondownfcn , Matrix ()
3151  callback_property closerequestfcn , "closereq"
3152  color_property color , color_property (color_values (1, 1, 1), radio_values ("none"))
3153  array_property colormap , viridis_colormap ()
3154  handle_property currentaxes S , graphics_handle ()
3155  string_property currentcharacter r , ""
3156  handle_property currentobject r , graphics_handle ()
3157  array_property currentpoint r , Matrix (2, 1, 0)
3158  bool_property dockcontrols , "off"
3159  string_property filename , ""
3160  bool_property graphicssmoothing , "on"
3161  bool_property integerhandle S , "on"
3162  bool_property inverthardcopy , "on"
3163  callback_property keypressfcn , Matrix ()
3164  callback_property keyreleasefcn , Matrix ()
3165  radio_property menubar , "{figure}|none"
3166  string_property name , ""
3167  array_property number rG , Matrix ()
3168  radio_property nextplot , "{add}|new|replace|replacechildren"
3169  bool_property numbertitle , "on"
3170  array_property outerposition s , Matrix (1, 4, -1.0)
3171  radio_property paperorientation U , "{portrait}|landscape"
3172  array_property paperposition m , default_figure_paperposition ()
3173  // FIXME: Matlab default is "auto", but this messes up hgsave BIST test.
3174  radio_property paperpositionmode au , "{auto}|manual"
3175  array_property papersize U , default_figure_papersize ()
3176  radio_property papertype SU , "{usletter}|uslegal|a0|a1|a2|a3|a4|a5|b0|b1|b2|b3|b4|b5|arch-a|arch-b|arch-c|arch-d|arch-e|a|b|c|d|e|tabloid|<custom>"
3177  radio_property paperunits Su , "{inches}|centimeters|normalized|points"
3178  radio_property pointer , "crosshair|{arrow}|ibeam|watch|topl|topr|botl|botr|left|top|right|bottom|circle|cross|fleur|custom|hand"
3179  array_property pointershapecdata , Matrix (16, 16, 1)
3180  array_property pointershapehotspot , Matrix (1, 2, 1)
3181  array_property position s , default_figure_position ()
3182  radio_property renderer m , "{opengl}|painters"
3183  radio_property renderermode , "{auto}|manual"
3184  bool_property resize , "on"
3185  // FIXME: "resizefcn" is no longer recommended by Matlab,
3186  // and has been replaced with "sizechangedfcn"
3187  // Eventually this will need to be hidden, and then removed.
3188  callback_property resizefcn , Matrix ()
3189  radio_property selectiontype , "{normal}|extend|alt|open"
3190  callback_property sizechangedfcn , Matrix ()
3191  radio_property toolbar , "{auto}|figure|none"
3192  radio_property units Su , "{pixels}|normalized|inches|centimeters|points|characters"
3193  callback_property windowbuttondownfcn , Matrix ()
3194  callback_property windowbuttonmotionfcn , Matrix ()
3195  callback_property windowbuttonupfcn , Matrix ()
3196  callback_property windowkeypressfcn , Matrix ()
3197  callback_property windowkeyreleasefcn , Matrix ()
3198  callback_property windowscrollwheelfcn , Matrix ()
3199  radio_property windowstyle , "{normal}|modal|docked"
3200 
3201  // Overridden base property
3202  // Property is not implemented for figures.
3203  // Hide it and set it to a default value that works.
3204  radio_property pickableparts h , "{visible}"
3205 
3206  // Octave-specific properties
3207  mutable string_property __gl_extensions__ hr , ""
3208  mutable string_property __gl_renderer__ hr , ""
3209  mutable string_property __gl_vendor__ hr , ""
3210  mutable string_property __gl_version__ hr , ""
3211  bool_property __gl_window__ h , "off"
3212  string_property __graphics_toolkit__ hs , default_graphics_toolkit ()
3213  any_property __guidata__ h , Matrix ()
3214  radio_property __mouse_mode__ hS , "{none}|pan|rotate|select|text|zoom"
3215  bool_property __printing__ h , "off"
3216  any_property __pan_mode__ h , Matrix ()
3217  any_property __plot_stream__ h , Matrix ()
3218  any_property __rotate_mode__ h , Matrix ()
3219  any_property __zoom_mode__ h , Matrix ()
3220  double_property __device_pixel_ratio__ hU , 1.0
3221 
3222  END_PROPERTIES
3223 
3224  protected:
3225  void init (void)
3226  {
3227  alphamap.add_constraint (dim_vector (-1, 1));
3228  colormap.add_constraint (dim_vector (-1, 3));
3229  colormap.add_constraint (dim_vector (0, 0));
3230  outerposition.add_constraint (dim_vector (1, 4));
3231  outerposition.add_constraint (FINITE);
3232  paperposition.add_constraint (dim_vector (1, 4));
3233  paperposition.add_constraint (FINITE);
3234  papersize.add_constraint (dim_vector (1, 2));
3235  papersize.add_constraint (FINITE);
3236  pointershapecdata.add_constraint (dim_vector (16, 16));
3237  pointershapecdata.add_constraint (dim_vector (32, 32));
3238  pointershapehotspot.add_constraint (dim_vector (1, 2));
3239  position.add_constraint (dim_vector (1, 4));
3240  position.add_constraint (FINITE);
3241 
3242  init_toolkit ();
3243  }
3244 
3245  private:
3246  Matrix get_auto_paperposition (void);
3247 
3248  void update_paperpositionmode (void)
3249  {
3250  if (paperpositionmode.is ("auto"))
3251  paperposition.set (get_auto_paperposition ());
3252  }
3253 
3254  void update_handlevisibility (void);
3255 
3256  void init_toolkit (void);
3257 
3258  octave::graphics_toolkit toolkit;
3259  };
3260 
3261 private:
3262  properties xproperties;
3263 
3264 public:
3265  figure (const graphics_handle& mh, const graphics_handle& p)
3266  : base_graphics_object (), xproperties (mh, p), default_properties ()
3267  { }
3268 
3269  ~figure (void) = default;
3270 
3271  void override_defaults (base_graphics_object& obj)
3272  {
3273  // Allow parent (root object) to override first (properties knows how
3274  // to find the parent object).
3275  xproperties.override_defaults (obj);
3276 
3277  // Now override with our defaults. If the default_properties
3278  // list includes the properties for all defaults (line,
3279  // surface, etc.) then we don't have to know the type of OBJ
3280  // here, we just call its set function and let it decide which
3281  // properties from the list to use.
3282  obj.set_from_list (default_properties);
3283  }
3284 
3285  void set (const caseless_str& name, const octave_value& value)
3286  {
3287  if (name.compare ("default", 7))
3288  // strip "default", pass rest to function that will
3289  // parse the remainder and add the element to the
3290  // default_properties map.
3291  default_properties.set (name.substr (7), value);
3292  else
3293  xproperties.set (name, value);
3294  }
3295 
3296  octave_value get (const caseless_str& name) const
3297  {
3298  octave_value retval;
3299 
3300  if (name.compare ("default", 7))
3301  retval = get_default (name.substr (7));
3302  else
3303  retval = xproperties.get (name);
3304 
3305  return retval;
3306  }
3307 
3308  octave_value get_default (const caseless_str& name) const;
3309 
3310  octave_value get_defaults (void) const
3311  {
3312  return default_properties.as_struct ("default");
3313  }
3314 
3315  property_list get_defaults_list (void) const
3316  {
3317  return default_properties;
3318  }
3319 
3320  base_properties& get_properties (void) { return xproperties; }
3321 
3322  const base_properties& get_properties (void) const { return xproperties; }
3323 
3324  bool valid_object (void) const { return true; }
3325 
3326  void reset_default_properties (void);
3327 
3328  bool has_readonly_property (const caseless_str& pname) const
3329  {
3330  bool retval = xproperties.has_readonly_property (pname);
3331  if (! retval)
3332  retval = base_properties::has_readonly_property (pname);
3333  return retval;
3334  }
3335 
3336 private:
3337  property_list default_properties;
3338 };
3339 
3340 // ---------------------------------------------------------------------
3341 
3342 class OCTINTERP_API graphics_xform
3343 {
3344 public:
3345  graphics_xform (void)
3346  : xform (xform_eye ()), xform_inv (xform_eye ()),
3347  sx ("linear"), sy ("linear"), sz ("linear"), zlim (1, 2, 0.0)
3348  {
3349  zlim(1) = 1.0;
3350  }
3351 
3352  graphics_xform (const Matrix& xm, const Matrix& xim,
3353  const scaler& x, const scaler& y, const scaler& z,
3354  const Matrix& zl)
3355  : xform (xm), xform_inv (xim), sx (x), sy (y), sz (z), zlim (zl) { }
3356 
3357  graphics_xform (const graphics_xform& g)
3358  : xform (g.xform), xform_inv (g.xform_inv), sx (g.sx),
3359  sy (g.sy), sz (g.sz), zlim (g.zlim) { }
3360 
3361  ~graphics_xform (void) = default;
3362 
3363  graphics_xform& operator = (const graphics_xform& g)
3364  {
3365  xform = g.xform;
3366  xform_inv = g.xform_inv;
3367  sx = g.sx;
3368  sy = g.sy;
3369  sz = g.sz;
3370  zlim = g.zlim;
3371 
3372  return *this;
3373  }
3374 
3375  static ColumnVector xform_vector (double x, double y, double z);
3376 
3377  static Matrix xform_eye (void);
3378 
3379  ColumnVector transform (double x, double y, double z,
3380  bool use_scale = true) const;
3381 
3382  ColumnVector untransform (double x, double y, double z,
3383  bool use_scale = true) const;
3384 
3385  ColumnVector untransform (double x, double y, bool use_scale = true) const
3386  { return untransform (x, y, (zlim(0)+zlim(1))/2, use_scale); }
3387 
3388  Matrix xscale (const Matrix& m) const { return sx.scale (m); }
3389  Matrix yscale (const Matrix& m) const { return sy.scale (m); }
3390  Matrix zscale (const Matrix& m) const { return sz.scale (m); }
3391 
3392  Matrix scale (const Matrix& m) const
3393  {
3394  bool has_z = (m.columns () > 2);
3395 
3396  if (sx.is_linear () && sy.is_linear ()
3397  && (! has_z || sz.is_linear ()))
3398  return m;
3399 
3400  Matrix retval (m.dims ());
3401 
3402  int r = m.rows ();
3403 
3404  for (int i = 0; i < r; i++)
3405  {
3406  retval(i,0) = sx.scale (m(i,0));
3407  retval(i,1) = sy.scale (m(i,1));
3408  if (has_z)
3409  retval(i,2) = sz.scale (m(i,2));
3410  }
3411 
3412  return retval;
3413  }
3414 
3415 private:
3416  Matrix xform;
3417  Matrix xform_inv;
3418  scaler sx, sy, sz;
3419  Matrix zlim;
3420 };
3421 
3422 enum
3423 {
3424  AXE_ANY_DIR = 0,
3425  AXE_DEPTH_DIR = 1,
3426  AXE_HORZ_DIR = 2,
3427  AXE_VERT_DIR = 3
3428 };
3429 
3430 class OCTINTERP_API axes : public base_graphics_object
3431 {
3432 public:
3433  class OCTINTERP_API properties : public base_properties
3434  {
3435  public:
3436  void set_defaults (base_graphics_object& obj, const std::string& mode);
3437 
3438  void remove_child (const graphics_handle& h, bool from_root = false);
3439 
3440  void adopt (const graphics_handle& h);
3441 
3442  const scaler& get_x_scaler (void) const { return sx; }
3443  const scaler& get_y_scaler (void) const { return sy; }
3444  const scaler& get_z_scaler (void) const { return sz; }
3445 
3446  Matrix get_boundingbox (bool internal = false,
3447  const Matrix& parent_pix_size = Matrix ()) const;
3448  Matrix get_extent (bool with_text = false,
3449  bool only_text_height=false) const;
3450 
3451  double get___fontsize_points__ (double box_pix_height = 0) const;
3452 
3453  void update_boundingbox (void)
3454  {
3455  if (units_is ("normalized"))
3456  {
3457  sync_positions ();
3458  base_properties::update_boundingbox ();
3459  }
3460  }
3461 
3462  void update_camera (void);
3463  void update_axes_layout (void);
3464  void update_aspectratios (void);
3465  void update_transform (void)
3466  {
3467  update_aspectratios ();
3468  update_camera ();
3469  update_axes_layout ();
3470  }
3471 
3472  void sync_positions (void);
3473 
3474  void update_autopos (const std::string& elem_type);
3475  void update_xlabel_position (void);
3476  void update_ylabel_position (void);
3477  void update_zlabel_position (void);
3478  void update_title_position (void);
3479 
3480  graphics_xform get_transform (void) const
3481  { return graphics_xform (x_render, x_render_inv, sx, sy, sz, x_zlim); }
3482 
3483  Matrix get_transform_matrix (void) const { return x_render; }
3484  Matrix get_inverse_transform_matrix (void) const { return x_render_inv; }
3485  Matrix get_opengl_matrix_1 (void) const { return x_gl_mat1; }
3486  Matrix get_opengl_matrix_2 (void) const { return x_gl_mat2; }
3487  Matrix get_transform_zlim (void) const { return x_zlim; }
3488 
3489  int get_xstate (void) const { return xstate; }
3490  int get_ystate (void) const { return ystate; }
3491  int get_zstate (void) const { return zstate; }
3492  double get_xPlane (void) const { return xPlane; }
3493  double get_xPlaneN (void) const { return xPlaneN; }
3494  double get_yPlane (void) const { return yPlane; }
3495  double get_yPlaneN (void) const { return yPlaneN; }
3496  double get_zPlane (void) const { return zPlane; }
3497  double get_zPlaneN (void) const { return zPlaneN; }
3498  double get_xpTick (void) const { return xpTick; }
3499  double get_xpTickN (void) const { return xpTickN; }
3500  double get_ypTick (void) const { return ypTick; }
3501  double get_ypTickN (void) const { return ypTickN; }
3502  double get_zpTick (void) const { return zpTick; }
3503  double get_zpTickN (void) const { return zpTickN; }
3504  double get_x_min (void) const { return std::min (xPlane, xPlaneN); }
3505  double get_x_max (void) const { return std::max (xPlane, xPlaneN); }
3506  double get_y_min (void) const { return std::min (yPlane, yPlaneN); }
3507  double get_y_max (void) const { return std::max (yPlane, yPlaneN); }
3508  double get_z_min (void) const { return std::min (zPlane, zPlaneN); }
3509  double get_z_max (void) const { return std::max (zPlane, zPlaneN); }
3510  double get_fx (void) const { return fx; }
3511  double get_fy (void) const { return fy; }
3512  double get_fz (void) const { return fz; }
3513  double get_xticklen (void) const { return xticklen; }
3514  double get_yticklen (void) const { return yticklen; }
3515  double get_zticklen (void) const { return zticklen; }
3516  double get_xtickoffset (void) const { return xtickoffset; }
3517  double get_ytickoffset (void) const { return ytickoffset; }
3518  double get_ztickoffset (void) const { return ztickoffset; }
3519  bool get_x2Dtop (void) const { return x2Dtop; }
3520  bool get_y2Dright (void) const { return y2Dright; }
3521  bool get_layer2Dtop (void) const { return layer2Dtop; }
3522  bool get_is2D (bool include_kids = false) const
3523  { return (include_kids ? (is2D && ! has3Dkids) : is2D); }
3524  void set_has3Dkids (bool val) { has3Dkids = val; }
3525  bool get_xySym (void) const { return xySym; }
3526  bool get_xyzSym (void) const { return xyzSym; }
3527  bool get_zSign (void) const { return zSign; }
3528  bool get_nearhoriz (void) const { return nearhoriz; }
3529 
3530  ColumnVector pixel2coord (double px, double py) const
3531  { return get_transform ().untransform (px, py, (x_zlim(0)+x_zlim(1))/2); }
3532 
3533  ColumnVector coord2pixel (double x, double y, double z) const
3534  { return get_transform ().transform (x, y, z); }
3535 
3536  void zoom_about_point (const std::string& mode, double x, double y,
3537  double factor, bool push_to_zoom_stack = true);
3538  void zoom (const std::string& mode, double factor,
3539  bool push_to_zoom_stack = true);
3540  void zoom (const std::string& mode, const Matrix& xl, const Matrix& yl,
3541  bool push_to_zoom_stack = true);
3542 
3543  void translate_view (const std::string& mode,
3544  double x0, double x1, double y0, double y1,
3545  bool push_to_zoom_stack = true);
3546 
3547  void pan (const std::string& mode, double factor,
3548  bool push_to_zoom_stack = true);
3549 
3550  void rotate3d (double x0, double x1, double y0, double y1,
3551  bool push_to_zoom_stack = true);
3552 
3553  void rotate_view (double delta_az, double delta_el,
3554  bool push_to_zoom_stack = true);
3555 
3556  void unzoom (void);
3557  void update_handlevisibility (void);
3558  void push_zoom_stack (void);
3559  void clear_zoom_stack (bool do_unzoom = true);
3560 
3561  void update_units (const caseless_str& old_units);
3562 
3563  void update_font (std::string prop = "");
3564 
3565  void update_fontunits (const caseless_str& old_fontunits);
3566 
3567  void increase_num_lights (void) { num_lights++; }
3568  void decrease_num_lights (void) { num_lights--; }
3569  unsigned int get_num_lights (void) const { return num_lights; }
3570 
3571  private:
3572 
3573  scaler sx = scaler ();
3574  scaler sy = scaler ();
3575  scaler sz = scaler ();
3576 
3577  Matrix x_render = Matrix ();
3578  Matrix x_render_inv = Matrix ();
3579  Matrix x_gl_mat1 = Matrix ();
3580  Matrix x_gl_mat2 = Matrix ();
3581  Matrix x_zlim = Matrix ();
3582 
3583  std::list<octave_value> zoom_stack = std::list<octave_value> ();
3584 
3585  // Axes layout data
3586  int xstate = 0;
3587  int ystate = 0;
3588  int zstate = 0;
3589 
3590  double xPlane = 0.0;
3591  double yPlane = 0.0;
3592  double zPlane = 0.0;
3593 
3594  double xPlaneN = 0.0;
3595  double yPlaneN = 0.0;
3596  double zPlaneN = 0.0;
3597 
3598  double xpTick = 0.0;
3599  double ypTick = 0.0;
3600  double zpTick = 0.0;
3601 
3602  double xpTickN = 0.0;
3603  double ypTickN = 0.0;
3604  double zpTickN = 0.0;
3605 
3606  double fx = 0.0;
3607  double fy = 0.0;
3608  double fz = 0.0;
3609 
3610  double xticklen = 0.0;
3611  double yticklen = 0.0;
3612  double zticklen = 0.0;
3613 
3614  double xtickoffset = 0.0;
3615  double ytickoffset = 0.0;
3616  double ztickoffset = 0.0;
3617 
3618  bool x2Dtop = false;
3619  bool y2Dright = false;
3620  bool layer2Dtop = false;
3621  bool is2D = false;
3622  bool has3Dkids = false;
3623  bool xySym = false;
3624  bool xyzSym = false;
3625  bool zSign = false;
3626  bool nearhoriz = false;
3627 
3628  unsigned int num_lights = 0;
3629 
3630  // Text renderer, used for calculation of text (tick labels) size
3631  octave::text_renderer txt_renderer;
3632 
3633  void set_text_child (handle_property& h, const std::string& who,
3634  const octave_value& v);
3635 
3636  void delete_text_child (handle_property& h, bool from_root = false);
3637 
3638  // See the genprops.awk script for an explanation of the
3639  // properties declarations.
3640  // Programming note: Keep property list sorted if new ones are added.
3641 
3642  BEGIN_PROPERTIES (axes)
3643  radio_property activepositionproperty , "{outerposition}|position"
3644  row_vector_property alim m , default_lim ()
3645  radio_property alimmode , "{auto}|manual"
3646  color_property ambientlightcolor , color_values (1, 1, 1)
3647  bool_property box u , "off"
3648  radio_property boxstyle , "{back}|full"
3649  row_vector_property cameraposition mu , Matrix (1, 3, 0.0)
3650  radio_property camerapositionmode u , "{auto}|manual"
3651  row_vector_property cameratarget mu , Matrix (1, 3, 0.0)
3652  radio_property cameratargetmode u , "{auto}|manual"
3653  row_vector_property cameraupvector mu , Matrix (1, 3, 0.0)
3654  radio_property cameraupvectormode u , "{auto}|manual"
3655  double_property cameraviewangle mu , 6.6086
3656  radio_property cameraviewanglemode u , "{auto}|manual"
3657  row_vector_property clim m , default_lim ()
3658  radio_property climmode al , "{auto}|manual"
3659  radio_property clippingstyle , "{3dbox}|rectangle"
3660  color_property color , color_property (color_values (1, 1, 1), radio_values ("none"))
3661  array_property colormap sg , Matrix ()
3662  array_property colororder , default_colororder ()
3663  double_property colororderindex , 1.0
3664  array_property currentpoint , Matrix (2, 3, 0.0)
3665  row_vector_property dataaspectratio mu , Matrix (1, 3, 1.0)
3666  radio_property dataaspectratiomode u , "{auto}|manual"
3667  radio_property fontangle u , "{normal}|italic"
3668  string_property fontname u , OCTAVE_DEFAULT_FONTNAME
3669  double_property fontsize u , 10
3670  bool_property fontsmoothing u , "on"
3671  radio_property fontunits SU , "{points}|inches|centimeters|normalized|pixels"
3672  radio_property fontweight u , "{normal}|bold"
3673  double_property gridalpha m , 0.15
3674  radio_property gridalphamode , "{auto}|manual"
3675  color_property gridcolor m , color_property (color_values (0.15, 0.15, 0.15), radio_values ("none"))
3676  radio_property gridcolormode , "{auto}|manual"
3677  radio_property gridlinestyle , "{-}|--|:|-.|none"
3678  double_property labelfontsizemultiplier u , 1.1
3679  radio_property layer u , "{bottom}|top"
3680  // FIXME: should be kind of string array.
3681  any_property linestyleorder S , "-"
3682  double_property linestyleorderindex , 1.0
3683  double_property linewidth , 0.5
3684  double_property minorgridalpha m , 0.25
3685  radio_property minorgridalphamode , "{auto}|manual"
3686  color_property minorgridcolor m , color_property (color_values (0.1, 0.1, 0.1), radio_values ("none"))
3687  radio_property minorgridcolormode , "{auto}|manual"
3688  radio_property minorgridlinestyle , "{:}|-|--|-.|none"
3689  radio_property nextplot , "{replace}|add|replacechildren"
3690  array_property outerposition u , default_axes_outerposition ()
3691  row_vector_property plotboxaspectratio mu , Matrix (1, 3, 1.0)
3692  radio_property plotboxaspectratiomode u , "{auto}|manual"
3693  array_property position u , default_axes_position ()
3694  radio_property projection , "{orthographic}|perspective"
3695  radio_property sortmethod , "{depth}|childorder"
3696  radio_property tickdir mu , "{in}|out"
3697  radio_property tickdirmode u , "{auto}|manual"
3698  // FIXME: Added recently to Matlab, should replace interpreter property.
3699  radio_property ticklabelinterpreter u , "{tex}|latex|none"
3700  array_property ticklength u , default_axes_ticklength ()
3701  array_property tightinset r , Matrix (1, 4, 0.0)
3702  handle_property title SOf , make_graphics_handle ("text", __myhandle__, false, false, false)
3703  double_property titlefontsizemultiplier u , 1.1
3704  radio_property titlefontweight u , "{bold}|normal"
3705  // FIXME: uicontextmenu should be moved here.
3706  radio_property units SU , "{normalized}|inches|centimeters|points|pixels|characters"
3707  array_property view u , default_axes_view ()
3708  radio_property xaxislocation u , "{bottom}|top|origin"
3709  color_property xcolor mu , color_property (color_values (0.15, 0.15, 0.15), radio_values ("none"))
3710  radio_property xcolormode , "{auto}|manual"
3711  radio_property xdir u , "{normal}|reverse"
3712  bool_property xgrid , "off"
3713  handle_property xlabel SOf , make_graphics_handle ("text", __myhandle__, false, false, false)
3714  row_vector_property xlim mu , default_lim ()
3715  radio_property xlimmode al , "{auto}|manual"
3716  bool_property xminorgrid , "off"
3717  bool_property xminortick , "off"
3718  radio_property xscale alu , "{linear}|log"
3719  row_vector_property xtick mu , default_axes_tick ()
3720  // FIXME: should be kind of string array.
3721  any_property xticklabel S , ""
3722  radio_property xticklabelmode u , "{auto}|manual"
3723  double_property xticklabelrotation , 0.0
3724  radio_property xtickmode u , "{auto}|manual"
3725  radio_property yaxislocation u , "{left}|right|origin"
3726  color_property ycolor mu , color_property (color_values (0.15, 0.15, 0.15), radio_values ("none"))
3727  radio_property ycolormode , "{auto}|manual"
3728  radio_property ydir u , "{normal}|reverse"
3729  bool_property ygrid , "off"
3730  handle_property ylabel SOf , make_graphics_handle ("text", __myhandle__, false, false, false)
3731  row_vector_property ylim mu , default_lim ()
3732  radio_property ylimmode al , "{auto}|manual"
3733  bool_property yminorgrid , "off"
3734  bool_property yminortick , "off"
3735  radio_property yscale alu , "{linear}|log"
3736  row_vector_property ytick mu , default_axes_tick ()
3737  any_property yticklabel S , ""
3738  radio_property yticklabelmode u , "{auto}|manual"
3739  double_property yticklabelrotation , 0.0
3740  radio_property ytickmode u , "{auto}|manual"
3741  color_property zcolor mu , color_property (color_values (0.15, 0.15, 0.15), radio_values ("none"))
3742  radio_property zcolormode , "{auto}|manual"
3743  radio_property zdir u , "{normal}|reverse"
3744  bool_property zgrid , "off"
3745  handle_property zlabel SOf , make_graphics_handle ("text", __myhandle__, false, false, false)
3746  row_vector_property zlim mu , default_lim ()
3747  radio_property zlimmode al , "{auto}|manual"
3748  bool_property zminorgrid , "off"
3749  bool_property zminortick , "off"
3750  radio_property zscale alu , "{linear}|log"
3751  row_vector_property ztick mu , default_axes_tick ()
3752  any_property zticklabel S , ""
3753  radio_property zticklabelmode u , "{auto}|manual"
3754  double_property zticklabelrotation , 0.0
3755  radio_property ztickmode u , "{auto}|manual"
3756 
3757  // Octave-specific properties
3758  array_property __colormap__ hu , Matrix ()
3759  double_property mousewheelzoom , 0.5
3760 
3761  // hidden properties for alignment of subplots
3762  radio_property __autopos_tag__ h , "{none}|subplot"
3763  // hidden properties for inset
3764  array_property looseinset hu , Matrix (1, 4, 0.0)
3765  // hidden properties for minor ticks
3766  row_vector_property xminortickvalues h , Matrix ()
3767  row_vector_property yminortickvalues h , Matrix ()
3768  row_vector_property zminortickvalues h , Matrix ()
3769  // hidden property for text rendering
3770  double_property __fontsize_points__ hgr , 0
3771  END_PROPERTIES
3772 
3773  protected:
3774  void init (void);
3775 
3776  private:
3777 
3778  std::string
3779  get_scale (const std::string& scale, const Matrix& lims)
3780  {
3781  std::string retval = scale;
3782 
3783  if (scale == "log" && lims.numel () > 1 && lims(0) < 0 && lims(1) < 0)
3784  retval = "neglog";
3785 
3786  return retval;
3787  }
3788 
3789  void update_xscale (void)
3790  {
3791  sx = get_scale (get_xscale (), xlim.get ().matrix_value ());
3792  }
3793 
3794  void update_yscale (void)
3795  {
3796  sy = get_scale (get_yscale (), ylim.get ().matrix_value ());
3797  }
3798 
3799  void update_zscale (void)
3800  {
3801  sz = get_scale (get_zscale (), zlim.get ().matrix_value ());
3802  }
3803 
3804  void update_label_color (handle_property label, color_property col);
3805  void update_xcolor (void)
3806  { update_label_color (xlabel, xcolor); }
3807 
3808  void update_ycolor (void)
3809  { update_label_color (ylabel, ycolor); }
3810 
3811  void update_zcolor (void)
3812  { update_label_color (zlabel, zcolor); }
3813 
3814  void update_view (void) { sync_positions (); }
3815 
3816  void update_cameraposition (void) { update_transform (); }
3817  void update_cameratarget (void) { update_transform (); }
3818  void update_cameraupvector (void) { update_transform (); }
3819  void update_cameraviewangle (void) { update_transform (); }
3820 
3821  void update_camerapositionmode (void)
3822  {
3823  if (camerapositionmode_is ("auto"))
3824  update_cameraposition ();
3825  }
3826  void update_cameratargetmode (void)
3827  {
3828  if (cameratargetmode_is ("auto"))
3829  update_cameratarget ();
3830  }
3831  void update_cameraupvectormode (void)
3832  {
3833  if (cameraupvectormode_is ("auto"))
3834  update_cameraupvector ();
3835  }
3836  void update_cameraviewanglemode (void)
3837  {
3838  if (cameraviewanglemode_is ("auto"))
3839  update_cameraviewangle ();
3840  }
3841 
3842  void update_dataaspectratio (void) { sync_positions (); }
3843  void update_dataaspectratiomode (void) { sync_positions (); }
3844  void update_plotboxaspectratio (void) { sync_positions (); }
3845  void update_plotboxaspectratiomode (void) { sync_positions (); }
3846 
3847  void update_layer (void) { update_axes_layout (); }
3848  void update_box (void)
3849  {
3850  if (xticklabelmode.is ("auto"))
3851  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
3852  xaxislocation_is ("origin"),
3853  yscale.is ("log") ? 2 :
3854  (yaxislocation_is ("origin") ? 0 :
3855  (yaxislocation_is ("left") ? -1 : 1)),
3856  xlim);
3857  if (yticklabelmode.is ("auto"))
3858  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
3859  yaxislocation_is ("origin"),
3860  xscale.is ("log") ? 2 :
3861  (xaxislocation_is ("origin") ? 0 :
3862  (xaxislocation_is ("bottom") ? -1 : 1)),
3863  ylim);
3864  }
3865  void update_yaxislocation (void)
3866  {
3867  sync_positions ();
3868  update_axes_layout ();
3869  if (xticklabelmode.is ("auto"))
3870  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
3871  xaxislocation_is ("origin"),
3872  yscale.is ("log") ? 2 :
3873  (yaxislocation_is ("origin") ? 0 :
3874  (yaxislocation_is ("left") ? -1 : 1)),
3875  xlim);
3876  if (yticklabelmode.is ("auto"))
3877  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
3878  yaxislocation_is ("origin"),
3879  xscale.is ("log") ? 2 :
3880  (xaxislocation_is ("origin") ? 0 :
3881  (xaxislocation_is ("bottom") ? -1 : 1)),
3882  ylim);
3883  update_ylabel_position ();
3884  }
3885  void update_xaxislocation (void)
3886  {
3887  sync_positions ();
3888  update_axes_layout ();
3889  if (xticklabelmode.is ("auto"))
3890  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
3891  xaxislocation_is ("origin"),
3892  yscale.is ("log") ? 2 :
3893  (yaxislocation_is ("origin") ? 0 :
3894  (yaxislocation_is ("left") ? -1 : 1)),
3895  xlim);
3896  if (yticklabelmode.is ("auto"))
3897  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
3898  yaxislocation_is ("origin"),
3899  xscale.is ("log") ? 2 :
3900  (xaxislocation_is ("origin") ? 0 :
3901  (xaxislocation_is ("bottom") ? -1 : 1)),
3902  ylim);
3903  update_xlabel_position ();
3904  }
3905 
3906  void update_xdir (void) { update_camera (); update_axes_layout (); }
3907  void update_ydir (void) { update_camera (); update_axes_layout (); }
3908  void update_zdir (void) { update_camera (); update_axes_layout (); }
3909 
3910  void update_ticklength (void);
3911  void update_tickdir (void) { update_ticklength (); }
3912  void update_tickdirmode (void) { update_ticklength (); }
3913 
3914  void update_ticklabelinterpreter (void)
3915  {
3916  update_xtick ();
3917  update_ytick ();
3918  update_ztick ();
3919  }
3920 
3921  void update_xtick (void)
3922  {
3923  calc_ticks_and_lims (xlim, xtick, xminortickvalues, xlimmode.is ("auto"),
3924  xtickmode.is ("auto"), xscale.is ("log"));
3925  if (xticklabelmode.is ("auto"))
3926  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
3927  xaxislocation_is ("origin"),
3928  yscale.is ("log") ? 2 :
3929  (yaxislocation_is ("origin") ? 0 :
3930  (yaxislocation_is ("left") ? -1 : 1)),
3931  xlim);
3932  sync_positions ();
3933  }
3934  void update_ytick (void)
3935  {
3936  calc_ticks_and_lims (ylim, ytick, yminortickvalues, ylimmode.is ("auto"),
3937  ytickmode.is ("auto"), yscale.is ("log"));
3938  if (yticklabelmode.is ("auto"))
3939  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
3940  yaxislocation_is ("origin"),
3941  xscale.is ("log") ? 2 :
3942  (xaxislocation_is ("origin") ? 0 :
3943  (xaxislocation_is ("bottom") ? -1 : 1)),
3944  ylim);
3945  sync_positions ();
3946  }
3947  void update_ztick (void)
3948  {
3949  calc_ticks_and_lims (zlim, ztick, zminortickvalues, zlimmode.is ("auto"),
3950  ztickmode.is ("auto"), zscale.is ("log"));
3951  if (zticklabelmode.is ("auto"))
3952  calc_ticklabels (ztick, zticklabel, zscale.is ("log"), false, 2, zlim);
3953  sync_positions ();
3954  }
3955 
3956  void update_xtickmode (void)
3957  {
3958  if (xtickmode.is ("auto"))
3959  update_xtick ();
3960  }
3961  void update_ytickmode (void)
3962  {
3963  if (ytickmode.is ("auto"))
3964  update_ytick ();
3965  }
3966  void update_ztickmode (void)
3967  {
3968  if (ztickmode.is ("auto"))
3969  update_ztick ();
3970  }
3971 
3972  void update_xticklabelmode (void)
3973  {
3974  if (xticklabelmode.is ("auto"))
3975  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
3976  xaxislocation_is ("origin"),
3977  yscale.is ("log") ? 2 :
3978  (yaxislocation_is ("origin") ? 0 :
3979  (yaxislocation_is ("left") ? -1 : 1)),
3980  xlim);
3981  }
3982  void update_yticklabelmode (void)
3983  {
3984  if (yticklabelmode.is ("auto"))
3985  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
3986  yaxislocation_is ("origin"),
3987  xscale.is ("log") ? 2 :
3988  (xaxislocation_is ("origin") ? 0 :
3989  (xaxislocation_is ("bottom") ? -1 : 1)),
3990  ylim);
3991  }
3992  void update_zticklabelmode (void)
3993  {
3994  if (zticklabelmode.is ("auto"))
3995  calc_ticklabels (ztick, zticklabel, zscale.is ("log"), false, 2, zlim);
3996  }
3997 
3998  void update_fontname (void)
3999  {
4000  update_font ("fontname");
4001  sync_positions ();
4002  }
4003  void update_fontsize (void)
4004  {
4005  update_font ("fontsize");
4006  sync_positions ();
4007  }
4008  void update_fontsmoothing (void)
4009  {
4010  update_font ("fontsmoothing");
4011  }
4012  void update_fontangle (void)
4013  {
4014  update_font ("fontangle");
4015  sync_positions ();
4016  }
4017  void update_fontweight (void)
4018  {
4019  update_font ("fontweight");
4020  sync_positions ();
4021  }
4022 
4023  void update_titlefontsizemultiplier (void)
4024  {
4025  // update_font handles title and axis labels
4026  update_font ("fontsize");
4027  sync_positions ();
4028  }
4029 
4030  void update_labelfontsizemultiplier (void)
4031  {
4032  update_font ("fontsize");
4033  sync_positions ();
4034  }
4035 
4036  void update_titlefontweight (void)
4037  {
4038  // update_font handles title and axis labels
4039  update_font ("fontweight");
4040  sync_positions ();
4041  }
4042 
4043  void update_outerposition (void);
4044  void update_position (void);
4045  void update_looseinset (void);
4046 
4047  double calc_tick_sep (double minval, double maxval);
4048  void calc_ticks_and_lims (array_property& lims, array_property& ticks,
4049  array_property& mticks, bool limmode_is_auto,
4050  bool tickmode_is_auto, bool is_logscale);
4051  void calc_ticklabels (const array_property& ticks, any_property& labels,
4052  bool is_logscale, const bool is_origin,
4053  const int other_axislocation,
4054  const array_property& axis_lims);
4055  Matrix get_ticklabel_extents (const Matrix& ticks,
4056  const string_vector& ticklabels,
4057  const Matrix& limits);
4058 
4059  void fix_limits (array_property& lims)
4060  {
4061  if (lims.get ().isempty ())
4062  return;
4063 
4064  Matrix l = lims.get ().matrix_value ();
4065  if (l(0) > l(1))
4066  {
4067  l(0) = 0;
4068  l(1) = 1;
4069  lims = l;
4070  }
4071  else if (l(0) == l(1))
4072  {
4073  l(0) -= 0.5;
4074  l(1) += 0.5;
4075  lims = l;
4076  }
4077  }
4078 
4079  Matrix calc_tightbox (const Matrix& init_pos);
4080 
4081  void set_colormap (const octave_value& val)
4082  {
4083  set___colormap__ (val);
4084  }
4085 
4086  void update___colormap__ (void)
4087  {
4088  colormap.run_listeners (GCB_POSTSET);
4089  }
4090 
4091  octave_value get_colormap (void) const;
4092 
4093  public:
4094  Matrix get_axis_limits (double xmin, double xmax,
4095  double min_pos, double max_neg,
4096  const bool logscale);
4097 
4098  void check_axis_limits (Matrix &limits, const Matrix kids,
4099  const bool logscale, char &update_type);
4100 
4101  void update_xlim ()
4102  {
4103  update_axis_limits ("xlim");
4104 
4105  calc_ticks_and_lims (xlim, xtick, xminortickvalues, xlimmode.is ("auto"),
4106  xtickmode.is ("auto"), xscale.is ("log"));
4107  if (xticklabelmode.is ("auto"))
4108  calc_ticklabels (xtick, xticklabel, xscale.is ("log"),
4109  xaxislocation.is ("origin"),
4110  yscale.is ("log") ? 2 :
4111  (yaxislocation_is ("origin") ? 0 :
4112  (yaxislocation_is ("left") ? -1 : 1)),
4113  xlim);
4114 
4115  fix_limits (xlim);
4116 
4117  update_xscale ();
4118 
4119  update_axes_layout ();
4120  }
4121 
4122  void update_ylim (void)
4123  {
4124  update_axis_limits ("ylim");
4125 
4126  calc_ticks_and_lims (ylim, ytick, yminortickvalues, ylimmode.is ("auto"),
4127  ytickmode.is ("auto"), yscale.is ("log"));
4128  if (yticklabelmode.is ("auto"))
4129  calc_ticklabels (ytick, yticklabel, yscale.is ("log"),
4130  yaxislocation_is ("origin"),
4131  xscale.is ("log") ? 2 :
4132  (xaxislocation_is ("origin") ? 0 :
4133  (xaxislocation_is ("bottom") ? -1 : 1)),
4134  ylim);
4135 
4136  fix_limits (ylim);
4137 
4138  update_yscale ();
4139 
4140  update_axes_layout ();
4141  }
4142 
4143  void update_zlim (void)
4144  {
4145  update_axis_limits ("zlim");
4146 
4147  calc_ticks_and_lims (zlim, ztick, zminortickvalues, zlimmode.is ("auto"),
4148  ztickmode.is ("auto"), zscale.is ("log"));
4149  if (zticklabelmode.is ("auto"))
4150  calc_ticklabels (ztick, zticklabel, zscale.is ("log"), false, 2, zlim);
4151 
4152  fix_limits (zlim);
4153 
4154  update_zscale ();
4155 
4156  update_axes_layout ();
4157  }
4158 
4159  void trigger_normals_calc (void);
4160 
4161  };
4162 
4163 private:
4164  properties xproperties;
4165 
4166 public:
4167  axes (const graphics_handle& mh, const graphics_handle& p)
4168  : base_graphics_object (), xproperties (mh, p), default_properties ()
4169  {
4170  xproperties.update_transform ();
4171  }
4172 
4173  ~axes (void) = default;
4174 
4175  void override_defaults (base_graphics_object& obj)
4176  {
4177  // Allow parent (figure) to override first (properties knows how
4178  // to find the parent object).
4179  xproperties.override_defaults (obj);
4180 
4181  // Now override with our defaults. If the default_properties
4182  // list includes the properties for all defaults (line,
4183  // surface, etc.) then we don't have to know the type of OBJ
4184  // here, we just call its set function and let it decide which
4185  // properties from the list to use.
4186  obj.set_from_list (default_properties);
4187  }
4188 
4189  void set (const caseless_str& name, const octave_value& value)
4190  {
4191  if (name.compare ("default", 7))
4192  // strip "default", pass rest to function that will
4193  // parse the remainder and add the element to the
4194  // default_properties map.
4195  default_properties.set (name.substr (7), value);
4196  else
4197  xproperties.set (name, value);
4198  }
4199 
4200  void set_defaults (const std::string& mode)
4201  {
4202  xproperties.set_defaults (*this, mode);
4203  }
4204 
4205  octave_value get (const caseless_str& name) const
4206  {
4207  octave_value retval;
4208 
4209  // FIXME: finish this.
4210  if (name.compare ("default", 7))
4211  retval = get_default (name.substr (7));
4212  else
4213  retval = xproperties.get (name);
4214 
4215  return retval;
4216  }
4217 
4218  octave_value get_default (const caseless_str& name) const;
4219 
4220  octave_value get_defaults (void) const
4221  {
4222  return default_properties.as_struct ("default");
4223  }
4224 
4225  property_list get_defaults_list (void) const
4226  {
4227  return default_properties;
4228  }
4229 
4230  base_properties& get_properties (void) { return xproperties; }
4231 
4232  const base_properties& get_properties (void) const { return xproperties; }
4233 
4234  void update_axis_limits (const std::string& axis_type);
4235 
4236  void update_axis_limits (const std::string& axis_type,
4237  const graphics_handle& h);
4238 
4239  bool valid_object (void) const { return true; }
4240 
4241  void reset_default_properties (void);
4242 
4243  bool has_readonly_property (const caseless_str& pname) const
4244  {
4245  bool retval = xproperties.has_readonly_property (pname);
4246  if (! retval)
4247  retval = base_properties::has_readonly_property (pname);
4248  return retval;
4249  }
4250 
4251 protected:
4252  void initialize (const graphics_object& go);
4253 
4254 private:
4255  property_list default_properties;
4256 };
4257 
4258 // ---------------------------------------------------------------------
4259 
4260 class OCTINTERP_API line : public base_graphics_object
4261 {
4262 public:
4263  class OCTINTERP_API properties : public base_properties
4264  {
4265  public:
4266  // See the genprops.awk script for an explanation of the
4267  // properties declarations.
4268  // Programming note: Keep property list sorted if new ones are added.
4269 
4270  BEGIN_PROPERTIES (line)
4271  color_property color , color_property (color_values (0, 0, 0), radio_values ("none"))
4272  string_property displayname , ""
4273  radio_property linejoin , "{round}|miter|chamfer"
4274  radio_property linestyle , "{-}|--|:|-.|none"
4275  double_property linewidth , 0.5
4276  radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram"
4277  color_property markeredgecolor , color_property (radio_values ("{auto}|none"), color_values (0, 0, 0))
4278  color_property markerfacecolor , color_property (radio_values ("auto|{none}"), color_values (0, 0, 0))
4279  double_property markersize , 6
4280  row_vector_property xdata u , default_data ()
4281  string_property xdatasource , ""
4282  row_vector_property ydata u , default_data ()
4283  string_property ydatasource , ""
4284  row_vector_property zdata u , Matrix ()
4285  string_property zdatasource , ""
4286 
4287  // hidden properties for limit computation
4288  row_vector_property xlim hlr , default_data_lim ()
4289  row_vector_property ylim hlr , default_data_lim ()
4290  row_vector_property zlim hlr , Matrix ()
4291  bool_property xliminclude hl , "on"
4292  bool_property yliminclude hl , "on"
4293  bool_property zliminclude hl , "on"
4294  END_PROPERTIES
4295 
4296  protected:
4297  void init (void)
4298  {
4299  linewidth.add_constraint ("min", 0, false);
4300  markersize.add_constraint ("min", 0, false);
4301  }
4302 
4303  private:
4304  Matrix compute_xlim (void) const;
4305  Matrix compute_ylim (void) const;
4306 
4307  void update_xdata (void) { set_xlim (compute_xlim ()); }
4308 
4309  void update_ydata (void) { set_ylim (compute_ylim ()); }
4310 
4311  void update_zdata (void) { set_zlim (zdata.get_limits ()); }
4312  };
4313 
4314 private:
4315  properties xproperties;
4316 
4317 public:
4318  line (const graphics_handle& mh, const graphics_handle& p)
4319  : base_graphics_object (), xproperties (mh, p)
4320  { }
4321 
4322  ~line (void) = default;
4323 
4324  base_properties& get_properties (void) { return xproperties; }
4325 
4326  const base_properties& get_properties (void) const { return xproperties; }
4327 
4328  bool valid_object (void) const { return true; }
4329 
4330  bool has_readonly_property (const caseless_str& pname) const
4331  {
4332  bool retval = xproperties.has_readonly_property (pname);
4333  if (! retval)
4334  retval = base_properties::has_readonly_property (pname);
4335  return retval;
4336  }
4337 };
4338 
4339 // ---------------------------------------------------------------------
4340 
4341 class OCTINTERP_API text : public base_graphics_object
4342 {
4343 public:
4344  class OCTINTERP_API properties : public base_properties
4345  {
4346  public:
4347  double get___fontsize_points__ (double box_pix_height = 0) const;
4348 
4349  void update_text_extent (void);
4350 
4351  void update_font (void);
4352 
4353  void set_position (const octave_value& val)
4354  {
4355  octave_value new_val (val);
4356 
4357  if (new_val.numel () == 2)
4358  {
4359  dim_vector dv (1, 3);
4360 
4361  new_val = new_val.resize (dv, true);
4362  }
4363 
4364  if (position.set (new_val, false))
4365  {
4366  set_positionmode ("manual");
4367  update_position ();
4368  position.run_listeners (GCB_POSTSET);
4369  mark_modified ();
4370  }
4371  else
4372  set_positionmode ("manual");
4373  }
4374 
4375  // See the genprops.awk script for an explanation of the
4376  // properties declarations.
4377  // Programming note: Keep property list sorted if new ones are added.
4378 
4379  BEGIN_PROPERTIES (text)
4380  color_property backgroundcolor , color_property (radio_values ("{none}"), color_values (1, 1, 1))
4381  color_property color u , color_property (color_values (0, 0, 0), radio_values ("none"))
4382  color_property edgecolor , color_property (radio_values ("{none}"), color_values (0, 0, 0))
4383  bool_property editing , "off"
4384  array_property extent rG , Matrix (1, 4, 0.0)
4385  // FIXME: DEPRECATED: Remove "oblique" in version 7.
4386  radio_property fontangle u , "{normal}|italic|oblique"
4387  string_property fontname u , OCTAVE_DEFAULT_FONTNAME
4388  double_property fontsize u , 10
4389  bool_property fontsmoothing u , "on"
4390  radio_property fontunits SU , "inches|centimeters|normalized|{points}|pixels"
4391  radio_property fontweight u , "{normal}|bold"
4392  radio_property horizontalalignment mu , "{left}|center|right"
4393  radio_property interpreter u , "{tex}|none|latex"
4394  radio_property linestyle , "{-}|--|:|-.|none"
4395  double_property linewidth , 0.5
4396  double_property margin , 3
4397  array_property position smu , Matrix (1, 3, 0.0)
4398  double_property rotation mu , 0
4399  text_label_property string u , ""
4400  radio_property units u , "{data}|pixels|normalized|inches|centimeters|points"
4401  radio_property verticalalignment mu , "top|cap|{middle}|baseline|bottom"
4402 
4403  // hidden properties for limit computation
4404  row_vector_property xlim hlr , Matrix ()
4405  row_vector_property ylim hlr , Matrix ()
4406  row_vector_property zlim hlr , Matrix ()
4407  bool_property xliminclude hl , "off"
4408  bool_property yliminclude hl , "off"
4409  bool_property zliminclude hl , "off"
4410  // hidden properties for auto-positioning
4411  radio_property positionmode hu , "{auto}|manual"
4412  radio_property rotationmode hu , "{auto}|manual"
4413  radio_property horizontalalignmentmode hu , "{auto}|manual"
4414  radio_property verticalalignmentmode hu , "{auto}|manual"
4415  radio_property __autopos_tag__ h , "{none}|xlabel|ylabel|zlabel|title"
4416  // hidden property for text rendering
4417  double_property __fontsize_points__ hgr , 0
4418  END_PROPERTIES
4419 
4420  Matrix get_data_position (void) const;
4421  Matrix get_extent_matrix (void) const;
4422  const uint8NDArray& get_pixels (void) const { return pixels; }
4423 
4424  // Text renderer, used for calculation of text size
4425  octave::text_renderer txt_renderer;
4426 
4427  protected:
4428  void init (void)
4429  {
4430  position.add_constraint (dim_vector (1, 3));
4431  fontsize.add_constraint ("min", 0.0, false);
4432  linewidth.add_constraint ("min", 0.0, false);
4433  margin.add_constraint ("min", 0.0, false);
4434  cached_units = get_units ();
4435  update_font ();
4436  }
4437 
4438  private:
4439  void update_position (void)
4440  {
4441  Matrix pos = get_data_position ();
4442  Matrix lim;
4443 
4444  lim = Matrix (1, 4, pos(0));
4445  lim(2) = (lim(2) <= 0 ? octave::numeric_limits<double>::Inf () : lim(2));
4446  lim(3) = (lim(3) >= 0 ? -octave::numeric_limits<double>::Inf () : lim(3));
4447  set_xlim (lim);
4448 
4449  lim = Matrix (1, 4, pos(1));
4450  lim(2) = (lim(2) <= 0 ? octave::numeric_limits<double>::Inf () : lim(2));
4451  lim(3) = (lim(3) >= 0 ? -octave::numeric_limits<double>::Inf () : lim(3));
4452  set_ylim (lim);
4453 
4454  if (pos.numel () == 3)
4455  {
4456  lim = Matrix (1, 4, pos(2));
4457  lim(2) = (lim(2) <= 0 ? octave::numeric_limits<double>::Inf ()
4458  : lim(2));
4459  lim(3) = (lim(3) >= 0 ? -octave::numeric_limits<double>::Inf ()
4460  : lim(3));
4461  set_zliminclude ("on");
4462  set_zlim (lim);
4463  }
4464  else
4465  set_zliminclude ("off");
4466  }
4467 
4468  void request_autopos (void);
4469  void update_positionmode (void) { request_autopos (); }
4470  void update_rotationmode (void) { request_autopos (); }
4471  void update_horizontalalignmentmode (void) { request_autopos (); }
4472  void update_verticalalignmentmode (void) { request_autopos (); }
4473 
4474  void update_string (void) { request_autopos (); update_text_extent (); }
4475  void update_rotation (void) { update_text_extent (); }
4476  void update_fontname (void) { update_font (); update_text_extent (); }
4477  void update_fontsize (void) { update_font (); update_text_extent (); }
4478  void update_fontsmoothing (void) { update_font (); update_text_extent (); }
4479 
4480  void update_color (void)
4481  {
4482  if (! color.is ("none"))
4483  {
4484  update_font ();
4485  update_text_extent ();
4486  }
4487  }
4488 
4489  void update_fontangle (void)
4490  {
4491  update_font ();
4492  update_text_extent ();
4493  // FIXME: DEPRECATED: Remove warning for "oblique" in version 7.
4494  if (fontangle.is ("oblique"))
4495  warning_with_id ("Octave:deprecated-property",
4496  "Setting 'fontangle' to '%s' is deprecated, \
4497 use 'italic' or 'normal'.", fontangle.current_value ().c_str ());
4498  }
4499  void update_fontweight (void) { update_font (); update_text_extent (); }
4500 
4501  void update_interpreter (void) { update_text_extent (); }
4502  void update_horizontalalignment (void) { update_text_extent (); }
4503  void update_verticalalignment (void) { update_text_extent (); }
4504 
4505  void update_units (void);
4506  void update_fontunits (const caseless_str& old_fontunits);
4507 
4508  private:
4509  std::string cached_units;
4510  uint8NDArray pixels;
4511  };
4512 
4513 private:
4514  properties xproperties;
4515 
4516 public:
4517  text (const graphics_handle& mh, const graphics_handle& p)
4518  : base_graphics_object (), xproperties (mh, p)
4519  {
4520  xproperties.set_clipping ("off");
4521  }
4522 
4523  ~text (void) = default;
4524 
4525  base_properties& get_properties (void) { return xproperties; }
4526 
4527  const base_properties& get_properties (void) const { return xproperties; }
4528 
4529  bool valid_object (void) const { return true; }
4530 
4531  bool has_readonly_property (const caseless_str& pname) const
4532  {
4533  bool retval = xproperties.has_readonly_property (pname);
4534  if (! retval)
4535  retval = base_properties::has_readonly_property (pname);
4536  return retval;
4537  }
4538 };
4539 
4540 // ---------------------------------------------------------------------
4541 
4542 class OCTINTERP_API image : public base_graphics_object
4543 {
4544 public:
4545  class OCTINTERP_API properties : public base_properties
4546  {
4547  public:
4548  bool is_aliminclude (void) const
4549  { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
4550  std::string get_aliminclude (void) const
4551  { return aliminclude.current_value (); }
4552 
4553  bool is_climinclude (void) const
4554  { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
4555  std::string get_climinclude (void) const
4556  { return climinclude.current_value (); }
4557 
4558  octave_value get_color_data (void) const;
4559 
4560  void initialize_data (void) { update_cdata (); }
4561 
4562  // See the genprops.awk script for an explanation of the
4563  // properties declarations.
4564  // Programming note: Keep property list sorted if new ones are added.
4565 
4566  BEGIN_PROPERTIES (image)
4567  array_property alphadata u , Matrix (1, 1, 1.0)
4568  radio_property alphadatamapping al , "{none}|direct|scaled"
4569  array_property cdata u , default_image_cdata ()
4570  radio_property cdatamapping al , "scaled|{direct}"
4571  row_vector_property xdata mu , Matrix ()
4572  row_vector_property ydata mu , Matrix ()
4573  // hidden properties for limit computation
4574  row_vector_property alim hlr , Matrix ()
4575  row_vector_property clim hlr , Matrix ()
4576  row_vector_property xlim hlr , Matrix ()
4577  row_vector_property ylim hlr , Matrix ()
4578  bool_property aliminclude hlg , "on"
4579  bool_property climinclude hlg , "on"
4580  bool_property xliminclude hl , "on"
4581  bool_property yliminclude hl , "on"
4582  radio_property xdatamode ha , "{auto}|manual"
4583  radio_property ydatamode ha , "{auto}|manual"
4584  END_PROPERTIES
4585 
4586  protected:
4587  void init (void)
4588  {
4589  xdata.add_constraint (2);
4590  xdata.add_constraint (dim_vector (0, 0));
4591  ydata.add_constraint (2);
4592  ydata.add_constraint (dim_vector (0, 0));
4593  cdata.add_constraint ("double");
4594  cdata.add_constraint ("single");
4595  cdata.add_constraint ("logical");
4596  cdata.add_constraint ("int8");
4597  cdata.add_constraint ("int16");
4598  cdata.add_constraint ("int32");
4599  cdata.add_constraint ("int64");
4600  cdata.add_constraint ("uint8");
4601  cdata.add_constraint ("uint16");
4602  cdata.add_constraint ("uint32");
4603  cdata.add_constraint ("uint64");
4604  cdata.add_constraint ("real");
4605  cdata.add_constraint (dim_vector (-1, -1));
4606  cdata.add_constraint (dim_vector (-1, -1, 3));
4607  alphadata.add_constraint ("double");
4608  alphadata.add_constraint ("uint8");
4609  alphadata.add_constraint (dim_vector (-1, -1));
4610  }
4611 
4612  private:
4613  void update_alphadata (void)
4614  {
4615  if (alphadatamapping_is ("scaled"))
4616  set_alim (alphadata.get_limits ());
4617  else
4618  alim = alphadata.get_limits ();
4619  }
4620 
4621  void update_cdata (void)
4622  {
4623  if (cdatamapping_is ("scaled"))
4624  set_clim (cdata.get_limits ());
4625  else
4626  clim = cdata.get_limits ();
4627 
4628  if (xdatamode.is ("auto"))
4629  update_xdata ();
4630 
4631  if (ydatamode.is ("auto"))
4632  update_ydata ();
4633  }
4634 
4635  void update_xdata (void)
4636  {
4637  if (xdata.get ().isempty ())
4638  set_xdatamode ("auto");
4639 
4640  if (xdatamode.is ("auto"))
4641  {
4642  set_xdata (get_auto_xdata ());
4643  set_xdatamode ("auto");
4644  }
4645 
4646  Matrix limits = xdata.get_limits ();
4647  float dp = pixel_xsize ();
4648 
4649  limits(0) = limits(0) - dp;
4650  limits(1) = limits(1) + dp;
4651  set_xlim (limits);
4652  }
4653 
4654  void update_ydata (void)
4655  {
4656  if (ydata.get ().isempty ())
4657  set_ydatamode ("auto");
4658 
4659  if (ydatamode.is ("auto"))
4660  {
4661  set_ydata (get_auto_ydata ());
4662  set_ydatamode ("auto");
4663  }
4664 
4665  Matrix limits = ydata.get_limits ();
4666  float dp = pixel_ysize ();
4667 
4668  limits(0) = limits(0) - dp;
4669  limits(1) = limits(1) + dp;
4670  set_ylim (limits);
4671  }
4672 
4673  Matrix get_auto_xdata (void)
4674  {
4675  dim_vector dv = get_cdata ().dims ();
4676  Matrix data;
4677  if (dv(1) > 0.)
4678  {
4679  data = Matrix (1, 2, 1);
4680  data(1) = dv(1);
4681  }
4682  return data;
4683  }
4684 
4685  Matrix get_auto_ydata (void)
4686  {
4687  dim_vector dv = get_cdata ().dims ();
4688  Matrix data;
4689  if (dv(0) > 0.)
4690  {
4691  data = Matrix (1, 2, 1);
4692  data(1) = dv(0);
4693  }
4694  return data;
4695  }
4696 
4697  float pixel_size (octave_idx_type dim, const Matrix limits)
4698  {
4699  octave_idx_type l = dim - 1;
4700  float dp;
4701 
4702  if (l > 0 && limits(0) != limits(1))
4703  dp = (limits(1) - limits(0))/(2*l);
4704  else
4705  {
4706  if (limits(1) == limits(2))
4707  dp = 0.5;
4708  else
4709  dp = (limits(1) - limits(0))/2;
4710  }
4711  return dp;
4712  }
4713 
4714  public:
4715  float pixel_xsize (void)
4716  {
4717  return pixel_size ((get_cdata ().dims ())(1), xdata.get_limits ());
4718  }
4719 
4720  float pixel_ysize (void)
4721  {
4722  return pixel_size ((get_cdata ().dims ())(0), ydata.get_limits ());
4723  }
4724  };
4725 
4726 private:
4727  properties xproperties;
4728 
4729 public:
4730  image (const graphics_handle& mh, const graphics_handle& p)
4731  : base_graphics_object (), xproperties (mh, p)
4732  {
4733  xproperties.initialize_data ();
4734  }
4735 
4736  ~image (void) = default;
4737 
4738  base_properties& get_properties (void) { return xproperties; }
4739 
4740  const base_properties& get_properties (void) const { return xproperties; }
4741 
4742  bool valid_object (void) const { return true; }
4743 
4744  bool has_readonly_property (const caseless_str& pname) const
4745  {
4746  bool retval = xproperties.has_readonly_property (pname);
4747  if (! retval)
4748  retval = base_properties::has_readonly_property (pname);
4749  return retval;
4750  }
4751 };
4752 
4753 // ---------------------------------------------------------------------
4754 
4755 class OCTINTERP_API light : public base_graphics_object
4756 {
4757 public:
4758  class OCTINTERP_API properties : public base_properties
4759  {
4760  // See the genprops.awk script for an explanation of the
4761  // properties declarations.
4762  // Programming note: Keep property list sorted if new ones are added.
4763 
4764  BEGIN_PROPERTIES (light)
4765  color_property color , color_values (1, 1, 1)
4766  array_property position , default_light_position ()
4767  radio_property style , "{infinite}|local"
4768  END_PROPERTIES
4769 
4770  protected:
4771  void init (void)
4772  {
4773  position.add_constraint (dim_vector (1, 3));
4774  }
4775 
4776  private:
4777  void update_visible (void);
4778  };
4779 
4780 private:
4781  properties xproperties;
4782 
4783 public:
4784  light (const graphics_handle& mh, const graphics_handle& p)
4785  : base_graphics_object (), xproperties (mh, p)
4786  { }
4787 
4788  ~light (void) = default;
4789 
4790  base_properties& get_properties (void) { return xproperties; }
4791 
4792  const base_properties& get_properties (void) const { return xproperties; }
4793 
4794  bool valid_object (void) const { return true; }
4795 
4796  bool has_readonly_property (const caseless_str& pname) const
4797  {
4798  bool retval = xproperties.has_readonly_property (pname);
4799  if (! retval)
4800  retval = base_properties::has_readonly_property (pname);
4801  return retval;
4802  }
4803 
4804 protected:
4805  void initialize (const graphics_object& go);
4806 };
4807 
4808 // ---------------------------------------------------------------------
4809 
4810 class OCTINTERP_API patch : public base_graphics_object
4811 {
4812 public:
4813  class OCTINTERP_API properties : public base_properties
4814  {
4815  public:
4816  octave_value get_color_data (void) const;
4817 
4818  // Matlab allows incoherent data to be stored into patch properties.
4819  // The patch should then be ignored by the renderer.
4820  bool has_bad_data (std::string& msg) const
4821  {
4822  msg = bad_data_msg;
4823  return ! msg.empty ();
4824  }
4825 
4826  bool is_aliminclude (void) const
4827  { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
4828  std::string get_aliminclude (void) const
4829  { return aliminclude.current_value (); }
4830 
4831  bool is_climinclude (void) const
4832  { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
4833  std::string get_climinclude (void) const
4834  { return climinclude.current_value (); }
4835 
4836  bool get_do_lighting (void) const;
4837 
4838  std::vector<std::vector<octave_idx_type>> coplanar_last_idx;
4839 
4840  // See the genprops.awk script for an explanation of the
4841  // properties declarations.
4842  // Programming note: Keep property list sorted if new ones are added.
4843 
4844  BEGIN_PROPERTIES (patch)
4845  radio_property alphadatamapping l , "none|{scaled}|direct"
4846  double_property ambientstrength , 0.3
4847  radio_property backfacelighting , "unlit|lit|{reverselit}"
4848  array_property cdata u , Matrix ()
4849  radio_property cdatamapping l , "{scaled}|direct"
4850  double_property diffusestrength , 0.6
4851  string_property displayname , ""
4852  double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp"))
4853  color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp"))
4854  radio_property edgelighting u , "{none}|flat|gouraud|phong"
4855  double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp"))
4856  color_property facecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp"))
4857  radio_property facelighting u , "none|{flat}|gouraud|phong"
4858  array_property facenormals m , Matrix ()
4859  radio_property facenormalsmode u , "{auto}|manual"
4860  array_property faces u , default_patch_faces ()
4861  array_property facevertexalphadata , Matrix ()
4862  array_property facevertexcdata u , Matrix ()
4863  radio_property linestyle , "{-}|--|:|-.|none"
4864  double_property linewidth , 0.5
4865  radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram"
4866  color_property markeredgecolor , color_property (radio_values ("none|{auto}|flat"), color_values (0, 0, 0))
4867  color_property markerfacecolor , color_property (radio_values ("{none}|auto|flat"), color_values (0, 0, 0))
4868  double_property markersize , 6
4869  double_property specularcolorreflectance , 1.0
4870  double_property specularexponent , 10.0
4871  double_property specularstrength , 0.9
4872  array_property vertexnormals m , Matrix ()
4873  radio_property vertexnormalsmode u , "{auto}|manual"
4874  array_property vertices u , default_patch_vertices ()
4875  array_property xdata u , default_patch_xdata ()
4876  array_property ydata u , default_patch_ydata ()
4877  array_property zdata u , Matrix ()
4878 
4879  // hidden properties for limit computation
4880  row_vector_property alim hlr , Matrix ()
4881  row_vector_property clim hlr , Matrix ()
4882  row_vector_property xlim hlr , Matrix ()
4883  row_vector_property ylim hlr , Matrix ()
4884  row_vector_property zlim hlr , Matrix ()
4885  bool_property aliminclude hlg , "on"
4886  bool_property climinclude hlg , "on"
4887  bool_property xliminclude hl , "on"
4888  bool_property yliminclude hl , "on"
4889  bool_property zliminclude hl , "on"
4890  END_PROPERTIES
4891 
4892  protected:
4893  void init (void)
4894  {
4895  xdata.add_constraint (dim_vector (-1, -1));
4896  ydata.add_constraint (dim_vector (-1, -1));
4897  zdata.add_constraint (dim_vector (-1, -1));
4898  faces.add_constraint (dim_vector (-1, -1));
4899  vertices.add_constraint (dim_vector (-1, 2));
4900  vertices.add_constraint (dim_vector (-1, 3));
4901  cdata.add_constraint ("double");
4902  cdata.add_constraint ("single");
4903  cdata.add_constraint ("logical");
4904  cdata.add_constraint ("int8");
4905  cdata.add_constraint ("int16");
4906  cdata.add_constraint ("int32");
4907  cdata.add_constraint ("int64");
4908  cdata.add_constraint ("uint8");
4909  cdata.add_constraint ("uint16");
4910  cdata.add_constraint ("uint32");
4911  cdata.add_constraint ("uint64");
4912  cdata.add_constraint ("real");
4913  cdata.add_constraint (dim_vector (-1, -1));
4914  cdata.add_constraint (dim_vector (-1, -1, 3));
4915  facevertexcdata.add_constraint (dim_vector (-1, 1));
4916  facevertexcdata.add_constraint (dim_vector (-1, 3));
4917  facevertexcdata.add_constraint (dim_vector (0, 0));
4918  facevertexalphadata.add_constraint (dim_vector (-1, 1));
4919  facevertexalphadata.add_constraint (dim_vector (0, 0));
4920  facenormals.add_constraint (dim_vector (-1, 3));
4921  facenormals.add_constraint (dim_vector (0, 0));
4922  vertexnormals.add_constraint (dim_vector (-1, 3));
4923  vertexnormals.add_constraint (dim_vector (0, 0));
4924 
4925  ambientstrength.add_constraint ("min", 0.0, true);
4926  ambientstrength.add_constraint ("max", 1.0, true);
4927  diffusestrength.add_constraint ("min", 0.0, true);
4928  diffusestrength.add_constraint ("max", 1.0, true);
4929  linewidth.add_constraint ("min", 0.0, false);
4930  markersize.add_constraint ("min", 0.0, false);
4931  specularcolorreflectance.add_constraint ("min", 0.0, true);
4932  specularcolorreflectance.add_constraint ("max", 1.0, true);
4933  specularexponent.add_constraint ("min", 0.0, false);
4934  specularstrength.add_constraint ("min", 0.0, true);
4935  specularstrength.add_constraint ("max", 1.0, true);
4936  }
4937 
4938  public:
4939  void update_normals (bool reset, bool force = false)
4940  {
4941  update_face_normals (reset, force);
4942  update_vertex_normals (reset, force);
4943  }
4944 
4945 
4946  private:
4947  std::string bad_data_msg;
4948 
4949  void update_faces (void) { update_data ();}
4950 
4951  void update_vertices (void) { update_data ();}
4952 
4953  void update_facevertexcdata (void) { update_data ();}
4954 
4955  void update_fvc (void);
4956 
4957  void update_xdata (void)
4958  {
4959  if (get_xdata ().isempty ())
4960  {
4961  // For compatibility with matlab behavior,
4962  // if x/ydata are set empty, silently empty other *data and
4963  // faces properties while vertices remain unchanged.
4964  set_ydata (Matrix ());
4965  set_zdata (Matrix ());
4966  set_cdata (Matrix ());
4967  set_faces (Matrix ());
4968  }
4969  else
4970  {
4971  update_fvc ();
4972  update_normals (true);
4973  }
4974 
4975  set_xlim (xdata.get_limits ());
4976  }
4977 
4978  void update_ydata (void)
4979  {
4980  if (get_ydata ().isempty ())
4981  {
4982  set_xdata (Matrix ());
4983  set_zdata (Matrix ());
4984  set_cdata (Matrix ());
4985  set_faces (Matrix ());
4986  }
4987  else
4988  {
4989  update_fvc ();
4990  update_normals (true);
4991  }
4992 
4993  set_ylim (ydata.get_limits ());
4994  }
4995 
4996  void update_zdata (void)
4997  {
4998  update_fvc ();
4999  update_normals (true);
5000  set_zlim (zdata.get_limits ());
5001  }
5002 
5003  void update_cdata (void)
5004  {
5005  update_fvc ();
5006  update_normals (false);
5007 
5008  if (cdatamapping_is ("scaled"))
5009  set_clim (cdata.get_limits ());
5010  else
5011  clim = cdata.get_limits ();
5012  }
5013 
5014  void update_data (void);
5015 
5016  void calc_face_normals (Matrix& normals);
5017  void update_face_normals (bool reset, bool force = false);
5018  void update_vertex_normals (bool reset, bool force = false);
5019 
5020  void update_edgelighting (void)
5021  {
5022  update_normals (false);
5023  }
5024 
5025  void update_facelighting (void)
5026  {
5027  update_normals (false);
5028  }
5029 
5030  void update_facenormalsmode (void)
5031  {
5032  update_face_normals (false);
5033  }
5034 
5035  void update_vertexnormalsmode (void)
5036  {
5037  update_vertex_normals (false);
5038  }
5039 
5040  void update_visible (void)
5041  {
5042  if (is_visible ())
5043  update_normals (false);
5044  }
5045  };
5046 
5047 private:
5048  properties xproperties;
5049  property_list default_properties;
5050 
5051 public:
5052  patch (const graphics_handle& mh, const graphics_handle& p)
5053  : base_graphics_object (), xproperties (mh, p)
5054  { }
5055 
5056  ~patch (void) = default;
5057 
5058  base_properties& get_properties (void) { return xproperties; }
5059 
5060  const base_properties& get_properties (void) const { return xproperties; }
5061 
5062  bool valid_object (void) const { return true; }
5063 
5064  bool has_readonly_property (const caseless_str& pname) const
5065  {
5066  bool retval = xproperties.has_readonly_property (pname);
5067  if (! retval)
5068  retval = base_properties::has_readonly_property (pname);
5069  return retval;
5070  }
5071 
5072  void reset_default_properties (void);
5073 
5074 protected:
5075  void initialize (const graphics_object& go);
5076 
5077 };
5078 
5079 // ---------------------------------------------------------------------
5080 
5081 class OCTINTERP_API surface : public base_graphics_object
5082 {
5083 public:
5084  class OCTINTERP_API properties : public base_properties
5085  {
5086  public:
5087  octave_value get_color_data (void) const;
5088 
5089  bool is_aliminclude (void) const
5090  { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
5091  std::string get_aliminclude (void) const
5092  { return aliminclude.current_value (); }
5093 
5094  bool is_climinclude (void) const
5095  { return (climinclude.is_on () && cdatamapping.is ("scaled")); }
5096  std::string get_climinclude (void) const
5097  { return climinclude.current_value (); }
5098 
5099  bool get_do_lighting (void) const;
5100 
5101  // See the genprops.awk script for an explanation of the
5102  // properties declarations.
5103  // Programming note: Keep property list sorted if new ones are added.
5104 
5105  BEGIN_PROPERTIES (surface)
5106  array_property alphadata u , Matrix (1, 1, 1.0)
5107  radio_property alphadatamapping l , "none|direct|{scaled}"
5108  double_property ambientstrength , 0.3
5109  radio_property backfacelighting , "unlit|lit|{reverselit}"
5110  array_property cdata u , default_surface_cdata ()
5111  radio_property cdatamapping al , "{scaled}|direct"
5112  string_property cdatasource , ""
5113  double_property diffusestrength , 0.6
5114  string_property displayname , ""
5115  double_radio_property edgealpha , double_radio_property (1.0, radio_values ("flat|interp"))
5116  color_property edgecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp"))
5117  radio_property edgelighting u , "{none}|flat|gouraud|phong"
5118  double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp|texturemap"))
5119  color_property facecolor , color_property (radio_values ("none|{flat}|interp|texturemap"), color_values (0, 0, 0))
5120  radio_property facelighting u , "none|{flat}|gouraud|phong"
5121  array_property facenormals m , Matrix ()
5122  radio_property facenormalsmode u , "{auto}|manual"
5123  radio_property linestyle , "{-}|--|:|-.|none"
5124  double_property linewidth , 0.5
5125  radio_property marker , "{none}|+|o|*|.|x|s|square|d|diamond|^|v|>|<|p|pentagram|h|hexagram"
5126  color_property markeredgecolor , color_property (radio_values ("none|{auto}|flat"), color_values (0, 0, 0))
5127  color_property markerfacecolor , color_property (radio_values ("{none}|auto|flat"), color_values (0, 0, 0))
5128  double_property markersize , 6
5129  radio_property meshstyle , "{both}|row|column"
5130  double_property specularcolorreflectance , 1
5131  double_property specularexponent , 10
5132  double_property specularstrength , 0.9
5133  array_property vertexnormals m , Matrix ()
5134  radio_property vertexnormalsmode u , "{auto}|manual"
5135  array_property xdata u , default_surface_xdata ()
5136  string_property xdatasource , ""
5137  array_property ydata u , default_surface_ydata ()
5138  string_property ydatasource , ""
5139  array_property zdata u , default_surface_zdata ()
5140  string_property zdatasource , ""
5141 
5142  // hidden properties for limit computation
5143  row_vector_property alim hlr , Matrix ()
5144  row_vector_property clim hlr , Matrix ()
5145  row_vector_property xlim hlr , Matrix ()
5146  row_vector_property ylim hlr , Matrix ()
5147  row_vector_property zlim hlr , Matrix ()
5148  bool_property aliminclude hlg , "on"
5149  bool_property climinclude hlg , "on"
5150  bool_property xliminclude hl , "on"
5151  bool_property yliminclude hl , "on"
5152  bool_property zliminclude hl , "on"
5153  END_PROPERTIES
5154 
5155  protected:
5156  void init (void)
5157  {
5158  xdata.add_constraint (dim_vector (-1, -1));
5159  ydata.add_constraint (dim_vector (-1, -1));
5160  zdata.add_constraint (dim_vector (-1, -1));
5161  cdata.add_constraint ("double");
5162  cdata.add_constraint ("single");
5163  cdata.add_constraint ("logical");
5164  cdata.add_constraint ("int8");
5165  cdata.add_constraint ("int16");
5166  cdata.add_constraint ("int32");
5167  cdata.add_constraint ("int64");
5168  cdata.add_constraint ("uint8");
5169  cdata.add_constraint ("uint16");
5170  cdata.add_constraint ("uint32");
5171  cdata.add_constraint ("uint64");
5172  cdata.add_constraint ("real");
5173  cdata.add_constraint (dim_vector (-1, -1));
5174  cdata.add_constraint (dim_vector (-1, -1, 3));
5175  alphadata.add_constraint ("double");
5176  alphadata.add_constraint ("uint8");
5177  alphadata.add_constraint (dim_vector (-1, -1));
5178  facenormals.add_constraint (dim_vector (-1, -1, 3));
5179  facenormals.add_constraint (dim_vector (0, 0));
5180  vertexnormals.add_constraint (dim_vector (-1, -1, 3));
5181  vertexnormals.add_constraint (dim_vector (0, 0));
5182 
5183  ambientstrength.add_constraint ("min", 0.0, true);
5184  ambientstrength.add_constraint ("max", 1.0, true);
5185  diffusestrength.add_constraint ("min", 0.0, true);
5186  diffusestrength.add_constraint ("max", 1.0, true);
5187  linewidth.add_constraint ("min", 0.0, false);
5188  markersize.add_constraint ("min", 0.0, false);
5189  specularcolorreflectance.add_constraint ("min", 0.0, true);
5190  specularcolorreflectance.add_constraint ("max", 1.0, true);
5191  specularexponent.add_constraint ("min", 0.0, false);
5192  specularstrength.add_constraint ("min", 0.0, true);
5193  specularstrength.add_constraint ("max", 1.0, true);
5194  }
5195 
5196  public:
5197  void update_normals (bool reset, bool force = false)
5198  {
5199  update_face_normals (reset, force);
5200  update_vertex_normals (reset, force);
5201  }
5202 
5203 
5204  private:
5205  void update_alphadata (void)
5206  {
5207  if (alphadatamapping_is ("scaled"))
5208  set_alim (alphadata.get_limits ());
5209  else
5210  alim = alphadata.get_limits ();
5211  }
5212 
5213  void update_cdata (void)
5214  {
5215  if (cdatamapping_is ("scaled"))
5216  set_clim (cdata.get_limits ());
5217  else
5218  clim = cdata.get_limits ();
5219  }
5220 
5221  void update_xdata (void)
5222  {
5223  update_normals (true);
5224  set_xlim (xdata.get_limits ());
5225  }
5226 
5227  void update_ydata (void)
5228  {
5229  update_normals (true);
5230  set_ylim (ydata.get_limits ());
5231  }
5232 
5233  void update_zdata (void)
5234  {
5235  update_normals (true);
5236  set_zlim (zdata.get_limits ());
5237  }
5238 
5239  void update_face_normals (bool reset, bool force = false);
5240  void update_vertex_normals (bool reset, bool force = false);
5241 
5242  void update_facenormalsmode (void)
5243  { update_face_normals (false); }
5244 
5245  void update_vertexnormalsmode (void)
5246  { update_vertex_normals (false); }
5247 
5248  void update_edgelighting (void)
5249  { update_normals (false); }
5250 
5251  void update_facelighting (void)
5252  { update_normals (false); }
5253 
5254  void update_visible (void)
5255  {
5256  if (is_visible ())
5257  update_normals (false);
5258  }
5259 
5260  };
5261 
5262 private:
5263  properties xproperties;
5264 
5265 public:
5266  surface (const graphics_handle& mh, const graphics_handle& p)
5267  : base_graphics_object (), xproperties (mh, p)
5268  { }
5269 
5270  ~surface (void) = default;
5271 
5272  base_properties& get_properties (void) { return xproperties; }
5273 
5274  const base_properties& get_properties (void) const { return xproperties; }
5275 
5276  bool valid_object (void) const { return true; }
5277 
5278  bool has_readonly_property (const caseless_str& pname) const
5279  {
5280  bool retval = xproperties.has_readonly_property (pname);
5281  if (! retval)
5282  retval = base_properties::has_readonly_property (pname);
5283  return retval;
5284  }
5285 };
5286 
5287 // ---------------------------------------------------------------------
5288 
5289 class OCTINTERP_API hggroup : public base_graphics_object
5290 {
5291 public:
5292  class OCTINTERP_API properties : public base_properties
5293  {
5294  public:
5295  void remove_child (const graphics_handle& h, bool from_root = false);
5296 
5297  void adopt (const graphics_handle& h);
5298 
5299  // See the genprops.awk script for an explanation of the
5300  // properties declarations.
5301  // Programming note: Keep property list sorted if new ones are added.
5302 
5303  BEGIN_PROPERTIES (hggroup)
5304  string_property displayname , ""
5305 
5306  // hidden properties for limit computation
5307  row_vector_property alim hr , Matrix ()
5308  row_vector_property clim hr , Matrix ()
5309  row_vector_property xlim hr , Matrix ()
5310  row_vector_property ylim hr , Matrix ()
5311  row_vector_property zlim hr , Matrix ()
5312  bool_property aliminclude h , "on"
5313  bool_property climinclude h , "on"
5314  bool_property xliminclude h , "on"
5315  bool_property yliminclude h , "on"
5316  bool_property zliminclude h , "on"
5317  END_PROPERTIES
5318 
5319  private:
5320  void update_limits (void) const;
5321 
5322  void update_limits (const graphics_handle& h) const;
5323 
5324  protected:
5325  void init (void)
5326  { }
5327 
5328  };
5329 
5330 private:
5331  properties xproperties;
5332 
5333 public:
5334  hggroup (const graphics_handle& mh, const graphics_handle& p)
5335  : base_graphics_object (), xproperties (mh, p)
5336  { }
5337 
5338  ~hggroup (void) = default;
5339 
5340  base_properties& get_properties (void) { return xproperties; }
5341 
5342  const base_properties& get_properties (void) const { return xproperties; }
5343 
5344  bool valid_object (void) const { return true; }
5345 
5346  void update_axis_limits (const std::string& axis_type);
5347 
5348  void update_axis_limits (const std::string& axis_type,
5349  const graphics_handle& h);
5350 
5351  bool has_readonly_property (const caseless_str& pname) const
5352  {
5353  bool retval = xproperties.has_readonly_property (pname);
5354  if (! retval)
5355  retval = base_properties::has_readonly_property (pname);
5356  return retval;
5357  }
5358 
5359 };
5360 
5361 // ---------------------------------------------------------------------
5362 
5363 class OCTINTERP_API uimenu : public base_graphics_object
5364 {
5365 public:
5366  class OCTINTERP_API properties : public base_properties
5367  {
5368  public:
5369  void remove_child (const graphics_handle& h, bool from_root = false)
5370  {
5371  base_properties::remove_child (h, from_root);
5372  }
5373 
5374  void adopt (const graphics_handle& h)
5375  {
5376  base_properties::adopt (h);
5377  }
5378 
5379  // See the genprops.awk script for an explanation of the
5380  // properties declarations.
5381  // Programming note: Keep property list sorted if new ones are added.
5382 
5383  BEGIN_PROPERTIES (uimenu)
5384  string_property accelerator , ""
5385  callback_property callback , Matrix ()
5386  bool_property checked , "off"
5387  bool_property enable , "on"
5388  color_property foregroundcolor , color_values (0, 0, 0)
5389  string_property label , ""
5390  double_property position , 0
5391  bool_property separator , "off"
5392 
5393  // Octave-specific properties
5394  string_property __fltk_label__ h , ""
5395  any_property __object__ h , Matrix ()
5396  END_PROPERTIES
5397 
5398  protected:
5399  void init (void)
5400  {
5401  position.add_constraint ("min", 0, false);
5402  }
5403  };
5404 
5405 private:
5406  properties xproperties;
5407 
5408 public:
5409  uimenu (const graphics_handle& mh, const graphics_handle& p)
5410  : base_graphics_object (), xproperties (mh, p)
5411  { }
5412 
5413  ~uimenu (void) = default;
5414 
5415  base_properties& get_properties (void) { return xproperties; }
5416 
5417  const base_properties& get_properties (void) const { return xproperties; }
5418 
5419  bool valid_object (void) const { return true; }
5420 
5421  bool has_readonly_property (const caseless_str& pname) const
5422  {
5423  bool retval = xproperties.has_readonly_property (pname);
5424  if (! retval)
5425  retval = base_properties::has_readonly_property (pname);
5426  return retval;
5427  }
5428 
5429 };
5430 
5431 // ---------------------------------------------------------------------
5432 
5433 class OCTINTERP_API uicontextmenu : public base_graphics_object
5434 {
5435 public:
5436  class OCTINTERP_API properties : public base_properties
5437  {
5438  public:
5439 
5440  void add_dependent_obj (graphics_handle gh)
5441  { dependent_obj_list.push_back (gh); }
5442 
5443  // FIXME: the list may contain duplicates.
5444  // Should we return only unique elements?
5445  const std::list<graphics_handle> get_dependent_obj_list (void)
5446  { return dependent_obj_list; }
5447 
5448  // See the genprops.awk script for an explanation of the
5449  // properties declarations.
5450  // Programming note: Keep property list sorted if new ones are added.
5451 
5452  BEGIN_PROPERTIES (uicontextmenu)
5453  callback_property callback , Matrix ()
5454  array_property position , Matrix (1, 2, 0.0)
5455 
5456  // Octave-specific properties
5457  any_property __object__ h , Matrix ()
5458  END_PROPERTIES
5459 
5460  protected:
5461  void init (void)
5462  {
5463  position.add_constraint (dim_vector (1, 2));
5464  position.add_constraint (dim_vector (2, 1));
5465  visible.set (octave_value (false));
5466  }
5467 
5468  private:
5469  // List of objects that might depend on this uicontextmenu object
5470  std::list<graphics_handle> dependent_obj_list;
5471 
5472  void update_beingdeleted (void);
5473 
5474  };
5475 
5476 private:
5477  properties xproperties;
5478 
5479 public:
5480  uicontextmenu (const graphics_handle& mh, const graphics_handle& p)
5481  : base_graphics_object (), xproperties (mh, p)
5482  { }
5483 
5484  ~uicontextmenu (void) = default;
5485 
5486  base_properties& get_properties (void) { return xproperties; }
5487 
5488  const base_properties& get_properties (void) const { return xproperties; }
5489 
5490  bool valid_object (void) const { return true; }
5491 
5492  bool has_readonly_property (const caseless_str& pname) const
5493  {
5494  bool retval = xproperties.has_readonly_property (pname);
5495  if (! retval)
5496  retval = base_properties::has_readonly_property (pname);
5497  return retval;
5498  }
5499 
5500 };
5501 
5502 // ---------------------------------------------------------------------
5503 
5504 class OCTINTERP_API uicontrol : public base_graphics_object
5505 {
5506 public:
5507  class OCTINTERP_API properties : public base_properties
5508  {
5509  public:
5510  Matrix get_boundingbox (bool internal = false,
5511  const Matrix& parent_pix_size = Matrix ()) const;
5512 
5513  double get___fontsize_points__ (double box_pix_height = 0) const;
5514 
5515  // See the genprops.awk script for an explanation of the
5516  // properties declarations.
5517  // Programming note: Keep property list sorted if new ones are added.
5518 
5519  BEGIN_PROPERTIES (uicontrol)
5520  color_property backgroundcolor , color_values (0.94, 0.94, 0.94)
5521  callback_property callback , Matrix ()
5522  array_property cdata , Matrix ()
5523  bool_property clipping , "on"
5524  radio_property enable , "{on}|inactive|off"
5525  array_property extent rG , Matrix (1, 4, 0.0)
5526  // FIXME: DEPRECATED: Remove "oblique" in version 7.
5527  radio_property fontangle u , "{normal}|italic|oblique"
5528  string_property fontname u , OCTAVE_DEFAULT_FONTNAME
5529  double_property fontsize u , 10
5530  radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
5531  radio_property fontweight u , "{normal}|bold"
5532  color_property foregroundcolor , color_values (0, 0, 0)
5533  radio_property horizontalalignment , "left|{center}|right"
5534  callback_property keypressfcn , Matrix ()
5535  double_property listboxtop , 1
5536  double_property max , 1
5537  double_property min , 0
5538  array_property position , default_control_position ()
5539  array_property sliderstep , default_control_sliderstep ()
5540  string_array_property string u , ""
5541  radio_property style S , "{pushbutton}|togglebutton|radiobutton|checkbox|edit|text|slider|frame|listbox|popupmenu"
5542  string_property tooltipstring , ""
5543  radio_property units u , "normalized|inches|centimeters|points|{pixels}|characters"
5544  row_vector_property value , Matrix (1, 1, 0.0)
5545  radio_property verticalalignment , "top|{middle}|bottom"
5546 
5547  // Octave-specific properties
5548  bool_property __focus__ h , "off"
5549  any_property __object__ h , Matrix ()
5550  END_PROPERTIES
5551 
5552  private:
5553  std::string cached_units;
5554 
5555  protected:
5556  void init (void)
5557  {
5558  cdata.add_constraint ("double");
5559  cdata.add_constraint ("single");
5560  cdata.add_constraint ("uint8");
5561  cdata.add_constraint (dim_vector (-1, -1, 3));
5562  cdata.add_constraint (dim_vector (0, 0));
5563  position.add_constraint (dim_vector (1, 4));
5564  sliderstep.add_constraint (dim_vector (1, 2));
5565  fontsize.add_constraint ("min", 0.0, false);
5566  cached_units = get_units ();
5567  }
5568 
5569  void update_text_extent (void);
5570 
5571  void update_string (void) { update_text_extent (); }
5572  void update_fontname (void) { update_text_extent (); }
5573  void update_fontsize (void) { update_text_extent (); }
5574  void update_fontangle (void)
5575  {
5576  update_text_extent ();
5577  // FIXME: DEPRECATED: Remove warning for "oblique" in version 7.
5578  if (fontangle.is ("oblique"))
5579  warning_with_id ("Octave:deprecated-property",
5580  "Setting 'fontangle' to '%s' is deprecated, \
5581 use 'italic' or 'normal'.", fontangle.current_value ().c_str ());
5582  }
5583  void update_fontweight (void) { update_text_extent (); }
5584 
5585  void update_fontunits (const caseless_str& old_units);
5586 
5587  void update_units (void);
5588 
5589  };
5590 
5591 private:
5592  properties xproperties;
5593 
5594 public:
5595  uicontrol (const graphics_handle& mh, const graphics_handle& p)
5596  : base_graphics_object (), xproperties (mh, p)
5597  { }
5598 
5599  ~uicontrol (void) = default;
5600 
5601  base_properties& get_properties (void) { return xproperties; }
5602 
5603  const base_properties& get_properties (void) const { return xproperties; }
5604 
5605  bool valid_object (void) const { return true; }
5606 
5607  bool has_readonly_property (const caseless_str& pname) const
5608  {
5609  bool retval = xproperties.has_readonly_property (pname);
5610  if (! retval)
5611  retval = base_properties::has_readonly_property (pname);
5612  return retval;
5613  }
5614 };
5615 
5616 // ---------------------------------------------------------------------
5617 
5618 class OCTINTERP_API uibuttongroup : public base_graphics_object
5619 {
5620 public:
5621  class OCTINTERP_API properties : public base_properties
5622  {
5623  public:
5624  void remove_child (const graphics_handle& h, bool from_root = false);
5625 
5626  void adopt (const graphics_handle& h);
5627 
5628  Matrix get_boundingbox (bool internal = false,
5629  const Matrix& parent_pix_size = Matrix ()) const;
5630 
5631  double get___fontsize_points__ (double box_pix_height = 0) const;
5632 
5633  // See the genprops.awk script for an explanation of the
5634  // properties declarations.
5635  // Programming note: Keep property list sorted if new ones are added.
5636 
5637  BEGIN_PROPERTIES (uibuttongroup)
5638  color_property backgroundcolor , color_values (0.94, 0.94, 0.94)
5639  radio_property bordertype , "none|{etchedin}|etchedout|beveledin|beveledout|line"
5640  double_property borderwidth , 1
5641  bool_property clipping , "on"
5642  // FIXME: DEPRECATED: Remove "oblique" in version 7.
5643  radio_property fontangle , "{normal}|italic|oblique"
5644  string_property fontname , OCTAVE_DEFAULT_FONTNAME
5645  double_property fontsize , 10
5646  radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
5647  radio_property fontweight , "{normal}|bold"
5648  color_property foregroundcolor , color_values (0, 0, 0)
5649  color_property highlightcolor , color_values (1, 1, 1)
5650  array_property position S , default_panel_position ()
5651  // FIXME: "resizefcn" is no longer recommended by Matlab,
5652  // and has been replaced with "sizechangedfcn"
5653  // Eventually this will need to be hidden, and then removed.
5654  callback_property resizefcn , Matrix ()
5655  handle_property selectedobject S , graphics_handle ()
5656  callback_property selectionchangedfcn , Matrix ()
5657  color_property shadowcolor , color_values (0.7, 0.7, 0.7)
5658  callback_property sizechangedfcn , Matrix ()
5659  radio_property units S , "{normalized}|inches|centimeters|points|pixels|characters"
5660  string_property title , ""
5661  radio_property titleposition , "{lefttop}|centertop|righttop|leftbottom|centerbottom|rightbottom"
5662 
5663  // Octave-specific properties
5664  any_property __object__ h , Matrix ()
5665  END_PROPERTIES
5666 
5667  protected:
5668  void init (void)
5669  {
5670  position.add_constraint (dim_vector (1, 4));
5671  borderwidth.add_constraint ("min", 0.0, true);
5672  fontsize.add_constraint ("min", 0.0, false);
5673  }
5674 
5675  // void update_text_extent (void);
5676  // void update_string (void) { update_text_extent (); }
5677  // void update_fontname (void) { update_text_extent (); }
5678  // void update_fontsize (void) { update_text_extent (); }
5679  // void update_fontangle (void) { update_text_extent (); }
5680  // void update_fontweight (void) { update_fontweight (); }
5681 
5682  void update_units (const caseless_str& old_units);
5683  void update_fontunits (const caseless_str& old_units);
5684 
5685  };
5686 
5687 private:
5688  properties xproperties;
5689 
5690 public:
5691  uibuttongroup (const graphics_handle& mh, const graphics_handle& p)
5692  : base_graphics_object (), xproperties (mh, p)
5693  { }
5694 
5695  ~uibuttongroup (void) = default;
5696 
5697  base_properties& get_properties (void) { return xproperties; }
5698 
5699  const base_properties& get_properties (void) const { return xproperties; }
5700 
5701  bool valid_object (void) const { return true; }
5702 
5703  bool has_readonly_property (const caseless_str& pname) const
5704  {
5705  bool retval = xproperties.has_readonly_property (pname);
5706  if (! retval)
5707  retval = base_properties::has_readonly_property (pname);
5708  return retval;
5709  }
5710 
5711 };
5712 
5713 // ---------------------------------------------------------------------
5714 
5715 class OCTINTERP_API uipanel : public base_graphics_object
5716 {
5717 public:
5718  class OCTINTERP_API properties : public base_properties
5719  {
5720  public:
5721  Matrix get_boundingbox (bool internal = false,
5722  const Matrix& parent_pix_size = Matrix ()) const;
5723 
5724  double get___fontsize_points__ (double box_pix_height = 0) const;
5725 
5726  // See the genprops.awk script for an explanation of the
5727  // properties declarations.
5728  // Programming note: Keep property list sorted if new ones are added.
5729 
5730  BEGIN_PROPERTIES (uipanel)
5731  color_property backgroundcolor , color_values (0.94, 0.94, 0.94)
5732  radio_property bordertype , "none|{etchedin}|etchedout|beveledin|beveledout|line"
5733  double_property borderwidth , 1
5734  // FIXME: DEPRECATED: Remove "oblique" in version 7.
5735  radio_property fontangle , "{normal}|italic|oblique"
5736  string_property fontname , OCTAVE_DEFAULT_FONTNAME
5737  double_property fontsize , 10
5738  radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
5739  radio_property fontweight , "{normal}|bold"
5740  color_property foregroundcolor , color_values (0, 0, 0)
5741  color_property highlightcolor , color_values (1, 1, 1)
5742  array_property position S , default_panel_position ()
5743  // FIXME: "resizefcn" is no longer recommended by Matlab,
5744  // and has been replaced with "sizechangedfcn"
5745  // Eventually this will need to be hidden, and then removed.
5746  callback_property resizefcn , Matrix ()
5747  color_property shadowcolor , color_values (0.7, 0.7, 0.7)
5748  callback_property sizechangedfcn , Matrix ()
5749  string_property title , ""
5750  radio_property titleposition , "{lefttop}|centertop|righttop|leftbottom|centerbottom|rightbottom"
5751  radio_property units S , "{normalized}|inches|centimeters|points|pixels|characters"
5752  // Octave-specific properties
5753  any_property __object__ h , Matrix ()
5754  END_PROPERTIES
5755 
5756  protected:
5757  void init (void)
5758  {
5759  borderwidth.add_constraint ("min", 0.0, true);
5760  fontsize.add_constraint ("min", 0.0, false);
5761  position.add_constraint (dim_vector (1, 4));
5762  }
5763 
5764  void update_units (const caseless_str& old_units);
5765  void update_fontunits (const caseless_str& old_units);
5766 
5767  };
5768 
5769 private:
5770  properties xproperties;
5771 
5772 public:
5773  uipanel (const graphics_handle& mh, const graphics_handle& p)
5774  : base_graphics_object (), xproperties (mh, p)
5775  { }
5776 
5777  ~uipanel (void) = default;
5778 
5779  base_properties& get_properties (void) { return xproperties; }
5780 
5781  const base_properties& get_properties (void) const { return xproperties; }
5782 
5783  bool valid_object (void) const { return true; }
5784 
5785  bool has_readonly_property (const caseless_str& pname) const
5786  {
5787  bool retval = xproperties.has_readonly_property (pname);
5788  if (! retval)
5789  retval = base_properties::has_readonly_property (pname);
5790  return retval;
5791  }
5792 };
5793 
5794 // ---------------------------------------------------------------------
5795 
5796 class OCTINTERP_API uitable : public base_graphics_object
5797 {
5798 public:
5799  class OCTINTERP_API properties : public base_properties
5800  {
5801  public:
5802  Matrix get_boundingbox (bool internal = false,
5803  const Matrix& parent_pix_size = Matrix ()) const;
5804 
5805  double get___fontsize_points__ (double box_pix_height = 0) const;
5806 
5807  double get_fontsize_pixels (double box_pix_height = 0) const;
5808 
5809  // See the genprops.awk script for an explanation of the
5810  // properties declarations.
5811  // Programming note: Keep property list sorted if new ones are added.
5812 
5813  // FIXME: keypressfcn, keyreleasefcn, rearrangeablecolumns properties
5814  // seem to have been removed from Matlab.
5815 
5816  BEGIN_PROPERTIES (uitable)
5817  any_property __object__ h , Matrix ()
5818  array_property backgroundcolor , default_table_backgroundcolor ()
5819  callback_property celleditcallback , Matrix ()
5820  callback_property cellselectioncallback , Matrix ()
5821  row_vector_property columneditable , Matrix ()
5822  any_property columnformat S , Cell ()
5823  any_property columnname , "numbered"
5824  any_property columnwidth S , "auto"
5825  any_property data u , Matrix ()
5826  bool_property enable , "on"
5827  array_property extent rG , Matrix (1, 4, 0.0)
5828  // FIXME: DEPRECATED: Remove "oblique" in version 7.
5829  radio_property fontangle u , "{normal}|italic|oblique"
5830  string_property fontname u , OCTAVE_DEFAULT_FONTNAME
5831  double_property fontsize u , 10
5832  radio_property fontunits S , "inches|centimeters|normalized|{points}|pixels"
5833  radio_property fontweight u , "{normal}|bold"
5834  color_property foregroundcolor , color_values (0, 0, 0)
5835  callback_property keypressfcn , Matrix ()
5836  callback_property keyreleasefcn , Matrix ()
5837  array_property position , default_table_position ()
5838  bool_property rearrangeablecolumns , "off"
5839  any_property rowname , "numbered"
5840  bool_property rowstriping , "on"
5841  string_property tooltipstring , ""
5842  radio_property units S , "normalized|inches|centimeters|points|{pixels}|characters"
5843  END_PROPERTIES
5844 
5845  Matrix get_extent_matrix (void) const;
5846 
5847  Matrix get_backgroundcolor_rgb (void);
5848 
5849  Matrix get_alternatebackgroundcolor_rgb (void);
5850 
5851  protected:
5852  void init (void)
5853  {
5854  position.add_constraint (dim_vector (1, 4));
5855  extent.add_constraint (dim_vector (1, 4));
5856  backgroundcolor.add_constraint ("double");
5857  backgroundcolor.add_constraint (dim_vector (-1, 3));
5858  columneditable.add_constraint ("logical");
5859  }
5860 
5861  void update_units (const caseless_str& old_units);
5862  void update_fontunits (const caseless_str& old_units);
5863  void update_table_extent (void) { };
5864  void update_data (void) { update_table_extent (); }
5865  void update_fontname (void) { update_table_extent (); }
5866  void update_fontsize (void) { update_table_extent (); }
5867  void update_fontangle (void)
5868  {
5869  update_table_extent ();
5870  // FIXME: DEPRECATED: Remove warning for "oblique" in version 7.
5871  if (fontangle.is ("oblique"))
5872  warning_with_id ("Octave:deprecated-property",
5873  "Setting 'fontangle' to '%s' is deprecated, \
5874 use 'italic' or 'normal'.", fontangle.current_value ().c_str ());
5875  }
5876  void update_fontweight (void) { update_table_extent (); }
5877  };
5878 
5879 private:
5880  properties xproperties;
5881 
5882 public:
5883  uitable (const graphics_handle& mh, const graphics_handle& p)
5884  : base_graphics_object (), xproperties (mh, p)
5885  { }
5886 
5887  ~uitable (void) { }
5888 
5889  base_properties& get_properties (void) { return xproperties; }
5890 
5891  const base_properties& get_properties (void) const { return xproperties; }
5892 
5893  bool valid_object (void) const { return true; }
5894 
5895  bool has_readonly_property (const caseless_str& pname) const
5896  {
5897  bool retval = xproperties.has_readonly_property (pname);
5898  if (! retval)
5899  retval = base_properties::has_readonly_property (pname);
5900  return retval;
5901  }
5902 };
5903 
5904 // ---------------------------------------------------------------------
5905 
5906 class OCTINTERP_API uitoolbar : public base_graphics_object
5907 {
5908 public:
5909  class OCTINTERP_API properties : public base_properties
5910  {
5911  public:
5912  // See the genprops.awk script for an explanation of the
5913  // properties declarations.
5914  // Programming note: Keep property list sorted if new ones are added.
5915 
5916  BEGIN_PROPERTIES (uitoolbar)
5917  // Octave-specific properties
5918  any_property __object__ h , Matrix ()
5919  END_PROPERTIES
5920 
5921  protected:
5922  void init (void)
5923  { }
5924  };
5925 
5926 private:
5927  properties xproperties;
5928 
5929 public:
5930  uitoolbar (const graphics_handle& mh, const graphics_handle& p)
5931  : base_graphics_object (), xproperties (mh, p), default_properties ()
5932  { }
5933 
5934  ~uitoolbar (void) = default;
5935 
5936  void override_defaults (base_graphics_object& obj)
5937  {
5938  // Allow parent (figure) to override first (properties knows how
5939  // to find the parent object).
5940  xproperties.override_defaults (obj);
5941 
5942  // Now override with our defaults. If the default_properties
5943  // list includes the properties for all defaults (line,
5944  // surface, etc.) then we don't have to know the type of OBJ
5945  // here, we just call its set function and let it decide which
5946  // properties from the list to use.
5947  obj.set_from_list (default_properties);
5948  }
5949 
5950  void set (const caseless_str& name, const octave_value& value)
5951  {
5952  if (name.compare ("default", 7))
5953  // strip "default", pass rest to function that will
5954  // parse the remainder and add the element to the
5955  // default_properties map.
5956  default_properties.set (name.substr (7), value);
5957  else
5958  xproperties.set (name, value);
5959  }
5960 
5961  octave_value get (const caseless_str& name) const
5962  {
5963  octave_value retval;
5964 
5965  if (name.compare ("default", 7))
5966  retval = get_default (name.substr (7));
5967  else
5968  retval = xproperties.get (name);
5969 
5970  return retval;
5971  }
5972 
5973  octave_value get_default (const caseless_str& name) const;
5974 
5975  octave_value get_defaults (void) const
5976  {
5977  return default_properties.as_struct ("default");
5978  }
5979 
5980  property_list get_defaults_list (void) const
5981  {
5982  return default_properties;
5983  }
5984 
5985  base_properties& get_properties (void) { return xproperties; }
5986 
5987  const base_properties& get_properties (void) const { return xproperties; }
5988 
5989  bool valid_object (void) const { return true; }
5990 
5991  void reset_default_properties (void);
5992 
5993  bool has_readonly_property (const caseless_str& pname) const
5994  {
5995  bool retval = xproperties.has_readonly_property (pname);
5996  if (! retval)
5997  retval = base_properties::has_readonly_property (pname);
5998  return retval;
5999  }
6000 
6001 private:
6002  property_list default_properties;
6003 };
6004 
6005 // ---------------------------------------------------------------------
6006 
6007 class OCTINTERP_API uipushtool : public base_graphics_object
6008 {
6009 public:
6010  class OCTINTERP_API properties : public base_properties
6011  {
6012  public:
6013  // See the genprops.awk script for an explanation of the
6014  // properties declarations.
6015  // Programming note: Keep property list sorted if new ones are added.
6016 
6017  BEGIN_PROPERTIES (uipushtool)
6018  array_property cdata , Matrix ()
6019  callback_property clickedcallback , Matrix ()
6020  bool_property enable , "on"
6021  bool_property separator , "off"
6022  string_property tooltipstring , ""
6023 
6024  // Octave-specific properties
6025  string_property __named_icon__ , ""
6026  any_property __object__ h , Matrix ()
6027  END_PROPERTIES
6028 
6029  protected:
6030  void init (void)
6031  {
6032  cdata.add_constraint ("double");
6033  cdata.add_constraint ("single");
6034  cdata.add_constraint ("uint8");
6035  cdata.add_constraint (dim_vector (-1, -1, 3));
6036  cdata.add_constraint (dim_vector (0, 0));
6037  }
6038  };
6039 
6040 private:
6041  properties xproperties;
6042 
6043 public:
6044  uipushtool (const graphics_handle& mh, const graphics_handle& p)
6045  : base_graphics_object (), xproperties (mh, p)
6046  { }
6047 
6048  ~uipushtool (void) = default;
6049 
6050  base_properties& get_properties (void) { return xproperties; }
6051 
6052  const base_properties& get_properties (void) const { return xproperties; }
6053 
6054  bool valid_object (void) const { return true; }
6055 
6056  bool has_readonly_property (const caseless_str& pname) const
6057  {
6058  bool retval = xproperties.has_readonly_property (pname);
6059  if (! retval)
6060  retval = base_properties::has_readonly_property (pname);
6061  return retval;
6062  }
6063 
6064 };
6065 
6066 // ---------------------------------------------------------------------
6067 
6068 class OCTINTERP_API uitoggletool : public base_graphics_object
6069 {
6070 public:
6071  class OCTINTERP_API properties : public base_properties
6072  {
6073  public:
6074  // See the genprops.awk script for an explanation of the
6075  // properties declarations.
6076  // Programming note: Keep property list sorted if new ones are added.
6077 
6078  BEGIN_PROPERTIES (uitoggletool)
6079  array_property cdata , Matrix ()
6080  callback_property clickedcallback , Matrix ()
6081  bool_property enable , "on"
6082  callback_property offcallback , Matrix ()
6083  callback_property oncallback , Matrix ()
6084  bool_property separator , "off"
6085  bool_property state , "off"
6086  string_property tooltipstring , ""
6087 
6088  // Octave-specific properties
6089  string_property __named_icon__ , ""
6090  any_property __object__ h , Matrix ()
6091  END_PROPERTIES
6092 
6093  protected:
6094  void init (void)
6095  {
6096  cdata.add_constraint ("double");
6097  cdata.add_constraint ("single");
6098  cdata.add_constraint ("uint8");
6099  cdata.add_constraint (dim_vector (-1, -1, 3));
6100  cdata.add_constraint (dim_vector (0, 0));
6101  }
6102  };
6103 
6104 private:
6105  properties xproperties;
6106 
6107 public:
6108  uitoggletool (const graphics_handle& mh, const graphics_handle& p)
6109  : base_graphics_object (), xproperties (mh, p)
6110  { }
6111 
6112  ~uitoggletool (void) = default;
6113 
6114  base_properties& get_properties (void) { return xproperties; }
6115 
6116  const base_properties& get_properties (void) const { return xproperties; }
6117 
6118  bool valid_object (void) const { return true; }
6119 
6120  bool has_readonly_property (const caseless_str& pname) const
6121  {
6122  bool retval = xproperties.has_readonly_property (pname);
6123  if (! retval)
6124  retval = base_properties::has_readonly_property (pname);
6125  return retval;
6126  }
6127 
6128 };
6129 
6130 // ---------------------------------------------------------------------
6131 
6132 octave_value
6133 get_property_from_handle (double handle, const std::string& property,
6134  const std::string& func);
6135 bool
6136 set_property_in_handle (double handle, const std::string& property,
6137  const octave_value& arg, const std::string& func);
6138 
6139 // ---------------------------------------------------------------------
6140 
6141 class graphics_event;
6142 
6143 class
6144 base_graphics_event
6145 {
6146 public:
6147  enum priority { INTERRUPT, QUEUE, CANCEL };
6148 
6149  friend class graphics_event;
6150 
6151  base_graphics_event (void)
6152  : m_busyaction (QUEUE)
6153  { };
6154 
6155  base_graphics_event (int busyaction)
6156  : m_busyaction (busyaction)
6157  { };
6158 
6159  virtual ~base_graphics_event (void) = default;
6160 
6161  int get_busyaction (void) { return m_busyaction; };
6162 
6163  virtual void execute (void) = 0;
6164 
6165  private:
6166  int m_busyaction;
6167 };
6168 
6169 class
6170 graphics_event
6171 {
6172 public:
6173 
6174  typedef void (*event_fcn) (void*);
6175 
6176  graphics_event (void) = default;
6177 
6178  graphics_event (base_graphics_event *new_rep) : rep (new_rep) { }
6179 
6180  graphics_event (const graphics_event&) = default;
6181 
6182  ~graphics_event (void) = default;
6183 
6184  graphics_event& operator = (const graphics_event&) = default;
6185 
6186  int get_busyaction (void)
6187  {
6188  if (ok ())
6189  return rep->get_busyaction ();
6190  else
6191  error ("graphics_event::busyaction: invalid graphics_event");
6192  }
6193 
6194  void execute (void)
6195  {
6196  if (ok ())
6197  rep->execute ();
6198  }
6199 
6200  bool ok (void) const { return (rep != nullptr); }
6201 
6202  static graphics_event
6203  create_callback_event (const graphics_handle& h,
6204  const std::string& name,
6205  const octave_value& data = Matrix (),
6206  int busyaction = base_graphics_event::QUEUE);
6207 
6208  static graphics_event
6209  create_callback_event (const graphics_handle& h,
6210  const octave_value& cb,
6211  const octave_value& data = Matrix (),
6212  int busyaction = base_graphics_event::QUEUE);
6213 
6214  static graphics_event
6215  create_mcode_event (const graphics_handle& h, const std::string& cmd,
6216  int busyaction);
6217 
6218  static graphics_event
6219  create_function_event (event_fcn fcn, void *data = nullptr);
6220 
6221  static graphics_event
6222  create_set_event (const graphics_handle& h, const std::string& name,
6223  const octave_value& value, bool notify_toolkit = true,
6224  bool redraw_figure = false);
6225 private:
6226 
6227  std::shared_ptr <base_graphics_event> rep;
6228 };
6229 
6230 class OCTINTERP_API gh_manager
6231 {
6232 public:
6233 
6234  gh_manager (octave::interpreter& interp);
6235 
6236  // FIXME: eventually eliminate these static functions and access
6237  // gh_manager object through the interpreter.
6238 
6239  graphics_handle get_handle (bool integer_figure_handle);
6240 
6241  void free (const graphics_handle& h, bool from_root = false);
6242 
6243  void renumber_figure (const graphics_handle& old_gh,
6244  const graphics_handle& new_gh);
6245 
6246  graphics_handle lookup (double val) const
6247  {
6248  const_iterator p = (octave::math::isnan (val)
6249  ? m_handle_map.end () : m_handle_map.find (val));
6250 
6251  return (p != m_handle_map.end ()) ? p->first : graphics_handle ();
6252  }
6253 
6254  graphics_handle lookup (const octave_value& val) const
6255  {
6256  return (val.is_real_scalar ()
6257  ? lookup (val.double_value ()) : graphics_handle ());
6258  }
6259 
6260  graphics_object get_object (double val) const
6261  {
6262  return get_object (lookup (val));
6263  }
6264 
6265  graphics_object get_object (const graphics_handle& h) const
6266  {
6267  const_iterator p = (h.ok () ? m_handle_map.find (h) : m_handle_map.end ());
6268 
6269  return (p != m_handle_map.end ()) ? p->second : graphics_object ();
6270  }
6271 
6272 graphics_handle make_graphics_handle (const std::string& go_name,
6273  const graphics_handle& p,
6274  bool integer_figure_handle = false,
6275  bool call_createfcn = true,
6276  bool notify_toolkit = true);
6277 
6278  graphics_handle make_figure_handle (double val,
6279  bool notify_toolkit = true);
6280 
6281  void push_figure (const graphics_handle& h);
6282 
6283  void pop_figure (const graphics_handle& h);
6284 
6285  graphics_handle current_figure (void) const
6286  {
6287  graphics_handle retval;
6288 
6289  for (const auto& hfig : m_figure_list)
6290  {
6291  if (is_handle_visible (hfig))
6292  retval = hfig;
6293  }
6294 
6295  return retval;
6296  }
6297 
6298  Matrix handle_list (bool show_hidden = false)
6299  {
6300  Matrix retval (1, m_handle_map.size ());
6301 
6302  octave_idx_type i = 0;
6303  for (const auto& h_iter : m_handle_map)
6304  {
6305  graphics_handle h = h_iter.first;
6306 
6307  if (show_hidden || is_handle_visible (h))
6308  retval(i++) = h.value ();
6309  }
6310 
6311  retval.resize (1, i);
6312 
6313  return retval;
6314  }
6315 
6316  void lock (void) { m_graphics_lock.lock (); }
6317 
6318  bool try_lock (void) { return m_graphics_lock.try_lock (); }
6319 
6320  void unlock (void) { m_graphics_lock.unlock (); }
6321 
6322  Matrix figure_handle_list (bool show_hidden = false)
6323  {
6324  Matrix retval (1, m_figure_list.size ());
6325 
6326  octave_idx_type i = 0;
6327  for (const auto& hfig : m_figure_list)
6328  {
6329  if (show_hidden || is_handle_visible (hfig))
6330  retval(i++) = hfig.value ();
6331  }
6332 
6333  retval.resize (1, i);
6334 
6335  return retval;
6336  }
6337 
6338  void execute_listener (const graphics_handle& h, const octave_value& l);
6339 
6340  void execute_callback (const graphics_handle& h,
6341  const std::string& name,
6342  const octave_value& data = Matrix ())
6343  {
6344  octave_value cb;
6345 
6346  if (true)
6347  {
6348  octave::autolock guard (graphics_lock ());
6349 
6350  graphics_object go = get_object (h);
6351 
6352  if (go.valid_object ())
6353  cb = go.get (name);
6354  }
6355 
6356  execute_callback (h, cb, data);
6357  }
6358 
6359  void execute_callback (const graphics_handle& h, const octave_value& cb,
6360  const octave_value& data = Matrix ());
6361 
6362  void post_callback (const graphics_handle& h, const std::string& name,
6363  const octave_value& data = Matrix ());
6364 
6365  void post_function (graphics_event::event_fcn fcn, void *fcn_data = nullptr);
6366 
6367  void post_set (const graphics_handle& h, const std::string& name,
6368  const octave_value& value, bool notify_toolkit = true,
6369  bool redraw_figure = false);
6370 
6371  int process_events (bool force = false);
6372 
6373  void enable_event_processing (bool enable = true);
6374 
6375  bool is_handle_visible (const graphics_handle& h) const
6376  {
6377  bool retval = false;
6378 
6379  graphics_object go = get_object (h);
6380 
6381  if (go.valid_object ())
6382  retval = go.is_handle_visible ();
6383 
6384  return retval;
6385  }
6386 
6387  void close_all_figures (void);
6388 
6389  void restore_gcbo (void);
6390 
6391  void post_event (const graphics_event& e);
6392 
6393  octave::mutex graphics_lock (void)
6394  {
6395  return m_graphics_lock;
6396  }
6397 
6398 private:
6399 
6400  typedef std::map<graphics_handle, graphics_object>::iterator iterator;
6401  typedef std::map<graphics_handle, graphics_object>::const_iterator
6402  const_iterator;
6403 
6404  typedef std::set<graphics_handle>::iterator free_list_iterator;
6405  typedef std::set<graphics_handle>::const_iterator const_free_list_iterator;
6406 
6407  typedef std::list<graphics_handle>::iterator figure_list_iterator;
6408  typedef std::list<graphics_handle>::const_iterator const_figure_list_iterator;
6409 
6410  octave::interpreter& m_interpreter;
6411 
6412  // A map of handles to graphics objects.
6413  std::map<graphics_handle, graphics_object> m_handle_map;
6414 
6415  // The available graphics handles.
6416  std::set<graphics_handle> m_handle_free_list;
6417 
6418  // The next handle available if m_handle_free_list is empty.
6419  double m_next_handle;
6420 
6421  // The allocated figure handles. Top of the stack is most recently
6422  // created.
6423  std::list<graphics_handle> m_figure_list;
6424 
6425  // The lock for accessing the graphics sytsem.
6426  octave::mutex m_graphics_lock;
6427 
6428  // The list of events queued by graphics toolkits.
6429  std::list<graphics_event> m_event_queue;
6430 
6431  // The stack of callback objects.
6432  std::list<graphics_object> m_callback_objects;
6433 
6434  // A flag telling whether event processing must be constantly on.
6435  int m_event_processing;
6436 };
6437 
6438 void get_children_limits (double& min_val, double& max_val,
6439  double& min_pos, double& max_neg,
6440  const Matrix& kids, char limit_type);
6441 
6442 OCTINTERP_API int calc_dimensions (const graphics_object& gh);
6443 
6444 // This function is NOT equivalent to the scripting language function gcf.
6445 OCTINTERP_API graphics_handle gcf (void);
6446 
6447 // This function is NOT equivalent to the scripting language function gca.
6448 OCTINTERP_API graphics_handle gca (void);
6449 
6450 OCTINTERP_API void close_all_figures (void);
6451 
6452 #endif
#define NaN
Definition: Faddeeva.cc:248
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
Array< T > sort(int dim=0, sortmode mode=ASCENDING) const
Size of the specified dimension.
Definition: Array.cc:1757
T & xelem(octave_idx_type n)
Size of the specified dimension.
Definition: Array.h:469
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
octave_idx_type rows(void) const
Definition: Array.h:415
const T * fortran_vec(void) const
Size of the specified dimension.
Definition: Array.h:583
Definition: Cell.h:43
bool iscellstr(void) const
Definition: Cell.cc:126
Array< std::string > cellstr_value(void) const
Definition: Cell.cc:145
MArray< T > reshape(const dim_vector &new_dims) const
Definition: MArray.h:93
Definition: dMatrix.h:42
Matrix stack(const Matrix &a) const
Definition: dMatrix.cc:325
octave_value data
Definition: graphics.in.h:1706
base_property * clone(void) const
Definition: graphics.in.h:1696
any_property(const any_property &p)
Definition: graphics.in.h:1685
any_property & operator=(const octave_value &val)
Definition: graphics.in.h:1690
any_property(const std::string &nm, const graphics_handle &h, const octave_value &m=Matrix())
Definition: graphics.in.h:1681
octave_value get(void) const
Definition: graphics.in.h:1688
bool do_set(const octave_value &v)
Definition: graphics.in.h:1699
finite_type finite_constraint
Definition: graphics.in.h:1496
array_property(const array_property &p)
Definition: graphics.in.h:1396
std::pair< double, bool > minval
Definition: graphics.in.h:1497
octave_value data
Definition: graphics.in.h:1489
std::pair< double, bool > maxval
Definition: graphics.in.h:1497
double max_val(void) const
Definition: graphics.in.h:1424
bool do_set(const octave_value &v)
Definition: graphics.in.h:1460
OCTINTERP_API void get_data_limits(void)
Definition: graphics.cc:1691
array_property(const std::string &nm, const graphics_handle &h, const octave_value &m)
Definition: graphics.in.h:1382
OCTINTERP_API bool is_equal(const octave_value &v) const
Definition: graphics.cc:1632
double min_val(void) const
Definition: graphics.in.h:1423
Matrix get_limits(void) const
Definition: graphics.in.h:1428
OCTINTERP_API bool validate(const octave_value &v)
Definition: graphics.cc:1525
base_property * clone(void) const
Definition: graphics.in.h:1446
double min_pos(void) const
Definition: graphics.in.h:1425
octave_value get(void) const
Definition: graphics.in.h:1404
std::list< dim_vector > size_constraints
Definition: graphics.in.h:1495
std::set< std::string > type_constraints
Definition: graphics.in.h:1494
array_property(void)
Definition: graphics.in.h:1372
void add_constraint(const dim_vector &dims)
Definition: graphics.in.h:1409
void add_constraint(const std::string &type, double val, bool inclusive)
Definition: graphics.in.h:1415
array_property & operator=(const octave_value &val)
Definition: graphics.in.h:1440
void add_constraint(const finite_type finite)
Definition: graphics.in.h:1412
void add_constraint(const std::string &type)
Definition: graphics.in.h:1406
double max_neg(void) const
Definition: graphics.in.h:1426
virtual octave::graphics_toolkit get_toolkit(void) const
Definition: graphics.in.h:2638
virtual graphics_handle get_parent(void) const
Definition: graphics.in.h:2555
virtual void adopt(const graphics_handle &h)
Definition: graphics.in.h:2579
virtual property_list get_defaults_list(void) const
Definition: graphics.in.h:2520
virtual property_list get_factory_defaults_list(void) const
Definition: graphics.in.h:2533
graphics_handle get_handle(void) const
Definition: graphics.in.h:2563
virtual void reparent(const graphics_handle &np)
Definition: graphics.in.h:2587
virtual octave_value get_defaults(void) const
Definition: graphics.in.h:2515
virtual base_properties & get_properties(void)
Definition: graphics.in.h:2604
virtual void set(const caseless_str &pname, const octave_value &pval)
Definition: graphics.in.h:2479
octave_value get(bool all=false) const
Definition: graphics.in.h:2495
virtual void remove_child(const graphics_handle &h, bool from_root=false)
Definition: graphics.in.h:2571
virtual octave_value get_factory_defaults(void) const
Definition: graphics.in.h:2528
virtual void set_from_list(property_list &plist)
Definition: graphics.in.h:2471
virtual void override_defaults(base_graphics_object &obj)
Definition: graphics.in.h:2461
virtual void set_defaults(const std::string &)
Definition: graphics.in.h:2487
virtual void mark_modified(void)
Definition: graphics.in.h:2453
virtual bool is_yliminclude(void) const
Definition: graphics.in.h:2358
void set___modified__(const octave_value &val)
Definition: graphics.in.h:2313
BEGIN_BASE_PROPERTIES bool_property beingdeleted s
Definition: graphics.in.h:2380
Matrix get_children(void) const
Definition: graphics.in.h:2292
void reparent(const graphics_handle &new_parent)
Definition: graphics.in.h:2315
virtual bool is_zliminclude(void) const
Definition: graphics.in.h:2359
virtual bool is_climinclude(void) const
Definition: graphics.in.h:2356
virtual bool is_aliminclude(void) const
Definition: graphics.in.h:2355
bool is_modified(void) const
Definition: graphics.in.h:2247
virtual octave_value get_ylim(void) const
Definition: graphics.in.h:2352
Matrix get_hidden_children(void) const
Definition: graphics.in.h:2302
virtual octave_value get_xlim(void) const
Definition: graphics.in.h:2351
std::set< std::string > dynamic_properties
Definition: graphics.in.h:2368
virtual ~base_properties(void)=default
Matrix get_all_children(void) const
Definition: graphics.in.h:2297
virtual octave_value get(bool all=false) const
static property_list::pval_map_type factory_defaults(void)
virtual void set(const caseless_str &, const octave_value &)
void insert_property(const std::string &name, property p)
Definition: graphics.in.h:2213
virtual bool is_xliminclude(void) const
Definition: graphics.in.h:2357
virtual bool has_property(const caseless_str &) const
Definition: graphics.in.h:2241
BEGIN_BASE_PROPERTIES bool_property beingdeleted off radio_property busyaction
Definition: graphics.in.h:2381
void set_modified(const octave_value &val)
Definition: graphics.in.h:2311
virtual octave_value get_alim(void) const
Definition: graphics.in.h:2349
virtual octave_value get(const caseless_str &pname) const
virtual octave_value get(const char *pname) const
Definition: graphics.in.h:2229
virtual void adopt(const graphics_handle &h)
Definition: graphics.in.h:2258
virtual octave_value get_zlim(void) const
Definition: graphics.in.h:2353
virtual octave_value get_clim(void) const
Definition: graphics.in.h:2350
void set_beingdeleted(const octave_value &val)
Definition: graphics.in.h:2282
virtual void init_integerhandle(const octave_value &)
Definition: graphics.in.h:2203
virtual void delete_children(bool clear=false, bool from_root=false)
Definition: graphics.in.h:2327
virtual void remove_child(const graphics_handle &h, bool=false)
Definition: graphics.in.h:2249
base_properties(const std::string &ty="unknown", const graphics_handle &mh=graphics_handle(), const graphics_handle &p=graphics_handle())
virtual property get_property(const caseless_str &pname)
virtual std::string graphics_object_name(void) const
Definition: graphics.in.h:2197
void renumber_child(graphics_handle old_gh, graphics_handle new_gh)
Definition: graphics.in.h:2332
virtual octave_value get(const std::string &pname) const
Definition: graphics.in.h:2224
virtual Matrix get_boundingbox(bool=false, const Matrix &=Matrix()) const
Definition: graphics.in.h:2268
void set_tag(const octave_value &val)
Definition: graphics.in.h:2288
void renumber_parent(graphics_handle new_gh)
Definition: graphics.in.h:2337
virtual base_property * clone(void) const
Definition: graphics.in.h:406
octave::refcount< octave_idx_type > count
Definition: graphics.in.h:424
void set_name(const std::string &s)
Definition: graphics.in.h:305
void set_parent(const graphics_handle &h)
Definition: graphics.in.h:309
std::map< listener_mode, octave_value_list >::iterator listener_map_iterator
Definition: graphics.in.h:418
graphics_handle parent
Definition: graphics.in.h:426
void add_listener(const octave_value &v, listener_mode mode=GCB_POSTSET)
Definition: graphics.in.h:347
bool is_hidden(void) const
Definition: graphics.in.h:311
std::map< listener_mode, octave_value_list >::const_iterator listener_map_const_iterator
Definition: graphics.in.h:420
base_property & operator=(const octave_value &val)
Definition: graphics.in.h:341
virtual Cell values_as_cell(void) const
Definition: graphics.in.h:336
base_property(const base_property &p)
Definition: graphics.in.h:294
virtual ~base_property(void)=default
virtual octave_value get(void) const
Definition: graphics.in.h:326
void delete_listener(const octave_value &v=octave_value(), listener_mode mode=GCB_POSTSET)
Definition: graphics.in.h:353
std::string get_name(void) const
Definition: graphics.in.h:303
virtual bool do_set(const octave_value &)
Definition: graphics.in.h:410
std::string name
Definition: graphics.in.h:425
virtual std::string values_as_string(void) const
Definition: graphics.in.h:331
void set_hidden(bool flag)
Definition: graphics.in.h:313
OCTINTERP_API void run_listeners(listener_mode mode=GCB_POSTSET)
Definition: graphics.cc:1283
base_property(const std::string &s, const graphics_handle &h)
Definition: graphics.in.h:290
base_property(void)
Definition: graphics.in.h:286
std::map< listener_mode, octave_value_list > listener_map
Definition: graphics.in.h:416
int get_id(void) const
Definition: graphics.in.h:317
listener_map listeners
Definition: graphics.in.h:428
graphics_handle get_parent(void) const
Definition: graphics.in.h:307
virtual bool is_radio(void) const
Definition: graphics.in.h:315
void set_id(int d)
Definition: graphics.in.h:319
bool ok(void) const
Definition: graphics.in.h:301
OCTINTERP_API bool set(const octave_value &v, bool do_run=true, bool do_notify_toolkit=true)
Definition: graphics.cc:1257
virtual ~base_scaler(void)=default
virtual double unscale(double) const
Definition: graphics.in.h:85
virtual double scale(double) const
Definition: graphics.in.h:80
virtual NDArray scale(const NDArray &) const
Definition: graphics.in.h:75
virtual bool is_linear(void) const
Definition: graphics.in.h:93
virtual base_scaler * clone() const
Definition: graphics.in.h:90
base_scaler(void)
Definition: graphics.in.h:66
virtual Matrix scale(const Matrix &) const
Definition: graphics.in.h:70
bool_property(const std::string &nm, const graphics_handle &h, bool val)
Definition: graphics.in.h:1597
bool is_on(void) const
Definition: graphics.in.h:1611
bool do_set(const octave_value &val)
Definition: graphics.in.h:1622
base_property * clone(void) const
Definition: graphics.in.h:1619
bool_property(const std::string &nm, const graphics_handle &h, const char *val)
Definition: graphics.in.h:1602
bool_property(const bool_property &p)
Definition: graphics.in.h:1608
bool_property & operator=(const octave_value &val)
Definition: graphics.in.h:1613
bool do_set(const octave_value &v)
Definition: graphics.in.h:1930
octave_value get(void) const
Definition: graphics.in.h:1912
callback_property(const callback_property &p)
Definition: graphics.in.h:1909
OCTINTERP_API void execute(const octave_value &data=octave_value()) const
Definition: graphics.cc:1941
callback_property & operator=(const octave_value &val)
Definition: graphics.in.h:1921
OCTINTERP_API bool validate(const octave_value &v) const
Definition: graphics.cc:1878
bool is_defined(void) const
Definition: graphics.in.h:1916
octave_value callback
Definition: graphics.in.h:1945
base_property * clone(void) const
Definition: graphics.in.h:1927
callback_property(const std::string &nm, const graphics_handle &h, const octave_value &m)
Definition: graphics.in.h:1905
bool compare(const std::string &s, size_t limit=std::string::npos) const
Definition: caseless-str.h:78
std::string row_as_string(octave_idx_type, bool strip_ws=false) const
Definition: chMatrix.cc:82
Matrix get_all(void) const
Definition: graphics.in.h:1761
Matrix get_children(void) const
Definition: graphics.in.h:1751
octave_value get(void) const
Definition: graphics.in.h:1766
void delete_children(bool clear=false, bool from_root=false)
Definition: graphics.in.h:1771
bool do_remove_child(double child)
Definition: graphics.in.h:1879
children_property(const children_property &p)
Definition: graphics.in.h:1727
void do_init_children(const Matrix &val)
Definition: graphics.in.h:1853
void adopt(double val)
Definition: graphics.in.h:1746
void do_adopt_child(double val)
Definition: graphics.in.h:1892
Matrix do_get_all_children(void) const
Definition: graphics.in.h:1868
std::list< double >::iterator children_list_iterator
Definition: graphics.in.h:1791
children_property & operator=(const octave_value &val)
Definition: graphics.in.h:1733
void do_delete_children(bool clear, bool from_root)
Definition: graphics.cc:1845
Matrix do_get_children(bool return_hidden) const
Definition: graphics.cc:1805
std::list< double > children_list
Definition: graphics.in.h:1793
std::list< double >::const_iterator const_children_list_iterator
Definition: graphics.in.h:1792
void do_init_children(const std::list< double > &val)
Definition: graphics.in.h:1860
void renumber(graphics_handle old_gh, graphics_handle new_gh)
Definition: graphics.in.h:1776
Matrix get_hidden(void) const
Definition: graphics.in.h:1756
bool remove_child(double val)
Definition: graphics.in.h:1741
children_property(const std::string &nm, const graphics_handle &h, const Matrix &val)
Definition: graphics.in.h:1720
bool do_set(const octave_value &val)
Definition: graphics.in.h:1796
base_property * clone(void) const
Definition: graphics.in.h:1739
color_property(const radio_values &v, const color_values &c)
Definition: graphics.in.h:1070
color_property(const std::string &nm, const graphics_handle &h, const color_values &c=color_values(), const radio_values &v=radio_values())
Definition: graphics.in.h:1076
const std::string & current_value(void) const
Definition: graphics.in.h:1133
radio_values radio_val
Definition: graphics.in.h:1162
bool is(const std::string &v) const
Definition: graphics.in.h:1122
color_property(const color_values &c, const radio_values &v)
Definition: graphics.in.h:1064
color_property(const color_property &p)
Definition: graphics.in.h:1105
OCTINTERP_API bool do_set(const octave_value &newval)
Definition: graphics.cc:1412
color_property(const std::string &nm, const graphics_handle &h, const radio_values &v)
Definition: graphics.in.h:1084
color_property(const std::string &nm, const graphics_handle &h, const color_property &v)
Definition: graphics.in.h:1098
bool is_rgb(void) const
Definition: graphics.in.h:1118
std::string current_val
Definition: graphics.in.h:1163
color_property(const std::string &nm, const graphics_handle &h, const std::string &v)
Definition: graphics.in.h:1091
base_property * clone(void) const
Definition: graphics.in.h:1149
color_values color_val
Definition: graphics.in.h:1161
enum color_property::current_enum current_type
std::string values_as_string(void) const
Definition: graphics.in.h:1151
bool is_radio(void) const
Definition: graphics.in.h:1120
Cell values_as_cell(void) const
Definition: graphics.in.h:1154
color_property & operator=(const octave_value &val)
Definition: graphics.in.h:1141
Matrix rgb(void) const
Definition: graphics.in.h:1125
octave_value get(void) const
Definition: graphics.in.h:1110
OCTINTERP_API bool str2rgb(const std::string &str)
Definition: graphics.cc:1370
color_values(double r=0, double g=0, double b=1)
Definition: graphics.in.h:1003
bool operator!=(const color_values &c) const
Definition: graphics.in.h:1039
Matrix rgb(void) const
Definition: graphics.in.h:1042
color_values(const std::string &str)
Definition: graphics.in.h:1013
color_values(const color_values &c)
Definition: graphics.in.h:1020
bool operator==(const color_values &c) const
Definition: graphics.in.h:1032
color_values & operator=(const color_values &c)
Definition: graphics.in.h:1024
void validate(void) const
Definition: graphics.in.h:1046
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
double_property(const double_property &p)
Definition: graphics.in.h:1185
finite_type finite_constraint
Definition: graphics.in.h:1281
double_property & operator=(const octave_value &val)
Definition: graphics.in.h:1195
void add_constraint(const finite_type finite)
Definition: graphics.in.h:1220
bool do_set(const octave_value &v)
Definition: graphics.in.h:1224
std::pair< double, bool > minval
Definition: graphics.in.h:1282
double_property(const std::string &nm, const graphics_handle &h, double d=0)
Definition: graphics.in.h:1178
std::pair< double, bool > maxval
Definition: graphics.in.h:1282
base_property * clone(void) const
Definition: graphics.in.h:1201
octave_value get(void) const
Definition: graphics.in.h:1191
void add_constraint(const std::string &type, double val, bool inclusive)
Definition: graphics.in.h:1212
double double_value(void) const
Definition: graphics.in.h:1193
base_property * clone(void) const
Definition: graphics.in.h:1354
const std::string & current_value(void) const
Definition: graphics.in.h:1338
double_radio_property(const double_radio_property &p)
Definition: graphics.in.h:1310
double_radio_property(const std::string &nm, const graphics_handle &h, const double_radio_property &v)
Definition: graphics.in.h:1303
double_radio_property & operator=(const octave_value &val)
Definition: graphics.in.h:1346
double double_value(void) const
Definition: graphics.in.h:1330
enum double_radio_property::current_enum current_type
OCTINTERP_API bool do_set(const octave_value &v)
Definition: graphics.cc:1483
double_radio_property(const std::string &nm, const graphics_handle &h, const std::string &v)
Definition: graphics.in.h:1296
std::string current_val
Definition: graphics.in.h:1364
octave_value get(void) const
Definition: graphics.in.h:1315
bool is_radio(void) const
Definition: graphics.in.h:1325
radio_values radio_val
Definition: graphics.in.h:1363
bool is_double(void) const
Definition: graphics.in.h:1323
bool is(const std::string &v) const
Definition: graphics.in.h:1327
double_radio_property(double d, const radio_values &v)
Definition: graphics.in.h:1290
std::set< std::string > type_constraints
Definition: graphics.in.h:1670
handle_property(const handle_property &p)
Definition: graphics.in.h:1641
base_property * clone(void) const
Definition: graphics.in.h:1663
handle_property(const std::string &nm, const graphics_handle &h, const graphics_handle &val=graphics_handle())
Definition: graphics.in.h:1636
graphics_handle current_val
Definition: graphics.in.h:1673
octave_value get(void) const
Definition: graphics.in.h:1644
void add_constraint(const std::string &type)
Definition: graphics.in.h:1665
void invalidate(void)
Definition: graphics.in.h:1660
OCTINTERP_API bool do_set(const octave_value &v)
Definition: graphics.cc:1731
graphics_handle handle_value(void) const
Definition: graphics.in.h:1646
handle_property & operator=(const octave_value &val)
Definition: graphics.in.h:1648
base_scaler * clone(void) const
Definition: graphics.in.h:110
bool is_linear(void) const
Definition: graphics.in.h:112
lin_scaler(void)
Definition: graphics.in.h:100
double unscale(double d) const
Definition: graphics.in.h:108
double scale(double d) const
Definition: graphics.in.h:106
NDArray scale(const NDArray &m) const
Definition: graphics.in.h:104
Matrix scale(const Matrix &m) const
Definition: graphics.in.h:102
Matrix scale(const Matrix &m) const
Definition: graphics.in.h:120
base_scaler * clone(void) const
Definition: graphics.in.h:144
NDArray scale(const NDArray &m) const
Definition: graphics.in.h:129
void do_scale(const double *src, double *dest, int n) const
Definition: graphics.in.h:148
double unscale(double d) const
Definition: graphics.in.h:141
log_scaler(void)
Definition: graphics.in.h:118
double scale(double d) const
Definition: graphics.in.h:138
neg_log_scaler(void)
Definition: graphics.in.h:158
Matrix scale(const Matrix &m) const
Definition: graphics.in.h:160
double unscale(double d) const
Definition: graphics.in.h:181
void do_scale(const double *src, double *dest, int n) const
Definition: graphics.in.h:188
NDArray scale(const NDArray &m) const
Definition: graphics.in.h:169
base_scaler * clone(void) const
Definition: graphics.in.h:184
double scale(double d) const
Definition: graphics.in.h:178
octave_value as_octave_value(void) const
Definition: oct-handle.h:80
double value(void) const
Definition: oct-handle.h:78
bool ok(void) const
Definition: oct-handle.h:113
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
Definition: ovl.h:117
octave_idx_type length(void) const
Definition: ovl.h:113
bool iscellstr(void) const
Definition: ov.h:563
bool iscell(void) const
Definition: ov.h:560
bool bool_value(bool warn=false) const
Definition: ov.h:838
bool isreal(void) const
Definition: ov.h:691
bool issparse(void) const
Definition: ov.h:706
charMatrix char_matrix_value(bool frc_str_conv=false) const
Definition: ov.h:847
bool is_bool_scalar(void) const
Definition: ov.h:578
octave_idx_type rows(void) const
Definition: ov.h:504
bool is_scalar_type(void) const
Definition: ov.h:697
octave_value full_value(void) const
Definition: ov.h:413
bool is_string(void) const
Definition: ov.h:593
bool is_defined(void) const
Definition: ov.h:551
Cell cell_value(void) const
octave_value reshape(const dim_vector &dv) const
Definition: ov.h:530
std::string string_value(bool force=false) const
Definition: ov.h:927
string_vector string_vector_value(bool pad=false) const
Definition: ov.h:930
bool isempty(void) const
Definition: ov.h:557
NDArray array_value(bool frc_str_conv=false) const
Definition: ov.h:812
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:806
double double_value(bool frc_str_conv=false) const
Definition: ov.h:794
dim_vector dims(void) const
Definition: ov.h:500
~property_list(void)=default
octave_scalar_map as_struct(const std::string &prefix_arg) const
Definition: graphics.cc:2505
plist_map_const_iterator end(void) const
Definition: graphics.in.h:2165
plist_map_iterator find(const std::string &go_name)
Definition: graphics.in.h:2167
plist_map_type plist_map
Definition: graphics.in.h:2180
property_list(const plist_map_type &m=plist_map_type())
Definition: graphics.in.h:2152
plist_map_iterator end(void)
Definition: graphics.in.h:2164
void set(const caseless_str &name, const octave_value &val)
Definition: graphics.cc:2271
plist_map_const_iterator find(const std::string &go_name) const
Definition: graphics.in.h:2172
plist_map_type::const_iterator plist_map_const_iterator
Definition: graphics.in.h:2150
pval_map_type::iterator pval_map_iterator
Definition: graphics.in.h:2146
octave_value lookup(const caseless_str &name) const
Definition: graphics.cc:2411
plist_map_iterator begin(void)
Definition: graphics.in.h:2161
pval_map_type::const_iterator pval_map_const_iterator
Definition: graphics.in.h:2147
std::map< std::string, pval_map_type > plist_map_type
Definition: graphics.in.h:2144
plist_map_type::iterator plist_map_iterator
Definition: graphics.in.h:2149
plist_map_const_iterator begin(void) const
Definition: graphics.in.h:2162
pval_vector pval_map_type
Definition: graphics.in.h:2143
property & operator=(const octave_value &val)
Definition: graphics.in.h:2013
~property(void)
Definition: graphics.in.h:1964
int get_id(void) const
Definition: graphics.in.h:1994
void delete_listener(const octave_value &v=octave_value(), listener_mode mode=GCB_POSTSET)
Definition: graphics.in.h:2033
void set_id(int d)
Definition: graphics.in.h:1997
std::string get_name(void) const
Definition: graphics.in.h:1973
bool ok(void) const
Definition: graphics.in.h:1970
property clone(void) const
Definition: graphics.in.h:2045
std::string values_as_string(void) const
Definition: graphics.in.h:2007
octave_value get(void) const
Definition: graphics.in.h:2000
property(void)
Definition: graphics.in.h:1953
static OCTINTERP_API property create(const std::string &name, const graphics_handle &parent, const caseless_str &type, const octave_value_list &args)
Definition: graphics.cc:1969
void set_hidden(bool flag)
Definition: graphics.in.h:1988
bool is_radio(void) const
Definition: graphics.in.h:1991
bool is_hidden(void) const
Definition: graphics.in.h:1985
base_property * rep
Definition: graphics.in.h:2069
void set_parent(const graphics_handle &h)
Definition: graphics.in.h:1982
property(base_property *bp, bool persist=false)
Definition: graphics.in.h:1956
property(const property &p)
Definition: graphics.in.h:1959
void set_name(const std::string &name)
Definition: graphics.in.h:1976
void run_listeners(listener_mode mode=GCB_POSTSET)
Definition: graphics.in.h:2037
graphics_handle get_parent(void) const
Definition: graphics.in.h:1979
void add_listener(const octave_value &v, listener_mode mode=GCB_POSTSET)
Definition: graphics.in.h:2030
bool set(const octave_value &val, bool do_run=true, bool do_notify_toolkit=true)
Definition: graphics.in.h:2003
Cell values_as_cell(void) const
Definition: graphics.in.h:2010
void erase(iterator it)
Definition: graphics.in.h:2133
octave_value lookup(const std::string pname) const
Definition: graphics.in.h:2101
iterator find(const std::string pname)
Definition: graphics.in.h:2090
octave_value & operator[](const std::string pname)
Definition: graphics.in.h:2113
void erase(const std::string pname)
Definition: graphics.in.h:2126
const_iterator find(const std::string pname) const
Definition: graphics.in.h:2079
base_property * clone(void) const
Definition: graphics.in.h:963
std::string values_as_string(void) const
Definition: graphics.in.h:948
Cell values_as_cell(void) const
Definition: graphics.in.h:950
radio_property(const std::string &nm, const graphics_handle &h, const std::string &v)
Definition: graphics.in.h:931
std::string current_val
Definition: graphics.in.h:995
radio_property(const std::string &nm, const graphics_handle &h, const radio_values &v=radio_values())
Definition: graphics.in.h:926
bool is_radio(void) const
Definition: graphics.in.h:955
radio_property(const std::string &nm, const graphics_handle &h, const radio_values &v, const std::string &def)
Definition: graphics.in.h:936
const std::string & current_value(void) const
Definition: graphics.in.h:946
bool is(const caseless_str &v) const
Definition: graphics.in.h:952
radio_values vals
Definition: graphics.in.h:994
radio_property & operator=(const octave_value &val)
Definition: graphics.in.h:957
radio_property(const radio_property &p)
Definition: graphics.in.h:941
bool do_set(const octave_value &newval)
Definition: graphics.in.h:966
octave_value get(void) const
Definition: graphics.in.h:944
radio_values & operator=(const radio_values &a)
Definition: graphics.in.h:849
octave_idx_type nelem(void) const
Definition: graphics.in.h:915
bool contains(const std::string &val, std::string &match)
Definition: graphics.in.h:872
Cell values_as_cell(void) const
Definition: graphics.cc:1358
OCTINTERP_API radio_values(const std::string &opt_string="")
Definition: graphics.cc:1294
std::string values_as_string(void) const
Definition: graphics.cc:1329
std::set< caseless_str > possible_vals
Definition: graphics.in.h:920
radio_values(const radio_values &a)
Definition: graphics.in.h:846
bool validate(const std::string &val, std::string &match)
Definition: graphics.in.h:862
std::string default_value(void) const
Definition: graphics.in.h:860
std::string default_val
Definition: graphics.in.h:919
row_vector_property(const row_vector_property &p)
Definition: graphics.in.h:1512
row_vector_property(const std::string &nm, const graphics_handle &h, const octave_value &m)
Definition: graphics.in.h:1503
base_property * clone(void) const
Definition: graphics.in.h:1556
bool do_set(const octave_value &v)
Definition: graphics.in.h:1570
OCTINTERP_API bool validate(const octave_value &v)
void add_constraint(const finite_type finite)
Definition: graphics.in.h:1530
row_vector_property & operator=(const octave_value &val)
Definition: graphics.in.h:1550
void add_constraint(octave_idx_type len)
Definition: graphics.in.h:1540
void add_constraint(const dim_vector &dims)
Definition: graphics.in.h:1525
void add_constraint(const std::string &type)
Definition: graphics.in.h:1520
void add_constraint(const std::string &type, double val, bool inclusive)
Definition: graphics.in.h:1535
scaler(void)
Definition: graphics.in.h:198
scaler & operator=(const scaler &s)
Definition: graphics.in.h:229
Matrix scale(const Matrix &m) const
Definition: graphics.in.h:214
~scaler(void)
Definition: graphics.in.h:212
scaler(const std::string &s)
Definition: graphics.in.h:202
base_scaler * rep
Definition: graphics.in.h:266
double scale(double d) const
Definition: graphics.in.h:220
double unscale(double d) const
Definition: graphics.in.h:223
bool is_linear(void) const
Definition: graphics.in.h:226
NDArray scale(const NDArray &m) const
Definition: graphics.in.h:217
scaler(const scaler &s)
Definition: graphics.in.h:200
base_property * clone(void) const
Definition: graphics.in.h:560
bool do_set(const octave_value &val)
Definition: graphics.in.h:564
std::string string_value(void) const
Definition: graphics.in.h:536
desired_enum desired_type
Definition: graphics.in.h:672
string_array_property(const std::string &s, const graphics_handle &h, const Cell &c, const char &sep='|', const desired_enum &typ=string_t)
Definition: graphics.in.h:507
string_array_property(const string_array_property &p)
Definition: graphics.in.h:524
string_vector string_vector_value(void) const
Definition: graphics.in.h:552
string_array_property(const std::string &s, const graphics_handle &h, const std::string &val="", const char &sep='|', const desired_enum &typ=string_t)
Definition: graphics.in.h:484
octave_value get(void) const
Definition: graphics.in.h:528
string_vector str
Definition: graphics.in.h:674
Cell cell_value(void) const
Definition: graphics.in.h:550
string_array_property & operator=(const octave_value &val)
Definition: graphics.in.h:554
string_property & operator=(const octave_value &val)
Definition: graphics.in.h:448
std::string str
Definition: graphics.in.h:474
string_property(const string_property &p)
Definition: graphics.in.h:440
base_property * clone(void) const
Definition: graphics.in.h:454
bool do_set(const octave_value &val)
Definition: graphics.in.h:457
string_property(const std::string &s, const graphics_handle &h, const std::string &val="")
Definition: graphics.in.h:436
octave_value get(void) const
Definition: graphics.in.h:443
std::string string_value(void) const
Definition: graphics.in.h:446
string_vector & append(const std::string &s)
Definition: str-vec.cc:110
void resize(octave_idx_type n, const std::string &rfv="")
Definition: str-vec.h:95
octave_idx_type numel(void) const
Definition: str-vec.h:100
bool empty(void) const
Definition: str-vec.h:77
bool do_set(const octave_value &val)
Definition: graphics.in.h:769
string_vector value
Definition: graphics.in.h:835
text_label_property(const text_label_property &p)
Definition: graphics.in.h:730
text_label_property(const std::string &s, const graphics_handle &h, const Cell &c)
Definition: graphics.in.h:705
text_label_property(const std::string &s, const graphics_handle &h, const std::string &val="")
Definition: graphics.in.h:684
base_property * clone(void) const
Definition: graphics.in.h:765
text_label_property(const std::string &s, const graphics_handle &h, const NDArray &nda)
Definition: graphics.in.h:689
octave_value get(void) const
Definition: graphics.in.h:740
Cell cell_value(void) const
Definition: graphics.in.h:757
string_vector string_vector_value(void) const
Definition: graphics.in.h:753
charMatrix char_value(void) const
Definition: graphics.in.h:755
std::string string_value(void) const
Definition: graphics.in.h:748
text_label_property & operator=(const octave_value &val)
Definition: graphics.in.h:759
bool empty(void) const
Definition: graphics.in.h:734
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:137
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:1065
void error(const char *fmt,...)
Definition: error.cc:968
#define panic_impossible()
Definition: error.h:380
ColumnVector cross(const ColumnVector &v1, const ColumnVector &v2)
Definition: graphics.cc:5899
static bool is_handle_visible(const graphics_handle &h)
Definition: graphics.cc:12494
std::pair< std::string, octave_value > pval_pair
Definition: graphics.in.h:2074
finite_type
Definition: graphics.in.h:1169
@ NOT_INF
Definition: graphics.in.h:1173
@ NOT_NAN
Definition: graphics.in.h:1172
@ NO_CHECK
Definition: graphics.in.h:1170
@ FINITE
Definition: graphics.in.h:1171
listener_mode
Definition: graphics.in.h:278
@ GCB_PREDELETE
Definition: graphics.in.h:278
@ GCB_POSTSET
Definition: graphics.in.h:278
@ GCB_PERSISTENT
Definition: graphics.in.h:278
QString name
#define octave_NaN
Definition: lo-ieee.h:44
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
T octave_idx_type m
Definition: mx-inlines.cc:773
octave_idx_type n
Definition: mx-inlines.cc:753
T * r
Definition: mx-inlines.cc:773
bool isfinite(double x)
Definition: lo-mappers.h:192
bool isnan(bool)
Definition: lo-mappers.h:178
bool isinf(double x)
Definition: lo-mappers.h:203
double round(double x)
Definition: lo-mappers.h:136
static int left
Definition: randmtzig.cc:191
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
const octave_base_value & a2
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
F77_RET_T len
Definition: xerbla.cc:61