Mercurial > octave-antonio
view scripts/plot/util/findobj.m @ 20115:7e0e8fb16201
Overhaul close.m to add "force" argument (bug #44324)
* close.m: Emit an error if there is no figure handle or "all" argument given.
Check for "force" argument and delete the requested figure handles rather than
calling closereqfcn. Add BIST input validation tests. Add new calling forms
and explanation of "force" to docstring.
author | Rik <rik@octave.org> |
---|---|
date | Wed, 22 Apr 2015 08:41:50 -0700 |
parents | ed53c87050e8 |
children |
line wrap: on
line source
## Copyright (C) 2007-2015 Ben Abbott ## ## 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} {@var{h} =} findobj () ## @deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value}, "-@var{logical_op}", @var{prop_name}, @var{prop_value}) ## @deftypefnx {Function File} {@var{h} =} findobj ("-property", @var{prop_name}) ## @deftypefnx {Function File} {@var{h} =} findobj ("-regexp", @var{prop_name}, @var{pattern}) ## @deftypefnx {Function File} {@var{h} =} findobj (@var{hlist}, @dots{}) ## @deftypefnx {Function File} {@var{h} =} findobj (@var{hlist}, "flat", @dots{}) ## @deftypefnx {Function File} {@var{h} =} findobj (@var{hlist}, "-depth", @var{d}, @dots{}) ## Find graphics object with specified property values. ## ## The simplest form is ## ## @example ## findobj (@var{prop_name}, @var{prop_value}) ## @end example ## ## @noindent ## which returns the handles of all objects which have a property named ## @var{prop_name} that has the value @var{prop_value}. If multiple ## property/value pairs are specified then only objects meeting all of the ## conditions are returned. ## ## The search can be limited to a particular set of objects and their ## descendants, by passing a handle or set of handles @var{hlist} as the first ## argument. ## ## The depth of the object hierarchy to search can be limited with the ## @qcode{"-depth"} argument. An example of searching only three generations ## of children is: ## ## @example ## findobj (@var{hlist}, "-depth", 3, @var{prop_name}, @var{prop_value}) ## @end example ## ## Specifying a depth @var{d} of 0, limits the search to the set of objects ## passed in @var{hlist}. A depth @var{d} of 0 is equivalent to the ## @qcode{"flat"} argument. ## ## A specified logical operator may be applied to the pairs of @var{prop_name} ## and @var{prop_value}. The supported logical operators are: ## @qcode{"-and"}, @qcode{"-or"}, ## @qcode{"-xor"}, @qcode{"-not"}. ## ## Objects may also be matched by comparing a regular expression to the ## property values, where property values that match ## @code{regexp (@var{prop_value}, @var{pattern})} are returned. ## ## Finally, objects may be matched by property name only by using the ## @qcode{"-property"} option. ## ## Implementation Note: The search only includes objects with visible ## handles (HandleVisibility = @qcode{"on"}). @xref{XREFfindall,,findall}, to ## search for all objects including hidden ones. ## @seealso{findall, allchild, get, set} ## @end deftypefn ## Author: Ben Abbott <bpabbott@mac.com> function h = findobj (varargin) depth = NaN; if (nargin == 0) handles = 0; n1 = 0; else if (! isempty (varargin{1})) if (ishandle (varargin{1}(1))) handles = varargin{1}; n1 = 2; else handles = 0; n1 = 1; endif else ## Return [](0x1) for compatibility. h = zeros (0, 1); return; endif if (n1 <= nargin) if (ischar (varargin{n1})) if (strcmpi (varargin{n1}, "flat")) depth = 0; n1 = n1 + 1; endif else error ("findobj: properties and options must be strings"); endif endif endif if (n1 <= nargin && nargin > 0) args = varargin(n1 : nargin); else args = {}; endif regularexpression = []; property = []; logicaloperator = {}; extranegation = []; pname = {}; pvalue = {}; np = 1; na = 1; operatorprecedence = {"-not", "-and", "-or", "-xor"}; while (na <= numel (args)) regularexpression(np) = 0; property(np) = 0; if (numel (extranegation) < np) extranegation(np) = false; endif logicaloperator{np} = "and"; if (ischar (args{na})) if (strcmpi (args{na}, "-property")) if (na + 1 <= numel (args)) na = na + 1; property(np) = 1; pname{np} = args{na}; na = na + 1; pvalue{np} = []; np = np + 1; else error ("findobj: inconsistent number of arguments"); endif elseif (strcmpi (args{na}, "-regexp")) if (na + 2 <= numel (args)) regularexpression(np) = 1; na = na + 1; pname{np} = args{na}; na = na + 1; pvalue{np} = args{na}; na = na + 1; np = np + 1; else error ("findobj: inconsistent number of arguments"); endif elseif (strcmpi (args{na}, "-depth")) if (na + 1 <= numel (args)) na = na + 1; depth = args{na}; na = na + 1; else error ("findobj: inconsistent number of arguments"); endif elseif (! strcmp (args{na}(1), "-")) ## Parameter/value pairs. if (na + 1 <= numel (args)) pname{np} = args{na}; na = na + 1; pvalue{np} = args{na}; na = na + 1; if (na <= numel (args)) if (ischar (args{na})) if (any (strcmpi (args{na}, operatorprecedence))) logicaloperator{np} = args{na}(2:end); na = na+1; endif else error ("findobj: properties and options must be strings"); endif else logicaloperator{np} = "and"; endif np = np + 1; else error ("findobj: inconsistent number of arguments"); endif else if (strcmpi (args{na}, "-not")) extranegation(np) = true; endif na = na + 1; endif else error ("findobj: properties and options must be strings"); endif endwhile numpairs = np - 1; if (! isempty (logicaloperator)) logicaloperator = shift (logicaloperator, 1); endif ## Load all objects which qualify for being searched. idepth = 0; h = handles; while (numel (handles) && ! (idepth >= depth)) children = []; for n = 1 : numel (handles) children = [children; get(handles(n), "children")]; endfor handles = children; h = [h; children]; idepth = idepth + 1; endwhile if (numpairs > 0) match = true (numel (h), numpairs); for nh = 1 : numel (h) p = get (h(nh)); for np = 1 : numpairs fields = fieldnames (p); fieldindex = find (strcmpi (fields, pname{np}), 1); if (numel (fieldindex)) pname{np} = fields{fieldindex}; if (property(np)) match(nh,np) = true; else if (regularexpression(np)) found = regexp (p.(pname{np}), pvalue{np}, "once"); if (isempty (found)) match(nh,np) = false; else match(nh,np) = true; endif elseif (numel (p.(pname{np})) == numel (pvalue{np})) if (ischar (pvalue{np}) && ischar (p.(pname{np}))) match(nh,np) = strcmpi (pvalue{np}, p.(pname{np})); elseif (isnumeric (pvalue{np} && isnumeric (p.(pname{np})))) match(nh,np) = (pvalue{np} == p.(pname{np})); else match(nh,np) = isequal (pvalue{np}, p.(pname{np})); endif else match(nh,np) = false; endif endif else match(nh,np) = false; endif if (extranegation(np)) match(nh,np) = ! match(nh,np); endif endfor endfor if (numpairs > 1) for no = 1 : numel (operatorprecedence) pairs = find (strcmp (logicaloperator(2:end), ... operatorprecedence{no}(2:end))); for np = sort (pairs, "descend") if (no == 1) match(:,np+1) = ! match(:,np+1); logicaloperator(np+1) = {"and"}; else match(:,np) = feval (logicaloperator{np+1}, match(:,np), ... match(:,np+1)); logicaloperator(np+1) = []; match(:,np+1) = []; numpairs = numpairs - 1; endif if (numpairs < 2) break; endif endfor if (numpairs < 2) break; endif endfor endif else match = true (numel (h), 1); endif h = h(match); h = h(:); endfunction %!test %! hf = figure ("visible", "off"); %! unwind_protect %! h = findobj (gca (), "-property", "foo"); %! assert (isempty (h)); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %!test %! hf = figure ("visible", "off"); %! unwind_protect %! h = plot (1:10); %! set (h, "tag", "foobar"); %! g = findobj (gcf (), "tag", "foobar", "type", "line", "color", [0 0 1]); %! assert (g, h); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %!test %! hf = figure ("visible", "off"); %! unwind_protect %! l = line; %! obj = findobj (hf, "type", "line"); %! assert (l, obj); %! assert (gca, findobj (hf, "type", "axes")); %! assert (hf, findobj (hf, "type", "figure")); %! assert (isempty (findobj (hf, "type", "xyzxyz"))); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %!test %! hf = figure ("visible", "off"); %! unwind_protect %! subplot (2,2,1); %! imagesc (rand (10)); %! subplot (2,2,2); %! surf (peaks); %! subplot (2,2,3); %! contour (peaks); %! subplot (2,2,4); %! plot (peaks); %! h1 = findobj (gcf (), "-regexp", "Type", "image|surface|hggroup"); %! h2 = findobj (gcf (), "Type", "image", %! "-or", "Type", "surface", %! "-or", "Type", "hggroup"); %! assert (h2, h1); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %!test %! toolkit = graphics_toolkit ("gnuplot"); %! hf = figure ("visible", "off"); %! unwind_protect %! h1 = subplot (2,2,1); %! h2 = subplot (2,2,2); %! h3 = subplot (2,2,3, "userdata", struct ("foo", "bar")); %! h4 = subplot (2,2,4); %! h = findobj (hf, "userdata", struct ("foo", "bar")); %! assert (h, h3); %! unwind_protect_cleanup %! close (hf); %! graphics_toolkit (toolkit); %! end_unwind_protect %!test %! toolkit = graphics_toolkit ("gnuplot"); %! hf = figure ("visible", "off"); %! unwind_protect %! h1 = subplot (2,2,1, "tag", "1"); %! h2 = subplot (2,2,2, "tag", "2"); %! h3 = subplot (2,2,3, "tag", "3"); %! h4 = subplot (2,2,4, "tag", "4"); %! h = findobj (hf, "type", "axes", "-not", "tag", "1"); %! assert (h, [h4; h3; h2]) %! unwind_protect_cleanup %! close (hf); %! graphics_toolkit (toolkit); %! end_unwind_protect %!test %! hf = figure ("visible", "off"); %! unwind_protect %! h1 = subplot (2, 2, 1); %! set (h1, "userdata", struct ("column", 1, "row", 1)); %! h2 = subplot (2, 2, 2); %! set (h2, "userdata", struct ("column", 2, "row", 1)); %! h3 = subplot (2, 2, 3); %! set (h3, "userdata", struct ("column", 1, "row", 2)); %! h4 = subplot (2, 2, 4); %! set (h4, "userdata", struct ("column", 2, "row", 2)); %! h = findobj (hf, "type", "axes", %! "-not", "userdata", struct ("column", 1, "row", 1)); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %! assert (h, [h4; h3; h2]) %!test %! hf = figure ("visible", "off"); %! unwind_protect %! ha = axes (); %! plot (1:10); %! h = findobj (hf, "type", "figure", %! "-or", "parent", hf, %! "-and", "type", "axes"); %! unwind_protect_cleanup %! close (hf) %! end_unwind_protect %! assert (h, [hf; ha]) %!test %! hf = figure ("visible", "off"); %! unwind_protect %! set (hf, "tag", "foo"); %! h1 = subplot (2,2,1, "tag", "foo"); %! h2 = subplot (2,2,2, "tag", "bar"); %! h3 = subplot (2,2,3, "tag", "foo"); %! h4 = subplot (2,2,4, "tag", "bar"); %! h = findobj (hf, "type", "axes", "-xor", "tag", "foo"); %! assert (h, [hf; h4; h2]); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect %!test %! hf = figure ("visible", "off"); %! unwind_protect %! hax1 = subplot (2,1,1); %! hl1 = plot (rand (10,1)); %! hax2 = subplot (2,1,2); %! hl2 = plot (rand (10,1)); %! hobj = findobj (hf); %! assert (hobj, [hf; hax2; hax1; hl2; hl1]); %! unwind_protect_cleanup %! close (hf); %! end_unwind_protect