diff src/graphics.cc @ 8208:f6ca8ff51818

[mq]: graphics-backend
author John W. Eaton <jwe@octave.org>
date Fri, 10 Oct 2008 11:07:53 -0400
parents 32e9e8103390
children 2abbc8036f6a
line wrap: on
line diff
--- a/src/graphics.cc	Fri Oct 10 16:44:21 2008 +0200
+++ b/src/graphics.cc	Fri Oct 10 11:07:53 2008 -0400
@@ -1291,19 +1291,25 @@
 
 	  if (p != handle_map.end ())
 	    {
-	      // FIXME: should we explicitely free all children first?
-	      //        => call delete_children () ?
-
-	      p->second.get_properties ().set_beingdeleted (true);
-	      p->second.get_properties ().execute_deletefcn ();
+	      base_properties& bp = p->second.get_properties ();
+	      
+	      bp.set_beingdeleted (true);
+
+	      bp.delete_children ();
+
+	      octave_value val = bp.get_deletefcn ();
+
+	      bp.execute_deletefcn ();
 
 	      // notify backend
 	      graphics_backend backend = p->second.get_backend ();
 	      if (backend)
                 backend.object_destroyed (p->second);
-                 // note - this will be valid only for first explicitly deleted object.
-                 // All his children will have unknown backend then.
-                 
+
+	      // Note: this will be valid only for first explicitly 
+	      // deleted object.  All its children will then have an
+	      // unknown backend.
+
 	      handle_map.erase (p);
 
 	      if (h.value () < 0)
@@ -1737,8 +1743,15 @@
 {
   octave_idx_type n = children.numel ();
 
+  // A callback function might have already deleted the child,
+  // so check before deleting
   for (octave_idx_type i = 0; i < n; i++)
-    gh_manager::free (children(i));
+    {
+      graphics_object go = gh_manager::get_object (children(i));
+
+      if (go.valid_object ())
+	gh_manager::free (children(i));
+    }
 }
 
 graphics_backend
@@ -2104,8 +2117,12 @@
 void 
 axes::properties::sync_positions (void)
 {
+#if 0
   // FIXME -- this should take font metrics into consideration,
-  // for now we'll just make it position 90% of outerposition
+  // and also the fact that the colorbox leaves the outerposition
+  // alone but alters the position. For now just don't adjust the
+  // positions relative to each other.
+
   if (activepositionproperty.is ("outerposition"))
     {
       Matrix outpos = outerposition.get ().matrix_value ();
@@ -2126,6 +2143,7 @@
       pos(3) *= 1.1;
       outerposition = pos;
     }
+#endif
 
   update_transform ();
 }
@@ -2182,7 +2200,8 @@
 axes::properties::set_defaults (base_graphics_object& obj,
 				const std::string& mode)
 {
-  title = graphics_handle ();
+  delete_text_child (title);
+
   box = "on";
   key = "off";
   keybox = "off";
@@ -2206,9 +2225,11 @@
   ylimmode = "auto";
   zlimmode = "auto";
   climmode = "auto";
-  xlabel = graphics_handle ();
-  ylabel = graphics_handle ();
-  zlabel = graphics_handle ();
+
+  delete_text_child (xlabel);
+  delete_text_child (ylabel);
+  delete_text_child (zlabel);
+
   xgrid = "off";
   ygrid = "off";
   zgrid = "off";
@@ -2289,7 +2310,6 @@
     }
 
   activepositionproperty = "outerposition";
-  __colorbar__  = "none";
 
   delete_children ();
 
@@ -2300,53 +2320,34 @@
   override_defaults (obj);
 }
 
-graphics_handle
-axes::properties::get_title (void) const
-{
-  if (! title.handle_value ().ok ())
-    title = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  return title.handle_value ();
-}
-
-graphics_handle
-axes::properties::get_xlabel (void) const
+void
+axes::properties::delete_text_child (handle_property& hp)
 {
-  if (! xlabel.handle_value ().ok ())
-    xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  return xlabel.handle_value ();
-}
-
-graphics_handle
-axes::properties::get_ylabel (void) const
-{
-  if (! ylabel.handle_value ().ok ())
-    ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  return ylabel.handle_value ();
-}
-
-graphics_handle
-axes::properties::get_zlabel (void) const
-{
-  if (! zlabel.handle_value ().ok ())
-    zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
-
-  return zlabel.handle_value ();
+  graphics_handle h = hp.handle_value ();
+
+  if (h.ok ())
+    {
+      graphics_object go = gh_manager::get_object (h);
+
+      if (go.valid_object ())
+	gh_manager::free (h);
+    }
+
+  if (! is_beingdeleted ())
+    hp = gh_manager::make_graphics_handle ("text", __myhandle__);
 }
 
 void
 axes::properties::remove_child (const graphics_handle& h)
 {
   if (title.handle_value ().ok () && h == title.handle_value ())
-    title = gh_manager::make_graphics_handle ("text", __myhandle__);
+    delete_text_child (title);
   else if (xlabel.handle_value ().ok () && h == xlabel.handle_value ())
-    xlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+    delete_text_child (xlabel);
   else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ())
-    ylabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+    delete_text_child (ylabel);
   else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ())
-    zlabel = gh_manager::make_graphics_handle ("text", __myhandle__);
+    delete_text_child (zlabel);
   else
     base_properties::remove_child (h);
 }
@@ -2356,10 +2357,11 @@
 {
   base_properties::delete_children ();
 
-  gh_manager::free (title.handle_value ());
-  gh_manager::free (xlabel.handle_value ());
-  gh_manager::free (ylabel.handle_value ());
-  gh_manager::free (zlabel.handle_value ());
+  delete_text_child (title);
+
+  delete_text_child (xlabel);
+  delete_text_child (ylabel);
+  delete_text_child (zlabel);
 }
 
 inline Matrix
@@ -4431,20 +4433,28 @@
 		{
 		  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);
-
-		  // NOTE: free the handle before removing it from its parent's
-		  //       children, such that the object's state is correct
-		  //       when the deletefcn callback is executed
-
-		  gh_manager::free (h);
-
-		  parent_obj.remove_child (h);
-
-		  Vdrawnow_requested = true;
+		  // Don't do recursive deleting, due to callbacks
+		  if (! obj.get_properties ().is_beingdeleted ())
+		    {
+		      graphics_handle parent_h = obj.get_parent ();
+
+		      graphics_object parent_obj = 
+			gh_manager::get_object (parent_h);
+
+		      // NOTE: free the handle before removing it from its
+		      //       parent's children, such that the object's 
+		      //       state is correct when the deletefcn callback
+		      //       is executed
+
+		      gh_manager::free (h);
+
+		      // A callback function might have already deleted 
+		      // the parent
+		      if (parent_obj.valid_object ())
+			parent_obj.remove_child (h);
+
+		      Vdrawnow_requested = true;
+		    }
 		}
 	      else
 		{
@@ -4500,6 +4510,10 @@
 	      graphics_object obj = gh_manager::get_object (h);
 
 	      obj.set_defaults (mode);
+
+	      h = gh_manager::lookup (val);
+	      if (! h.ok ())
+		error ("__go_axes_init__: axis deleted during initialization (= %g)", val);
 	    }
 	  else
 	    error ("__go_axes_init__: invalid graphics object (= %g)", val);