Mercurial > octave
changeset 24395:41cf6ee90cb6
Better handling of "handlevisibility" property (bug #52621).
* graphics.in.h (base_property::handlevisibility): Declare virtual updater
(figure::properties::update_handlevisibility): Declare overloaded method.
* graphics.cc (base_properties::update_handlevisibility): Don't let objects
with "handlevisibility" = "off" be the root callbaackobject or figure
currentobject. Add BIST for handlevisibility property.
(figure::properties::update_handlevisibility): Don't let figure with
"handlevisibility" = "off" be the root currentfigure.
(axes::properties::update_handlevisibility): Don't let axes with
"handlevisibility" = "off" be the figure currentaxes.
* figure.m: Don't let figure become "currentfigure" if its handle is not
visible.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Sun, 10 Dec 2017 14:35:06 +0100 |
parents | f997aa4be0ce |
children | c652f2637063 |
files | libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h scripts/plot/util/figure.m |
diffstat | 3 files changed, 134 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc Mon Dec 11 08:51:12 2017 -0800 +++ b/libinterp/corefcn/graphics.cc Sun Dec 10 14:35:06 2017 +0100 @@ -2057,6 +2057,28 @@ } } +void +figure::properties::update_handlevisibility (void) +{ + if (! is_handle_visible ()) + { + octave_value cf = gh_manager::get_object (0).get ("currentfigure"); + if (! cf.isempty () && cf.double_value () == __myhandle__) + { + gh_manager::auto_lock guard; + octave_value kids = gh_manager::get_object (0).get ("children"); + if (kids.isempty ()) + gh_manager::get_object (0).set ("currentfigure", Matrix ()); + else + { + NDArray kidsarray = kids.array_value (); + gh_manager::get_object (0).set ("currentfigure", kidsarray(0)); + } + } + } + + base_properties::update_handlevisibility (); +} // --------------------------------------------------------------------- void @@ -3283,6 +3305,78 @@ } void +base_properties::update_handlevisibility (void) +{ + if (is_handle_visible ()) + return; + + // This object should not be the root "callbackobject" + graphics_object rt = gh_manager::get_object (0); + octave_value cbo = rt.get ("callbackobject"); + if (! cbo.isempty () && cbo.double_value () == __myhandle__) + { + gh_manager::auto_lock guard; + auto& root_props = + dynamic_cast<root_figure::properties&> (rt.get_properties ()); + root_props.set_callbackobject (Matrix ()); + } + + // This object should not be the figure "currentobject" + graphics_object go (gh_manager::get_object (get___myhandle__ ())); + graphics_object fig (go.get_ancestor ("figure")); + if (fig.valid_object ()) + { + octave_value co = fig.get ("currentobject"); + if (! co.isempty () && co.double_value () == __myhandle__) + { + gh_manager::auto_lock guard; + auto& fig_props = + dynamic_cast<figure::properties&> (fig.get_properties ()); + fig_props.set_currentobject (Matrix ()); + } + } +} + +/* +## test current figure and current axes have visible handles +%!test +%! hf1 = figure ("visible", "off"); +%! hf2 = figure ("visible", "off"); +%! hax1 = axes (); +%! hax2 = axes (); +%! unwind_protect +%! assert (get (0, "currentfigure"), hf2); +%! assert (get (hf2, "currentaxes"), hax2); +%! set (hf2, "handlevisibility", "off"); +%! assert (get (0, "currentfigure"), hf1); +%! set (hax2, "handlevisibility", "off"); +%! assert (get (hf2, "currentaxes"), hax1); +%! assert (get (hf2, "currentobject"), []); +%! unwind_protect_cleanup +%! close ([hf1, hf2]); +%! end_unwind_protect; +*/ + +/* +## test current callback object have visible handle +%!test +%! hf = figure ("visible", "off"); +%! hax = axes (); +%! unwind_protect +%! fcn = @(h) assert (gcbo (), h); +%! addlistener (hax, "color", fcn); +%! set (hax, "color", "r"); +%! dellistener (hax, "color", fcn); +%! set (hax, "handlevisibility", "off"); +%! fcn = @() assert (gcbo (), []); +%! addlistener (hax, "color", fcn); +%! set (hax, "color", "b"); +%! unwind_protect_cleanup +%! close (hf); +%! end_unwind_protect; +*/ + +void base_properties::add_listener (const caseless_str& pname, const octave_value& val, listener_mode mode) @@ -8486,6 +8580,31 @@ } void +axes::properties::update_handlevisibility (void) +{ + if (! is_handle_visible ()) + { + graphics_object go (gh_manager::get_object (get___myhandle__ ())); + graphics_object fig (go.get_ancestor ("figure")); + octave_value ca = fig.get ("currentaxes"); + if (! ca.isempty () && ca.double_value () == __myhandle__) + { + gh_manager::auto_lock guard; + octave_value kids = fig.get ("children"); + if (kids.isempty ()) + fig.set ("currentaxes", Matrix ()); + else + { + NDArray kidsarray = kids.array_value (); + fig.set ("currentaxes", kidsarray(0)); + } + } + } + + base_properties::update_handlevisibility (); +} + +void axes::properties::clear_zoom_stack (bool do_unzoom) { size_t items_to_leave_on_stack = (do_unzoom ? 7 : 0); @@ -10133,13 +10252,11 @@ octave::unwind_protect_safe frame; frame.add_fcn (gh_manager::restore_gcbo); - if (true) - { - gh_manager::auto_lock guard; - - callback_objects.push_front (get_object (h)); - xset_gcbo (h); - } + gh_manager::auto_lock guard; + graphics_object go (get_object (h)); + callback_objects.push_front (go); + if (go.get ("handlevisibility").string_value () != "off") + xset_gcbo (h); // Copy CB because "function_value" method is non-const.
--- a/libinterp/corefcn/graphics.in.h Mon Dec 11 08:51:12 2017 -0800 +++ b/libinterp/corefcn/graphics.in.h Sun Dec 10 14:35:06 2017 +0100 @@ -2362,7 +2362,7 @@ bool_property clipping , "on" callback_property createfcn , Matrix () callback_property deletefcn , Matrix () - radio_property handlevisibility , "{on}|callback|off" + radio_property handlevisibility u , "{on}|callback|off" bool_property hittest , "on" bool_property interruptible , "on" handle_property parent fs , p @@ -2378,6 +2378,8 @@ graphics_handle __myhandle__ fhrs , mh END_PROPERTIES + virtual void update_handlevisibility (void); + protected: struct cmp_caseless_str { @@ -3202,6 +3204,8 @@ paperposition.set (get_auto_paperposition ()); } + void update_handlevisibility (void); + mutable graphics_toolkit toolkit; }; @@ -3499,6 +3503,7 @@ bool push_to_zoom_stack = true); void unzoom (void); + void update_handlevisibility (void); void push_zoom_stack (void); void clear_zoom_stack (bool do_unzoom = true);
--- a/scripts/plot/util/figure.m Mon Dec 11 08:51:12 2017 -0800 +++ b/scripts/plot/util/figure.m Sun Dec 10 14:35:06 2017 +0100 @@ -90,7 +90,10 @@ set (f, varargin{:}); endif - set (0, "currentfigure", f); + if (strcmp (get (f, "handlevisibility"), "on")) + set (0, "currentfigure", f); + endif + ## When switching to figure N, make figure visible and on top of stack, ## unless visibility is explicitly switched off. if (! init_new_figure && ! any (strcmpi (varargin(1:2:end), "visible")