www.gusucode.com > wavelet工具箱matlab源码程序 > wavelet/wavelet/+wavelet/+internal/+layout/AbstractLayout.m
classdef AbstractLayout < handle %AbstractLayout Define the AbstractLayout class. properties (SetAccess = private) Panel; end properties (Access = protected) Invalid = true; OldPosition; end properties (Access = protected, Constant) CONSTRAINTSTAG = 'Layout_Manager_Constraints'; end properties (Access = protected, Dependent) PanelPosition; end properties PreLayoutCallback; PostLayoutCallback; end methods function this = AbstractLayout(hPanel) %AbstractLayout Construct the AbstractLayout class. this.Panel = hPanel; end function add(this, h, varargin) %ADD Add the component to the layout manager. % Make sure there isn't already a component in the location. hOld = getComponent(this, varargin{:}); if ~isempty(hOld) error(message('Wavelet:divGUIRF:gridbagcomponentexists')); end set(h, 'Parent', this.Panel); end function update(this, force) %UPDATE Update the layout. if nargin < 2 force = 'noforce'; end % When UPDATE is called, we assume the layout is dirty. if this.Invalid || strcmpi(force, 'force') % Nothing to do if the panel is invisible, to avoid multiple updates. if strcmpi(get(this.Panel, 'Visible'), 'Off') return; end preCallback = this.PreLayoutCallback; if ~isempty(preCallback) try hgfeval(preCallback, this.Panel, []); catch ME % Rethrow the error as a warning. end end layout(this); postCallback = this.PostLayoutCallback; if ~isempty(postCallback) try hgfeval(postCallback, this.Panel, []); catch ME end end % The layout is now clean. this.Invalid = false; end end function onVisibleChanged(this, ~, ~) if strcmp(this.Panel.Visible, 'on') update(this); end end end methods (Abstract, Access = protected) getComponent(this); layout(this); end methods function set.Panel(this, panel) % This is faster than STRCMPI if ~ishghandle(panel) && ... any(strcmp(get(panel, 'type'), {'uipanel', 'figure', 'uicontainer'})) error(message('Wavelet:divGUIRF:gridbagpanelproperty')); end % Do this before we create the listeners to avoid accidental firing. pos = getpixelposition(panel); this.OldPosition = pos(3:4); addlistener(panel, 'Visible', 'PostSet', @this.onVisibleChanged); set(panel, 'ResizeFcn', @(hsrc, ev) onResize(this)); this.Panel = panel; function onResize(this) newPos = this.PanelPosition; newPos(1:2) = []; % Only resize if the panel position (width and height) actually changed. if ~all(this.OldPosition == newPos) this.OldPosition = newPos; this.Invalid = true; update(this); end end end function panelPosition = get.PanelPosition(this) hp = this.Panel; oldResizeFcn = get(hp, 'ResizeFcn'); set(hp, 'ResizeFcn', ''); panelPosition = getpixelposition(hp); if ishghandle(hp, 'uipanel') % We need to remove the extra spaces taken up by the border % which we cannot use. panelPosition(3:4) = panelPosition(3:4)-2*get(hp, 'BorderWidth'); end set(hp, 'ResizeFcn', oldResizeFcn); end end end % [EOF]