www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/+mbcgui/+container/titlebarpanel.m
function P = titlebarpanel(varargin) %TITLEBARPANEL Construct a panel that has a title bar above some content. % % P = TITLEBARPANEL(VARARGIN) constructs a uipanel that has additional % properties added to it and which displays its Title in a bar at the top. % All arguments to this function are passed on to the panel constructor. % % The additional properties will be: % % BarTitle : Title string to place in the titlebar. % ContentHandle : 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.) % FocusAppearance: 'on'/'off'/['none']. Specifies the appearance of the % title bar. 'on' makes the bar look "selected", 'off' % makes the bar look "unselected" and 'none' makes it % look like selection is not supported here. The % default value is 'none'. % % 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 'beveledin' % % Example: % pnl = mbcgui.container.titlebarpanel(... % 'Position', [20 20 300 200], ... % 'BarTitle', 'My Panel', ... % '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, 'ContentHandle', {L}); % Copyright 2010-2015 The MathWorks, Inc. % Pull out BarTitle, ContentHandle, FocusAppearance from property list and % set them later CH = []; FA = 'none'; Title = ''; PanelProps = true(size(varargin)); for n=1:2:length(varargin) switch varargin{n} case 'ContentHandle' CH = varargin{n+1}; PanelProps(n:n+1) = false; case 'FocusAppearance' FA = varargin{n+1}; PanelProps(n:n+1) = false; case 'BarTitle' Title = varargin{n+1}; PanelProps(n:n+1) = false; end end P = uipanel(... 'Units', 'pixels', ... 'Position', [0 0 1 1], ... 'BorderType', 'beveledin', ... varargin{PanelProps}); % Create the title components TitlePanel = uipanel('Parent', P, ... 'Units', 'pixels', ... 'BorderType', 'beveledout', ... 'UIContextMenu',get(P,'UIContextMenu'),... 'ButtonDownFcn',get(P,'ButtonDownFcn'),... 'HitTest', 'off'); TitleText = mbcgui.widget.Label('Parent',TitlePanel,... 'HorizontalAlignment','left',... 'Enable', 'inactive', ... 'UseTooltip', false, ... 'String', Title); % Create hidden properties to store data mbcgui.hgclassesutil.addprop(P, 'pBorderTypeListener', 'Hidden', true); mbcgui.hgclassesutil.addprop(P, 'MotionManagerStore', 'Hidden', true); mbcgui.hgclassesutil.addprop(P, 'ControlHook', 'Hidden', true); fHandles = manageLayoutPanel(TitlePanel,{TitleText}); % Title mbcgui.hgclassesutil.addprop(P, 'BarTitle', ... 'SetMethod', fHandles.setTitle); % Component that is resized with the layout mbcgui.hgclassesutil.addprop(P, 'ContentHandle', ... 'SetMethod', fHandles.setContentHandle); % Titlebar appearance control mbcgui.hgclassesutil.addprop(P, 'FocusAppearance', ... 'SetMethod', fHandles.setFocusAppearance); % Set the component if it has been provided if ~isempty(CH) set(P, 'ContentHandle', {CH}); end set(P, 'FocusAppearance', FA); set(P, 'BarTitle', Title); % Add a listener to BorderType to force an update of the contained layout addlistener(P, 'BorderType', 'PostSet', ... fHandles.postSetUpdateLayout); addlistener(P, 'UIContextMenu', 'PostSet', ... fHandles.postSetContextMenu); addlistener(P, 'ButtonDownFcn', 'PostSet', ... fHandles.postSetButtonDownFcn); evt.AffectedObject = P; fHandles.postSetButtonDownFcn(P,evt); fHandles.postSetContextMenu(P,evt); % Add a listener to the panel resize to update the layout addlistener(P, 'SizeChanged', fHandles.setPosition); % Add a destruction listener to destroy the contained objects addlistener(P, 'ObjectBeingDestroyed', fHandles.deleteLayout); addlistener(P, 'Visible', 'PostSet', fHandles.setVisible); end function fHandles = manageLayoutPanel(pTitlebarPanelHandle,pTitlebarTextHandle) %manageLayoutPanel nested function to manage positionin,visibility and border of inner layout ContentHandle = []; FocusAppearance = []; fHandles.setContentHandle = @setContentHandle; fHandles.setPosition = @setPosition; fHandles.setBorder = @iSetBorder; fHandles.setFocusAppearance = @setFocusAppearance; fHandles.postSetUpdateLayout = @postSetUpdateLayout; fHandles.postSetButtonDownFcn = @postSetButtonDownFcn; fHandles.postSetContextMenu = @postSetContextMenu; fHandles.deleteLayout = @deleteLayout; fHandles.setVisible = @setVisible; fHandles.setTitle = @setTitle; function setContentHandle(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.ContentHandle = Layout; ContentHandle = Layout; setPosition(P); end function setFocusAppearance(P, Focus) % FocusAppearance must be one of 'on', 'off' or 'none' FocusOK = ischar(Focus) ... && any(strcmp(Focus, {'on', 'off', 'none'})); if ~FocusOK error(message('mbc:mbcgui:container:layoutpanel:InvalidPropertyValue3')) end if ~isequal(Focus, P.FocusAppearance) P.FocusAppearance = Focus; FocusAppearance = Focus; updateFocusLook(P); end end function setTitle(P, Title) if ~ischar(Title) error(message('mbc:mbcgui:container:layoutpanel:InvalidPropertyValue4')) end P.BarTitle = Title; set(pTitlebarTextHandle{1}, 'String', Title) end function postSetUpdateLayout(~,~,P) setPosition(P); end function setPosition(P, ~) % Position all of the contained components Pos = get(P, 'Position'); Inset = mbcgui.util.getPanelBorderWidth(P); W = max(1, Pos(3) - 2*Inset); H = max(1, Pos(4) - 2*Inset); TitleHeight = 19; DividerStrip = 0; if strcmp(get(P, 'BorderType'), 'none') % Leave a small gap between the title bar and the content. DividerStrip = 2; % Add extra pixels for the wider border around the top bit. TitleHeight = TitleHeight+2; set(pTitlebarPanelHandle, 'BorderType', 'etchedin'); else set(pTitlebarPanelHandle, 'BorderType', 'beveledout'); end if ~isempty(ContentHandle) CompPos = [1 1 W H-TitleHeight-DividerStrip]; CompPos = mbcgui.util.clipRect(CompPos, [1 1 W H]); set(ContentHandle, 'Position', CompPos); end TitlePos = [1 H-TitleHeight+1 W TitleHeight]; TitlePos = mbcgui.util.clipRect(TitlePos, [1 1 W H]); set(pTitlebarPanelHandle, 'Position', TitlePos); TitleInset = mbcgui.util.getPanelBorderWidth(pTitlebarPanelHandle); TextPos = [3 1 W-2*TitleInset-2 TitleHeight-2*TitleInset-2]; set(pTitlebarTextHandle{1}, 'Position', TextPos); end function updateFocusLook(P) sc=xregGui.SystemColorsDbl; switch FocusAppearance case 'off' fg_col = sc.TITLE_INACTIVE_TEXT; bg_col = sc.TITLE_INACTIVE_BG; case 'on' fg_col = sc.TITLE_ACTIVE_TEXT; bg_col = sc.TITLE_ACTIVE_BG; otherwise fg_col = get(P, 'ForegroundColor'); bg_col = sc.CTRL_BACK; end set(pTitlebarPanelHandle, ... 'ForegroundColor', fg_col, ... 'BackgroundColor', bg_col); set(pTitlebarTextHandle{1}, ... 'ForegroundColor', fg_col, ... 'BackgroundColor', bg_col); end function deleteLayout(~, ~) L = ContentHandle; if mbcgui.util.isComponentHandle(L) && ~isgraphics(L) delete(L); end end function postSetContextMenu(~,evt) P=evt.AffectedObject; if ~mbcgui.util.isBeingDestroyed(P) uic= get(P,'UIContextMenu'); set(pTitlebarPanelHandle,'UIContextMenu',uic); set(pTitlebarTextHandle{1},'UIContextMenu',uic); end end function postSetButtonDownFcn(~,evt) P=evt.AffectedObject; if ~mbcgui.util.isBeingDestroyed(P) Fcn= get(P,'ButtonDownFcn'); set(pTitlebarPanelHandle,'ButtonDownFcn',Fcn); set(pTitlebarTextHandle{1},'ButtonDownFcn',Fcn); end end %-------------------------------------------------------------------------- % Functions that help patch up visible setting for java function setVisible(~, evt) P = evt.AffectedObject; if ~isempty(ContentHandle) VisVal = get(P, 'Visible'); set(ContentHandle, 'Visible',VisVal); end end end