www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/@xregoptmgr/gui_setup.m

    function [out1, OK] = gui_setup(Omgr,action, displayoptions, varargin)
%GUI_SETUP  GUI for altering xregoptmgr settings
%
%  [Omgr,OK] = GUI_SETUP(Omgr, 'figure', DISPLAYOPTS, varargin) creates a
%  blocking GUI for choosing the xregoptmgr options and altering its
%  settings.  OK indicates whether the user pressed 'OK' or 'CANCEL'.
%  DISPLAYOPTS is a cell array that contains named parameter/value pairs.
%  The following parameter/value pairs may be specified:
%
%      'expanded'      [true]/false.  Initially expand tree.
%      'title'         String.  Figure label.
%      'topname'       String.  Top-level algorithm name.
%      'basiclayout'   true/[false].  Show only basic options.
%
%  LYT = GUI_SETUP(Omgr, 'layout', DISPLAYOPTS, FIG, P, varargin) creates a
%  layout object in the figure FIG which updates the dynamic copy of a
%  model in the pointer P.

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


switch action
    case 'figure'
        if nargin < 3
            displayoptions = {};
        end
        if isempty(varargin) && ~isempty(Omgr.Context)
            % context implementation so need a context class
            Args = {feval(Omgr.Context)};
        else
            Args = varargin;
        end
        [Omgr, OK] = i_createfig(Omgr, displayoptions, Args{:});
        out1 = Omgr;
    case 'layout'
        hFig = varargin{1};
        p = varargin{2};
        if nargin >5
            otherArgs = varargin(3:end);
        else
            otherArgs = {};
        end
        if isempty(displayoptions)
            displayoptions = {};
        end
        s = i_getdisplayopts(p.info, displayoptions{:});

        lyt = i_createlyt(hFig, p, s, otherArgs{:});
        set(lyt,'Visible','on');
        out1 = lyt;
        OK = 1;
    case 'updatelayout'
        lyt = varargin{1};
        p = varargin{2};
        if nargin >5
            otherArgs = varargin(3:end);
        else
            otherArgs = {};
        end        
        
        if nargin < 3
            displayoptions = {};
        end
        s = i_getdisplayopts(p.info, displayoptions{:});
        updateLayout(lyt, p, s, otherArgs{:});
        out1= lyt;
        OK = 1;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Omgr, OK] = i_createfig(Omgr, displayoptions, varargin)

if isempty(displayoptions)
    displayoptions = {};
end
s = i_getdisplayopts(Omgr, displayoptions{:});

% create the figure to display the xregoptmgr results
dlg= mbcgui.container.Dialog('Name', s.Title,...
    'Size',[500 500],...
    'Buttons','OK_CANCEL',...
    'Tag','OptimMgrGui');

hFig = dlg.Figure;
p=xregGui.RunTimePointer(Omgr);
LinkToObject(p,hFig);

dlg.Content = i_createlyt(hFig, p, s, varargin{:});


closeMode = dlg.showDialog();
switch lower(closeMode)
    case 'ok'
        Omgr=p.info;
        OK=1;
    otherwise
        OK=0;
end
delete(dlg);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function treepanel = i_createlyt(hFig, p, sOpts, varargin)
% create a gridlayout for the xregoptmgr pointed to by p
% topname will provide a label for the top level xregoptmgr

Omgr = p.info;
ud.pointer = p;
ud.figure = hFig;
ud.expandflag = sOpts.ExpandTree;
ud.basiclayout = sOpts.BasicOptions;

treepanel = mbcgui.container.layoutpanel(...
    'Parent', hFig, ...
    'BorderType', 'beveledin');

% if the optmgr name, and the option parameter are the same,
% and there are no alternative algorithms
% then don't display the popup
if isequal(sOpts.TopAlg, getname(Omgr)) && isempty(Omgr.Alternatives)
    ctrl = [];
else
    ctrl= AltSetupUI(Omgr,treepanel,varargin{:});
    ctrl=ctrl{1};
end

udh=xregGui.labelcontrol('parent',treepanel,...
    'LabelSizeMode','absolute',...
    'LabelSize',240,...
    'ControlSize',150,...
    'border',[0 2 0 2]);


if ~isempty(ctrl)
    % If a control will be displayed, use a colon
    set(udh, 'String',[sOpts.TopAlg ':']);
    % get enabling from control
    set(udh, 'Enable', get(ctrl, 'Enable'));
    % popup menu callback
    set(ctrl,'Callback',[{@i_setAlternatives,udh,[]}, varargin]); 
else
    set(udh, 'String', sOpts.TopAlg);
end

set(udh, 'Control', ctrl);

% Create a tree
tree = xregGui.tree('parent',treepanel,...
    'NodeHeight',24);
tree.PerformDraw = 'off';

root = tree.addNode([],[], sOpts.TopAlg, udh);

% put the tree in user data
ud.tree = tree;
ud.treepanel = treepanel;
ud.root = root;
set(udh, 'UserData', ud);

% a string of the option names for the parent omgrs to help with setting options
OmgrsOptNames = [];
addOptionNodes(tree, root, Omgr, udh, OmgrsOptNames, varargin{:});
if ud.expandflag
    root.expand;
    for i =1:length(tree.nodes)
        tree.nodes(i).expand;
    end
end

set(mbcgui.hgclassesutil.toHandle(treepanel), 'LayoutComponent', tree,'UserData',udh,'LayoutBorder',[2 3 1 3]);


tree.PerformDraw = 'on';
tree.redraw;


function updateLayout(lyt, p, sOpts, varargin)

udh = get(lyt,'UserData');
ud = get(udh,'UserData');
tree = ud.tree;


for i=2:length(tree.Nodes)
    % delete all children
    delete(tree.Nodes(i).Layout)
end

tree.clear;
drawnow
tree.PerformDraw = 'off';

root = tree.addNode([],[], sOpts.TopAlg, udh);

Omgr = p.info;
% a string of the option names for the parent omgrs to help with setting options
OmgrsOptNames = [];
addOptionNodes(tree, root, Omgr, udh, OmgrsOptNames, varargin{:});
if ud.expandflag
    root.expand;
    for i =1:length(tree.nodes)
        tree.nodes(i).expand;
    end
end

tree.PerformDraw = 'on';
tree.redraw;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function addOptionNodes(tree, leaf, Omgr, udh, OmgrsOptNames, varargin)
% add the options of Omgr to the tree, attaching them to the leaf

ud = get(udh,'UserData');
basiclayout = ud.basiclayout;

if ~isempty(Omgr.foptions)
    if basiclayout
        gs= find([Omgr.foptions.GuiSetable]==2);
    else
        gs= find([Omgr.foptions.GuiSetable]);
    end
else
    gs = [];
end
n= length(gs);

nodes = cell(n,1);

% set up the flow layouts for each of the options
for i=1:n
    opt= Omgr.foptions(gs(i));
    % add the name of the option
    if ~isempty(OmgrsOptNames)
        ParamName = [OmgrsOptNames '.' opt.Param];
    else
        ParamName = opt.Param;
    end

    cstr= opt.CheckInput;
    if iscell(cstr)
        cstr = cstr{1};
    end

    h = i_labelcontrol(udh, opt, ParamName, varargin{:});

    % add a child node to leaf with full tag OmgrsOptNames.opt.Param and layout h
    nodes{i} = tree.addNode(leaf, tree.relChild, ParamName, h);

    % if we are adding an optmgr recurse inwards and add options
    if strcmpi(cstr, 'xregoptmgr')
        addOptionNodes(tree, nodes{i}, opt.Value,udh, ParamName, varargin{:});
    end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function h = i_labelcontrol(udh, opt, ParamName, varargin)

ud = get(udh, 'UserData');
Parent = ud.treepanel;

% create the label control for the options
ctrl=i_OptProps(udh,opt,ParamName, varargin{:});
if iscell(ctrl)
    ctrl=ctrl{1};
end
h=xregGui.labelcontrol('parent',Parent,...
    'LabelSizeMode','absolute',...
    'LabelSize',240,...
    'ControlSize',150,...
    'visible','off',...
    'border',[0 2 0 2]);

nm= opt.Name;
if isempty(nm)
    nm= opt.Param;
end

% If a control will be displayed, use a colon
if ~isempty(ctrl) && ~strcmp(get(ctrl, 'Style'), 'checkbox')
    set(h, 'String',[nm ':']);
    % get enabling from control
    set(h, 'Enable', get(ctrl, 'Enable'));
else
    set(h, 'String',nm);
end

set(h, 'control', ctrl);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function  h= i_OptProps(udh,opt,ParamName,varargin)

ud = get(udh,'UserData');
Parent = ud.treepanel;

h={};
cstr= opt.CheckInput;
if iscell(cstr)
    cstr = cstr{1};
end
if ~isempty(cstr) && ischar(cstr)
    if ~isempty(strfind(cstr,'|'))
        cstrCell = textscan( cstr, '%s','delimiter', '|' );
        cstrCell = cstrCell{1};
        sp = find( strcmp( opt.Value,cstrCell  ));
        Props= {'style','popupmenu',...
            'string',cstr,...
            'Callback',{@i_setEnumerated,udh,ParamName}...
            'value',sp};
    else
        switch lower(cstr)
            case {'numeric','int'}
                Props= {'style','edit',...
                    'Callback',{@i_setValue,udh,ParamName}...
                    'string',opt.Value};
            case 'vector'
                Props= {'style','edit',...
                    'Callback',{@i_setVector,udh,ParamName}...
                    'string',prettify(opt.Value)};
            case 'range'
                Props= {'style','edit',...
                    'Callback',{@i_setRange,udh,ParamName}...
                    'string',num2str(opt.Value)};
            case 'boolean'
                Props= {'style','checkbox',...
                    'Callback',{@i_setBoolean,udh,ParamName},...
                    'BackGroundColor',get(0,'DefaultUicontrolBackgroundColor'),...
                    'value',opt.Value};
            case 'evalstr'
                Props= {'style','edit',...
                    'Callback',{@i_setChar,udh,ParamName}...
                    'string',opt.Value{1}};
            case 'char'
                Props= {'style','edit',...
                    'Callback',{@i_setChar,udh,ParamName}...
                    'string',opt.Value};
            case 'xregoptmgr'
                h= AltSetupUI(opt.Value,Parent,varargin{:});
                % if the optmgr name, and the option parameter are the same,
                % and there are no alternative algorithms
                % then don't display the popup
                if isequal(getname(opt.Value),opt.Param) && isempty(opt.Value.Alternatives)
                    h = [];
                end
                if ~isempty(h) && ~isempty(opt.Value.Alternatives)
                    % popup menu callback
                    set(h{1},'Callback',[{@i_setAlternatives,udh,ParamName}, varargin]);
                end
                Props=[];
            otherwise
                str= evalc('disp(opt.Value)');
                Props= {'style','text',...
                    'string',str};
        end
    end
else
    str= evalc('disp(opt.Value)');
    Props= {'style','text',...
        'string',str};
end

if ~isempty(Props)
    if isgraphics(Parent, 'figure') || isgraphics(Parent, 'uipanel')
        h{1}= uicontrol('Parent',Parent,...
            'HorizontalAlignment','Left',...
            'BackgroundColor','w',...
            'Visible','off',...
            Props{:});
    else
        set(Parent,Props{:});
    end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setEnumerated(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
i= get(h,'Value');
cstr= get(h,'String');
switch class(cstr)
    case 'char'
        if size(cstr,1)>1
            val= strtrim(cstr(i,:));
        else
            pbar= [1 strfind(cstr,'|') length(cstr+1)];
            val= cstr(pbar(i):pbar(i+1));
        end
    case 'cell'
        val= cstr{i};
end
set(Omgr,Param,val);
p.info = Omgr;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setValue(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
try
    val= evalin('base',get(h,'String'));
catch ME %#ok<NASGU>
    xregerror('Input Error', ['Scalar numerical input is required for ',Param]);
    set(h,'String',get(Omgr,Param));
    return
end

try
    set(Omgr,Param,val);
catch ME
    xregerror('Input Error',ME.message);
    set(h,'String',get(Omgr,Param));
end
p.info = Omgr;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setVector(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
str = get(h,'String');
val= str2num(str); %#ok<ST2NM>
if ~isempty(str) && isempty(val)
    xregerror( 'Input Error',['Numeric values are required for ',Param]);
    set(h,'String',prettify(get(Omgr,Param)));
else
    try
        set(Omgr,Param,val);
catch ME
    xregerror('Input Error',ME.message);
        set(h,'String',prettify(get(Omgr,Param)));
    end
    p.info = Omgr;
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setRange(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
try
    val= str2num(get(h,'String')); %#ok<ST2NM>
    set(Omgr,Param,val);
catch ME
    xregerror('Input Error',ME.message);
    set(h,'String',num2str(get(Omgr,Param)));
end
p.info = Omgr;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setChar(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
try
    val= get(h,'String');
    set(Omgr,Param,val);
catch ME
    xregerror('Input Error',ME.message);
    set(h,'String',num2str(get(Omgr,Param)));
end
p.info = Omgr;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_setBoolean(h,~,udh,Param)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr = p.info;
val= get(h,'Value');
set(Omgr,Param,val);
p.info = Omgr;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function i_setAlternatives(h,~,udh, Param, varargin)

ud=get(udh,'UserData');
p = ud.pointer;
Omgr =p.info;
tree = ud.tree;
val=get(h,'Value');


if ~isempty(Param)
    OldOM = get(Omgr, Param);
else % we are at the top level
    OldOM = Omgr;
end

if isempty(OldOM.Alternatives) % no change possible
    return
end

[NewOM,OK]=  feval(OldOM.Alternatives{val},varargin{:});
% copy alternatives
if OK
    NewOM.Alternatives= OldOM.Alternatives;
    if ~isempty(Param)
        % change the suboptmgr
        set(Omgr,Param, NewOM);
        p.info = Omgr;
    else % change the toplevel optmgr
        p.info = NewOM;
    end

    % find the node that contains the optmgr
    if isempty(Param) % when we are at the top level
        node = tree.Nodes(1);
    else
        for i = 1:length(tree.Nodes)
            if strcmp(tree.Nodes(i).Tag, Param)
                node = tree.Nodes(i);
            end
        end
    end

    % delete the tree nodes children
    i_deletechildren(node);

    % add the new tree nodes
    addOptionNodes(tree, node, NewOM, udh, Param, varargin{:});

    set(udh, 'UserData', ud);

    if ud.expandflag
        while ~isempty(node)
            node.expand;
            node = node.down;
        end
    end

    tree.redraw;
else
    % alternative not valid
    msgbox('The new alternative is not valid');
    val= find(strcmp(OldOM.name,OldOM.Alternatives));
    set(h,'Value',val(1));
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function i_deletechildren(node)

while ~isempty(node.down)
    i_deletechildren(node.down)
    delete(node.down.layout);
    delete(node.down);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function s = i_getdisplayopts(om, varargin)
s = struct('ExpandTree', true, ...
    'Title', 'Optimization Setup', ...
    'TopAlg', getname(om), ...
    'BasicOptions', false);

for n = 1:2:length(varargin)
    switch lower(varargin{n})
        case 'title'
            s.Title = varargin{n+1};
        case 'expanded'
            s.ExpandTree = varargin{n+1};
        case 'topname'
            s.TopAlg = varargin{n+1};
        case 'basiclayout'
            s.BasicOptions = varargin{n+1};
        otherwise
            error(message('mbc:xregoptmgr:InvalidArgument1', varargin{ n }));
    end
end