# HG changeset patch # User Michael Goffioul # Date 1209134699 -7200 # Node ID b74039822fd22dfc13373a9fb1461b43fb5b1c58 # Parent 56f781f38f0bd168b17cd63cf5a62ffd2b8eb315 Add support for hggroup diff --git a/scripts/ChangeLog b/scripts/ChangeLog --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,9 @@ +2008-06-04 Michael Goffioul + + * plot/__go_draw_axes__.m: Support hggroup objects. + * plot/hggroup.m: New file. + * plot/Makefile.in: Handle it. + 2008-06-02 David Bateman * miscellaneous/debug.m: New file.. diff --git a/scripts/plot/Makefile.in b/scripts/plot/Makefile.in --- a/scripts/plot/Makefile.in +++ b/scripts/plot/Makefile.in @@ -111,6 +111,7 @@ ginput.m \ grid.m \ gtext.m \ + hggroup.m \ hidden.m \ hist.m \ hold.m \ diff --git a/scripts/plot/__go_draw_axes__.m b/scripts/plot/__go_draw_axes__.m --- a/scripts/plot/__go_draw_axes__.m +++ b/scripts/plot/__go_draw_axes__.m @@ -325,9 +325,10 @@ ximg_data = {}; ximg_data_idx = 0; - for i = 1:length (kids) + while (! isempty (kids)) - obj = get (kids(i)); + obj = get (kids(1)); + kids = kids(2:end); switch (obj.type) case "image" @@ -992,12 +993,16 @@ __do_enhanced_option__ (enhanced, obj), colorspec); endif + case "hggroup" + # push group children into the kid list + kids = [obj.children kids]; + otherwise error ("__go_draw_axes__: unknown object class, %s", obj.type); endswitch - endfor + endwhile ## This is need to prevent warnings for rotations in 3D plots, while ## allowing colorbars with contours.. @@ -1421,6 +1426,11 @@ endif case "surface" nd = 3; + case "hggroup" + obj_nd = __calc_dimensions__ (obj); + if (obj_nd == 3) + nd = 3; + endif endswitch endfor endfunction diff --git a/scripts/plot/hggroup.m b/scripts/plot/hggroup.m new file mode 100644 --- /dev/null +++ b/scripts/plot/hggroup.m @@ -0,0 +1,43 @@ +## Copyright (C) 2008 Michael Goffioul +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} {} hggroup () +## @deftypefnx {Function File} {} hggroup (@var{h}) +## @deftypefnx {Function File} {} hggroup (@dots{}, @var{property}, @var{value}, @dots{}) +## Create group object with parent @var{h}. If no parent is specified, +## the group is created in the current axes. Return the handle of the +## group object created. +## +## Multiple property-value pairs may be specified for the group, but they +## must appear in pairs. +## @end deftypefn + +## Author: goffioul + +function h = hggroup (varargin) + + [ax, varargin] = __plt_get_axis_arg__ ("hggroup", varargin{:}); + + tmp = __go_hggroup__ (ax, varargin{:}); + + if (nargout > 0) + h = tmp; + endif + +endfunction diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -47,6 +47,20 @@ 2008-06-04 Michael Goffioul + * genprops.awk (emit_source): Fix if-then-else statement generation + when the first property is hidden. + * graphics.h.in (base_properties::adopt): Call mark_modified. + (class hggroup): New graphics object class. + * graphics.cc (lookup_object_name, make_graphics_object_from_type, + property_list::lookup, property_list::set, + root_figure::init_factory_properties): Support hggroup as possible + object type. + (hggroup::update_axis_limits): New graphics object class. + (make_graphics_object): Look for "parent" property in the arguments + and use it as actual parent for the created object. + (F__go_hggroup__): New function. + (F__go_delete__): Set Vdrawnow_requested to true. + * graphics.h.in (base_property::clone, string_property::clone, radio_property::clone, color_property::clone, double_property::clone, double_radio_property::clone, array_property::clone, diff --git a/src/genprops.awk b/src/genprops.awk --- a/src/genprops.awk +++ b/src/genprops.awk @@ -391,11 +391,16 @@ printf ("void\n%s::properties::set (const caseless_str& pname, const octave_value& val)\n{\n", class_name) >> filename; + first = 1; + for (i = 1; i <= idx; i++) { if (! readonly[i]) + { printf (" %sif (pname.compare (\"%s\"))\n set_%s (val);\n", - (i > 1 ? "else " : ""), name[i], name[i]) >> filename; + (first == 0 ? "else " : ""), name[i], name[i]) >> filename; + first = 0; + } } printf (" else\n base_properties::set (pname, val);\n}\n\n") >> filename; diff --git a/src/graphics.cc b/src/graphics.cc --- a/src/graphics.cc +++ b/src/graphics.cc @@ -487,7 +487,7 @@ { pfx = name.substr (0, 7); - if (pfx.compare ("surface")) + if (pfx.compare ("surface") || pfx.compare ("hggroup")) offset = 7; } } @@ -525,6 +525,8 @@ go = new patch (h, p); else if (type.compare ("surface")) go = new surface (h, p); + else if (type.compare ("hggroup")) + go = new hggroup (h, p); return go; } @@ -1024,7 +1026,7 @@ { pfx = name.substr (0, 7); - if (pfx.compare ("surface")) + if (pfx.compare ("surface") || pfx.compare ("hggroup")) offset = 7; } } @@ -1097,7 +1099,7 @@ { pfx = name.substr (0, 7); - if (pfx.compare ("surface")) + if (pfx.compare ("surface") || pfx.compare ("hggroup")) offset = 7; } } @@ -3478,6 +3480,88 @@ // --------------------------------------------------------------------- +void +hggroup::update_axis_limits (const std::string& axis_type) +{ + 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; + + char update_type = 0; + + if (axis_type == "xlim") + { + get_children_limits (min_val, max_val, min_pos, kids, 'x'); + + update_type = 'x'; + } + else if (axis_type == "ylim") + { + get_children_limits (min_val, max_val, min_pos, kids, 'y'); + + update_type = 'y'; + } + else if (axis_type == "zlim") + { + get_children_limits (min_val, max_val, min_pos, kids, 'z'); + + update_type = 'z'; + } + else if (axis_type == "clim") + { + get_children_limits (min_val, max_val, min_pos, kids, 'c'); + + update_type = 'c'; + + } + else if (axis_type == "alim") + { + get_children_limits (min_val, max_val, min_pos, kids, 'a'); + + update_type = 'a'; + } + + Matrix limits (1, 3, 0.0); + + limits(0) = min_val; + limits(1) = max_val; + limits(2) = min_pos; + + switch (update_type) + { + case 'x': + xproperties.set_xlim (limits); + break; + + case 'y': + xproperties.set_ylim (limits); + break; + + case 'z': + xproperties.set_zlim (limits); + break; + + case 'c': + xproperties.set_clim (limits); + break; + + case 'a': + xproperties.set_alim (limits); + break; + + default: + break; + } + + base_graphics_object::update_axis_limits (axis_type); +} + +// --------------------------------------------------------------------- + octave_value base_graphics_object::get_default (const caseless_str& name) const { @@ -3575,6 +3659,7 @@ plist_map["image"] = image::properties::factory_defaults (); plist_map["patch"] = patch::properties::factory_defaults (); plist_map["surface"] = surface::properties::factory_defaults (); + plist_map["hggroup"] = hggroup::properties::factory_defaults (); return plist_map; } @@ -3777,7 +3862,33 @@ { octave_value retval; - double val = args(0).double_value (); + double val = octave_NaN; + + octave_value_list xargs = args.splice (0, 1); + + caseless_str p ("parent"); + + for (int i = 0; i < xargs.length (); i++) + if (xargs(i).is_string () + && p.compare (xargs(i).string_value ())) + { + if (i < (xargs.length () - 1)) + { + val = xargs(i+1).double_value (); + + if (! error_state) + { + xargs = xargs.splice (i, 2); + break; + } + } + else + error ("__go_%s__: missing value for parent property", + go_name.c_str ()); + } + + if (! error_state && xisnan (val)) + val = args(0).double_value (); if (! error_state) { @@ -3792,7 +3903,7 @@ { adopt (parent, h); - xset (h, args.splice (0, 1)); + xset (h, xargs); xcreatefcn (h); retval = h.value (); @@ -3932,6 +4043,15 @@ GO_BODY (patch); } +DEFUN (__go_hggroup__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __go_hggroup__ (@var{parent})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + GO_BODY (hggroup); +} + DEFUN (__go_delete__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_delete__ (@var{h})\n\ @@ -3965,6 +4085,8 @@ gh_manager::free (h); parent_obj.remove_child (h); + + Vdrawnow_requested = true; } else error ("delete: invalid graphics object (= %g)", val); diff --git a/src/graphics.h.in b/src/graphics.h.in --- a/src/graphics.h.in +++ b/src/graphics.h.in @@ -1591,6 +1591,7 @@ octave_idx_type n = children.numel (); children.resize (1, n+1); children(n) = h.value (); + mark_modified (); } virtual graphics_backend get_backend (void) const; @@ -3393,6 +3394,81 @@ bool valid_object (void) const { return true; } }; +// --------------------------------------------------------------------- + +class OCTINTERP_API hggroup : public base_graphics_object +{ +public: + class OCTINTERP_API properties : public base_properties + { + public: + void remove_child (const graphics_handle& h) + { + base_properties::remove_child (h); + update_limits (); + } + + void adopt (const graphics_handle& h) + { + base_properties::adopt (h); + update_limits (); + } + + // See the genprops.awk script for an explanation of the + // properties declarations. + + BEGIN_PROPERTIES(hggroup) + // hidden properties for limit computation + row_vector_property xlim hr , Matrix() + row_vector_property ylim hr , Matrix() + row_vector_property zlim hr , Matrix() + row_vector_property clim hr , Matrix() + row_vector_property alim hr , Matrix() + bool_property xliminclude h , "on" + bool_property yliminclude h , "on" + bool_property zliminclude h , "on" + bool_property climinclude h , "on" + bool_property aliminclude h , "on" + END_PROPERTIES + + private: + void update_limits (void) + { + update_axis_limits ("xlim"); + update_axis_limits ("ylim"); + update_axis_limits ("zlim"); + update_axis_limits ("clim"); + update_axis_limits ("alim"); + } + + protected: + void init (void) + { } + }; + +private: + properties xproperties; + +public: + hggroup (const graphics_handle& mh, const graphics_handle& p) + : base_graphics_object (), xproperties (mh, p) + { + xproperties.override_defaults (*this); + } + + ~hggroup (void) { xproperties.delete_children (); } + + base_properties& get_properties (void) { return xproperties; } + + const base_properties& get_properties (void) const { return xproperties; } + + bool valid_object (void) const { return true; } + + void update_axis_limits (const std::string& axis_type); +}; + +// --------------------------------------------------------------------- + octave_value get_property_from_handle (double handle, const std::string &property, const std::string &func);