Mercurial > hg > octave-terminal
changeset 6935:5cd272497aae
[project @ 2007-09-30 19:16:49 by dbateman]
author | dbateman |
---|---|
date | Sun, 30 Sep 2007 19:16:49 +0000 |
parents | 37676450044a |
children | e92bc778c634 |
files | scripts/ChangeLog scripts/plot/Makefile.in scripts/plot/findobj.m |
diffstat | 3 files changed, 240 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +2007-09-30 Ben Abbott <bpabbott@mac.com> + + * plot/findobj.m: New function. + * plot/Makefile.m (SOURCES): Add it to SOURCES. + 2007-09-26 David Bateman <dbateman@free.fr> * pkg/pkg.m: Add second argument to setting for prefix for
--- a/scripts/plot/Makefile.in +++ b/scripts/plot/Makefile.in @@ -60,6 +60,7 @@ drawnow.m \ errorbar.m \ figure.m \ + findobj.m \ fplot.m \ gca.m \ gcf.m \
new file mode 100644 --- /dev/null +++ b/scripts/plot/findobj.m @@ -0,0 +1,234 @@ +## Copyright (C) 2007 Ben Abbott <bpabbott@mac.com> +## +## This program 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 2 of the License, or +## (at your option) any later version. +## +## This program 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 this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{h} =} findobj () +## @deftypefnx {Function File} {@var{h} =} findobj (@var{propName}, @var{propValue}) +## @deftypefnx {Function File} {@var{h} =} findobj ('-property', @var{propName}) +## @deftypefnx {Function File} {@var{h} =} findobj ('-regexp', @var{propName},, @var{pattern}) +## @deftypefnx {Function File} {@var{h} =} findobj ('flat', @dots{}) +## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{}) +## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, '-depth', @var{d}, @dots{}) +## Find object with specified property values. The simpliest form is +## +## @example +## findobj (@var{propName}, @var{propValue}) +## @end example +## +## @noindent +## which returns all of the handles to the objects with the name +## @var{propName} and the name @var{propValue}. The search can be limited +## to a particular object or set of objects and their descendants by +## passing a handle or set of handles @var{h} as the first argument to +## @code{findobj}. +## +## The depth of hierarchy of objects to which to search to can be limited +## with the '-depth' argument. To limit the number depth of the hierarchy +## to search to @var{d} generations of children, and example is +## +## @example +## findobj (@var{h}, '-depth', @var{d}, @var{propName}, @var{propValue}) +## @end example +## +## Specifying a depth @var{d} of 0, limits the search to the set of object +## passed in @var{h}. A depth @var{d} of 0 is equivalent to the '-flat' +## argument. +## +## A specified logical operator may be applied to the pairs of @var{propName} +## and @var{propValue}. The supported logical operators are '-and', '-or', +## '-xor', '-not'. +## +## The objects may also be matched by comparing a regular expression to the +## property values, where property values that match @code{regexp +## (@var{propValue}, @var{pattern})} are returned. Finally, objects may be +## matched by property name only, using the '-property' option. +## @seealso{get, set} +## @end deftypefn + +function h = findobj (varargin) + + depth = NaN; + if (nargin == 0) + handles = 0; + n1 = 0; + else + if (ishandle (varargin{1}(1))) + handles = varargin{1}; + n1 = 2; + else + handles = 0; + n1 = 1; + end + if (n1 <= nargin) + if (ischar (varargin{n1})) + if (strcmpi (varargin{n1}, 'flat')) + depth = 0; + n1 = n1 + 1; + elseif (strcmpi(varargin{n1}, '-depth')) + depth = varargin{n1+1}; + n1 = n1 + 2; + 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 = {}; + pname = {}; + pvalue = {}; + np = 1; + na = 1; + + while (na <= numel (args)) + regularexpression(np) = 0; + property(np) = 0; + logicaloperator{np} = 'and'; + if (ischar (args {na})) + if (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}, '-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 (! 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 strcmpi(args{na}, '-and') + logicaloperator{np} = 'and'; + na = na+1; + elseif strcmpi(args{na}, '-or') + logicaloperator{np} = 'or'; + na = na+1; + elseif strcmpi(args{na}, '-xor') + logicaloperator{np} = 'xor'; + na = na+1; + elseif strcmpi(args{na}, '-not') + logicaloperator{np} = 'not'; + 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 + ## this is sloppy ... but works like matlab + if strcmpi(args{na}, '-not') + h = []; + return + endif + na = na + 1; + endif + else + error ("findobj: properties and options must be strings"); + endif + endwhile + + numpairs = np - 1; + + ## load all objects which qualify for being searched + idepth = 0; + h = handles; + while (numel (handles) && ! (idepth >= depth)) + children = []; + for n = 1 : numel (handles) + children = union (children, get(handles(n), 'children')); + endfor + handles = children; + h = union (h, children); + idepth = idepth + 1; + endwhile + + keepers = ones (size (h)); + if (numpairs > 0) + 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 = 1; + else + if (regularexpression(np)) + match = regexp (p.(pname{np}), pvalue{np}); + if isempty (match) + match = 0; + end + elseif (numel (p.(pname{np})) == numel (pvalue{np})) + if (ischar (pvalue{np})) + match = strcmpi (pvalue{np}, p.(pname{np})); + else + match = (pvalue{np} == p.(pname{np})); + endif + else + match = 0; + endif + match = all (match); + endif + if (strcmpi (logicaloperator{np}, 'not')) + keepers(nh) = ! keepers(nh) & ! match; + else + keepers(nh) = feval (logicaloperator{np}, keepers(nh), match); + endif + else + keepers(nh) = 0; + endif + endfor + endfor + endif + + h = h (keepers != 0); + h = reshape (h, [numel(h), 1]); +endfunction