www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+motion/MotionManager.m

    classdef MotionManager < matlab.mixin.SetGet & matlab.mixin.Copyable & matlab.mixin.Heterogeneous
    %mbcgui.motion.MotionManager class
    %    mbcgui.motion.MotionManager properties:
    %       Figure - Property is of type 'MATLAB array'
    %       Mode - Property is of type 'string'
    %       Enable - Property is of type 'on/off'
    %       MouseMoveFcn - Property is of type 'MATLAB callback'
    %       MouseInFcn - Property is of type 'MATLAB callback'
    %       MouseOutFcn - Property is of type 'MATLAB callback'
    %       EnableTree - Property is of type 'bool'
    %       Region - Property is of type 'rect'
    %       UseExternalRef - Property is of type 'on/off'
    %       ExternalRef - Property is of type 'MATLAB array'
    %
    %    mbcgui.motion.MotionManager methods:
    %       AttachToFigure - Attach Motion Manager to figure
    %       ExecuteMovement - Execute MotionManager callbacks
    %       FindManager - Find the existing MotionManager for a figure or panel
    %       RecoverMotion - Re-apply motion function to figure
    %       RegisterManager - Register a MotionManager
    %       RegisterSingleManager - Register a MotionManager
    %       UnregisterManager - Unregister a MotionManager
    %       UnregisterSingleManager - Unregister a MotionManager
    %       clearRegions - Emit MouseOut event to all sub-Managers
    %       doUpdate - Force an update of mouse position tracking
    %       enableManager - determine whether to enable manager
    %       getChildren - Return the registered sub-managers
    %       getEnabled - Return vector of enabled values for a vector of Managers
    %       getXmax - Return vector of Xmax values from a vector of MotionManagers
    %       getXmin - Return vector of Xmin values from a vector of MotionManagers
    %       getYmax - Return vector of Ymax values from a vector of MotionManagers
    %       getYmin - Return vector of Ymin values from a vector of MotionManagers
    %       setCallback - Set up new callback function
    %       setEnable - Finalise new enable value
    %       setEnableTree - Finalise new EnableTree setting
    %       setExternalRef - Finalise new external reference setting
    %       setExternalRefFlag - Finalise new external reference setting
    %       setRegion - Finalise new region value
    
    %  Copyright 2000-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    properties
        %FIGURE Property is of type 'MATLAB array'
        Figure
        %MODE Property is of type 'string'
        Mode = 'Multi';
        %ENABLETREE Property is of type 'bool'
        EnableTree = true;
        %REGION Property is of type 'rect'
        Region = [ 0, 0, 1, 1 ];
        %USEEXTERNALREF Property is of type 'on/off'
        UseExternalRef = 'off';
        %EXTERNALREF Property is of type 'MATLAB array'
        ExternalRef
        
        %
        UserEnabled = 'on';
    end
    
    properties(SetAccess=protected)
        %Parent parent motionmanager.
        Parent
    end
    
    properties (Access=protected)
        %SINGLELISTENER Property is of type 'handle'
        SingleListener
        %MULTILISTENER Property is of type 'handle vector'
        MultiListener
        %INREGION Property is of type 'MATLAB array'
        InRegion
        %HMOVEFCNLIST Property is of type 'handle'
        hMoveFcnList
        %HINFCNLIST Property is of type 'handle'
        hInFcnList
        %HOUTFCNLIST Property is of type 'handle'
        hOutFcnList
        %XMIN Property is of type 'double'
        Xmin=0;
        %XMAX Property is of type 'double'
        Xmax=1;
        %YMIN Property is of type 'double'
        Ymin=0;
        %YMAX Property is of type 'double'
        Ymax=1;
        %EXTERNALREFFLAG Property is of type 'bool'
        ExternalRefFlag = false;
        %EXTERNALREFLISTENER Property is of type 'MATLAB array'
        ExternalRefListener
        %FIGLISTENER Property is of type 'MATLAB array'
        FigListener
        %MOUSEMOVELISTENER Property is of type 'handle'
        MouseMoveListener
        %MOUSEOUTLISTENER Property is of type 'handle'
        MouseOutListener
    end
    
    properties (SetAccess=protected,SetObservable)
        %ENABLE Property is of type 'on/off'. A motion manager is
        %enabled if UserEnabled, all its parent motion managers are
        %enabled and the state of the container/figure allows an active
        %motion manager. Use UserEnabled to manually disabled a
        %MotionManager
        Enable = 'on';
        
    end
    
    properties (SetObservable)
        %MOUSEMOVEFCN Property is of type 'MATLAB callback'
        MouseMoveFcn
        %MOUSEINFCN Property is of type 'MATLAB callback'
        MouseInFcn
        %MOUSEOUTFCN Property is of type 'MATLAB callback'
        MouseOutFcn
    end
    
    
    events (NotifyAccess=protected)
        MouseMove
        MouseIn
        MouseOut
    end  % events
    
    methods  % constructor block
        function obj = MotionManager(varargin)
        %MOTIONMANAGER  Window Motion management class
        %  OBJ = MOTIONMANAGER(PROP, VALUE, ...)
        
        if nargin
            set(obj,varargin{:});
        end
        
        obj.MouseMoveListener = event.listener(obj, 'MouseMove',@obj.ExecuteMovement);
        obj.MouseOutListener = event.listener(obj, 'MouseOut',@obj.clearRegions);
        
        end  % MotionManager
        
    end  % constructor block
    
    methods
        function set.Enable(obj,value)
        obj.Enable = value;
        obj.setEnable;
        end
        
        function set.UserEnabled(obj,value)
        obj.UserEnabled = value;
        obj.setEnable;

        end
        
        function set.MouseMoveFcn(obj,value)
        obj.MouseMoveFcn = value;
        obj.setCallback('MouseMove', 'hMoveFcnList', value);
        end
        
        function set.MouseInFcn(obj,value)
        obj.MouseInFcn = value;
        obj.setCallback('MouseIn', 'hInFcnList', value);
        end
        
        function set.MouseOutFcn(obj,value)
        obj.MouseOutFcn = value;
        obj.setCallback('MouseOut', 'hOutFcnList', value);
        end
        
        function set.EnableTree(obj,value)
        obj.EnableTree = value;
        obj.setEnableTree(value);
        end
        
        function set.Region(obj,value)
        obj.Region = value;
        obj.setRegion(value);
        end
        
        function set.UseExternalRef(obj,value)
        obj.UseExternalRef = value;
        obj.setExternalRefFlag(value);
        end
        
        function set.ExternalRef(obj,value)
        obj.ExternalRef = value;
        obj.setExternalRef(value)
        end
        
    end   % set and get functions
    
    methods  % public methods
        %----------------------------------------
        function AttachToFigure(obj, figh)
        %ATTACHTOFIGURE Attach Motion Manager to figure
        %  ATTACHTOFIGURE(OBJ, FIG) attaches OBJ to the figure FIG.
        
        if isempty(figh)
            obj.RecoverMotion(@i_motion, false);
            return
        end
        
        % check the figure is valid, and doesn't already have a manager
        if ~isgraphics(figh,'figure')
            error(message('mbc:xregGui:MotionManager:InvalidHandle'));
        end
        
        if ~isprop(figh,'MotionManagerStore')
            mbcgui.hgclassesutil.addprop(figh, 'MotionManagerStore', 'Hidden', true);
        end
        
        % If we get to here, then the figure should be ok for attaching to
        set(figh,'MotionManagerStore',obj);
        
        % attach to motion function
        set(figh,'WindowButtonMotionFcn', {@i_motion, obj});
        obj.Figure = figh;
        
        % Connect to Figure's control hook
        % addChildren(xregfigurehook( figh ),obj);
        
        % These listeners keep control of situations when someone else nabs the
        % WindowButtonMotionFcn The logic is a bit convoluted, in order to get
        % round some current UDD oddities The second two listeners actually hide my
        % MotionFcn when someone tries to get it: needed to make the class work
        % with some MATLAB Gui Tools like Zoom, Rotate3D
        obj.FigListener = { ...
            event.proplistener(figh, figh.findprop('WindowButtonMotionFcn'), 'PostSet', mbcutils.callback(@i_recovermotionfcn, obj)), ...
            event.proplistener(figh, figh.findprop('WindowButtonMotionFcn'), 'PreGet', mbcutils.callback(@i_hidemotionfcn, obj)), ...
            event.proplistener(figh, figh.findprop('Visible'), 'PostSet', @obj.onSetVisible) ...
            };
        obj.Enable = mbconoff(enableManager(obj));
        end  % AttachToFigure
        
        
        %----------------------------------------
        function ExecuteMovement(obj,~, evt)
        %EXECUTEMOVEMENT Execute MotionManager callbacks
        %  EXECUTEMOVEMENT(OBJ, EVENTDATA) is the function that responds to a
        %  MouseMove event on the object.  Sub-Managers are checked to see whether
        %  the mouse has moved into or out of their region and events are sent
        %  accordingly.
        
        if strcmp(obj.Enable, 'on')
            cp = evt.CurrentPoint;
            if strcmpi(obj.Mode, 'multi')
                % need to check x, y coords with Listeners
                list = obj.MultiListener;
                if ~isempty(list)
                    % Check for dead handles and remove them
                    if ~all(isvalid(list))
                        % remove dead MM's
                        alive_ind = isvalid(list);
                        list = list(alive_ind);
                        obj.MultiListener = list;
                        obj.InRegion = obj.InRegion(alive_ind);
                    end
                    
                    Oldreg = obj.InRegion;
                    if length(Oldreg)~=length(list)
                        % This condition should never happen but has been known to.
                        % Reset the inreg to match correctly - may cause graphical
                        % glitches.
                        Oldreg = false(size(list));
                    end
                    
                    if ~isempty(list)
                        en = getEnabled(list);
                    else
                        en = false(0);
                    end
                    
                    % x-direction
                    xmn= getXmin(list);
                    xmx= getXmax(list);
                    ymn= getYmin(list);
                    ymx= getYmax(list);
                    
                    PlayersToExecute = en & ...
                        (cp(1)>=xmn) & ...
                        (cp(1)<=xmx) & ...
                        (cp(2)>=ymn) & ...
                        (cp(2)<=ymx);
                    
                    % Look for region in/out shifts
                    delt = PlayersToExecute - Oldreg;
                    if any(delt)
                        for n = find(delt==-1)
                            % mouse out
                            notify(list(n), 'MouseOut');
                        end
                        for n = find(delt==1)
                            % mouse in
                            notify(list(n), 'MouseIn');
                        end
                    end
                    
                    if any(PlayersToExecute)
                        for n = find(PlayersToExecute)
                            notify(list(n), 'MouseMove', evt);
                        end
                    end
                    obj.InRegion = PlayersToExecute;
                end
            else
                if ~isempty(obj.SingleListener)
                    obj.SingleListener.notify('MouseMove', evt);
                end
            end
        end
        
        end  % ExecuteMovement
        
        %----------------------------------------
        function RecoverMotion(obj, fcnhndl, KILLPROP)
        %RECOVERMOTION Re-apply motion function to figure
        %  RECOVERMOTION(FUNCTION_HANDLE)
        
        if nargin<3
            KILLPROP = false;
        end
        
        if KILLPROP
            % remove the motion function very temporarily
            mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{1}, false);
            set(obj.Figure, 'WindowButtonMotionFcn', 'MotionManager(gcbf,''reconnect'');');
            mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{1}, true);
        else
            mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{2}, false);
            wbmf = get(obj.Figure, 'WindowButtonMotionFcn');
            mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{2}, true);
            if ~isempty(wbmf)
                mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{2}, false)
            else
                mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{1}, false)
                set(obj.Figure, 'WindowButtonMotionFcn',{fcnhndl,obj});
                mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{1}, true);
                mbcgui.hgclassesutil.setListenerEnabled(obj.FigListener{2}, true);
            end
        end
        
        end  % RecoverMotion
        
        %----------------------------------------
        function RegisterManager(obj, pl, DoEvents)
        %REGISTERMANAGER Register a MotionManager
        %  REGISTERMANAGER(OBJ, MANAGER, DOEVENTS) registers MANAGER as a
        %  sub-region of the MotionManager OBJ.  The boolean flag DOEVENTS controls
        %  whether the new manager should be checked to see whether the mouse is in
        %  the region.
        
        if ~all(isa(pl,'mbcgui.motion.MotionManager'))
            error(message('mbc:xregGui:MotionManager:InvalidObject'));
        end
        
        % append new manager to list of multi ones
        if isempty(obj.MultiListener)
            obj.MultiListener = pl;
            pl.Parent = obj;
            inreg = false;
        else
            % check for dead MM's first
            if ~all(isvalid(obj.MultiListener))
                % remove dead MM's
                alive_ind = isvalid(obj.MultiListener);
                obj.MultiListener = obj.MultiListener(alive_ind);
                obj.InRegion = obj.InRegion(alive_ind);
            end
            % add new MM
            if ~any(pl==obj.MultiListener)
                obj.MultiListener = [obj.MultiListener  pl];
                pl.Parent = obj;
                inreg = [obj.InRegion false];
            else
                return
            end
        end
        
        if nargin<3
            DoEvents = true;
        end
        
        % Check new player for being currently active
        if ~isempty(obj.Figure)
            ploc = get(0,'PointerLocation');
            cp = get(obj.Figure,'Position');
            cp = ploc - cp(1:2) + [1 1];
            if ~isempty(cp)
                inreg(end) = (cp(1)>=getXmin(pl) ...
                    && cp(1)<=getXmax(pl) ...
                    && cp(2)>=getYmin(pl) ...
                    && cp(2)<=getYmax(pl));
                if inreg(end) && DoEvents
                    % fire MouseIn and MouseMove Events
                    pl.notify('MouseIn');
                    pl.notify('MouseMove', mbcgui.motion.MotionEvent(cp));
                end
            end
        end
        obj.InRegion = inreg;
        pl.Figure = obj.Figure;
        pl.Enable = obj.Enable;
        
        end  % RegisterManager
        
        %----------------------------------------
        function RegisterSingleManager(obj, pl)
        %REGISTERSINGLEMANAGER Register a MotionManager
        %  REGISTERSINGLEMANAGER(OBJ, MANAGER) registers MANAGER as the single
        %  sub-region of the MotionManager OBJ.
        
        if ~isa(pl,'mbcgui.motion.MotionManager')
            error(message('mbc:xregGui:MotionManager:InvalidObject1'));
        end
        
        % Save Manager as the single-usage one
        obj.SingleListener = pl;
        pl.Parent = obj;

        pl.Figure = obj.Figure;
        
        end  % RegisterSingleManager
        
        %----------------------------------------
        function UnregisterManager(obj, pl, sendclear)
        %UNREGISTERMANAGER Unregister a MotionManager
        %  UNREGISTERMANAGER(OBJ, MANAGER) removes MANAGER from the list of
        %  sub-managers of OBJ.
        
        if nargin<3
            sendclear = true;
        end
        
        if ~isa(pl,'mbcgui.motion.MotionManager')
            error(message('mbc:xregGui:MotionManager:InvalidObject2'));
        end
        
        if ~isempty(obj.Figure) && ~strcmp(obj.Figure.BeingDeleted,'on')
            if ~all(isvalid(obj.MultiListener))
                % remove dead MM's
                alive_ind = isvalid(obj.MultiListener);
                obj.MultiListener = obj.MultiListener(alive_ind);
                obj.InRegion = obj.InRegion(alive_ind);
            end
            
            % remove specified pl
            ind = (obj.MultiListener==pl);
            if any(ind)
                inreg = obj.InRegion(ind);
                pl.Parent = [];
                % remove player from list
                obj.MultiListener = obj.MultiListener(~ind);
                obj.InRegion = obj.InRegion(~ind);
                
                if any(inreg) && sendclear
                    % send a MouseOut event
                    pl.notify('MouseOut');
                end
            end
        end
        
        end  % UnregisterManager
        
        %----------------------------------------
        function UnregisterSingleManager(obj, pl)
        %UNREGISTERSINGLEMANAGER Unregister a MotionManager
        %  UNREGISTERSINGLEMANAGER(OBJ, MANAGER) removes MANAGER as the single
        %  child manager of OBJ.
        
        if ~isa(pl,'mbcgui.motion.MotionManager')
            error(message('mbc:xregGui:MotionManager:InvalidObject3'));
        end
        
        if ~isempty(obj.Figure) && ~strcmp(obj.Figure.BeingDeleted,'on')
            % clear player as the single-usage one
            if ~isempty(obj.SingleListener)
                if ~isvalid(obj.SingleListener) || pl==obj.SingleListener
                    obj.SingleListener= [];
                    pl.Parent = [];
                end
            end
        end
        end  % UnregisterSingleManager
        
        %----------------------------------------
        function clearRegions(obj, ~,~)
        %CLEARREGIONS Emit MouseOut event to all sub-Managers
        %  CLEARREGIONS(OBJ) sends a MouseOut event on all sub-Managers and marks
        %  the mouse as being in none of the regions
        
        if any(obj.InRegion)
            for n = find(obj.InRegion)
                notify(obj.MultiListener(n), 'MouseOut');
            end
            obj.InRegion = false(size(obj.InRegion));
        end
        
        end  % clearRegions
        
        %----------------------------------------
        function doUpdate(obj)
        %DOUPDATE Force an update of mouse position tracking
        %  DOUPDATE(OBJ) sends a mouse position update down the MotionManager tree.
        
        % Get main MotionManager for the figure since this is the only coordinate
        % system we know the correct location for
        MainMM = MotionManager(obj.Figure);
        pl = get(0,'PointerLocation');
        cp = get(obj.Figure,'Position');
        cp = pl - cp(1:2) + [1 1];
        notify(MainMM,'MouseMove', mbcgui.motion.MotionEvent(cp));
        
        end  % doUpdate
        
        %----------------------------------------
        function en = enableManager(obj)
        %enableManager determine whether to enable manager
        %   en = enableManager(obj)
        
        % figure is visible
        en = strcmp(obj.Figure.Visible,'on');
        
        end  % enableManager
        
        %----------------------------------------
        function ch=getChildren(mm)
        %GETCHILDREN Return the registered sub-managers
        %  CH=getChildren(mm) returns a vector of handles to the registered
        %  sub-managers of a motion manager.
        
        ch = mm.MultiListener;
        
        end  % getChildren
        
        %----------------------------------------
        function setCallback(obj, eventName, prop, cb)
        %SETCALLBACK Set up new callback function
        %  SETCALLBACK(OBJ, EVENT, PROP, CALLBACK)
        
        if isempty(cb)
            L = [];
        else
            if iscell(cb)
               cb = mbcutils.callback(cb{:});
            else
                cb =  mbcutils.callback(cb);
            end
            L = event.listener(obj, eventName,  cb);
            L.Enabled = strcmp(obj.Enable,'on');
        end
        set(obj, prop, L);
        
        end  % setCallback
        
        %----------------------------------------
        function setEnable(obj)
        %SETENABLE Finalise new enable value
        %  SETENABLE(OBJ)
        
        % set callback enable status
        
        enval = strcmp(obj.Enable,'on') && strcmp(obj.UserEnabled,'on');
        
        if ~isempty(obj.hMoveFcnList)
            obj.hMoveFcnList.Enabled = enval;
        end
        if ~isempty(obj.hInFcnList)
            obj.hInFcnList.Enabled = enval;
        end
        if ~isempty(obj.hOutFcnList)
            obj.hOutFcnList.Enabled = enval;
        end
        if ~isempty(obj.MultiListener)
            % propogate enable down
            if enval
                for i=1:length(obj.MultiListener)
                    % enable depending on child state
                    set(obj.MultiListener(i),'Enable',mbconoff(enableManager(obj.MultiListener(i))));
                end
            else
                % turn all children off
                [obj.MultiListener.Enable]= deal(mbconoff(enval));
            end
        end
        
        end  % setEnable
        
        %----------------------------------------
        function setEnableTree(obj, enval)
        %SETENABLETREE Finalise new EnableTree setting
        %   SETENABLETREE(OBJ, ENABLEVAL)
        
        % Pass on enabletree settting to the listener which fires the mousemove cascade
        if ~isempty(obj.MouseMoveListener)
            obj.MouseMoveListener.Enabled  = enval; 
        end
        
        end  % setEnableTree
        
        %----------------------------------------
        function setExternalRef(obj, ref, addlistener)
        %SETEXTERNALREF Finalise new external reference setting
        %   SETEXTERNALREF(OBJ, REF, ADDLISTENER)
        
        if nargin<3
            addlistener = true;
        end
        
        if addlistener && ~isempty(ref)
            % Attach listener to the object's position
            if isgraphics(ref)
                % HG
                if isgraphics(ref, 'axes') % always listen to position on an axes
                    obj.ExternalRefListener = event.proplistener(ref, ...
                        ref.findprop('Position'), 'PostSet', mbcutils.callback(@i_getpos, obj));
                else
                    obj.ExternalRefListener = mbcgui.hgclassesutil.positionlistener(...
                        ref, ...
                        mbcutils.callback(@i_getpos, obj), ...
                        'PostSet');
                end
            elseif ishandle(ref)
                % UDD widget
                obj.ExternalRefListener = handle.listener(ref, ...
                    ref.findprop('Position'), 'PropertyPostSet', {@i_getpos, obj});
            else
                % MCOS
                obj.ExternalRefListener = event.proplistener(ref, ...
                    findprop(ref, 'Position'), 'PostSet', mbcutils.callback(@i_getpos, obj));
            end
        end
        
        if obj.ExternalRefFlag
            pos = get(ref, 'Position');
            if ~isempty(pos)
                set(obj, ...
                    'Xmin', pos(1), ...
                    'Xmax', pos(1) + pos(3) - 1, ...
                    'Ymin', pos(2), ...
                    'Ymax', pos(2) + pos(4) - 1 ...
                    )
            end
        end
        end  % setExternalRef
        
        
        
        
        %----------------------------------------
        function setExternalRefFlag(obj, refsetting)
        %SETEXTERNALREFFLAG Finalise new external reference setting
        %  SETEXTERNALREFFLAG(OBJ, REFSETTING)
        
        if strcmp(refsetting,'on')
            obj.ExternalRefFlag = true;
            % update min/max from externalref
            obj.setExternalRef(obj.ExternalRef);
        else
            obj.ExternalRefFlag = false;
            % update min/max from region
            obj.setRegion;
        end
        
        end  % setExternalRefFlag
        
        %----------------------------------------
        function setRegion(obj, region)
        %SETREGION Finalise new region value
        %  SETREGION(OBJ, REGION)
        
        % Grab min and max values from the region
        if ~obj.ExternalRefFlag
            set(obj, ...
                'Xmin', region(1), ...
                'Xmax', region(1) + region(3) - 1, ...
                'Ymin', region(2), ...
                'Ymax', region(2) + region(4) - 1 ...
                )
        end
        
        end  % setRegion
        
    end  % public methods
    
    methods (Sealed)
        %----------------------------------------
        function en = getEnabled(hvect)
        %GETENABLED Return vector of enabled values for a vector of Managers
        %  enVect = getEnabled(Hvect) returns a vector of logical values indicating
        %  whether the MotionManagers are enabled.
        
        en = {hvect.Enable};
        en = reshape(strcmp(en,'on'),size(hvect));
        
        end  % getEnabled
        
        %----------------------------------------
        function xm = getXmax(hvect)
        %GETXMAX Return vector of Xmax values from a vector of MotionManagers
        %  XmaxVect = GETXMAX(Hvect) returns a vector of maximum X values for the
        %  vector of MotionManager handles Hvect.
        
        xm = {hvect.Xmax};
        xm = reshape([xm{:}],size(hvect));
        
        end  % getXmax
        
        %----------------------------------------
        function xm = getXmin(hvect)
        %GETXMIN Return vector of Xmin values from a vector of MotionManagers
        %  XminVect = GETXMIN(Hvect) returns a vector of minimum X values for the
        %  vector of MotionManager handles Hvect.
        
        xm = {hvect.Xmin};
        xm = reshape([xm{:}],size(hvect));
        
        end  % getXmin
        
        %----------------------------------------
        function ym = getYmax(hvect)
        %GETYMAX Return vector of Ymax values from a vector of MotionManagers
        %  YmaxVect = GETYMAX(Hvect) returns a vector of maximum Y values for the
        %  vector of MotionManager handles Hvect.
        
        ym = {hvect.Ymax};
        ym = reshape([ym{:}],size(hvect));
        
        end  % getYmax
        
        %----------------------------------------
        function ym = getYmin(hvect)
        %GETYMIN Return vector of Ymin values from a vector of MotionManagers
        %  YminVect = GETYMIN(Hvect) returns a vector of minimum Y values for the
        %  vector of MotionManager handles Hvect.
        
        ym = {hvect.Ymin};
        ym = reshape([ym{:}],size(hvect));
        
        end  % getYmin
        
        function OK = eq(A,B)
        OK = eq@matlab.mixin.SetGet(A,B);
        end
        
        function OK = ne(A,B)
        OK = ne@matlab.mixin.SetGet(A,B);
        end        
        
        function set(obj,varargin)
        set@matlab.mixin.SetGet(obj,varargin{:});
        end 
        
        function out = get(obj,prop)
        out = get@matlab.mixin.SetGet(obj,prop);
        end 
        
    end
    
    
    methods (Static)
        %----------------------------------------
        function hout=FindManager(figh)
        %FINDMANAGER Find the existing MotionManager for a figure or panel
        %  M=obj.FindManager(FIG) returns the current manager for a figure, or
        %  empty if one doesn't exist.
        
        try
            hout = figh.MotionManagerStore;
        catch
            hout = [];
        end
        
        end  % FindManager        
    end
    
    methods (Access=protected)
        function onSetVisible(M,~, evt)
        M.Enable =  mbconoff(strcmp(get(evt.AffectedObject, 'Visible'),'on'));
        end  % onSetVisible
        
        function OK = isParentEnabled(M)
        OK = isempty(M.Parent) || strcmp(M.Parent.Enable,'on');
        end        
    end
end  % classdef



function i_motion(~, ~, obj)
if isa(obj,'mbcgui.motion.MotionManager')
    obj.doUpdate;
end
end  % i_motion


function i_recovermotionfcn(~,~,obj)
obj.RecoverMotion(@i_motion, false);
end  % i_recovermotionfcn


function i_hidemotionfcn(~,~,obj)
obj.RecoverMotion([], true);
end  % i_hidemotionfcn

function i_getpos(~, ~, obj)
obj.setExternalRef(obj.ExternalRef, false);
end  % i_getpos