www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+widget/Component.m
classdef Component < mbcgui.widget.AbstractComponent %COMPONENT Base widget class for MBC % mbcgui.widget.Component is the base class for all user interface % components in MBC. This class provides a basic set of component % properties - Parent, Position, Visible, Enable and UserData - as well % as a printing interface and utility methods for managing event % listeners. % % Component properties: % Parent - Handle to a parent container. % Position - [X Y W H] position rectangle. % Enable - on/inactive/off % Visible - on/off % UserData - Freeform field for use by the user. % Tag - Freeform string for use by the user. % % Property notification (protected) % setParent - Called when the Parent property is altered. % setPosition - Called when the Position property is altered. % setEnable - Called when the Enable property is altered. % setVisible - Called when the Visible property is altered. % % Printing interface: % canPrint - Test whether the component supports printing % print - print the component % printCopy - (Protected) Generate a copy of the component that is % suitable for printing. % printSize - Return a [W H] preferred aspect ratio for the % printed component. % % Listener utilities (protected): % These utilities can be used to manage listeners in subclasses. % % storeListeners - Save a copy of specified listeners. % enableListeners - Enable all the saved listeners. % disableListeners - Disable all the saved listeners. % % Dependent property utilities (protected): % These utilities are useful when you want to create dependent properties % that map directly to properties on contained objects. % % forwardProperty - Forward a property value to a contained object or % store in a temporary location if the object does % not exist yet. % retrieveProperty - Retrieve a property value from a contained object % or look up a value from the temporary store if % the object does not exist yet. % getPVPairs - Retrieve specified property-value pairs from the % temporary store and remove the values from the % store. % Copyright 2008-2016 The MathWorks, Inc. properties(SetObservable,GetObservable, AbortSet) %PARENT Handle to a parent container % H.Parent contains a handle to a container that the component is % positioned in. Valid containers are either a figure handle or a % uipanel handle. % % If no parent is specified during construction then the the % component automatically parents itself to the handle returned by % 'gcf'. % % See also gcf, uicontrol.Parent. Parent = -1; %POSITION Position rectangle % H.Position contains a 4-element vector ([X Y W H])that specifies % the position of a component in pixel units. % % See also uicontrol.Position. Position = [1 1 10 10]; %ENABLE Enable setting % H.Enable contains one of the strings 'on', 'inactive' or 'off'. % % See also uicontrol.Enable. Enable = 'on'; %VISIBLE Visible setting % H.Visible contains one of the strings 'on' or 'off'. When a % component has its Visible property set to 'off', it should make all % of its contained control invisible. % % See also uicontrol.Visible. Visible = 'on'; %USERDATA User-defined data store % H.UserData may be set to any Matlab array. It is not used by the % component and can be used to store associated application data. % % See also uicontrol.UserData. UserData = []; %TAG User-defined tag % H.Tag may be set to any Matlab string. It is not used by the % component and can be used to label controls to aid later finding % them. % % See also uicontrol.Tag. Tag = ''; end properties(SetAccess=private, GetAccess=private) %COMPONENTLISTENERS Store of event listeners ComponentListeners = cell(0,1); %CONSTRUCTEDFLAG Flag to indicate whether object is post construction ConstructedFlag = false; %PARENTLISTENER Event listener for reacting to parent deletion ParentListener = []; %CONSTRUCTPROPMAP Map that temporarily contains dependent properties %that are set at construction time. ConstructPropMap = []; end methods(Access=protected) function obj = Component(varargin) %COMPONENT Construct a new Component % H = COMPONENT(PROP1, VAL1, ...) constructs a new component and sets % the specified property-value pairs. Property set functions are not % triggered during construction. if ~isempty(varargin) set(obj, varargin{:}); end if isempty(obj.Parent) obj.Parent = gcf; end obj.ConstructedFlag = true; end end methods function delete(obj) try P = obj.Parent; catch E if strcmp(E.identifier, 'MATLAB:class:InvalidHandle') % Assume that the object is invalid return else rethrow(E); end end if isgraphics(P) && ~mbcgui.util.isBeingDestroyed(P) removeFromComponentStore(obj, P); end end end % Property set notification. These methods check for valid settings % and then notify subclasses by calling an associated protected method. methods function set.Parent(obj, P) if ~mbcgui.util.isComponentParent(P) error(message('mbc:mbcgui:widget:Component:InvalidPropertyValue')); end if isnumeric(P) % TODO P = mbcgui.hgclassesutil.toHandle(P); end % Register the component handle in a store on the new figure. This % will prevent the component from being destroyed if the handle is % cleared from the Matlab workspace. OldP = obj.Parent; if ~isempty(OldP) removeFromComponentStore(obj, OldP); end addToComponentStore(obj, P) obj.Parent = P; if obj.ConstructedFlag %#ok<*MCSUP> obj.setParent(P); end end function set.Position(obj, Pos) if ~isnumeric(Pos) || ~isequal(size(Pos), [1 4]) error(message('mbc:mbcgui:widget:Component:InvalidPropertyValue1')); end if Pos(3)<1 Pos(3) = 1; end if Pos(4)<1 Pos(4) = 1; end obj.Position = Pos; if obj.ConstructedFlag obj.setPosition(Pos); end end function set.Enable(obj, En) En = lower(En); if ~strcmp(En, 'on') && ~strcmp(En, 'off') && ~strcmp(En, 'inactive') error(message('mbc:mbcgui:widget:Component:InvalidPropertyValue2')); end obj.Enable = En; if obj.ConstructedFlag obj.setEnable(En); end end function set.Visible(obj, Vis) Vis = lower(Vis); if ~strcmp(Vis, 'on') && ~strcmp(Vis, 'off') error(message('mbc:mbcgui:widget:Component:InvalidPropertyValue3')); end obj.Visible = Vis; if obj.ConstructedFlag obj.setVisible(Vis); end end function set.Tag(obj, Tag) if isempty(Tag) Tag = ''; end if ~ischar(Tag) error(message('mbc:mbcgui:widget:Component:InvalidPropertyValue4')); end obj.Tag = Tag; end end methods (Access = protected) function ok = isvalidcomponent(obj) %isvalidcomponent component exists % called from Heterogeneous method % % See also mbcgui.widget.AbstractComponent.iscomponent ok = isgraphics(obj.Parent); end function setParent(obj, P) %#ok<INUSD> %SETPARENT Notification of new parent % SETPARENT(H, PARENT) is called when the component's Parent property % is changed to PARENT. The Parent property is automatically set to % contain the new value before this method is called. Subclasses % should override this method to perform component-specific actions % when the parent is changed. % % See also Parent. end function setPosition(obj, Pos) %#ok<INUSD> %SETPOSITION Notification of new position setting % SETPOSITION(H, POS) is called when the component's Position % property is changed to POS. The Position property is automatically % set to contain the new value before this method is called. % Subclasses should override this method to perform % component-specific actions when the position value is changed. % % See also Position. end function setEnable(obj, En) %#ok<INUSD> %SETENABLE Notification of new enable setting % SETENABLE(H, EN) is called when the component's Enable property % is changed to EN. The Enable property is automatically set to % contain the new value before this method is called. Subclasses % should override this method to perform component-specific actions % when the enable value is changed. % % See also Enable. end function setVisible(obj, Vis) %#ok<INUSD> %SETVISIBLE Notification of new visible setting % SETVISIBLE(H, VIS) is called when the component's Visible property % is changed to VIS. The Visible property is automatically set to % contain the new value before this method is called. Subclasses % should override this method to perform component-specific actions % when the visible value is changed. % % See also Visible. end end % Utility methods methods function ret = isShowing(obj) ret = mbcgui.util.isShowing(obj); end end methods(Access=protected) function ret = isConstructed(obj) ret = obj.ConstructedFlag; end end % Printing methods function ret = canPrint(obj) %#ok<MANU> %CANPRINT Check whether component can be printed % CANPRINT(H) returns true if the component supports being printed. % Printable components should overload the printCopy method and % possibly the printSize method. % % See also print, printCopy, printSize. ret = false; end function print(obj, dest) %PRINT Prints a component % PRINT(H, DEST) prints out a copy of the component. DEST specifies % where the copy should be sent and must be one of 'clipboard', % 'printer', 'printdialog' or 'printpreview'. See MBCPRINT for more % details on these options. If DEST is not specified, 'printer' will % be assumed'. % % This method calls the PRINTCOPY and PRINTSIZE methods of the % component. % % See also canPrint, printCopy, printSize. if nargin<2 dest = 'printer'; end hFig = figure('Visible', 'off', ... 'Renderer', get(ancestor(obj.Parent, 'figure'), 'Renderer'), ... 'Color','w', ... 'MenuBar', 'none', ... 'ToolBar', 'none', ... 'NumberTitle', 'off', ... 'Name', 'MBC Printing Figure', ... 'Tag', 'MBCPrintFig',... 'IntegerHandle', 'off', ... 'HandleVisibility', 'off'); pObj = obj.printCopy(hFig); set(pObj, 'Visible', 'on'); if isa(pObj, 'xregcontainer') set(pObj, 'packstatus', 'on'); end mbcprint(pObj, obj.printSize, dest); delete(hFig); end function newobj = printCopy(obj, fig) %#ok<INUSL> %PRINTCOPY Create a printable version of the component % NEWOBJ = PRINTCOPY(H, FIG) creates and returns a handle to a new % component, NEWOBJ, parented by the specified figure, FIG. The new % object will be used for printing a copy of this component. % % Normally the printable version of a component is not a complete % copy of the object. There are often controls that should not % appear, such as popup menus, or components whose information needs % to be transformed, such as edit boxes. % % See also canPrint, print, printSize. newobj = uicontrol('Parent', fig, ... 'Style', 'text', ... 'HorizontalAlignment', 'center', ... 'String', sprintf('This component does not\nsupport printing')); end function sz = printSize(obj) %PRINTSIZE Returns the preferred printing size for the component % SZ = PRINTSIZE(H) returns a two element vector containing the % preferred width and height for printing the component. % % This default implementation returns the current width and height of % the component and this is likely to be adequate for many % subclasses. However, some classes may want to modify this, for % example scrolling components that want to print their entire % visible area. % % See also canPrint, print, printCopy. sz = obj.Position(3:4); end end % Listener utilities methods(Access=protected) function addListeners(obj, List) %addListeners Add listeners for storage. % addListeners(H, LIST) adds listeners to be stored by the object. % LIST may be either a scalar listener handle, a vector of listeners % or a cell array. % % See also storeListeners, enableListeners, disableListeners. storeListeners(obj, List) end function storeListeners(obj, List) %STORELISTENERS Add listeners for storage. % STORELISTENERS(H, LIST) adds listeners to be stored by the object. % LIST may be either a scalar listener handle, a vector of listeners % or a cell array. % % See also enableListeners, disableListeners. % Convert non-cell input to a cell for storage if ~iscell(List) ListVect = List; NumNew = numel(List); List = cell(NumNew, 1); for n = 1:NumNew List{n} = ListVect(n); end end obj.ComponentListeners = [obj.ComponentListeners; List(:)]; end function enableListeners(obj) %ENABLELISTENERS Enable stored listeners. % ENABLELISTENERS(H) enables all listeners that have been added to % this object using the storeListeners method. % % See also storeListeners, disableListeners. L = obj.ComponentListeners; for n=1:numel(L) if isa(L{n},'handle.listener') L{n}.Enabled = 'on'; else L{n}.Enabled = true; end end end function disableListeners(obj) %DISABLELISTENERS Disable stored listeners. % DISABLELISTENERS(H) disables all listeners that have been added to % this object using the storeListeners method. % % See also storeListeners, enableListeners. L = obj.ComponentListeners; for n=1:numel(L) if isa(L{n},'handle.listener') L{n}.Enabled = 'off'; else L{n}.Enabled = false; end end end function L = addPropertyListeners(obj, Prop, Callback, Event) %ADDPROPERTYLISTENERS Create and add listeners to object properties % L = ADDPROPERTYLISTENERS(OBJ, PROP, CALLBACK, EVENT) creates a new % listener, L, that is attached to the EVENT event of property PROP % and that fires CALLBACK. L = ADDPROPERTYLISTENERS(OBJ, PROPS, % CALLBACKS, EVENT) where PROPS and CALLBACKS are cell arrays of % properties and corresponding callbacks will create a vector of % listeners. The EVENT argument defaults to 'PropertyPostSet' if not % supplied. if nargin < 4 Event = 'PostSet'; end if ischar(Prop) % Single listener being created. if iscell(Callback) Callback = mbcutils.callback(Callback{:}); end L = {event.proplistener(obj, obj.findprop(Prop), Event, Callback)}; else % Lots of listeners being created. nL = numel(Prop); L = cell(nL,1); for n = 1:nL if iscell(Callback{n}) Callback{n} = mbcutils.callback(Callback{n}{:}); end L{n} = event.proplistener(obj, obj.findprop(Prop{n}), Event, Callback{n}); end end obj.ComponentListeners = [obj.ComponentListeners; L]; end end % Dependent property utilities methods(Access=protected) function forwardProperty(obj, hComp, PropName, PropValue) %FORWARDPROPERTY Forward a property value to a contained object % FORWARDPROPERTY(OBJ, H, PROPNAME, PROPVALUE) sets the sepecified % property on the component H. If H is empty, as is typical for % contained components during construction, the property value is % saved in a temporary store and can be retrieved when H is % constructed using GETDEPPROPPAIRS. % % This method is design to be called in the property set function for % dependent properties that directly map to the property of a % contained object. All properties that use this function should % also be listed in a GETDEPPROPPAIRS in the constructor to retrieve % and clear temporary stored values. % % See also RETRIEVEPROPERTY, GETDEPPROPPAIRS. if isempty(hComp) % Store the property if isempty(obj.ConstructPropMap) obj.ConstructPropMap = containers.Map; end obj.ConstructPropMap(PropName) = PropValue; else set(hComp, PropName, PropValue); end end function PropValue = retrieveProperty(obj, hComp, PropName, DefaultValue) %RETRIEVEPROPERTY Retrieve a property value from a contained object % RETRIEVEPROPERTY(OBJ, H, PROPNAME) gets the specified property from % the component H. If H is empty, as is typical for contained % components during construction, the property value is looked for in % the temporary store, If a value is not found here then an empty % matrix is returned. % % RETRIEVEPROPERTY(OBJ, H, PROPNAME, DEFAULT) specifies a default % value to return if a property value cannot be found elsewhere. % % This method is design to be called in the property get function for % dependent properties that directly map to the property of a % contained object. % % See also FORWARDPROPERTY, GETDEPPROPPAIRS. if isempty(hComp) % Retrieve from the temporary store if possible if isempty(obj.ConstructPropMap) || ~isKey(obj.ConstructPropMap, PropName) if nargin>3 PropValue = DefaultValue; else PropValue = []; end else PropValue = obj.ConstructPropMap(PropName); end else PropValue = get(hComp, PropName); end end function PVPairs = getDepPropPairs(obj, PropNames) %GETDEPPROPPAIRS Get a list of property-value pairs for construction % GETDEPPROPPAIRS(OBJ, PROPNAMES) checks the temporary store for the % specified property names. Any that are found are assembled in a % cell array of property-value pairs that is returned. The property % values are removed from the temporary store. % % This method is design to be called in subclass constructors to % retrieve contained object property values that have been set at % construction and saved by the FORWARDPROPERTY method. % % See also FORWARDPROPERTY, RETRIEVEPROPERTY. PropMap = obj.ConstructPropMap; if isempty(PropMap) || isempty(PropNames) PVPairs = {}; return end if ischar(PropNames) PropNames = {PropNames}; end % Find known properties and retrieve their values KnownProps = intersect(PropNames, PropMap.keys); PVPairs = cell(2, numel(KnownProps)); for n=1:numel(KnownProps) PVPairs{1,n} = KnownProps{n}; PVPairs{2,n} = PropMap(KnownProps{n}); end PVPairs = PVPairs(:)'; PropMap.remove(KnownProps); if PropMap.Count==0; % Destroyed the map object since it is no longer needed obj.ConstructPropMap = []; end end end % Methods that manage a private store of Components in a parent methods(Access=protected) %TODO: These should be private, a bug in MCOS means that they can't be: g582234 function S = makeComponentStore(obj, hParent) %#ok<INUSL> if ~isprop(hParent, 'mbcguiComponentStore') mbcgui.hgclassesutil.addprop(hParent, 'mbcguiComponentStore', 'Hidden', true); S.Handles = mbcgui.widget.Component.empty; S.DeletionListener = mbcgui.hgclassesutil.listener( ... hParent, 'ObjectBeingDestroyed', @iDeleteObjects); set(hParent, 'mbcguiComponentStore', S); else S = get(hParent, 'mbcguiComponentStore'); end end function addToComponentStore(obj, hParent) if isgraphics(hParent) S = makeComponentStore(obj, hParent); S.Handles(end+1) = obj; set(hParent, 'mbcguiComponentStore', S); end end function removeFromComponentStore(obj, hParent) if isgraphics(hParent) S = get(hParent, 'mbcguiComponentStore'); S.Handles(S.Handles==obj)=[]; set(hParent, 'mbcguiComponentStore', S); end end end end function iDeleteObjects(src, evt) %#ok<INUSD> % Delete all objects in the store of this parent if isgraphics(src) && ~strcmp(src.BeingDeleted,'on') S = get(src, 'mbcguiComponentStore'); for n=1:numel(S.Handles) h = S.Handles(n); if isvalid(h) delete(h); end end end end