Mercurial > hg > octave-nkf
view src/graphics.cc @ 7259:9f02c32eb70d ss-2-9-18
[project @ 2007-12-05 18:02:33 by jwe]
author | jwe |
---|---|
date | Wed, 05 Dec 2007 18:02:34 +0000 |
parents | 3a695b7adf8e |
children | 9c6e93b7a3f7 |
line wrap: on
line source
/* Copyright (C) 2007 John W. Eaton This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <cctype> #include <cfloat> #include <algorithm> #include <list> #include <map> #include <set> #include <string> #include "defun.h" #include "error.h" #include "graphics.h" #include "ov.h" #include "oct-obj.h" #include "oct-map.h" #include "ov-fcn-handle.h" #include "parse.h" #include "unwind-prot.h" static void gripe_set_invalid (const std::string& pname) { error ("set: invalid value for %s property", pname.c_str ()); } // --------------------------------------------------------------------- radio_values::radio_values (const std::string& opt_string) { size_t beg = 0; size_t len = opt_string.length (); bool done = len == 0; while (! done) { size_t end = opt_string.find ('|', beg); if (end == std::string::npos) { end = len; done = true; } std::string t = opt_string.substr (beg, end-beg); // Might want more error checking here... if (t[0] == '{') { t = t.substr (1, t.length () - 2); default_val = t; } else if (beg == 0) // ensure default value default_val = t; possible_vals.insert (t); beg = end + 1; } } bool color_values::str2rgb (std::string str) { double tmp_rgb[3] = {0, 0, 0}; bool retval = true; unsigned int len = str.length(); std::transform (str.begin (), str.end (), str.begin (), tolower); if (str.compare(0, len, "blue", 0, len) == 0) tmp_rgb[2] = 1; else if (str.compare(0, len, "black", 0, len) == 0 || str.compare(0, len, "k", 0, len) == 0) tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 0; else if (str.compare(0, len, "red", 0, len) == 0) tmp_rgb[0] = 1; else if (str.compare(0, len, "green", 0, len) == 0) tmp_rgb[1] = 1; else if (str.compare(0, len, "yellow", 0, len) == 0) tmp_rgb[0] = tmp_rgb[1] = 1; else if (str.compare(0, len, "magenta", 0, len) == 0) tmp_rgb[0] = tmp_rgb[2] = 1; else if (str.compare(0, len, "cyan", 0, len) == 0) tmp_rgb[1] = tmp_rgb[2] = 1; else if (str.compare(0, len, "white", 0, len) == 0 || str.compare(0, len, "w", 0, len) == 0) tmp_rgb[0] = tmp_rgb[1] = tmp_rgb[2] = 1; else retval = false; if (retval) { for (int i = 0; i < 3; i++) xrgb[i] = tmp_rgb[i]; } return retval; } color_property::color_property (const octave_value& val) : radio_val (), current_val () { // FIXME -- need some error checking here. if (val.is_string ()) { std::string s = val.string_value (); if (! s.empty ()) { color_values col (s); if (! error_state) { color_val = col; current_type = color_t; } } else error ("invalid color specification"); } else if (val.is_real_matrix ()) { Matrix m = val.matrix_value (); if (m.numel () == 3) { color_values col (m (0), m (1), m(2)); if (! error_state) { color_val = col; current_type = color_t; } } else error ("invalid color specification"); } else error ("invalid color specification"); } // We also provide this assignment operator so that assignment from an // octave_value object can happen without wiping out list of possible // radio_values set in color_property constructor. color_property& color_property::operator = (const octave_value& val) { if (val.is_string ()) { std::string s = val.string_value (); if (! s.empty ()) { if (radio_val.contains (s)) { current_val = s; current_type = radio_t; } else { color_values col (s); if (! error_state) { color_val = col; current_type = color_t; } else error ("invalid color specification"); } } else error ("invalid color specification"); } else if (val.is_real_matrix ()) { Matrix m = val.matrix_value (); if (m.numel () == 3) { color_values col (m (0), m (1), m(2)); if (! error_state) { color_val = col; current_type = color_t; } } else error ("invalid color specification"); } else error ("invalid color specification"); return *this; } void property_list::set (const caseless_str& name, const octave_value& val) { size_t offset = 0; size_t len = name.length (); if (len > 4) { caseless_str pfx = name.substr (0, 4); if (pfx.compare ("axes") || pfx.compare ("line") || pfx.compare ("text")) offset = 4; else if (len > 5) { pfx = name.substr (0, 5); if (pfx.compare ("image") || pfx.compare ("patch")) offset = 5; else if (len > 6) { pfx = name.substr (0, 6); if (pfx.compare ("figure")) offset = 6; else if (len > 7) { pfx = name.substr (0, 7); if (pfx.compare ("surface")) offset = 7; } } } if (offset > 0) { // FIXME -- should we validate property names and values here? std::string pname = name.substr (offset); std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower); std::transform (pname.begin (), pname.end (), pname.begin (), tolower); bool remove = false; if (val.is_string ()) { caseless_str tval = val.string_value (); remove = tval.compare ("remove"); } pval_map_type& pval_map = plist_map[pfx]; if (remove) { pval_map_iterator p = pval_map.find (pname); if (p != pval_map.end ()) pval_map.erase (p); } else pval_map[pname] = val; } } if (offset == 0) error ("invalid default property specification"); } octave_value property_list::lookup (const caseless_str& name) const { octave_value retval; size_t offset = 0; size_t len = name.length (); if (len > 4) { caseless_str pfx = name.substr (0, 4); if (pfx.compare ("axes") || pfx.compare ("line") || pfx.compare ("text")) offset = 4; else if (len > 5) { pfx = name.substr (0, 5); if (pfx.compare ("image") || pfx.compare ("patch")) offset = 5; else if (len > 6) { pfx = name.substr (0, 6); if (pfx.compare ("figure")) offset = 6; else if (len > 7) { pfx = name.substr (0, 7); if (pfx.compare ("surface")) offset = 7; } } } if (offset > 0) { std::string pname = name.substr (offset); std::transform (pfx.begin (), pfx.end (), pfx.begin (), tolower); std::transform (pname.begin (), pname.end (), pname.begin (), tolower); plist_map_const_iterator p = find (pfx); if (p != end ()) { const pval_map_type& pval_map = p->second; pval_map_const_iterator q = pval_map.find (pname); if (q != pval_map.end ()) retval = q->second; } } } return retval; } Octave_map property_list::as_struct (const std::string& prefix_arg) const { Octave_map m; for (plist_map_const_iterator p = begin (); p != end (); p++) { std::string prefix = prefix_arg + p->first; const pval_map_type pval_map = p->second; for (pval_map_const_iterator q = pval_map.begin (); q != pval_map.end (); q++) m.assign (prefix + q->first, q->second); } return m; } graphics_handle::graphics_handle (const octave_value& a) : val (octave_NaN) { if (a.is_empty ()) /* do nothing */; else { double tval = a.double_value (); if (! error_state) val = tval; else error ("invalid graphics handle"); } } void graphics_object::set (const octave_value_list& args) { int nargin = args.length (); if (nargin == 0) rep->defaults (); else if (nargin % 2 == 0) { for (int i = 0; i < nargin; i += 2) { caseless_str name = args(i).string_value (); if (! error_state) { octave_value val = args(i+1); if (val.is_string ()) { caseless_str tval = val.string_value (); if (tval.compare ("default")) val = get_default (name); else if (tval.compare ("factory")) val = get_factory_default (name); } if (error_state) break; rep->set (name, val); } else error ("set: expecting argument %d to be a property name", i); } } else error ("set: invalid number of arguments"); } graphics_handle gh_manager::get_handle (const std::string& go_name) { graphics_handle retval; if (go_name == "figure") { // We always want the lowest unused figure number. retval = 1; while (handle_map.find (retval) != handle_map.end ()) retval++; } else { free_list_iterator p = handle_free_list.begin (); if (p != handle_free_list.end ()) { retval = *p; handle_free_list.erase (p); } else retval = next_handle--; } return retval; } void gh_manager::do_free (const graphics_handle& h) { if (h.ok ()) { if (h.value () != 0) { iterator p = handle_map.find (h); if (p != handle_map.end ()) { handle_map.erase (p); if (h.value () < 0) handle_free_list.insert (h); } else error ("graphics_handle::free: invalid object %g", h.value ()); } else error ("graphics_handle::free: can't delete root figure"); } } gh_manager *gh_manager::instance = 0; static void xset (const graphics_handle& h, const caseless_str& name, const octave_value& val) { graphics_object obj = gh_manager::get_object (h); obj.set (name, val); } static void xset (const graphics_handle& h, const octave_value_list& args) { if (args.length () > 0) { graphics_object obj = gh_manager::get_object (h); obj.set (args); } } static octave_value xget (const graphics_handle& h, const caseless_str& name) { graphics_object obj = gh_manager::get_object (h); return obj.get (name); } static graphics_handle reparent (const octave_value& ov, const std::string& who, const std::string& property, const graphics_handle& new_parent, bool adopt = true) { graphics_handle h = octave_NaN; double val = ov.double_value (); if (! error_state) { h = gh_manager::lookup (val); if (h.ok ()) { graphics_object obj = gh_manager::get_object (h); graphics_handle parent_h = obj.get_parent (); graphics_object parent_obj = gh_manager::get_object (parent_h); parent_obj.remove_child (h); if (adopt) obj.set ("parent", new_parent.value ()); else obj.reparent (new_parent); } else error ("%s: invalid graphics handle (= %g) for %s", who.c_str (), val, property.c_str ()); } else error ("%s: expecting %s to be a graphics handle", who.c_str (), property.c_str ()); return h; } // This function is NOT equivalent to the scripting language function gcf. graphics_handle gcf (void) { octave_value val = xget (0, "currentfigure"); return val.is_empty () ? octave_NaN : val.double_value (); } // This function is NOT equivalent to the scripting language function gca. graphics_handle gca (void) { octave_value val = xget (gcf (), "currentaxes"); return val.is_empty () ? octave_NaN : val.double_value (); } static void adopt (const graphics_handle& p, const graphics_handle& h) { graphics_object parent_obj = gh_manager::get_object (p); parent_obj.adopt (h); } static bool is_handle (const graphics_handle& h) { return h.ok (); } static bool is_handle (double val) { graphics_handle h = gh_manager::lookup (val); return h.ok (); } static bool is_handle (const octave_value& val) { return val.is_real_scalar () && is_handle (val.double_value ()); } static bool is_figure (double val) { graphics_object obj = gh_manager::get_object (val); return obj && obj.isa ("figure"); } // --------------------------------------------------------------------- static int compare (const void *a_arg, const void *b_arg) { double a = *(static_cast<const double *> (a_arg)); double b = *(static_cast<const double *> (b_arg)); return a > b ? 1 : (a < b) ? -1 : 0; } static Matrix maybe_set_children (const Matrix& kids, const octave_value& val) { const Matrix new_kids = val.matrix_value (); bool ok = true; if (! error_state) { if (kids.numel () == new_kids.numel ()) { Matrix t1 = kids; Matrix t2 = new_kids; t1.qsort (compare); t2.qsort (compare); if (t1 != t2) ok = false; } else ok = false; if (! ok) error ("set: new children must be a permutation of existing children"); } else { ok = false; error ("set: expecting children to be array of graphics handles"); } return ok ? new_kids : kids; } void base_properties::set_from_list (base_graphics_object& obj, property_list& defaults) { std::string go_name = graphics_object_name (); property_list::plist_map_const_iterator p = defaults.find (go_name); if (p != defaults.end ()) { const property_list::pval_map_type pval_map = p->second; for (property_list::pval_map_const_iterator q = pval_map.begin (); q != pval_map.end (); q++) { std::string pname = q->first; obj.set (pname, q->second); if (error_state) { error ("error setting default property %s", pname.c_str ()); break; } } } } void base_properties::remove_child (const graphics_handle& h) { octave_idx_type k = -1; octave_idx_type n = children.numel (); for (octave_idx_type i = 0; i < n; i++) { if (h.value () == children(i)) { k = i; break; } } if (k >= 0) { Matrix new_kids (1, n-1); octave_idx_type j = 0; for (octave_idx_type i = 0; i < n; i++) { if (i != k) new_kids(j++) = children(i); } children = new_kids; } } void base_properties::set_tag (const octave_value& val) { std::string tmp = val.string_value (); if (! error_state) tag = tmp; else error ("set: expecting tag to be a character string"); } void base_properties::set_parent (const octave_value& val) { double tmp = val.double_value (); graphics_handle new_parent = octave_NaN; if (! error_state) { new_parent = gh_manager::lookup (tmp); if (new_parent.ok ()) { graphics_object parent_obj = gh_manager::get_object (parent); parent_obj.remove_child (__myhandle__); parent = new_parent; ::adopt (parent, __myhandle__); } else error ("set: invalid graphics handle (= %g) for parent", tmp); } else error ("set: expecting parent to be a graphics handle"); } void base_properties::mark_modified (void) { __modified__ = true; graphics_object parent_obj = gh_manager::get_object (parent); parent_obj.mark_modified (); } void base_properties::override_defaults (base_graphics_object& obj) { graphics_object parent_obj = gh_manager::get_object (parent); parent_obj.override_defaults (obj); } void base_properties::update_axis_limits (const std::string& axis_type) const { graphics_handle h = (type == "axes") ? __myhandle__ : parent; graphics_object obj = gh_manager::get_object (h); if (obj.isa ("axes")) obj.update_axis_limits (axis_type); } void base_properties::delete_children (void) { octave_idx_type n = children.numel (); for (octave_idx_type i = 0; i < n; i++) gh_manager::free (children(i)); } void root_figure::properties::set_currentfigure (const graphics_handle& val) { if (error_state) return; if (xisnan (val.value ()) || is_handle (val)) { currentfigure = val; gh_manager::push_figure (currentfigure); } else gripe_set_invalid ("currentfigure"); } void root_figure::properties::set (const caseless_str& name, const octave_value& val) { if (name.compare ("tag")) set_tag (val); else if (name.compare ("currentfigure")) set_currentfigure (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("visible")) set_visible (val); else warning ("set: invalid property `%s'", name.c_str ()); } octave_value root_figure::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("currentfigure", currentfigure.as_octave_value ()); m.assign ("children", children); m.assign ("visible", visible); return m; } octave_value root_figure::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = type; else if (name.compare ("tag")) retval = type; else if (name.compare ("currentfigure")) retval = currentfigure.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("visible")) retval = visible; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list root_figure::factory_properties = root_figure::init_factory_properties (); std::string root_figure::properties::go_name ("root figure"); // --------------------------------------------------------------------- figure::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), __plot_stream__ (Matrix ()), __enhanced__ (false), nextplot ("replace"), closerequestfcn (make_fcn_handle ("closereq")), currentaxes (octave_NaN), colormap (), visible ("on"), paperorientation ("portrait") { } void figure::properties::set_currentaxes (const graphics_handle& val) { if (error_state) return; if (xisnan (val.value ()) || is_handle (val)) currentaxes = val; else gripe_set_invalid ("currentaxes"); } void figure::properties::set_visible (const octave_value& val) { std::string s = val.string_value (); if (! error_state) { if (s == "on") xset (0, "currentfigure", __myhandle__.value ()); visible = val; } } void figure::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("__plot_stream__")) set___plot_stream__ (val); else if (name.compare ("__enhanced__")) set___enhanced__ (val); else if (name.compare ("nextplot")) set_nextplot (val); else if (name.compare ("closerequestfcn")) set_closerequestfcn (val); else if (name.compare ("currentaxes")) set_currentaxes (val); else if (name.compare ("colormap")) set_colormap (val); else if (name.compare ("visible")) set_visible (val); else if (name.compare ("paperorientation")) set_paperorientation (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value figure::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("__plot_stream__", __plot_stream__); m.assign ("__enhanced__", __enhanced__); m.assign ("nextplot", nextplot); m.assign ("closerequestfcn", closerequestfcn); m.assign ("currentaxes", currentaxes.as_octave_value ()); m.assign ("colormap", colormap); m.assign ("visible", visible); m.assign ("paperorientation", paperorientation); return m; } octave_value figure::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("__plot_stream__")) retval = __plot_stream__; else if (name.compare ("__enhanced__")) retval = __enhanced__; else if (name.compare ("nextplot")) retval = nextplot; else if (name.compare ("closerequestfcn")) retval = closerequestfcn; else if (name.compare ("currentaxes")) retval = currentaxes.as_octave_value (); else if (name.compare ("colormap")) retval = colormap; else if (name.compare ("visible")) retval = visible; else if (name.compare ("paperorientation")) retval = paperorientation; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } void figure::properties::close (void) { if (! __plot_stream__.is_empty ()) { octave_value_list args; args(1) = "\nquit;\n"; args(0) = __plot_stream__; feval ("fputs", args); args.resize (1); feval ("fflush", args); feval ("pclose", args); } gh_manager::pop_figure (__myhandle__); graphics_handle cf = gh_manager::current_figure (); xset (0, "currentfigure", cf.value ()); } property_list::pval_map_type figure::properties::factory_defaults (void) { property_list::pval_map_type m; m["nextplot"] = "replace"; // m["closerequestfcn"] = make_fcn_handle ("closereq"); m["colormap"] = colormap_property (); m["visible"] = "on"; m["paperorientation"] = "portrait"; return m; } octave_value figure::get_default (const caseless_str& name) const { octave_value retval = default_properties.lookup (name); if (retval.is_undefined ()) { graphics_handle parent = get_parent (); graphics_object parent_obj = gh_manager::get_object (parent); retval = parent_obj.get_default (name); } return retval; } std::string figure::properties::go_name ("figure"); // --------------------------------------------------------------------- static Matrix default_colororder (void) { Matrix retval (7, 3, 0.0); retval(0,2) = 1.0; retval(1,1) = 0.5; retval(2,0) = 1.0; retval(3,1) = 0.75; retval(3,2) = 0.75; retval(4,0) = 0.75; retval(4,2) = 0.75; retval(5,0) = 0.75; retval(5,1) = 0.75; retval(6,0) = 0.25; retval(6,1) = 0.25; retval(6,2) = 0.25; return retval; } axes::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), position (Matrix ()), title (octave_NaN), box ("on"), key ("off"), keybox ("off"), keypos (1), colororder (default_colororder ()), dataaspectratio (Matrix (1, 3, 1.0)), dataaspectratiomode ("auto"), xlim (), ylim (), zlim (), clim (), xlimmode (radio_values ("{auto}|manual")), ylimmode (radio_values ("{auto}|manual")), zlimmode (radio_values ("{auto}|manual")), climmode (radio_values ("{auto}|manual")), xlabel (octave_NaN), ylabel (octave_NaN), zlabel (octave_NaN), xgrid ("off"), ygrid ("off"), zgrid ("off"), xminorgrid ("off"), yminorgrid ("off"), zminorgrid ("off"), xtick (Matrix ()), ytick (Matrix ()), ztick (Matrix ()), xtickmode ("auto"), ytickmode ("auto"), ztickmode ("auto"), xticklabel (""), yticklabel (""), zticklabel (""), xticklabelmode ("auto"), yticklabelmode ("auto"), zticklabelmode ("auto"), color (color_values(0, 0, 0), radio_values ("flat|none|interp")), xcolor (), ycolor (), zcolor (), xscale (radio_values ("{linear}|log")), yscale (radio_values ("{linear}|log")), zscale (radio_values ("{linear}|log")), xdir ("normal"), ydir ("normal"), zdir ("normal"), xaxislocation ("bottom"), yaxislocation ("left"), view (), visible ("on"), nextplot ("replace"), outerposition (), activepositionproperty (radio_values ("{outerposition}|position")), __colorbar__ (radio_values ("{none}|north|south|east|west|northoutside|southoutside|eastoutside|westoutside")) { Matrix tlim (1, 2, 0.0); tlim(1) = 1; xlim = tlim; ylim = tlim; zlim = tlim; Matrix cl (1, 2, 0); cl(1) = 1; clim = cl; Matrix tview (1, 2, 0.0); tview(1) = 90; view = tview; Matrix touterposition (1, 4, 0.0); touterposition(2) = 1; touterposition(3) = 1; outerposition = touterposition; } void axes::properties::set_title (const graphics_handle& val) { if (! error_state) { gh_manager::free (title); title = val; } } void axes::properties::set_title (const octave_value& val) { set_title (::reparent (val, "set", "title", __myhandle__, false)); } void axes::properties::set_xlabel (const graphics_handle& val) { if (! error_state) { gh_manager::free (xlabel); xlabel = val; } } void axes::properties::set_xlabel (const octave_value& val) { set_xlabel (::reparent (val, "set", "xlabel", __myhandle__, false)); } void axes::properties::set_ylabel (const graphics_handle& val) { if (! error_state) { gh_manager::free (ylabel); ylabel = val; } } void axes::properties::set_ylabel (const octave_value& val) { set_ylabel (::reparent (val, "set", "ylabel", __myhandle__, false)); } void axes::properties::set_zlabel (const graphics_handle& val) { if (! error_state) { gh_manager::free (zlabel); zlabel = val; } } void axes::properties::set_zlabel (const octave_value& val) { set_zlabel (::reparent (val, "set", "zlabel", __myhandle__, false)); } void axes::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("position")) set_position (val); else if (name.compare ("title")) set_title (val); else if (name.compare ("box")) set_box (val); else if (name.compare ("key")) set_key (val); else if (name.compare ("keybox")) set_keybox (val); else if (name.compare ("keypos")) set_keypos (val); else if (name.compare ("colororder")) set_colororder (val); else if (name.compare ("dataaspectratio")) set_dataaspectratio (val); else if (name.compare ("dataaspectratiomode")) set_dataaspectratiomode (val); else if (name.compare ("xlim")) set_xlim (val); else if (name.compare ("ylim")) set_ylim (val); else if (name.compare ("zlim")) set_zlim (val); else if (name.compare ("clim")) set_clim (val); else if (name.compare ("xlimmode")) set_xlimmode (val); else if (name.compare ("ylimmode")) set_ylimmode (val); else if (name.compare ("zlimmode")) set_zlimmode (val); else if (name.compare ("climmode")) set_climmode (val); else if (name.compare ("xlabel")) set_xlabel (val); else if (name.compare ("ylabel")) set_ylabel (val); else if (name.compare ("zlabel")) set_zlabel (val); else if (name.compare ("xgrid")) set_xgrid (val); else if (name.compare ("ygrid")) set_ygrid (val); else if (name.compare ("zgrid")) set_zgrid (val); else if (name.compare ("xminorgrid")) set_xminorgrid (val); else if (name.compare ("yminorgrid")) set_yminorgrid (val); else if (name.compare ("zminorgrid")) set_zminorgrid (val); else if (name.compare ("xtick")) set_xtick (val); else if (name.compare ("ytick")) set_ytick (val); else if (name.compare ("ztick")) set_ztick (val); else if (name.compare ("xtickmode")) set_xtickmode (val); else if (name.compare ("ytickmode")) set_ytickmode (val); else if (name.compare ("ztickmode")) set_ztickmode (val); else if (name.compare ("xticklabel")) set_xticklabel (val); else if (name.compare ("yticklabel")) set_yticklabel (val); else if (name.compare ("zticklabel")) set_zticklabel (val); else if (name.compare ("xticklabelmode")) set_xticklabelmode (val); else if (name.compare ("yticklabelmode")) set_yticklabelmode (val); else if (name.compare ("zticklabelmode")) set_zticklabelmode (val); else if (name.compare ("color")) set_color (val); else if (name.compare ("xcolor")) set_xcolor (val); else if (name.compare ("ycolor")) set_ycolor (val); else if (name.compare ("zcolor")) set_zcolor (val); else if (name.compare ("xscale")) set_xscale (val); else if (name.compare ("yscale")) set_yscale (val); else if (name.compare ("zscale")) set_zscale (val); else if (name.compare ("xdir")) set_xdir (val); else if (name.compare ("ydir")) set_ydir (val); else if (name.compare ("zdir")) set_zdir (val); else if (name.compare ("xaxislocation")) set_xaxislocation (val); else if (name.compare ("yaxislocation")) set_yaxislocation (val); else if (name.compare ("view")) set_view (val); else if (name.compare ("visible")) set_visible (val); else if (name.compare ("nextplot")) set_nextplot (val); else if (name.compare ("outerposition")) set_outerposition (val); else if (name.compare ("activepositionproperty")) set_activepositionproperty (val); else if (name.compare ("__colorbar__")) set___colorbar__ (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } void axes::properties::set_defaults (base_graphics_object& obj, const std::string& mode) { position = Matrix (); title = octave_NaN; box = "on"; key = "off"; keybox = "off"; keypos = 1; colororder = default_colororder (); dataaspectratio = Matrix (1, 3, 1.0); dataaspectratiomode = "auto"; Matrix tlim (1, 2, 0.0); tlim(1) = 1; xlim = tlim; ylim = tlim; zlim = tlim; Matrix cl (1, 2, 0); cl(1) = 1; clim = cl; xlimmode = radio_property (radio_values ("{auto}|manual")); ylimmode = radio_property (radio_values ("{auto}|manual")); zlimmode = radio_property (radio_values ("{auto}|manual")); climmode = radio_property (radio_values ("{auto}|manual")); xlabel = octave_NaN; ylabel = octave_NaN; zlabel = octave_NaN; xgrid = "off"; ygrid = "off"; zgrid = "off"; xminorgrid = "off"; yminorgrid = "off"; zminorgrid = "off"; xtick = Matrix (); ytick = Matrix (); ztick = Matrix (); xtickmode = "auto"; ytickmode = "auto"; ztickmode = "auto"; xticklabel = ""; yticklabel = ""; zticklabel = ""; xticklabelmode = "auto"; yticklabelmode = "auto"; zticklabelmode = "auto"; color = color_property (color_values (0, 0, 0), radio_values("flat|none|interp")); xcolor = color_property ("black"); ycolor = color_property ("black"); zcolor = color_property ("black"); xscale = radio_property (radio_values ("{linear}|log")); yscale = radio_property (radio_values ("{linear}|log")); zscale = radio_property (radio_values ("{linear}|log")); xdir = "normal"; ydir = "normal"; zdir = "normal"; xaxislocation = "left"; yaxislocation = "bottom"; Matrix tview (1, 2, 0.0); tview(1) = 90; view = tview; visible = "on"; nextplot = "replace"; // FIXME -- this is not quite right; we should preserve // "position" and "units". if (mode != "replace") { Matrix touterposition (1, 4, 0.0); touterposition(2) = 1; touterposition(3) = 1; outerposition = touterposition; } activepositionproperty = radio_property (radio_values ("{outerposition}|position")); __colorbar__ = radio_property (radio_values ("{none}|north|south|east|west|northoutside|southoutside|eastoutside|westoutside")); delete_children (); children = Matrix (); override_defaults (obj); } graphics_handle axes::properties::get_title (void) const { if (! title.ok ()) title = gh_manager::make_graphics_handle ("text", __myhandle__); return title; } graphics_handle axes::properties::get_xlabel (void) const { if (! xlabel.ok ()) xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); return xlabel; } graphics_handle axes::properties::get_ylabel (void) const { if (! ylabel.ok ()) ylabel = gh_manager::make_graphics_handle ("text", __myhandle__); return ylabel; } graphics_handle axes::properties::get_zlabel (void) const { if (! zlabel.ok ()) zlabel = gh_manager::make_graphics_handle ("text", __myhandle__); return zlabel; } octave_value axes::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("position", position); m.assign ("title", get_title().as_octave_value ()); m.assign ("box", box); m.assign ("key", key); m.assign ("keybox", keybox); m.assign ("keypos", keypos); m.assign ("colororder", colororder); m.assign ("dataaspectratio", dataaspectratio); m.assign ("dataaspectratiomode", dataaspectratiomode); m.assign ("xlim", xlim); m.assign ("ylim", ylim); m.assign ("zlim", zlim); m.assign ("clim", clim); m.assign ("xlimmode", xlimmode); m.assign ("ylimmode", ylimmode); m.assign ("zlimmode", zlimmode); m.assign ("climmode", climmode); m.assign ("xlabel", get_xlabel().as_octave_value ()); m.assign ("ylabel", get_ylabel().as_octave_value ()); m.assign ("zlabel", get_zlabel().as_octave_value ()); m.assign ("xgrid", xgrid); m.assign ("ygrid", ygrid); m.assign ("zgrid", zgrid); m.assign ("xminorgrid", xminorgrid); m.assign ("yminorgrid", yminorgrid); m.assign ("zminorgrid", zminorgrid); m.assign ("xtick", xtick); m.assign ("ytick", ytick); m.assign ("ztick", ztick); m.assign ("xtickmode", xtickmode); m.assign ("ytickmode", ytickmode); m.assign ("ztickmode", ztickmode); m.assign ("xticklabel", xticklabel); m.assign ("yticklabel", yticklabel); m.assign ("zticklabel", zticklabel); m.assign ("xticklabelmode", xticklabelmode); m.assign ("yticklabelmode", yticklabelmode); m.assign ("zticklabelmode", zticklabelmode); m.assign ("color", color); m.assign ("xcolor", xcolor); m.assign ("ycolor", ycolor); m.assign ("zcolor", zcolor); m.assign ("xscale", xscale); m.assign ("yscale", yscale); m.assign ("zscale", zscale); m.assign ("xdir", xdir); m.assign ("ydir", ydir); m.assign ("zdir", zdir); m.assign ("xaxislocation", xaxislocation); m.assign ("yaxislocation", yaxislocation); m.assign ("view", view); m.assign ("visible", visible); m.assign ("nextplot", nextplot); m.assign ("outerposition", outerposition); m.assign ("activepositionproperty", activepositionproperty); m.assign ("__colorbar__", __colorbar__); return m; } octave_value axes::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("position")) retval = position; else if (name.compare ("title")) retval = get_title().as_octave_value (); else if (name.compare ("box")) retval = box; else if (name.compare ("key")) retval = key; else if (name.compare ("keybox")) retval = keybox; else if (name.compare ("keypos")) retval = keypos; else if (name.compare ("colororder")) retval = colororder; else if (name.compare ("dataaspectratio")) retval = dataaspectratio; else if (name.compare ("dataaspectratiomode")) retval = dataaspectratiomode; else if (name.compare ("xlim")) retval = xlim; else if (name.compare ("ylim")) retval = ylim; else if (name.compare ("zlim")) retval = zlim; else if (name.compare ("clim")) retval = clim; else if (name.compare ("xlimmode")) retval = xlimmode; else if (name.compare ("ylimmode")) retval = ylimmode; else if (name.compare ("zlimmode")) retval = zlimmode; else if (name.compare ("climmode")) retval = climmode; else if (name.compare ("xlabel")) retval = get_xlabel().as_octave_value (); else if (name.compare ("ylabel")) retval = get_ylabel().as_octave_value (); else if (name.compare ("zlabel")) retval = get_zlabel().as_octave_value (); else if (name.compare ("xgrid")) retval = xgrid; else if (name.compare ("ygrid")) retval = ygrid; else if (name.compare ("zgrid")) retval = zgrid; else if (name.compare ("xminorgrid")) retval = xminorgrid; else if (name.compare ("yminorgrid")) retval = yminorgrid; else if (name.compare ("zminorgrid")) retval = zminorgrid; else if (name.compare ("xtick")) retval = xtick; else if (name.compare ("ytick")) retval = ytick; else if (name.compare ("ztick")) retval = ztick; else if (name.compare ("xtickmode")) retval = xtickmode; else if (name.compare ("ytickmode")) retval = ytickmode; else if (name.compare ("ztickmode")) retval = ztickmode; else if (name.compare ("xticklabel")) retval = xticklabel; else if (name.compare ("yticklabel")) retval = yticklabel; else if (name.compare ("zticklabel")) retval = zticklabel; else if (name.compare ("xticklabelmode")) retval = xticklabelmode; else if (name.compare ("yticklabelmode")) retval = yticklabelmode; else if (name.compare ("zticklabelmode")) retval = zticklabelmode; else if (name.compare ("color")) retval = color; else if (name.compare ("xcolor")) retval = xcolor; else if (name.compare ("ycolor")) retval = ycolor; else if (name.compare ("zcolor")) retval = zcolor; else if (name.compare ("xscale")) retval = xscale; else if (name.compare ("yscale")) retval = yscale; else if (name.compare ("zscale")) retval = zscale; else if (name.compare ("xdir")) retval = xdir; else if (name.compare ("ydir")) retval = ydir; else if (name.compare ("zdir")) retval = zdir; else if (name.compare ("xaxislocation")) retval = xaxislocation; else if (name.compare ("yaxislocation")) retval = yaxislocation; else if (name.compare ("view")) retval = view; else if (name.compare ("visible")) retval = visible; else if (name.compare ("nextplot")) retval = nextplot; else if (name.compare ("outerposition")) retval = outerposition; else if (name.compare ("activepositionproperty")) retval = activepositionproperty; else if (name.compare ("__colorbar__")) retval = __colorbar__; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } void axes::properties::remove_child (const graphics_handle& h) { if (title.ok () && h == title) title = gh_manager::make_graphics_handle ("text", __myhandle__); else if (xlabel.ok () && h == xlabel) xlabel = gh_manager::make_graphics_handle ("text", __myhandle__); else if (ylabel.ok () && h == ylabel) ylabel = gh_manager::make_graphics_handle ("text", __myhandle__); else if (zlabel.ok () && h == zlabel) zlabel = gh_manager::make_graphics_handle ("text", __myhandle__); else base_properties::remove_child (h); } void axes::properties::delete_children (void) { base_properties::delete_children (); gh_manager::free (title); gh_manager::free (xlabel); gh_manager::free (ylabel); gh_manager::free (zlabel); } property_list::pval_map_type axes::properties::factory_defaults (void) { property_list::pval_map_type m; m["position"] = Matrix (); m["title"] = octave_NaN; m["box"] = "on"; m["key"] = "off"; m["keybox"] = "off"; m["keypos"] = 1; m["colororder"] = default_colororder (); m["dataaspectratio"] = Matrix (1, 3, 1.0); m["dataaspectratiomode"] = "auto"; Matrix tlim (1, 2, 0.0); tlim(1) = 1; m["xlim"] = tlim; m["ylim"] = tlim; m["zlim"] = tlim; Matrix cl(1, 2, 0); cl(1) = 1; m["clim"] = cl; m["xlimmode"] = radio_property (radio_values ("{auto}|manual")); m["ylimmode"] = radio_property (radio_values ("{auto}|manual")); m["zlimmode"] = radio_property (radio_values ("{auto}|manual")); m["climmode"] = radio_property (radio_values ("{auto}|manual")); m["xlabel"] = octave_NaN; m["ylabel"] = octave_NaN; m["zlabel"] = octave_NaN; m["xgrid"] = "off"; m["ygrid"] = "off"; m["zgrid"] = "off"; m["xminorgrid"] = "off"; m["yminorgrid"] = "off"; m["zminorgrid"] = "off"; m["xtick"] = Matrix (); m["ytick"] = Matrix (); m["ztick"] = Matrix (); m["xtickmode"] = "auto"; m["ytickmode"] = "auto"; m["ztickmode"] = "auto"; m["xticklabel"] = ""; m["yticklabel"] = ""; m["zticklabel"] = ""; m["xticklabelmode"] = "auto"; m["yticklabelmode"] = "auto"; m["zticklabelmode"] = "auto"; m["color"] = color_property (color_values (0, 0, 0), radio_values("flat|none|interp")); m["xcolor"] = color_property ("black"); m["ycolor"] = color_property ("black"); m["zcolor"] = color_property ("black"); m["xscale"] = radio_property (radio_values ("{linear}|log")); m["yscale"] = radio_property (radio_values ("{linear}|log")); m["zscale"] = radio_property (radio_values ("{linear}|log")); m["xdir"] = "normal"; m["ydir"] = "normal"; m["zdir"] = "normal"; m["xaxislocation"] = "bottom"; m["yaxislocation"] = "left"; Matrix tview (1, 2, 0.0); tview(1) = 90; m["view"] = tview; m["visible"] = "on"; m["nextplot"] = "replace"; Matrix touterposition (1, 4, 0.0); touterposition(2) = 1; touterposition(3) = 1; m["outerposition"] = touterposition; m["activepositionproperty"] = radio_property (radio_values ("{outerposition}|position")); m["__colorbar__"] = radio_property (radio_values ("{none}|north|south|east|west|northoutside|southoutside|eastoutside|westoutside")); return m; } octave_value axes::get_default (const caseless_str& name) const { octave_value retval = default_properties.lookup (name); if (retval.is_undefined ()) { graphics_handle parent = get_parent (); graphics_object parent_obj = gh_manager::get_object (parent); retval = parent_obj.get_default (name); } return retval; } static void check_limit_val (double& min_val, double& max_val, double& min_pos, double val) { if (! (xisinf (val) || xisnan (val))) { if (val < min_val) min_val = val; if (val > max_val) max_val = val; if (val > 0 && val < min_pos) min_pos = val; } } static void check_limit_vals (double& min_val, double& max_val, double& min_pos, const data_property& data) { check_limit_val (min_val, max_val, min_pos, data.min_val ()); check_limit_val (max_val, max_val, min_pos, data.max_val ()); check_limit_val (min_pos, max_val, min_pos, data.min_pos ()); } // Attempt to make "nice" limits from the actual max and min of the // data. For log plots, we will also use the smallest strictly positive // value. static Matrix get_axis_limits (double xmin, double xmax, double min_pos, bool logscale) { Matrix retval; double min_val = xmin; double max_val = xmax; if (! (xisinf (min_val) || xisinf (max_val))) { if (logscale) { if (xisinf (min_pos)) { // warning ("axis: logscale with no positive values to plot"); return retval; } if (min_val <= 0) { warning ("axis: omitting nonpositive data in log plot"); min_val = min_pos; } // FIXME -- maybe this test should also be relative? if (std::abs (min_val - max_val) < sqrt (DBL_EPSILON)) { min_val *= 0.9; max_val *= 1.1; } min_val = pow (10, floor (log10 (min_val))); max_val = pow (10, ceil (log10 (max_val))); } else { if (min_val == 0 && max_val == 0) { min_val = -1; max_val = 1; } // FIXME -- maybe this test should also be relative? else if (std::abs (min_val - max_val) < sqrt (DBL_EPSILON)) { min_val -= 0.1 * std::abs (min_val); max_val += 0.1 * std::abs (max_val); } // FIXME -- to do a better job, we should consider the tic spacing. double scale = pow (10, floor (log10 (max_val - min_val) - 1)); min_val = scale * floor (min_val / scale); max_val = scale * ceil (max_val / scale); } } retval.resize (1, 2); retval(0) = min_val; retval(1) = max_val; return retval; } static bool updating_axis_limits = false; void axes::update_axis_limits (const std::string& axis_type) { if (updating_axis_limits) return; Matrix kids = xproperties.get_children (); octave_idx_type n = kids.numel (); double min_val = octave_Inf; double max_val = -octave_Inf; double min_pos = octave_Inf; radio_property tmp; char update_type = 0; Matrix limits; if (axis_type == "xdata" || axis_type == "xscale" || axis_type == "xldata" || axis_type == "xudata" || axis_type == "xlimmode") { tmp = xproperties.get_xlimmode (); if (tmp.current_value () == "auto") { for (octave_idx_type i = 0; i < n; i++) { graphics_object obj = gh_manager::get_object (kids(i)); if (obj.isa ("line") || obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface")) { data_property xdata = obj.get_xdata (); check_limit_vals (min_val, max_val, min_pos, xdata); if (obj.isa ("line")) { data_property xldata = obj.get_xldata (); data_property xudata = obj.get_xudata (); check_limit_vals (min_val, max_val, min_pos, xldata); check_limit_vals (min_val, max_val, min_pos, xudata); } } } tmp = xproperties.get_xscale (); limits = get_axis_limits (min_val, max_val, min_pos, tmp.current_value () == "log"); update_type = 'x'; } } else if (axis_type == "ydata" || axis_type == "yscale" || axis_type == "ldata" || axis_type == "udata" || axis_type == "ylimmode") { tmp = xproperties.get_ylimmode (); if (tmp.current_value () == "auto") { for (octave_idx_type i = 0; i < n; i++) { graphics_object obj = gh_manager::get_object (kids(i)); if (obj.isa ("line") || obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface")) { data_property ydata = obj.get_ydata (); check_limit_vals (min_val, max_val, min_pos, ydata); if (obj.isa ("line")) { data_property ldata = obj.get_ldata (); data_property udata = obj.get_udata (); check_limit_vals (min_val, max_val, min_pos, ldata); check_limit_vals (min_val, max_val, min_pos, udata); } } } tmp = xproperties.get_yscale (); limits = get_axis_limits (min_val, max_val, min_pos, tmp.current_value () == "log"); update_type = 'y'; } } else if (axis_type == "zdata" || axis_type == "zscale" || axis_type == "zlimmode") { tmp = xproperties.get_zlimmode (); if (tmp.current_value () == "auto") { for (octave_idx_type i = 0; i < n; i++) { graphics_object obj = gh_manager::get_object (kids(i)); if (obj.isa ("line") || obj.isa ("patch") || obj.isa ("surface")) { data_property zdata = obj.get_zdata (); check_limit_vals (min_val, max_val, min_pos, zdata); } } tmp = xproperties.get_zscale (); limits = get_axis_limits (min_val, max_val, min_pos, tmp.current_value () == "log"); update_type = 'z'; } } else if (axis_type == "cdata" || axis_type == "climmode") { tmp = xproperties.get_climmode (); if (tmp.current_value () == "auto") { for (octave_idx_type i = 0; i < n; i++) { graphics_object obj = gh_manager::get_object (kids(i)); if (obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface")) { data_property cdata = obj.get_cdata (); check_limit_vals (min_val, max_val, min_pos, cdata); } } if (min_val == max_val) max_val = min_val + 1; limits.resize (1, 2); limits(0) = min_val; limits(1) = max_val; update_type = 'c'; } } unwind_protect_bool (updating_axis_limits); updating_axis_limits = true; switch (update_type) { case 'x': xproperties.set_xlim (limits); xproperties.set_xlimmode ("auto"); break; case 'y': xproperties.set_ylim (limits); xproperties.set_ylimmode ("auto"); break; case 'z': xproperties.set_zlim (limits); xproperties.set_zlimmode ("auto"); break; case 'c': xproperties.set_clim (limits); xproperties.set_climmode ("auto"); break; default: break; } unwind_protect::run (); } std::string axes::properties::go_name ("axes"); // --------------------------------------------------------------------- static Matrix default_data (void) { Matrix retval (1, 2); retval(0) = 0; retval(1) = 1; return retval; } line::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), xdata (default_data ()), ydata (default_data ()), zdata (Matrix ()), ldata (Matrix ()), udata (Matrix ()), xldata (Matrix ()), xudata (Matrix ()), color (), linestyle ("-"), linewidth (0.5), marker ("none"), markeredgecolor ("auto"), markerfacecolor ("none"), markersize (1), keylabel (""), interpreter (radio_values ("{tex}|none|latex")) { } void line::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("xdata")) set_xdata (val); else if (name.compare ("ydata")) set_ydata (val); else if (name.compare ("zdata")) set_zdata (val); else if (name.compare ("ldata")) set_ldata (val); else if (name.compare ("udata")) set_udata (val); else if (name.compare ("xldata")) set_xldata (val); else if (name.compare ("xudata")) set_xudata (val); else if (name.compare ("color")) set_color (val); else if (name.compare ("linestyle")) set_linestyle (val); else if (name.compare ("linewidth")) set_linewidth (val); else if (name.compare ("marker")) set_marker (val); else if (name.compare ("markeredgecolor")) set_markeredgecolor (val); else if (name.compare ("markerfacecolor")) set_markerfacecolor (val); else if (name.compare ("markersize")) set_markersize (val); else if (name.compare ("keylabel")) set_keylabel (val); else if (name.compare ("interpreter")) set_interpreter (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value line::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("xdata", xdata); m.assign ("ydata", ydata); m.assign ("zdata", zdata); m.assign ("ldata", ldata); m.assign ("udata", udata); m.assign ("xldata", xldata); m.assign ("xudata", xudata); m.assign ("color", color); m.assign ("linestyle", linestyle); m.assign ("linewidth", linewidth); m.assign ("marker", marker); m.assign ("markeredgecolor", markeredgecolor); m.assign ("markerfacecolor", markerfacecolor); m.assign ("markersize", markersize); m.assign ("keylabel", keylabel); m.assign ("interpreter", interpreter); return m; } octave_value line::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("xdata")) retval = xdata; else if (name.compare ("ydata")) retval = ydata; else if (name.compare ("zdata")) retval = zdata; else if (name.compare ("ldata")) retval = ldata; else if (name.compare ("udata")) retval = udata; else if (name.compare ("xldata")) retval = xldata; else if (name.compare ("xudata")) retval = xudata; else if (name.compare ("color")) retval = color; else if (name.compare ("linestyle")) retval = linestyle; else if (name.compare ("linewidth")) retval = linewidth; else if (name.compare ("marker")) retval = marker; else if (name.compare ("markeredgecolor")) retval = markeredgecolor; else if (name.compare ("markerfacecolor")) retval = markerfacecolor; else if (name.compare ("markersize")) retval = markersize; else if (name.compare ("keylabel")) retval = keylabel; else if (name.compare ("interpreter")) retval = interpreter; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list::pval_map_type line::properties::factory_defaults (void) { property_list::pval_map_type m; m["xdata"] = default_data (); m["ydata"] = default_data (); m["zdata"] = Matrix (); m["ldata"] = Matrix (); m["udata"] = Matrix (); m["xldata"] = Matrix (); m["xudata"] = Matrix (); m["color"] = color_property (); m["linestyle"] = "-"; m["linewidth"] = 0.5; m["marker"] = "none"; m["markeredgecolor"] = "auto"; m["markerfacecolor"] = "none"; m["markersize"] = 1; m["keylabel"] = ""; m["interpreter"] = radio_property (radio_values ("{tex}|none|latex")); return m; } std::string line::properties::go_name ("line"); // --------------------------------------------------------------------- text::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), string (""), units ("data"), position (Matrix (1, 3, 0.0)), rotation (0), horizontalalignment ("left"), color (Matrix (1, 3, 0.0)), fontname ("Helvetica"), fontsize (10), fontangle (radio_values ("{normal}|italic|oblique")), fontweight (radio_values ("{normal}|bold|demi|light")), interpreter (radio_values ("{tex}|none|latex")) { } void text::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("string")) set_string (val); else if (name.compare ("units")) set_units (val); else if (name.compare ("position")) set_position (val); else if (name.compare ("rotation")) set_rotation (val); else if (name.compare ("horizontalalignment")) set_horizontalalignment (val); else if (name.compare ("color")) set_color (val); else if (name.compare ("fontname")) set_fontname (val); else if (name.compare ("fontsize")) set_fontsize (val); else if (name.compare ("fontangle")) set_fontangle (val); else if (name.compare ("fontweight")) set_fontweight (val); else if (name.compare ("interpreter")) set_interpreter (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value text::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("string", string); m.assign ("units", units); m.assign ("position", position); m.assign ("rotation", rotation); m.assign ("horizontalalignment", horizontalalignment); m.assign ("color", color); m.assign ("fontname", fontname); m.assign ("fontsize", fontsize); m.assign ("fontangle", fontangle); m.assign ("fontweight", fontweight); m.assign ("interpreter", interpreter); return m; } octave_value text::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("string")) retval = string; else if (name.compare ("units")) retval = units; else if (name.compare ("position")) retval = position; else if (name.compare ("rotation")) retval = rotation; else if (name.compare ("horizontalalignment")) retval = horizontalalignment; else if (name.compare ("color")) retval = color; else if (name.compare ("fontname")) retval = fontname; else if (name.compare ("fontsize")) retval = fontsize; else if (name.compare ("fontangle")) retval = fontangle; else if (name.compare ("fontweight")) retval = fontweight; else if (name.compare ("interpreter")) retval = interpreter; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list::pval_map_type text::properties::factory_defaults (void) { property_list::pval_map_type m; m["string"] = ""; m["units"] = "data"; m["position"] = Matrix (1, 3, 0.0); m["rotation"] = 0; m["horizontalalignment"] = "left"; m["color"] = Matrix (1, 3, 1.0); m["fontname"] = "Helvetica"; m["fontsize"] = 10; m["fontangle"] = radio_property (radio_values ("{normal}|italic|oblique")); m["fontweight"] = radio_property (radio_values ("{normal}|bold|demi|light")); m["interpreter"] = radio_property (radio_values ("{tex}|none|latex")); return m; } std::string text::properties::go_name ("text"); // --------------------------------------------------------------------- image::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), xdata (Matrix ()), ydata (Matrix ()), cdata (Matrix ()) { } void image::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("xdata")) set_xdata (val); else if (name.compare ("ydata")) set_ydata (val); else if (name.compare ("cdata")) set_cdata (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value image::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("xdata", xdata); m.assign ("ydata", ydata); m.assign ("cdata", cdata); return m; } octave_value image::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("xdata")) retval = xdata; else if (name.compare ("ydata")) retval = ydata; else if (name.compare ("cdata")) retval = cdata; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list::pval_map_type image::properties::factory_defaults (void) { property_list::pval_map_type m; m["xdata"] = Matrix (); m["ydata"] = Matrix (); m["cdata"] = Matrix (); return m; } std::string image::properties::go_name ("image"); // --------------------------------------------------------------------- patch::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), xdata (Matrix ()), ydata (Matrix ()), zdata (Matrix ()), cdata (Matrix ()), faces (Matrix ()), vertices (Matrix ()), facecolor (radio_values ("{flat}|none|interp")), facealpha (1.0), edgecolor (color_values(0, 0, 0), radio_values ("flat|none|interp")), linestyle ("-"), linewidth (0.5), marker ("none"), markeredgecolor ("auto"), markerfacecolor ("none"), markersize (1), keylabel (""), interpreter (radio_values ("{tex}|none|latex")) { } void patch::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("xdata")) set_xdata (val); else if (name.compare ("ydata")) set_ydata (val); else if (name.compare ("zdata")) set_zdata (val); else if (name.compare ("cdata")) set_cdata (val); else if (name.compare ("faces")) set_faces (val); else if (name.compare ("vertices")) set_vertices (val); else if (name.compare ("facecolor")) set_facecolor (val); else if (name.compare ("facealpha")) set_facealpha (val); else if (name.compare ("edgecolor")) set_edgecolor (val); else if (name.compare ("linestyle")) set_linestyle (val); else if (name.compare ("linewidth")) set_linewidth (val); else if (name.compare ("marker")) set_marker (val); else if (name.compare ("markeredgecolor")) set_markeredgecolor (val); else if (name.compare ("markerfacecolor")) set_markerfacecolor (val); else if (name.compare ("markersize")) set_markersize (val); else if (name.compare ("keylabel")) set_keylabel (val); else if (name.compare ("interpreter")) set_interpreter (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value patch::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("xdata", xdata); m.assign ("ydata", ydata); m.assign ("zdata", zdata); m.assign ("cdata", cdata); m.assign ("faces", faces); m.assign ("vertices", vertices); m.assign ("facecolor", facecolor); m.assign ("facealpha", facealpha); m.assign ("edgecolor", edgecolor); m.assign ("linestyle", linestyle); m.assign ("linewidth", linewidth); m.assign ("marker", marker); m.assign ("markeredgecolor", markeredgecolor); m.assign ("markerface", markerfacecolor); m.assign ("markersize", markersize); m.assign ("keylabel", keylabel); m.assign ("interpreter", interpreter); return m; } octave_value patch::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("xdata")) retval = xdata; else if (name.compare ("ydata")) retval = ydata; else if (name.compare ("zdata")) retval = zdata; else if (name.compare ("cdata")) retval = cdata; else if (name.compare ("faces")) retval = faces; else if (name.compare ("vertices")) retval = vertices; else if (name.compare ("facecolor")) retval = facecolor; else if (name.compare ("facealpha")) retval = facealpha; else if (name.compare ("egdecolor")) retval = edgecolor; else if (name.compare ("linestyle")) retval = linestyle; else if (name.compare ("linewidth")) retval = linewidth; else if (name.compare ("marker")) retval = marker; else if (name.compare ("markeredgecolor")) retval = markeredgecolor; else if (name.compare ("markerfacecolor")) retval = markerfacecolor; else if (name.compare ("markersize")) retval = markersize; else if (name.compare ("keylabel")) retval = keylabel; else if (name.compare ("interpreter")) retval = interpreter; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list::pval_map_type patch::properties::factory_defaults (void) { property_list::pval_map_type m; m["xdata"] = Matrix (); m["ydata"] = Matrix (); m["zdata"] = Matrix (); m["cdata"] = Matrix (); m["faces"] = Matrix (); m["vertices"] = Matrix (); m["facecolor"] = color_property (); m["facealpha"] = 1.0; m["edgecolor"] = color_property ("black"); m["linestyle"] = "-"; m["linewidth"] = 0.5; m["marker"] = "none"; m["markeredgecolor"] = "auto"; m["markerfacecolor"] = "none"; m["markersize"] = 1; m["keylabel"] = ""; m["interpreter"] = radio_property (radio_values ("{tex}|none|latex")); return m; } std::string patch::properties::go_name ("patch"); // --------------------------------------------------------------------- surface::properties::properties (const graphics_handle& mh, const graphics_handle& p) : base_properties (go_name, mh, p), xdata (Matrix ()), ydata (Matrix ()), zdata (Matrix ()), cdata (Matrix ()), facecolor (radio_values ("{flat}|none|interp")), facealpha (1.0), edgecolor (color_values(0, 0, 0), radio_values ("flat|none|interp")), linestyle ("-"), linewidth (0.5), marker ("none"), markeredgecolor ("auto"), markerfacecolor ("none"), markersize (1), keylabel (""), interpreter (radio_values ("{tex}|none|latex")) { } void surface::properties::set (const caseless_str& name, const octave_value& val) { bool modified = true; if (name.compare ("tag")) set_tag (val); else if (name.compare ("parent")) set_parent (val); else if (name.compare ("children")) children = maybe_set_children (children, val); else if (name.compare ("__modified__")) { __modified__ = val.bool_value (); modified = false; } else if (name.compare ("xdata")) set_xdata (val); else if (name.compare ("ydata")) set_ydata (val); else if (name.compare ("zdata")) set_zdata (val); else if (name.compare ("cdata")) set_cdata (val); else if (name.compare ("facecolor")) set_facecolor (val); else if (name.compare ("facealpha")) set_facealpha (val); else if (name.compare ("edgecolor")) set_edgecolor (val); else if (name.compare ("linestyle")) set_linestyle (val); else if (name.compare ("linewidth")) set_linewidth (val); else if (name.compare ("marker")) set_marker (val); else if (name.compare ("markeredgecolor")) set_markeredgecolor (val); else if (name.compare ("markerfacecolor")) set_markerfacecolor (val); else if (name.compare ("markersize")) set_markersize (val); else if (name.compare ("keylabel")) set_keylabel (val); else if (name.compare ("interpreter")) set_interpreter (val); else { modified = false; warning ("set: invalid property `%s'", name.c_str ()); } if (modified) mark_modified (); } octave_value surface::properties::get (void) const { Octave_map m; m.assign ("tag", tag); m.assign ("type", type); m.assign ("parent", parent.as_octave_value ()); m.assign ("children", children); m.assign ("__modified__", __modified__); m.assign ("xdata", xdata); m.assign ("ydata", ydata); m.assign ("zdata", zdata); m.assign ("cdata", cdata); m.assign ("facecolor", facecolor); m.assign ("facealpha", facealpha); m.assign ("edgecolor", edgecolor); m.assign ("linestyle", linestyle); m.assign ("linewidth", linewidth); m.assign ("marker", marker); m.assign ("markeredgecolor", markeredgecolor); m.assign ("markerface", markerfacecolor); m.assign ("markersize", markersize); m.assign ("keylabel", keylabel); m.assign ("interpreter", interpreter); return m; } octave_value surface::properties::get (const caseless_str& name) const { octave_value retval; if (name.compare ("tag")) retval = tag; else if (name.compare ("type")) retval = type; else if (name.compare ("parent")) retval = parent.as_octave_value (); else if (name.compare ("children")) retval = children; else if (name.compare ("__modified__")) retval = __modified__; else if (name.compare ("xdata")) retval = xdata; else if (name.compare ("ydata")) retval = ydata; else if (name.compare ("zdata")) retval = zdata; else if (name.compare ("cdata")) retval = cdata; else if (name.compare ("facecolor")) retval = facecolor; else if (name.compare ("facealpha")) retval = facealpha; else if (name.compare ("edgecolor")) retval = edgecolor; else if (name.compare ("linestyle")) retval = linestyle; else if (name.compare ("linewidth")) retval = linewidth; else if (name.compare ("marker")) retval = marker; else if (name.compare ("markeredgecolor")) retval = markeredgecolor; else if (name.compare ("markerfacecolor")) retval = markerfacecolor; else if (name.compare ("markersize")) retval = markersize; else if (name.compare ("keylabel")) retval = keylabel; else if (name.compare ("interpreter")) retval = interpreter; else warning ("get: invalid property `%s'", name.c_str ()); return retval; } property_list::pval_map_type surface::properties::factory_defaults (void) { property_list::pval_map_type m; m["xdata"] = Matrix (); m["ydata"] = Matrix (); m["zdata"] = Matrix (); m["cdata"] = Matrix (); m["facecolor"] = color_property (); m["facealpha"] = 1.0; m["edgecolor"] = color_property ("black"); m["linestyle"] = "-"; m["linewidth"] = 0.5; m["marker"] = "none"; m["markeredgecolor"] = "auto"; m["markerfacecolor"] = "none"; m["markersize"] = 1; m["keylabel"] = ""; m["interpreter"] = radio_property (radio_values ("{tex}|none|latex")); return m; } std::string surface::properties::go_name ("surface"); // --------------------------------------------------------------------- octave_value base_graphics_object::get_default (const caseless_str& name) const { graphics_handle parent = get_parent (); graphics_object parent_obj = gh_manager::get_object (parent); return parent_obj.get_default (type () + name); } octave_value base_graphics_object::get_factory_default (const caseless_str& name) const { graphics_object parent_obj = gh_manager::get_object (0); return parent_obj.get_factory_default (type () + name); } gh_manager::gh_manager (void) : handle_map (), handle_free_list (), next_handle (-1) { handle_map[0] = graphics_object (new root_figure ()); } graphics_handle gh_manager::do_make_graphics_handle (const std::string& go_name, const graphics_handle& p) { graphics_handle h = get_handle (go_name); base_graphics_object *go = 0; if (go_name == "figure") go = new figure (h, p); else if (go_name == "axes") go = new axes (h, p); else if (go_name == "line") go = new line (h, p); else if (go_name == "text") go = new text (h, p); else if (go_name == "image") go = new image (h, p); else if (go_name == "patch") go = new patch (h, p); else if (go_name == "surface") go = new surface (h, p); if (go) handle_map[h] = graphics_object (go); else error ("gh_manager::do_make_graphics_handle: invalid object type `%s'", go_name.c_str ()); return h; } graphics_handle gh_manager::do_make_figure_handle (double val) { graphics_handle h = val; handle_map[h] = graphics_object (new figure (h, 0)); return h; } void gh_manager::do_push_figure (const graphics_handle& h) { do_pop_figure (h); figure_list.push_front (h); } void gh_manager::do_pop_figure (const graphics_handle& h) { for (figure_list_iterator p = figure_list.begin (); p != figure_list.end (); p++) { if (*p == h) { figure_list.erase (p); break; } } } property_list::plist_map_type root_figure::init_factory_properties (void) { property_list::plist_map_type plist_map; plist_map["figure"] = figure::properties::factory_defaults (); plist_map["axes"] = axes::properties::factory_defaults (); plist_map["line"] = line::properties::factory_defaults (); plist_map["text"] = text::properties::factory_defaults (); plist_map["image"] = image::properties::factory_defaults (); plist_map["patch"] = patch::properties::factory_defaults (); plist_map["surface"] = surface::properties::factory_defaults (); return plist_map; } // --------------------------------------------------------------------- DEFUN (ishandle, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} ishandle (@var{h})\n\ Return true if @var{h} is a graphics handle and false otherwise.\n\ @end deftypefn") { octave_value retval; if (args.length () == 1) retval = is_handle (args(0)); else print_usage (); return retval; } DEFUN (set, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} set (@var{h}, @var{p}, @var{v}, @dots{})\n\ Set the named property value or vector @var{p} to the value @var{v}\n\ for the graphics handle @var{h}.\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); if (nargin > 0) { ColumnVector hcv (args(0).vector_value ()); if (! error_state) { bool request_drawnow = false; for (octave_idx_type n = 0; n < hcv.length (); n++) { graphics_object obj = gh_manager::get_object (hcv(n)); if (obj) { obj.set (args.splice (0, 1)); request_drawnow = true; } else { error ("set: invalid handle (= %g)", hcv(n)); break; } } if (! error_state && request_drawnow) feval ("__request_drawnow__"); } else error ("set: expecting graphics handle as first argument"); } else print_usage (); return retval; } DEFUN (get, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} get (@var{h}, @var{p})\n\ Return the named property @var{p} from the graphics handle @var{h}.\n\ If @var{p} is omitted, return the complete property list for @var{h}.\n\ If @var{h} is a vector, return a cell array including the property\n\ values or lists respectively.\n\ @end deftypefn") { octave_value retval; octave_value_list vlist; int nargin = args.length (); if (nargin == 1 || nargin == 2) { ColumnVector hcv (args(0).vector_value ()); if (! error_state) { octave_idx_type len = hcv.length (); vlist.resize (len); for (octave_idx_type n = 0; n < len; n++) { graphics_object obj = gh_manager::get_object (hcv(n)); if (obj) { if (nargin == 1) vlist(n) = obj.get (); else { caseless_str property = args(1).string_value (); if (! error_state) vlist(n) = obj.get (property); else { error ("get: expecting property name as second argument"); break; } } } else { error ("get: invalid handle (= %g)", hcv(n)); break; } } } else error ("get: expecting graphics handle as first argument"); } else print_usage (); if (! error_state) { octave_idx_type len = vlist.length (); if (len > 1) retval = Cell (vlist); else if (len == 1) retval = vlist(0); } return retval; } static octave_value make_graphics_object (const std::string& go_name, const octave_value_list& args) { octave_value retval; double val = args(0).double_value (); if (! error_state) { graphics_handle parent = gh_manager::lookup (val); if (parent.ok ()) { graphics_handle h = gh_manager::make_graphics_handle (go_name, parent); if (! error_state) { adopt (parent, h); xset (h, args.splice (0, 1)); retval = h.value (); } else error ("__go%s__: unable to create graphics handle", go_name.c_str ()); } else error ("__go_%s__: invalid parent", go_name.c_str ()); } else error ("__go_%s__: invalid parent", go_name.c_str ()); return retval; } DEFUN (__go_figure__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_figure__ (@var{fignum})\n\ Undocumented internal function.\n\ @end deftypefn") { octave_value retval; if (args.length () > 0) { double val = args(0).double_value (); if (! error_state) { if (is_figure (val)) { graphics_handle h = gh_manager::lookup (val); xset (h, args.splice (0, 1)); retval = h.value (); } else { graphics_handle h = octave_NaN; if (xisnan (val)) h = gh_manager::make_graphics_handle ("figure", 0); else if (val > 0 && D_NINT (val) == val) h = gh_manager::make_figure_handle (val); else error ("__go_figure__: invalid figure number"); if (! error_state && h.ok ()) { adopt (0, h); xset (h, args.splice (0, 1)); retval = h.value (); } else error ("__go_figure__: failed to create figure handle"); } } else error ("__go_figure__: expecting figure number to be double value"); } else print_usage (); return retval; } #define GO_BODY(TYPE) \ octave_value retval; \ \ if (args.length () > 0) \ retval = make_graphics_object (#TYPE, args); \ else \ print_usage (); \ \ return retval DEFUN (__go_axes__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_axes__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (axes); } DEFUN (__go_line__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_line__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (line); } DEFUN (__go_text__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_text__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (text); } DEFUN (__go_image__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_image__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (image); } DEFUN (__go_surface__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_surface__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (surface); } DEFUN (__go_patch__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_patch__ (@var{parent})\n\ Undocumented internal function.\n\ @end deftypefn") { GO_BODY (patch); } DEFUN (__go_delete__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_delete__ (@var{h})\n\ Undocumented internal function.\n\ @end deftypefn") { octave_value_list retval; if (args.length () == 1) { graphics_handle h = octave_NaN; double val = args(0).double_value (); if (! error_state) { h = gh_manager::lookup (val); if (h.ok ()) { graphics_object obj = gh_manager::get_object (h); graphics_handle parent_h = obj.get_parent (); graphics_object parent_obj = gh_manager::get_object (parent_h); parent_obj.remove_child (h); gh_manager::free (h); } else error ("delete: invalid graphics object (= %g)", val); } else error ("delete: invalid graphics object"); } else print_usage (); return retval; } DEFUN (__go_axes_init__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_axes_init__ (@var{h}, @var{mode})\n\ Undocumented internal function.\n\ @end deftypefn") { octave_value retval; int nargin = args.length (); std::string mode = ""; if (nargin == 2) { mode = args(1).string_value (); if (error_state) return retval; } if (nargin == 1 || nargin == 2) { graphics_handle h = octave_NaN; double val = args(0).double_value (); if (! error_state) { h = gh_manager::lookup (val); if (h.ok ()) { graphics_object obj = gh_manager::get_object (h); obj.set_defaults (mode); } else error ("__go_axes_init__: invalid graphics object (= %g)", val); } else error ("__go_axes_init__: invalid graphics object"); } else print_usage (); return retval; } DEFUN (__go_handles__, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_handles__ ()\n\ Undocumented internal function.\n\ @end deftypefn") { return octave_value (gh_manager::handle_list ()); } DEFUN (__go_figure_handles__, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_figure_handles__ ()\n\ Undocumented internal function.\n\ @end deftypefn") { return octave_value (gh_manager::figure_handle_list ()); } octave_value get_property_from_handle (double handle, const std::string &property, const std::string &func) { graphics_object obj = gh_manager::get_object (handle); octave_value retval; if (obj) { caseless_str p = std::string (property); retval = obj.get (p); } else error ("%s: invalid handle (= %g)", func.c_str(), handle); return retval; } bool set_property_in_handle (double handle, const std::string &property, const octave_value &arg, const std::string &func) { graphics_object obj = gh_manager::get_object (handle); int ret = false; if (obj) { caseless_str p = std::string (property); obj.set (p, arg); if (!error_state) ret = true; } else error ("%s: invalid handle (= %g)", func.c_str(), handle); return ret; } /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */