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