changeset 8299:be9b14945774

Add code to remove listeners from properties and use it with newplot
author David Bateman <dbateman@free.fr>
date Fri, 31 Oct 2008 12:30:20 +0100
parents 7e87d3d76a56
children 4b9bce36109b
files scripts/ChangeLog scripts/plot/__contour__.m scripts/plot/clabel.m scripts/plot/plotyy.m src/ChangeLog src/graphics.cc src/graphics.h.in
diffstat 7 files changed, 183 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Fri Oct 31 12:09:16 2008 +0100
+++ b/scripts/ChangeLog	Fri Oct 31 12:30:20 2008 +0100
@@ -1,3 +1,11 @@
+2008-10-31  David Bateman  <dbateman@free.fr>
+
+	* plot/__contour__.m: Exclude infinite values when calculating contour
+	levels.
+	* plot/clabel.m: Close previous plots in demos to avoid pollution
+	between other plot demos.
+	* plot/plotyy.m: Ditto.
+
 2008-10-30  David Bateman  <dbateman@free.fr>
 
 	* plot/legend.m: Add support for the "left" and "right" options.
--- a/scripts/plot/__contour__.m	Fri Oct 31 12:09:16 2008 +0100
+++ b/scripts/plot/__contour__.m	Fri Oct 31 12:30:20 2008 +0100
@@ -78,6 +78,13 @@
     vn = 10; 
   endif
 
+  if (isscalar (vn))
+    lvl = linspace (min (z1(!isinf(z1))), max (z1(!isinf(z1))), 
+		    vn + 2)(1:end-1);
+  else
+    lvl = vn;
+  endif
+
   if (strcmpi (filled, "on"))
     if (isvector (x1) || isvector (y1))
       [x1, y1] = meshgrid (x1, y1);
@@ -91,9 +98,9 @@
     y0 = [y0(:, 1), y0, y0(:, 1)];
     z0 = -Inf(nr+2, nc+2);
     z0(2:nr+1, 2:nc+1) = z1;
-    [c, lev] = contourc (x0, y0, z0, vn);
+    [c, lev] = contourc (x0, y0, z0, lvl);
   else
-    [c, lev] = contourc (x1, y1, z1, vn);
+    [c, lev] = contourc (x1, y1, z1, lvl);
   endif
 
   hg = hggroup ();
@@ -128,11 +135,7 @@
     endif
   endif
 
-  if (isscalar (vn))
-    lvlstep = (max(z1(:)) - min(z1(:))) / vn;
-  else
-    lvlstep = (max(z1(:)) - min(z1(:))) / 10;
-  endif
+  lvlstep = sum (abs (diff (lvl))) / (length (lvl) - 1);
 
   addproperty ("levellist", hg, "data", lev);
   addproperty ("levelstep", hg, "double", lvlstep);
--- a/scripts/plot/clabel.m	Fri Oct 31 12:09:16 2008 +0100
+++ b/scripts/plot/clabel.m	Fri Oct 31 12:30:20 2008 +0100
@@ -129,9 +129,11 @@
 endfunction
 
 %!demo
+%! close all
 %! [c, h] = contour (peaks(), -4 : 6);
 %! clabel (c, h, -4 : 2 : 6, 'fontsize', 12);
 
 %!demo
+%! close all
 %! [c, h] = contourf (peaks(), -7 : 6);
 %! clabel (c, h, -6 : 2 : 6, 'fontsize', 12);
--- a/scripts/plot/plotyy.m	Fri Oct 31 12:09:16 2008 +0100
+++ b/scripts/plot/plotyy.m	Fri Oct 31 12:30:20 2008 +0100
@@ -182,6 +182,7 @@
 endfunction
 
 %!demo
+%! close all;
 %! x = 0:0.1:2*pi; 
 %! y1 = sin (x);
 %! y2 = exp (x - 1);
--- a/src/ChangeLog	Fri Oct 31 12:09:16 2008 +0100
+++ b/src/ChangeLog	Fri Oct 31 12:30:20 2008 +0100
@@ -2,10 +2,24 @@
 
 	* oct-map.cc (Octave_map::index): Copy key_list.
 
+2008-10-31  David Bateman  <dbateman@free.fr>
+
+	* graphics.h.in (base_property::delete_listener): New method.
+	(property::delete_listener): New method.
+	(base_graphics_object::delete_listener): New method.
+	(base_graphics_object::delete_property_listener): New method.
+	(base_graphics_object::remove_all_listeners): New method.
+	(graphics_object::delete_property_listener): New method.
+	(axes::set_defaults): Call remove_all_listeners.
+	* graphics.cc (void base_properties::delete_listener): New method
+	(void base_graphics_object::remove_all_listeners (void)): New method
+	(Fdellistener): New command to remove listener functions associated
+	with a property.
+	
 2008-10-30  David Bateman  <dbateman@free.fr>
 
-	* graphic.h.in (axes::properties): Add keyreverse property.
-	* graphic.cc (axes::properties::set_defaults): Initialize
+	* graphics.h.in (axes::properties): Add keyreverse property.
+	* graphics.cc (axes::properties::set_defaults): Initialize
 	keyreverse property.
 
 2008-10-28  Jaroslav Hajek <highegg@gmail.com>
--- a/src/graphics.cc	Fri Oct 31 12:09:16 2008 +0100
+++ b/src/graphics.cc	Fri Oct 31 12:30:20 2008 +0100
@@ -1808,6 +1808,16 @@
     p.add_listener (v, mode);
 }
 
+void
+base_properties::delete_listener (const caseless_str& nm, 
+				  const octave_value& v, listener_mode mode)
+{
+  property p = get_property (nm);
+
+  if (! error_state && p.ok ())
+    p.delete_listener (v, mode);
+}
+
 // ---------------------------------------------------------------------
 
 class gnuplot_backend : public base_graphics_backend
@@ -1940,6 +1950,23 @@
     error ("base_graphics_object::update_axis_limits: invalid graphics object");
 }
 
+void
+base_graphics_object::remove_all_listeners (void)
+{
+  Octave_map m = get (true).map_value ();
+
+  for (Octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++)
+    {
+      if (get_properties().has_property (pa->first))
+	{
+	  property p = get_properties ().get_property (pa->first);
+
+	  if (! error_state && p.ok ())
+	    p.delete_listener ();
+	}
+    }
+}
+
 // ---------------------------------------------------------------------
 
 #include "graphics-props.cc"
@@ -4961,6 +4988,72 @@
   return retval;
 }
 
+DEFUN (dellistener, args, ,
+   "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} dellistener (@var{h}, @var{prop}, @var{fcn})\n\
+Remove the registration of @var{fcn} as a listener for the property\n\
+@var{prop} of the graphics object @var{h}. The function @var{fcn} must\n\
+be the same variable (not just the same value), as was passed to the\n\
+original call to @code{addlistener}.\n\
+\n\
+If @var{fcn} is not defined then all listener functions of @var{prop}\n\
+are removed.\n\
+\n\
+Example:\n\
+\n\
+@example\n\
+function my_listener (h, dummy, p1)\n\
+  fprintf (\"my_listener called with p1=%s\\n\", p1);\n\
+endfunction\n\
+\n\
+c = @{@@my_listener, \"my string\"@};\n\
+addlistener (gcf, \"position\", c);\n\
+dellistener (gcf, \"position\", c);\n\
+@end example\n\
+\n\
+@end deftypefn")
+{
+  gh_manager::autolock guard;
+
+  octave_value retval;
+
+  if (args.length () == 3 || args.length () == 2)
+    {
+      double h = args(0).double_value ();
+
+      if (! error_state)
+	{
+	  std::string pname = args(1).string_value ();
+
+	  if (! error_state)
+	    {
+	      graphics_handle gh = gh_manager::lookup (h);
+
+	      if (gh.ok ())
+		{
+		  graphics_object go = gh_manager::get_object (gh);
+
+		  if (args.length () == 2)
+		    go.delete_property_listener (pname, octave_value (), POSTSET);
+		  else
+		    go.delete_property_listener (pname, args(2), POSTSET);
+		}
+	      else
+		error ("dellistener: invalid graphics object (= %g)",
+		       h);
+	    }
+	  else
+	    error ("dellistener: invalid property name, expected a string value");
+	}
+      else
+	error ("dellistener: invalid handle");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 DEFUN (addproperty, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} addproperty (@var{name}, @var{h}, @var{type}, [@var{arg}, @dots{}])\n\
--- a/src/graphics.h.in	Fri Oct 31 12:09:16 2008 +0100
+++ b/src/graphics.h.in	Fri Oct 31 12:30:20 2008 +0100
@@ -398,6 +398,37 @@
       l.resize (l.length () + 1, v);
     }
 
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+    {
+      octave_value_list& l = listeners[mode];
+
+      if (v.is_defined ())
+	{
+	  bool found = false;
+	  int i;
+
+	  for (i = 0; i < l.length (); i++)
+	    {
+	      if (v.internal_rep () == l(i).internal_rep ())
+		{
+		  found = true;
+		  break;
+		}
+	    }
+	  if (found)
+	    {
+	      for (int j = i; j < l.length() - 1; j++)
+		l(j) = l (j + 1);
+
+	      l.resize (l.length () - 1);
+	    }
+	}
+      else
+	l.resize (0);
+
+    }
+
   OCTINTERP_API void run_listeners (listener_mode mode = POSTSET);
 
   virtual base_property* clone (void) const
@@ -1287,6 +1318,10 @@
   void add_listener (const octave_value& v, listener_mode mode = POSTSET)
     { rep->add_listener (v, mode); }
 
+  void delete_listener (const octave_value& v = octave_value (), 
+			listener_mode mode = POSTSET)
+  { rep->delete_listener (v, mode); }
+
   void run_listeners (listener_mode mode = POSTSET)
     { rep->run_listeners (mode); }
 
@@ -1632,6 +1667,9 @@
   virtual void add_listener (const caseless_str&, const octave_value&,
 			     listener_mode = POSTSET);
 
+  virtual void delete_listener (const caseless_str&, const octave_value&,
+				listener_mode = POSTSET);
+
   void set_tag (const octave_value& val) { tag = val; }
 
   void set_parent (const octave_value& val);
@@ -1927,6 +1965,16 @@
 	get_properties ().add_listener (nm, v, mode);
     }
 
+  virtual void delete_property_listener (const std::string& nm,
+					 const octave_value& v,
+					 listener_mode mode = POSTSET)
+    {
+      if (valid_object ())
+	get_properties ().delete_listener (nm, v, mode);
+    }
+
+  virtual void remove_all_listeners (void);
+
 protected:
   // A reference count.
   int count;
@@ -2087,6 +2135,10 @@
 			      listener_mode mode = POSTSET)
     { rep->add_property_listener (nm, v, mode); }
 
+  void delete_property_listener (const std::string& nm, const octave_value& v,
+				 listener_mode mode = POSTSET)
+    { rep->delete_property_listener (nm, v, mode); }
+
 private:
   base_graphics_object *rep;
 };
@@ -2773,6 +2825,7 @@
 
   void set_defaults (const std::string& mode)
   {
+    remove_all_listeners ();
     xproperties.set_defaults (*this, mode);
   }