www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/@designdev/draw.m

    function ud = draw(d,ax,Enable,T)
%DRAW Draw hierarchy diagram editor
%
%  ud = draw(d,ax,Enable)

%  Copyright 2000-2015 The MathWorks, Inc. and Ford Global Technologies, Inc.

if nargin==1
    ax=gca;
end
if nargin<3
    Enable= 1;
end
if nargin<4
    T = info(get(MBrowser,'CurrentNode'));
end

delete(allchild(ax));
set(ax,'DefaultRectangleBusyAction','cancel');
hFig= ancestor(ax,'figure');

set(ax,'SortMethod','childorder')

% context menu for model blocks
uc_model = findobj(hFig,'Type','uicontextmenu','Tag','xregtpdiag');
if isempty(uc_model)
    uc_model = uicontextmenu('Parent',hFig,'Tag','xregtpdiag');
    str = {'&Set Up Model...', 'Design &Experiment', 'View &Design Data', 'View &Model', 'Summary Statistics'};
    cb = {@i_SetupModel, @i_Design, @i_ViewDesign, @i_ViewModel, @i_SummaryStats};
    for n = 1:length(str)
        u(n) = uimenu('Parent',uc_model,...
            'Label',str{n},...
            'Callback',cb{n});
    end
else
    u= get(uc_model,'Children');
    u= u(end:-1:1);
end
if IsMatched(T)
    set(u(3),'Enable','on');
else
    set(u(3),'Enable','off');
end

uc_inports = findobj(hFig,'Type','uicontextmenu','Tag','xregtpinports');
if isempty(uc_inports)
    uc_inports = uicontextmenu('Parent',hFig,'Tag','xregtpinports');
    uimenu('Parent', uc_inports, 'Label', '&Set Up Inputs...', 'Callback', @i_Inputs);
end

uc_outport = findobj(hFig,'Type','uicontextmenu','Tag','xregtpoutport');
if isempty(uc_outport)
    uc_outport = uicontextmenu('Parent',hFig,'Tag','xregtpoutport');
    uimenu('Parent', uc_outport, 'Label', '&New Response Model...', 'Callback', @i_ResponseContext);
end

ud.Menu= u;

ud.Enable= Enable;

N= length(d);
D= DesignDev2Cell(d);
ud.IsPointByPoint = strcmpi(type(T),'point-by-point');

xp= 0.9-0.1/N;
ip= 0.05; % 0.35-0.1/N;

% colors for blockdiagram
Colors.BackGround= [1 1 1];
Colors.Port     = [240 150 150]/255;  % in and out ports
Colors.Model    = [120 180 220]/255;  % model block
Colors.Selected  = [220 220 170]/255; % blocks when selected

ud.Colors= Colors;


ht= (diff(get(ax,'YLim'))/(N+1));
wid= diff(get(ax,'XLim'));
% scale axes to fit the dialog
set(ax,'XLim',[0 wid*(ip+1.15)]);
if N==1
    set(ax,'YLim',[0 ht*(2+0.7)]-ht/2);
else
    set(ax,'YLim',[0 ht*(N+0.75)]);
end
set(ax,'YLim',[0 ht*(N+0.75)]);
yht= get(ax,'YLim');

% border
rectangle('Parent',ax,...
    'FaceColor','none',...
    'EdgeColor',[0 0 0],...
    'Position',[(ip+0.15)*wid ht*.2  0.8*wid ht*(N+0.3)]);

if N==2
    ud.StageNames= {'Local','Global'};
else
    ud.StageNames= {''};
end


for i=N:-1:1

    xp= xp-0.2;
    Stage = N-i+1;

    m= getModel(D{Stage});

    % inports for defining Stage Input Factors
    ud.hInput(Stage)= rectangle('Parent',ax,...
        'FaceColor',Colors.Port,...
        'EdgeColor','k',...
        'ButtonDownFcn',{@i_Inputs,Stage},...
        'UIContextMenu', uc_inports, ...
        'Position',[ip*wid ht*(i-0.15)  0.1*wid ht*.3],...
        'UserData',Stage,...
        'Curvature',[0.75 0.75]);
    % use rectangle for selection
    ud.pBorder(Stage) = ud.hInput(Stage);
    
    % Stage Label on inport
    inTxt = text('Parent',ax,...
        'Position',[(ip+.05)*wid ht*i],...
        'HorizontalAlignment','Center',...
        'String',int2str(Stage));
    mbcgui.hgclassesutil.setNotPickable(inTxt);
    
    % Labels above port 
    if ~isempty(ud.StageNames{Stage})
        lab= char([ud.StageNames(Stage),{'Inputs'}]);
    else
        lab= 'Inputs';
    end
    hTitle = text('Parent',ax,...
        'Position',[(ip+.05)*wid ht*(i+0.18)],...
        'VerticalAlignment','Bottom',...
        'HorizontalAlignment','Center',...
        'String',lab);
    mbcgui.hgclassesutil.setNotPickable(hTitle);

    % model block
    if Stage>1 && ud.IsPointByPoint
        % Point-by-point doesn't have a model
        modelName = 'Operating Point Selector';
        lab = '';
    else
        modelName = name(m);
        lab= [ud.StageNames{Stage}, ' Model'];
    end
    Cbk = {@i_Select,Stage};

    hTitle = text('Parent',ax,...
        'Position',[(xp+0.1)*wid ht*(i+0.26)],...
        'VerticalAlignment','Bottom',...
        'HorizontalAlignment','Center',...
        'String',lab);
    mbcgui.hgclassesutil.setNotPickable(hTitle);

    % model rectangle
    ud.hStage(Stage)= rectangle('Parent',ax,...
        'ButtonDownFcn',Cbk,...
        'FaceColor',Colors.Model,...
        'UserData',Stage,...
        'UIContextMenu',uc_model,...
        'EdgeColor','k',...
        'Position',[xp*wid  ht*(i-0.25)  0.2*wid ht*.5]);
    ud.hBorder(Stage) = ud.hStage(Stage);

    % input labels
    str= InputLabels(m);
    ud.InpLabels(Stage) = text('Parent',ax,...
        'Interpreter','none',...
        'FontSize',8,...
        'Position',[(ip+0.16)*wid ht*(i-0.05)],...
        'VerticalAlignment','Top',...
        'Clipping','on',...
        'String',char(str));
    mbcgui.hgclassesutil.setNotPickable(ud.InpLabels(Stage));


    % model name
    ud.hModel(Stage)= text('Parent',ax,...
        'String',modelName,...
        'HorizontalAlignment','center',...
        'VerticalAlignment','middle',...
        'Interpreter','none',...
        'Position',[(xp+0.1)*wid  ht*i]);
    mbcgui.hgclassesutil.setNotPickable(ud.hModel(Stage));
    
    % workout model block position based on size of name
    ext = ud.hModel(Stage).Extent;
    % make sure rectangle covers text and right align to (xp+0.2)*wid
    % allow 0.01*wid spacing on each side
    mdlPos = ud.hStage(Stage).Position;
    MinPos = (xp+0.2)*wid - ext(3) - 0.02*wid;
    
    if MinPos > (ip+0.15+0.02)*wid
         %still inside main block diagram
        mdlPos(1) = min(mdlPos(1),MinPos);
        mdlPos(3) = max(mdlPos(3),ext(3)+0.02*wid);
    end
    ud.hStage(Stage).Position = mdlPos;
    % reposition text to the center of the rectangle
    ud.hModel(Stage).Position(1) = mdlPos(1)+mdlPos(3)/2;
    hTitle.Position(1) = mdlPos(1)+mdlPos(3)/2;
    % absolute rectangle
    rectPos = mdlPos;
    rectPos(3:4) = mdlPos(1:2)+mdlPos(3:4);
    
    % line joining inputs to model block
    line('Parent',ax,...
        'LineWidth',3,...
        'XData',[(ip+0.1)*wid rectPos(1)],...
        'YData',[ht*i ht*i]);
    drawarrow(ax,[rectPos(1),ht*i 0.02*wid 0.05*ht],0);    

    
    if Stage~=1
        % join stages for higher levels
        line('Parent',ax,...
            'LineWidth',3,...
            'XData',[rectPos(3) [xp+0.3 xp+0.3]*wid],...
            'YData',[ht*i ht*i ht*(i+0.75)]);
        drawarrow(ax,[(xp+0.3)*wid,ht*(i+0.75),0.05*ht 0.02*wid],1);
    else
        % level 1 has a normal output
        line('Parent',ax,...
            'LineWidth',3,...
            'XData',[rectPos(3) (ip+1)*wid],...
            'YData',[ht*i ht*i]);
        drawarrow(ax,[(ip+1)*wid,ht*(i),0.02*wid 0.05*ht],0);
        
        % response outport
        ud.Models= rectangle('Parent',ax,...
            'ButtonDownFcn',@i_ResponseClick,...
            'UIContextMenu', uc_outport, ...
            'FaceColor',Colors.Port,...
            'Position',[(ip+1)*wid , ht*(i-0.15) , 0.1*wid , ht*.3],...
            'Curvature',[0.75 0.75]);
        % select the rectangle
        ud.pBorder(N+1) = ud.Models;
        hTitle = text('Parent',ax,...
            'Position',[(ip+1.05)*wid , ht*(i)],...
            'VerticalAlignment','Middle',...
            'HorizontalAlignment','Center',...
            'String',int2str(Stage));
        mbcgui.hgclassesutil.setNotPickable(hTitle);

        % responese labels
        str= ResponseLabels(T);
        ud.Responses= text('Parent',ax,...
            'Interpreter','none',...
            'VerticalAlignment','Top',...
            'HorizontalAlignment','Left',...
            'HitTest','off',...
            'Clipping','on',...
            'String',char(str));
        ext=get(ud.Responses,'Extent');
        set(ud.Responses,'Position',[(ip+0.93)*wid-ext(3) , ht*(i-0.27)])
        
        text('Parent',ax,...
            'Position',[(ip+1.05)*wid , ht*(i+0.18)],...
            'Interpreter','none',...
            'VerticalAlignment','Bottom',...
            'HorizontalAlignment','Center',...
            'HitTest','off',...
            'String','Responses');
    end
end

% select outer stage input port

if IsMatched(T) || hasRespModels(T)
    set(ud.pBorder(end),'Selected','on');
else
    m= getModel(d);
    s= get(m,'symbols');
    if any(ismember(s,{'L1','G1','X1'}))
        set(ud.pBorder(N),'Selected','on');
    elseif any(ismember(get(HSModel(d),'symbols'),{'L1','G1','X1'}))
        % local inputs
        set(ud.pBorder(1),'Selected','on');
    elseif ud.IsPointByPoint
        % select local model
        set(ud.hBorder(1),'Selected','on');
    else        
        % select global model
        set(ud.hBorder(N),'Selected','on');
    end
end


ud.msg= text('Parent',ax,...
    'Position',[0.02*wid , yht(2)-ht*0.025],...
    'VerticalAlignment','Top',...
    'HorizontalAlignment','left',...
    'HitTest','off',...
    'String',i_Message(ud,address(T)));


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   drawarrow
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h= drawarrow(ax,pos,up)

s= pos(3:4)/2;
pos= pos(1:2);
if up
    s= s([2 1]);
    xp= [pos(1)-s(1) pos(1)+s(1) pos(1) pos(1)-s(1)];
    yp= [pos(2)-s(2) pos(2)-s(2) pos(2) pos(2)-s(2)];
else
    xp= [pos(1)-s(1) pos(1)-s(1) pos(1) pos(1)-s(1)];
    yp= [pos(2)-s(2) pos(2)+s(2) pos(2) pos(2)-s(2)];
end

h= patch('Parent',ax,'XData',xp,'YData',yp,'FaceColor','k');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_GetDesignDev
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function d= i_GetDesignDev(Stage)

% store in base workspace for now
p= get(MBrowser,'CurrentNode');

d= p.designdev;
if nargin
    d= DesignDev2Cell(d);
    d= d{Stage};
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_PutDesignDev
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_PutDesignDev(ds,Stage)

% store in base workspace for now

p= get(MBrowser,'CurrentNode');
d= p.designdev;

d= DesignDev2Cell(d);
d{Stage}=ds;
d= Cell2DesignDev(d);

p.designdev(d);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_FindDOE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [hDOE,hAutoMatch]= i_FindDOE

hDOE       = findobj(allchild(0),'flat','Tag','DOEeditor','Visible','on');
hAutoMatch = findobj(allchild(0),'flat','Tag','dataEditor','Visible','on');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_Inputs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_Inputs(h,~,Stage)

if nargin<3
    Stage = get(gco, 'UserData');
end
mbH= MBrowser;
p= get(mbH,'CurrentNode');
View= mbH.GetViewData;

if ~any(strcmp(get(View.hHSM.pBorder,'Selected'),'on'))
    i_HighLight(Stage)
end
set(View.hHSM.pBorder,'Selected','off')
set(View.hHSM.hBorder,'Selected','off');


set(View.hHSM.pBorder(Stage),'Selected','on')
set(View.hHSM.msg,'String',i_Message(View.hHSM,p));

p.EnableMenus(View);

srcType = get( h, 'Type' );
selType = get( mbH.Figure, 'SelectionType' );

% if this came from a mouse click on the rectangle, but isn't an open
% selection we have finished, it is is from elsewhere (ie the menu, we
% always carry on)
if strcmpi( srcType, 'rectangle' ) && ~strcmpi( selType, 'open' )
    return;
end

[hDOE,hAutoMatch]= i_FindDOE;

ReadOnly= p.IsMatched || ~isempty(hDOE) || ~isempty(hAutoMatch);


% selected color for port
set(View.hHSM.hInput(Stage),'FaceColor',View.hHSM.Colors.Selected);

set(mbH.Figure,'Pointer','watch');

if ~isempty(View.hHSM.StageNames{Stage})
    Title= sprintf('%s Input Factor Setup',View.hHSM.StageNames{Stage});
else
    Title= 'Input Factor Set Up';
end

Inputs = p.getInputs;
done= false;
while ~done
    [Inputs{Stage},OK]= gui_InputSetup(Inputs{Stage},'figure',~ReadOnly,Title);
    if OK
        AllInputs = cat(1,Inputs{:});
        if OK && length( unique(getList(AllInputs,'Symbol')) ) ~= length(AllInputs);
            h= errordlg('Duplicate symbols in two-stage model','Input Error','modal');
            uiwait(h);
            done= false;
        else
            done= true;
        end
    else
        done= true;
    end
end

set(mbH.Figure,'Pointer',get(0,'DefaultFigurePointer'));
% normal color for port
set(View.hHSM.hInput(Stage),'FaceColor',View.hHSM.Colors.Port);

if OK
    % update test plan inputs
    p.setInputs(Inputs);
    
    % update display
    d = i_GetDesignDev(Stage);
    m = getModel(d);
    
    set(View.hHSM.hModel(Stage),'String',name(m))
    set( View.hHSM.InpLabels(Stage),'String',InputLabels(m));
    
    RedrawNode(MBrowser);
    
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_Design
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_Design(~,~,Stage)
mbH= MBrowser;
p= get(mbH,'CurrentNode');
View= mbH.GetViewData;
if nargin<3
    Stage= get(gco,'UserData');
end
d= i_GetDesignDev(Stage);

if ~any(strcmp(get(View.hHSM.hBorder,'Selected'),'on'))
    i_HighLight(Stage)
end


[hDOE,hAutoMatch]= i_FindDOE;
if ~isempty(hAutoMatch)
    xregerror('Error','The design editor cannot be used while the data selection figure is open');
    return
end



if isempty(hDOE)
    % create a design editor
    hDOE=xregdesigneditor;
    xregdesigneditor(hDOE,'loadtree',d.DesignTree,'closefcn',{@i_DEclose,Stage},...
        'currentstage',Stage);
else
    hDOE_Stage=xregdesigneditor(hDOE,'getcurrentstage',[]);
    if hDOE_Stage~=Stage
        % switch design editor's design stage
        i_DEclose(hDOE,[],hDOE_Stage);
        hDOE=xregdesigneditor;
        xregdesigneditor(hDOE,'loadtree',d.DesignTree,'closefcn',{@i_DEclose,Stage},...
            'currentstage',Stage);
    else
        % push figure to foreground
        figure(hDOE);
    end
end

if length(p.designdev)>1
    set(hDOE,'Name',['Design Editor - [',p.name,  ' (',View.hHSM.StageNames{Stage},')]']);
else
    set(hDOE,'Name',['Design Editor - [',p.name,']']);
end
RegisterSubFigure(mbH,hDOE);
return



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_DEClose
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_DEclose(hDOE,~,Stage)
mbH= MBrowser;
View= mbH.GetViewData;

d= i_GetDesignDev(Stage);

% grab a copy of the design tree
dtree=xregdesigneditor(hDOE,'savetree',[]);

OldTree= d.DesignTree;
OldDes= factorsettings(getdesign(d));
NewDes= factorsettings(dtree.designs{dtree.chosen});

if OldTree.chosen ~= dtree.chosen || size(OldDes,1)~=size(NewDes,1) || any(OldDes(:)~=NewDes(:))
    % make best design model the default
    m = model(dtree.designs{dtree.chosen});
    dtree.designs{1}= model(dtree.designs{1},m);

    % display name of model
    set(View.hHSM.hModel(Stage),'String',name(m))
end

d.DesignTree= dtree;
i_PutDesignDev(d,Stage);

return


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%   i_SetupModel
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_SetupModel(~,~,Stage)

D= i_GetDesignDev;
if nargin<3
    Stage= get(gco,'UserData');
end

[hDOE,hAutoMatch]= i_FindDOE;
if ~isempty(hDOE) || ~isempty(hAutoMatch)
    xregerror('Error','The model cannot be setup while the design editor or the data selection figure is open');
    return
end
mbH= MBrowser;
View= mbH.GetViewData;
if ~any(strcmp(get(View.hHSM.hBorder,'Selected'),'on'))
    i_HighLight(Stage)
end

d= subsref(D,substruct('()',{Stage}));
m= getModel(d);

set(View.hHSM.hStage(Stage),'FaceColor',View.hHSM.Colors.Selected);
drawnow('expose');
% setup gui
if Stage>1
    [m,OK]= gui_ModelSetup(m,'criteria','global');
else
    WasPointByPoint = isa(m,'localmulti');
    [m,OK]= gui_ModelSetup(m);
end
set(View.hHSM.hStage(Stage),'FaceColor',View.hHSM.Colors.Model);
set(View.hHSM.hModel(Stage),'String',name(m))
if OK
    d= setmodel(d,m);
    i_PutDesignDev(d,Stage);
    
    if Stage==1 && WasPointByPoint ~=  isa(m,'localmulti')
        % redraw diagram
        ViewNode(MBrowser);
    end
end




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% i_ViewDesign
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_ViewDesign(~,~,Stage)

if nargin<3
    Stage= get(gco,'UserData');
end

mbH= MBrowser;
p= get(mbH,'CurrentNode');
View= mbH.GetViewData;

D= i_GetDesignDev;
NStages= length(D);
d= i_GetDesignDev(Stage);

dtree= d.DesignTree;
if dtree.chosen
    if Stage < NStages

        if p.IsMatched
            % get the data
            X= p.getdata('X',0);
            X=X{Stage};

            des= dtree.designs{dtree.chosen};
            m= model(des);
            dtree.designs= dtree.designs(1);
            tn= testnum(X);
            for i= 1:size(X,3)
                des= reinit(des,code(m,X{i}));
                des= name(des,sprintf('Test %2d',tn(i)));
                dtree.designs=[dtree.designs,{des}];
            end

            dtree.parents=[0,ones(1,size(X,3))];
            d.DesignTree= dtree;
        end
    else
        if p.IsMatched
            X= p.getdata('X',0);
            if iscell(X)
                X=X{end};
            end
            des= dtree.designs{dtree.chosen};
            m= model(des);
            des= reinit(des,code(m,double(X)));
            des= name(des,'Selected Data');
            dtree.designs=[dtree.designs(1),{des}];
            dtree.parents= [0,1];
        end
    end
    dtree.chosen=1;

    hDOE=xregdesigneditor;
    xregdesigneditor(hDOE,'loadtree',dtree,'closefcn','',...
        'currentstage',Stage,'lockgui',1);

    if length(p.designdev)>1
        set(hDOE,'Name',['Design Editor - [',p.name,  ' (',View.hHSM.StageNames{Stage},')]']);
    else
        set(hDOE,'Name',['Design Editor - [',p.name,']']);
    end

    RegisterSubFigure(MBrowser,hDOE);

end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% i_ViewModel
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_ViewModel(~,~,Stage)

if nargin<3
    Stage= get(gco,'UserData');
end


mbH= MBrowser;
p= get(mbH,'CurrentNode');
View= mbH.GetViewData;
if ~any(strcmp(get(View.hHSM.hBorder,'Selected'),'on'))
    i_HighLight(Stage)
end

d= i_GetDesignDev(Stage);

hFig= view(getModel(d));

if length(p.designdev)>1
    set(hFig,'Name',['Default ' View.hHSM.StageNames{Stage} ' Model']);
else
    set(hFig,'Name','Default Model');
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% i_Select
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_Select(h,EventData,Stage)
hFig = ancestor(h,'figure');
View =GetViewData(MBrowser);

if strcmp(get(hFig,'SelectionType'),'open') && ~(View.hHSM.IsPointByPoint && Stage>1)
    set(hFig,'Pointer','watch');
    drawnow('expose');
    i_SetupModel(h,EventData,Stage);
    drawnow('expose');
    set(hFig,'Pointer',get(0,'DefaultFigurePointer'));
else
    % this is a single click - just need to highlight the block
    i_HighLight( Stage );
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% i_HighLight
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_HighLight( Stage )
% Highlights (selects) the block associated with the given Stage

mbH= MBrowser;
p = get(mbH,'CurrentNode');
View =GetViewData(mbH);

if View.hHSM.IsPointByPoint && Stage>1
    % don't select operating point selector
    
    % no models (Setup, View, Summary Statistics)
    set(View.hHSM.Menu([1 4 5]),'Enable','off')
else
    set(View.hHSM.Menu([1 4 5]),'Enable','on')

    % all items are cyan
    set(View.hHSM.hBorder,'Selected','off');
    set(View.hHSM.pBorder,'Selected','off');
    set(View.hHSM.hBorder(Stage),'Selected','on');
    set(View.hHSM.msg,'String',i_Message(View.hHSM,p));
    
    
    if Stage == p.numstages
        % summary statistics only available for outer stage
        set(View.hHSM.Menu(end),'Enable','on');
    else
        set(View.hHSM.Menu(end),'Enable','off');
    end
    p.EnableMenus(View);

end




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Functions to handle clicking/context menu on response outport
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_ResponseClick(~,~)
% Collect clicks on the response outport
mbH= MBrowser;
View= mbH.GetViewData;
if strcmp(get(mbH.Figure,'SelectionType'),'open')
    i_NewResponse(mbH,View);
else
    p= get(mbH,'CurrentNode');

    set(View.hHSM.pBorder,'Selected','off')
    set(View.hHSM.hBorder,'Selected','off');

    set(View.hHSM.pBorder(end),'Selected','on')
    set(View.hHSM.msg,'String',i_Message(View.hHSM,p));
    p.EnableMenus(View);
end


function i_ResponseContext(~, ~)
% Collect callback from context menu
mbH = MBrowser;
View = mbH.GetViewData;
i_NewResponse(mbH, View);


function i_NewResponse(mbH, View)
% Create a new response model
set(mbH.Figure,'Pointer','watch');
set(View.hHSM.Models,'FaceColor',View.hHSM.Colors.Selected);
drawnow('expose');
mbH.NewNode;
if isgraphics(View.hHSM.Models)
    set(View.hHSM.Models,'FaceColor',View.hHSM.Colors.Port);
end
set(mbH.Figure,'Pointer',get(0,'DefaultFigurePointer'));



function Msg= i_Message(ud,p)

D= DesignDev2Cell(p.designdev);
L = getModel(D{1});
IsPointByPoint = isa(L,'localmulti');

selPort  = find(strcmp(get(ud.pBorder,'Selected'),'on'));
selModel = find(strcmp(get(ud.hBorder,'Selected'),'on'));


Msg= '';
% display a status bar message as well ?
if ~isempty(selPort)
    if selPort<length(ud.pBorder)
        % inport
        sname= ud.StageNames{selPort};
        if ~isempty(sname)
            sname= [sname,' '];
        end
        Msg    = sprintf('Set up %sinput factors',lower(sname));
        if IsPointByPoint
            NextMsg=  sprintf('%s Model',ud.StageNames{1});
        else
            NextMsg=  sprintf('%sModel',sname);
        end
    else
        % outport
        NextMsg= '';
        if p.IsMatched
            Msg= 'Build new response model';
        else
            Msg= 'Select data and build new response model';
        end
    end
elseif ~isempty(selModel)
    % model
    sname= ud.StageNames{selModel};
    if ~isempty(sname)
        sname= [sname,' '];
    end
    if IsPointByPoint
        Msg=  sprintf('Set up %s model and design experiment',lower(ud.StageNames{1}));
    else
        Msg=  sprintf('Set up %smodel and design experiment',lower(sname));
    end
    if selModel>1
        NextMsg    = sprintf('%s Inputs',ud.StageNames{selModel-1});
    else
        % select output port
        NextMsg= 'Responses';
    end
end

Msg= sprintf('{\\bfCurrent selection       :} %s',Msg);
if ~isempty(NextMsg);
    Msg = char( {Msg,sprintf('{\\bfSuggested next block:} %s',NextMsg)} );
end


function i_SummaryStats(~,~)

D= i_GetDesignDev;
if nargin<3
    Stage= get(gco,'UserData');
end

[hDOE,hAutoMatch]= i_FindDOE;
if ~isempty(hDOE) || ~isempty(hAutoMatch)
    xregerror('Error','The model statistics cannot be defined while the design editor or the data selection figure is open');
    return
end
mbH= MBrowser;
View= mbH.GetViewData;
if ~any(strcmp(get(View.hHSM.hBorder,'Selected'),'on'))
    i_HighLight(Stage)
end

d= subsref(D,substruct('()',{Stage}));
m= getModel(d);

set(View.hHSM.hStage(Stage),'FaceColor',View.hHSM.Colors.Selected);
% setup gui
[m,OK]= gui_SummaryStats(m);
set(View.hHSM.hStage(Stage),'FaceColor',View.hHSM.Colors.Model);

set(View.hHSM.hModel(Stage),'String',name(m))

if OK
    d= setmodel(d,m);
    i_PutDesignDev(d,Stage);
end