changeset 7865:b74039822fd2

Add support for hggroup
author Michael Goffioul <michael.goffioul@gmail.com>
date Fri, 25 Apr 2008 16:44:59 +0200
parents 56f781f38f0b
children 35e8d6199455
files scripts/ChangeLog scripts/plot/Makefile.in scripts/plot/__go_draw_axes__.m scripts/plot/hggroup.m src/ChangeLog src/genprops.awk src/graphics.cc src/graphics.h.in
diffstat 8 files changed, 286 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Thu Apr 24 16:43:31 2008 +0200
+++ b/scripts/ChangeLog	Fri Apr 25 16:44:59 2008 +0200
@@ -1,3 +1,9 @@
+2008-06-04  Michael Goffioul  <michael.goffioul@gmail.com>
+
+	* plot/__go_draw_axes__.m: Support hggroup objects.
+	* plot/hggroup.m: New file.
+	* plot/Makefile.in: Handle it.
+
 2008-06-02  David Bateman  <dbateman@free.fr>
 
 	* miscellaneous/debug.m: New file..
--- a/scripts/plot/Makefile.in	Thu Apr 24 16:43:31 2008 +0200
+++ b/scripts/plot/Makefile.in	Fri Apr 25 16:44:59 2008 +0200
@@ -111,6 +111,7 @@
   ginput.m \
   grid.m \
   gtext.m \
+  hggroup.m \
   hidden.m \
   hist.m \
   hold.m \
--- a/scripts/plot/__go_draw_axes__.m	Thu Apr 24 16:43:31 2008 +0200
+++ b/scripts/plot/__go_draw_axes__.m	Fri Apr 25 16:44:59 2008 +0200
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/hggroup.m	Fri Apr 25 16:44:59 2008 +0200
@@ -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
+## <http://www.gnu.org/licenses/>.
+
+## -*- 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
--- a/src/ChangeLog	Thu Apr 24 16:43:31 2008 +0200
+++ b/src/ChangeLog	Fri Apr 25 16:44:59 2008 +0200
@@ -47,6 +47,20 @@
 
 2008-06-04  Michael Goffioul <michael.goffioul@gmail.com>
 
+	* 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,
--- a/src/genprops.awk	Thu Apr 24 16:43:31 2008 +0200
+++ b/src/genprops.awk	Fri Apr 25 16:44:59 2008 +0200
@@ -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;
--- a/src/graphics.cc	Thu Apr 24 16:43:31 2008 +0200
+++ b/src/graphics.cc	Fri Apr 25 16:44:59 2008 +0200
@@ -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);
--- a/src/graphics.h.in	Thu Apr 24 16:43:31 2008 +0200
+++ b/src/graphics.h.in	Fri Apr 25 16:44:59 2008 +0200
@@ -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);