diff libinterp/corefcn/graphics.cc @ 20112:69f92e0affd2

Handle uicontextmenu deletion/reset (bug #44801) *graphics.in.h (base_graphics_opbject::properties): add updater for uicontextmenu property *graphics.in.h (uicontextmenu::properties::dependent_obj_list): new private attribute to store the list of objects that may depend on this uicontextmenu. *graphics.in.h (uicontextmenu::properties::get_dependent_obj_list (), uicontextmenu::properties::add_dependent_obj ()): new methods * graphics.cc (base_graphics_opbject::properties::update_uicontextmenu): new method to mark this graphics object as dependent on an uicontextmenu object. * graphics.cc (uicontextmenu::~uicontextmenu): reset the "uicontextmenu" property of objects that have this uicontextmenu as current. * graphics.cc (handle_property::do_set): let users reset a handle property using empty matrix. * graphics.cc: add BIST for bug #44801 * genpropdoc.m: document "uicontextmenu" property
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Sat, 11 Apr 2015 17:25:35 +0200
parents 10600b2dd3c1
children ade6e5ae6164
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc	Tue Apr 14 14:27:22 2015 -0400
+++ b/libinterp/corefcn/graphics.cc	Sat Apr 11 17:25:35 2015 +0200
@@ -1473,6 +1473,18 @@
 bool
 handle_property::do_set (const octave_value& v)
 {
+  // Users may want to use empty matrix to reset a handle property
+  if (v.is_empty ())
+    {
+      if (! get ().is_empty ())
+        {
+          current_val = graphics_handle ();
+          return true;
+        }
+      else
+        return false;
+    }
+
   double dv = v.double_value ();
 
   if (! error_state)
@@ -3085,6 +3097,21 @@
     obj.update_axis_limits (axis_type, h);
 }
 
+void
+base_properties::update_uicontextmenu (void) const
+{
+  if (uicontextmenu.get ().is_empty ())
+    return;
+  
+  graphics_object obj = gh_manager::get_object (uicontextmenu.get ());
+  if (obj && obj.isa ("uicontextmenu"))
+    {
+      uicontextmenu::properties& props =
+        reinterpret_cast<uicontextmenu::properties&> (obj.get_properties ());
+      props.add_dependent_obj (__myhandle__);
+    }
+}
+
 bool
 base_properties::is_handle_visible (void) const
 {
@@ -8813,6 +8840,51 @@
 
 // ---------------------------------------------------------------------
 
+uicontextmenu::~uicontextmenu (void)
+{ 
+  std::list<graphics_handle> lst = xproperties.get_dependent_obj_list ();
+  std::list<graphics_handle>::const_iterator it;
+  
+  for (it = lst.begin (); it != lst.end (); it++)
+    {
+      graphics_object go = gh_manager::get_object (*it);
+      
+      if (go.valid_object () &&
+          go.get ("uicontextmenu") == xproperties.get___myhandle__ ())
+        go.set ("uicontextmenu", Matrix ());
+    }
+}
+
+
+/*
+## Test deletion/reset of uicontextmenu
+%!test
+%! hf = figure ("visible", "off");
+%! hax = axes ("parent", hf);
+%! unwind_protect
+%!   hctx1 = uicontextmenu ("parent", hf);
+%!   hctx2 = uicontextmenu ("parent", hf);
+%!   set (hf, "uicontextmenu", hctx2);
+%!   set (hax, "uicontextmenu", hctx2);
+%!   assert (get (hf, "uicontextmenu"), hctx2);
+%!   assert (get (hax, "uicontextmenu"), hctx2);
+%!   assert (get (hf, "children"), [hctx2; hctx1; hax]);
+%!   delete (hctx2);
+%!   assert (get (hf, "uicontextmenu"), []);
+%!   assert (get (hax, "uicontextmenu"), []);
+%!   assert (get (hf, "children"), [hctx1; hax]);
+%!   set (hf, "uicontextmenu", hctx1);
+%!   assert (get (hf, "uicontextmenu"), hctx1);
+%!   set (hf, "uicontextmenu", []);
+%!   assert (get (hf, "uicontextmenu"), []);
+%!   assert (get (hf, "children"), [hctx1; hax]);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect;
+ */
+
+// ---------------------------------------------------------------------
+
 octave_value
 uicontrol::properties::get_extent (void) const
 {