www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/xregfigure.m

    function h=xregfigure(varargin)
%XREGFIGURE Create an MBC application figure
%
%  h=xregfigure(prop,value...) creates a modified figure window
%  and returns the handle to it.  Enhancements on the figure
%  include:
% 
%  * Useful default properties:  MenuBar          = 'none'
%                                ToolBar          = 'none'
%                                IntegerHandle    = 'off'
%                                Color            = default UI background
%                                NumberTitle      = 'off'
%                                HandleVisibility = 'callback'
%
%  * Automatic resizing.  Use the property 'MinimumSize' to set a minimum
%    [height width] for the figure.  Use the property 'LayoutManager' to 
%    set a layout for the figure which will be repacked during resize.
%    To turn off the resizing function set the property 'ManageResize' to
%    'off'.
%  
%  SEE ALSO: XREGDIALOG
 
%  Copyright 2000-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.
 
% Pull out properties that we add - these can't be set at construction
ThisClassProps = {'MinimumSize', 'LayoutManager', 'ContentHandle'};
isThisClassProp = false(2, length(varargin).*0.5);
isThisClassProp(1,:) = ismember(lower(varargin(1:2:end)), lower(ThisClassProps));
isThisClassProp(2,:) = isThisClassProp(1,:);
isThisClassProp = reshape(isThisClassProp, 1, length(varargin));
 
sc = xregGui.SystemColorsDbl;
 
UIFontSize = 8;
AxesFontSize = 8;
 
h = figure( ...
    'DefaultUicontrolInterruptible','off',...
    'DefaultUimenuInterruptible','off',...
    'DefaultUipushtoolInterruptible','off',...
    'DefaultUitoggletoolInterruptible','off',...
    'DefaultAxesInterruptible','off',...
    'DefaultLineInterruptible','off',...
    'DefaultRectangleInterruptible','off',...
    'DefaultTextInterruptible','off',...
    'DefaultImageInterruptible','off',...
    'DefaultSurfaceInterruptible','off',...
    'DefaultPatchInterruptible','off',...
    'DefaultUicontrolBusyAction','cancel',...
    'DefaultUimenuBusyAction','cancel',...
    'DefaultUipushtoolBusyAction','cancel',...
    'DefaultUitoggletoolBusyAction','cancel',...
    'DefaultAxesBusyAction','cancel',...
    'DefaultLineBusyAction','cancel',...
    'DefaultRectangleBusyAction','cancel',...
    'DefaultTextBusyAction','cancel',...
    'DefaultImageBusyAction','cancel',...
    'DefaultSurfaceBusyAction','cancel',...
    'DefaultPatchBusyAction','cancel',...    
    'DefaultUicontrolFontSize',UIFontSize,...
    'DefaultAxesFontSize',AxesFontSize,...
    'DefaultTextFontSize',AxesFontSize, ...
    'DefaultUipanelFontSize',UIFontSize,...  
    'DefaultUipanelBackgroundColor',sc.CTRL_BACK,...
    'DefaultUicontrolBackgroundColor',sc.CTRL_BACK,...
    'DefaultUitabBackgroundColor',sc.CTRL_BACK,...
    'Color', sc.CTRL_BACK,...
    'WindowStyle', 'normal', ...
    'DockControls', 'off', ...
    'MenuBar', 'none',...
    'ToolBar', 'none',...
    'IntegerHandle', 'off',...
    'HandleVisibility', 'callback',...
    'NumberTitle', 'off',...
    'Serializable','off',...
    'Interruptible', 'off', ...
    'DefaultUicontrolBackgroundColor',sc.CTRL_BACK,... 
    varargin{~isThisClassProp});
 
set(h,'Renderer','opengl',...
    'DefaultAxesTitleFontSizeMultiplier',1,...
    'DefaultAxesTitleFontWeight','normal',...
    'DefaultAxesLabelFontSizeMultiplier',1)

% Ensure that h is a handle in all cases
h = mbcgui.hgclassesutil.toHandle(h);
 
% Add custom properties
mbcgui.hgclassesutil.addprop(h, 'MinimumSize');
mbcgui.hgclassesutil.addprop(h, 'LayoutManager', ...  % Deprecated interface
    'Hidden', true, ...
    'Transient',true,...
    'SetMethod', @iSetLM, ...
    'GetMethod', @iGetLM);
mbcgui.hgclassesutil.addprop(h, 'ContentHandle', 'SetMethod', @iSetContent);
 
mbcgui.hgclassesutil.addprop(h, 'LastValidResizePosition', 'Hidden', true);
mbcgui.hgclassesutil.addprop(h, 'LastInvalidResizePosition', 'Hidden', true);
 
mbcgui.hgclassesutil.addprop(h, 'OldPosition', 'Hidden', true);
mbcgui.hgclassesutil.addprop(h, 'MBCFigureListeners', 'Hidden', true,'Transient',true);
mbcgui.hgclassesutil.addprop(h, 'showDialog');
mbcgui.hgclassesutil.addprop(h, 'MotionManagerStore', 'Hidden', true);
mbcgui.hgclassesutil.addprop(h, 'ControlHook', 'Hidden', true);
 
mbcgui.hgclassesutil.addprop(h, 'Timer', 'Hidden', true);
 
% Set default minimum size
set(h, 'MinimumSize', [1 1], 'showDialog', iCreateShowDialog(h));
 
% Set any other input properties
if any(isThisClassProp)
    set(h, varargin{isThisClassProp});
end
 
% Initialize private properties
set(h,'OldPosition',get(h, 'Position'));
set(h,'LastInvalidResizePosition',get(h, 'Position'));
set(h,'LastValidResizePosition',get(h, 'Position'));
set(h, 'MBCFigureListeners', ...
    {...
    mbcgui.hgclassesutil.locationlistener(h, @i_setPosition, 'PreSet'), ...
    mbcgui.hgclassesutil.listener(h, 'SizeChanged', @i_sizechange), ...
    });
 
 
function restartResizeTimer(src)
T = xregGui.getUITimer;
setContentPosition(src);

figTimer = get(src, 'Timer');
if isempty(figTimer)
    newFigTimer = T.scheduleAt(300, {@iResizeOnFinishTimer, src}); %0.3s
else
    newFigTimer = T.restartTask(figTimer);
end
set(src, 'Timer', newFigTimer);

 
function iResizeOnFinishTimer(~,~,fig)
if ishghandle(fig)
    set(fig, 'Timer', [])
    iResize(fig, true)
end
 
 
% Respond to Content being set
function iSetLM(obj, hContent)
obj.ContentHandle = hContent;
 
function hContent = iGetLM(obj)
hContent = obj.ContentHandle;
 
function iSetContent(obj, hContent)
obj.ContentHandle = hContent;
setContentPosition(obj);
 
% Dialog showing 
function hFcn = iCreateShowDialog(obj)
hFcn = @(varargin) mbcgui.util.showDialog(obj, varargin{:});
 
 
% Layout re-positioning
function i_setPosition(~, event)
iResize(event.Source, false);
 
function i_sizechange(src, ~)
restartResizeTimer(src);
 
function iResize(obj, IsResizeEvent)
%IRESIZE React to figure position changes
%
%  IRESIZE(OBJ) is called whenever the figure is moved.
 
if nargin<2
    IsResizeEvent = true;
end
 
pos = get(obj, 'Position');
oldpos = get(obj, 'OldPosition');
if all(pos == oldpos)
    % This shouldn't even occur
elseif all(pos(3:4) == oldpos(3:4))
    % This corresponds to a pure movement.  We just need to track the fact
    % that it occurred
    set(obj, 'OldPosition', pos);
else
    if IsResizeEvent
        % Resize event
        
        pos = protectAgainstDoubleResizePosition(obj,pos);
        
        pos = makeWindowValidSize(obj,pos,oldpos);
        
        % Store the current position so we can detect which edges are resized
        % in future
        set(obj, 'OldPosition', pos);
        set(obj, 'LastValidResizePosition', pos);
        
    end
end
 
function [resizeIsInvalid,pos] = iCheckResize(obj,pos)
% The figure been resized and we need to check the size and sync
% the layout
MinSize = get(obj, 'MinimumSize');
resizeIsInvalid = false;
if pos(3) < MinSize(1)
    pos(3) = MinSize(1);
    resizeIsInvalid = true;
end
if pos(4) < MinSize(2)
    pos(4) = MinSize(2);
    resizeIsInvalid = true;
end
 
function pos = calcMinSizePos(pos,oldpos)
if pos(1) ~= oldpos(1);
    % need to move left edge back as well
    pos(1) = oldpos(1) + oldpos(3) - pos(3);
end
if pos(2) ~= oldpos(2);
    % need to move bottom edge back as well
    pos(2) = oldpos(2) + oldpos(4) - pos(4);
end
% The way that position property changes are structured means
% that we might misinterpret a resize as a move followed by a
% resize, and this can lead to the wrong window edge being
% moved back.  One thing we can do that reduces the severity is
% to explicitly check whether the window is off the right or
% bottom edge of the screen.
scr = get(0, 'ScreenSize');
if pos(1)+pos(3)>scr(3)
    pos(1) = scr(3)-pos(3);
end
if pos(2)<1
    pos(2) = 1;
end
 
function pos = makeWindowValidSize(obj,pos,oldpos)
origPos = pos;
[resizeIsInvalid,pos] = iCheckResize(obj,pos);
if resizeIsInvalid
    pos = calcMinSizePos(pos,oldpos);
    setPosition(obj,pos);
    set(obj, 'LastInvalidResizePosition', origPos);
end
 
function setContentPosition(obj)
pos = get(obj,'Position');
hContent = get(obj, 'ContentHandle');
if ~builtin('isempty',hContent)
    % Re-calculate the layout
    set(hContent, 'Position', [1 1 pos(3:4)]);
end
 
function pos = protectAgainstDoubleResizePosition(obj,pos)
% If the current position is identical to the previous (invalid) position
% then we could be in the situation where the user has resized the figure
% and held the mouse down (until the timer fired) then let go.
% In this case we should use the last valid resize position, to prevent
% resizing on the wrong side
lastinvalidpos = get(obj, 'LastInvalidResizePosition');
if all(pos == lastinvalidpos)
    pos = get(obj, 'LastValidResizePosition');
    setPosition(obj,pos);
end



function setPosition(obj,pos)
set(obj, 'Position', pos);
setContentPosition(obj);