www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+container/layoutpanel.m
function P = layoutpanel(varargin) %LAYOUTPANEL Construct a panel that has an associated layout. % % P = LAYOUTPANEL(VARARGIN) constructs a uipanel that has additional % properties added to it. All arguments to this function are passed on to % the panel constructor. % % The additional properties will be: % % LayoutComponent : A component handle that will be resized so that its % position matches the size of the panel. This % property may be set to either a component handle % or to a single-element cell array that contains the % component handle. This second form allows Matlab % to correctly dispatch the "set" to the uipanel % property instead of the component set method. % LayoutBorder : Border in pixels to apply between the % LayoutComponent and the panel. The border is % specified as a 4-element vector that contains the % [W S E N] border. % % The panel will also have the following properties set to non-standard % values unless overridden by new values in the input list: % % Units : Set to 'pixels' % Position : Set to [0 0 1 1] % BorderType : Set to 'none' % HitTest : Set to 'off' % % Example: % pnl = mbcgui.container.layoutpanel(... % 'Position', [20 20 300 200], ... % 'BorderType', 'beveledin', ... % 'LayoutBorder', [20 10 20 30]); % hEdit = uicontrol('Parent', pnl, ... % 'Style', 'edit', ... % 'String', 'Edit box'); % hButton = uicontrol('Parent', pnl, ... % 'Style', 'pushbutton', ... % 'String', 'Button'); % L = xreggridbaglayout(pnl, ... % 'dimension', [1 2], ... % 'colsizes', [-1 65], ... % 'elements', {hEdit, hButton}); % set(pnl, 'LayoutComponent', {L}); % Copyright 2008-2013 The MathWorks, Inc. % Pull out LayoutComponent/LayoutBorder from property list and set them % later LC = []; LB = [0 0 0 0]; LCidx = find(strcmpi('LayoutComponent',varargin),1,'last'); if ~isempty(LCidx) LC = varargin{LCidx+1}; varargin([LCidx LCidx+1]) = []; end LBidx = find(strcmpi('LayoutBorder',varargin),1,'last'); if ~isempty(LBidx) LB = varargin{LBidx+1}; varargin([LBidx LBidx+1]) = []; end P = uipanel(... 'Units', 'pixels', ... 'Position', [0 0 1 1], ... 'BorderType', 'none', ... 'HitTest', 'off', ... varargin{:}); fHandles = manageLayoutPanel(P); % Component that is resized with the layout mbcgui.hgclassesutil.addprop(P, 'LayoutComponent','SetMethod',fHandles.setLayout); % Border to apply between the panel edge and the component. This is a % vector of pixel widths to apply to the [top, right, bottom, left] edges. mbcgui.hgclassesutil.addprop(P, 'LayoutBorder','SetMethod',fHandles.setBorder); mbcgui.hgclassesutil.addprop(P, 'MotionManagerStore', 'Hidden', true); mbcgui.hgclassesutil.addprop(P, 'ControlHook', 'Hidden', true); % Set the component and border if they have been provided if ~isempty(LB) set(P, 'LayoutBorder', LB); end if ~isempty(LC) set(P, 'LayoutComponent', {LC}); end % Add a listener to the panel resize to update the layout addlistener(P, 'SizeChanged', fHandles.setPosition); % Add a destruction listener to destroy the contained layout addlistener(P, 'ObjectBeingDestroyed', fHandles.deleteLayout); addlistener(P, 'Visible', 'PostSet', fHandles.setVisible); end function fHandles = manageLayoutPanel(Panel) %manageLayoutPanel nested function to manage positionin,visibility and border of inner layout LayoutComponent = []; LayoutBorder = []; fHandles.setLayout = @iSetLayout; fHandles.setPosition = @iSetLayoutPosition; fHandles.setBorder = @iSetBorder; fHandles.deleteLayout = @iDestroyLayout; fHandles.setVisible = @iSetVisible; function iSetLayout(P, Layout) % Layout must be an object or empty % Also accept a cell array - this insulates us from set-dispatch problems if iscell(Layout) Layout = Layout{1}; end if ~(mbcgui.util.isComponentHandle(Layout) || isempty(Layout)) error(message('mbc:mbcgui:container:layoutpanel:InvalidPropertyValue')) end P.LayoutComponent = Layout; LayoutComponent = Layout; iSetLayoutPosition(P); end function iSetBorder(~, Border) % Border must be a 1x4 vector or empty BorderOK = isempty(Border) ... || (isnumeric(Border) && ismatrix(Border) && all(size(Border)==[1 4]) && all(Border>=0)); if ~BorderOK error(message('mbc:mbcgui:container:layoutpanel:InvalidPropertyValue1')) end if ~isequal(Border, LayoutBorder) Panel.LayoutBorder = Border; LayoutBorder = Border; iSetLayoutPosition(Panel); end end function iSetLayoutPosition(~, ~) L = LayoutComponent; if ~isempty(L) if ~strcmp(Panel.Units,'pixels') pos = getpixelposition(Panel); else pos= Panel.Position; end panelpos = pos; pos(1:2) = 1; % Adjust for the pixels lost due to the border decoration and title [W, titleW] = mbcgui.util.getPanelBorderWidth(Panel); pos(3:4) = pos(3:4)-2*W; pos(4) = pos(4) - titleW; B = LayoutBorder; if ~isempty(B) pos = pos + [B(1) B(2) -(B(1)+B(3)) -(B(2)+B(4))]; end pos = mbcgui.util.clipRect(pos, [1 1 panelpos(3:4)]); set(L, 'Position', pos); end end function iDestroyLayout(~, ~) L = LayoutComponent; if mbcgui.util.isComponentHandle(L) && ~isgraphics(L) delete(L); end end %-------------------------------------------------------------------------- % Functions that help patch up visible setting for java function iSetVisible(~, ~) component = LayoutComponent; VisVal = Panel.Visible; if ~isempty(component) set(component, 'Visible',VisVal); end end end