Documentation of prepareui


Global Index (short | long) | Local contents | Local Index (short | long)


Function Synopsis

pj = prepareui( pj, Fig )

Help text

PREPAREUI Method to draw Uicontrol objects in output.
   Mimics user interface objects as Images so they appear in output.
   Takes screen captures of user interface objects and creates true  
   color Images in the same location as the user interface objects so 
   the uicontrols themselves seem to print (which they can not because
   they are drawn by the windowing system, not MATLAB).

   Ex:
      pj = PREPAREUI( pj, h ); %modifies PrintJob object pj and creates
                               %Images of Uicontrols in Figure h

   See also PREPARE, RESTORE, PREPAREHG, RESTOREUI.

Cross-Reference Information

This function calls This function is called by

Listing of function prepareui

function pj = prepareui( pj, Fig )

%   Copyright 1984-2000 The MathWorks, Inc. 
%   $Revision: 1.4 $  $Date: 2000/08/15 14:37:53 $

error( nargchk(2,2,nargin) )

if ~isequal(size(Fig), [1 1]) | ~isfigure( Fig )
    error( 'Need a handle to a Figure object.' )
end
    
%Early exist if the user has requested not to see controls in output.
if ~pj.PrintUI
    return
end

%Bail if device doesn't support TC images.
if  strcmp( pj.Driver, 'hpgl' ) | strcmp( pj.Driver, 'ill' )
    pj.UIData = [];
    return
end

%Now that we know it is a Figure, see if there is anything to do
pj.UIData.UICHandles = findall(Fig,'Type','uicontrol','Visible','on');
if isempty(pj.UIData.UICHandles)
    pj.UIData = [];
    return
end
    

ComputerType=computer;
pj.UIData.OldRootUnits=get(0,'Units');
pj.UIData.OldFigUnits=get(Fig,'Units');
pj.UIData.OldFigPosition=get(Fig,'Position');
pj.UIData.OldFigVisible=get(Fig,'Visible');
set( Fig, 'units', 'points' )
pj.UIData.MovedFigure = screenpos( Fig, get( Fig, 'position' ) );
pj.UIData.OldFigCMap=get(Fig,'Colormap');

set([0 Fig],'Units','pixels');

%%% UI Controls %%%

pj.UIData.AxisHandles = [];
Frame = [];
FrameNum = 0;
if ~isempty(pj.UIData.UICHandles)
    % Making the assumption that the bottom uicontrol is usually
    % created first and underneath the others.
    pj.UIData.UICHandles=flipud(pj.UIData.UICHandles);
    pj.UIData.UICUnits=get(pj.UIData.UICHandles,{'Units'});
    set(pj.UIData.UICHandles,'Units','pixels');
    
    for Clp=1:length(pj.UIData.UICHandles)
        FrameFlag=1;
        CurCtrlPos = rectaroundcontrol( pj.UIData.UICHandles(Clp) );
        CurCtrlUnits = pj.UIData.UICUnits{Clp};
        
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %Check to see if completely contained in previous frames
        %and that the framing control has same units (so the scale similarly)
        for Frmlp=1:FrameNum
            if CurCtrlPos(1)>=Frame{Frmlp}.Pos(1) & ...
                    CurCtrlPos(2)>=Frame{Frmlp}.Pos(2) & ...
                    sum(CurCtrlPos([1 3]))<=sum(Frame{Frmlp}.Pos([1 3])) & ...
                    sum(CurCtrlPos([2 4]))<=sum(Frame{Frmlp}.Pos([2 4])) & ...
                    strcmp( Frame{Frmlp}.Units, CurCtrlUnits )
                
                FrameFlag=0;
                break;
            end % if CurCtrlPos
        end % Frmlp
        
        %%%%%%%%%%%%%%%%%%%
        % It is the first, or a new frame
        if FrameNum > 0
            RmvFrmLoc=[];
            if FrameFlag,
                for inlp=1:length(Frame),
                    if CurCtrlPos(1)>=Frame{inlp}.Pos(1) & ...
                            CurCtrlPos(2)>=Frame{inlp}.Pos(2) & ...
                            sum(CurCtrlPos([1 3]))<=sum(Frame{inlp}.Pos([1 3])) & ...
                            sum(CurCtrlPos([2 4]))<=sum(Frame{inlp}.Pos([2 4])) & ...
                            strcmp( Frame{Frmlp}.Units, CurCtrlUnits )
                        
                        % New Frame Contains an old frame
                        RmvFrmLoc=[RmvFrmLoc inlp];
                    end
                end
                
                if ~isempty( RmvFrmLoc )
                    Frame(RmvFrmLoc) = [];
                end
                FrameNum=length(Frame)+1;
                Frame{FrameNum}.Pos = CurCtrlPos;
                Frame{FrameNum}.Units = CurCtrlUnits;
            end % if FrameFlag
            
        else
            Frame{1}.Pos = CurCtrlPos;
            Frame{1}.Units = CurCtrlUnits;
            FrameNum=1;
        end % if FrameNum
    end % for Clp
    
end % if ~isempty(UIC)


%%% Create images %%%

if FrameNum > 0
    CapturedImages = [];
    CapturedMaps = [];
    
    %Pop it to top of window stacking order
    figure( Fig )
    
    % Capture images for each uicontrol first
    [prevWarnState,prevWarnFreq]=warning;
    warning('off');
    for lp=1:length(Frame)
        if feature('NewMovieFormat')
            CapturedImages{lp} = getframe(Fig,Frame{lp}.Pos(:)); 
        else
            [CapturedImages{lp}.cdata, CapturedImages{lp}.colormap]=getframe(Fig,Frame{lp}.Pos(:));
        end
    end
    warning(prevWarnState);
    warning(prevWarnFreq);
    
    %reinstate warning status
    
    % Draw each image to stand in for the uicontrols
    for lp=1:length(Frame)
        if ~isempty(CapturedImages{lp})
            if ~isempty( CapturedImages{lp}.colormap )
                CapturedImages{lp}.cdata = ind2rgb(CapturedImages{lp}.cdata, CapturedImages{lp}.colormap);    
                CapturedImages{lp}.colormap = [];
            end
            
            pj.UIData.AxisHandles(lp)=axes('Parent',Fig, ...
                'Units'         ,'pixels'        , ...
                'Position'      ,Frame{lp}.Pos(:), ...
                'Tag'           ,'PrintUI'         ...
                );                       
            %call low level command so NextPlot has no affect, fix Axes.
            ImgHandle=image('cdata',CapturedImages{lp}.cdata, 'Parent',pj.UIData.AxisHandles(lp));
            set(pj.UIData.AxisHandles(lp), ...
                'Units'          ,Frame{lp}.Units, ...
                'Visible'        ,'on'       , ...
                'ColorOrder'     ,[0 0 0]     , ...
                'XTick'          ,[]          , ...
                'XTickLabelMode' ,'manual'    , ...
                'YTick'          ,[]          , ...
                'YTickLabelMode' ,'manual'    , ...
                'YDir'           ,'reverse'   , ...
                'XLim'           ,[0.5 Frame{lp}.Pos(3)+0.5], ...
                'YLim'           ,[0.5 Frame{lp}.Pos(4)+0.5]  ...
                );
        else
            pj.UIData.AxisHandles(lp)=[-1];
            warning('Screen capture failed - UIcontrol will not appear in output.');
        end %if ~isempty(capturedimages)
    end % for lp
    
end % if FrameNum

set(Fig, 'Units', pj.UIData.OldFigUnits );
set(0,   'Units', pj.UIData.OldRootUnits);
if ~isempty(pj.UIData.UICHandles),
  set(pj.UIData.UICHandles,{'Units'},pj.UIData.UICUnits);
end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% RectAroundControl %%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function rect = rectaroundcontrol( ch )
%RECTAROUNDCONTROL Get rectangle that tightly bounds UiControl
%   On some platforms the asked for position is not used because it
%   is the LAF on those platforms to have the height of some styles of
%   UiControls be dependent upon the fontsize of the label of the control.

rect = get(ch,'position');

%A little fudgying is required since pop-up menus do not obey their
%position property -- they are Windows widgets we can't control completely.
if strcmp( 'popupmenu', get(ch,'style') ) & strncmp(computer,'PC',2)
    ext = get(ch,'extent');
    %Mac and PC both draw a little bit differently.
    if strncmp(computer,'PC',2)
        rect(2) = rect(2) + rect(4) - ext(4) - 4;
        rect(4) = ext(4)+4;
    end
end