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

    function [mout,ok]=gui_globalmodsetup(m,action,varargin)
%GUI_GLOBALMODSETUP  GUI for altering xreglinear settings
%
%  [M,OK]=GUI_GLOBALMODSETUP(M) creates a blocking GUI for choosing the
%  subclass of linear model and altering its settings.  OK indicates
%  whether the user pressed 'OK' or 'Cancel'.
%
%  LYT=GUI_GLOBALMODSETUP(M,'layout',FIG,P) creates a layout in figure
%  FIG, using the dynamic copy of a model in P.
%
%  LYT=GUI_GLOBALMODSETUP(M,'layout',FIG,P,'callback',CBSTR) attaches a
%  callback string, CBSTR, which is fired when the model definition is
%  changed.  The string may contain the tokens %MODEL% and %POINTER% which
%  will be replaced with the current model and the pointer before the
%  callback is executed.
%
%  LYT=GUI_GLOBALMODSETUP(M,'layout',FIG,P,'stepwise',false)
%  doesn't include the  stepwise controls. By default stepwise controls are
%  included.

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

if nargin<2
    action = 'figure';
end

switch lower(action)
    case 'figure'
        [mout,ok] = gui_ModelDialog(m,'Linear Model Settings', varargin{:});
    case 'layout'
        mout = i_createlyt(varargin{:});
        ok = 1;
    case 'getclasslevel'
        mout = mfilename('class');
    case 'finalise'
        mout = m;
    otherwise
        error(message('mbc:xreglinear:InvalidArgument3'));
end

function lyt = i_createlyt(figh, p, varargin)
if ~isa(figh,'xregcontainer')
    pUD = xregGui.RunTimePointer;
    pUD.LinkToObject(figh);
    
    ud= xregLinearClasses(p.info);
    ud.callback = '';
    ud.ShowStepwise = true;
    if nargin>2
        for n = 1:2:length(varargin)
            switch lower(varargin{n})
                case 'callback'
                    ud.callback = varargin{n+1};
                case 'stepwise'
                    ud.ShowStepwise = varargin{n+1};
            end
        end
    end

    ud.pointer = p;
    ud.figure = figh;
    m = p.info;
    ud.termsel = [];
    ud.popval = [];
    for n = 1:length(ud.Group);
        if isa(m,ud.Group{n})
            ud.popval = n;
            break
        end
    end
    if isempty(ud.popval)
        close(figh);
        str = sprintf('a %s, ',ud.DisplayName{1:end-1});
        error(message('mbc:xreglinear:InvalidArgument4', str( 1:end - 2 ), ud.DisplayName{ end }));
    end
    
    SC = xregGui.SystemColorsDbl;
    
    % This level controls a popup menu and term selection controls
    ud.popup = uicontrol('Style','popupmenu',...
        'Parent',figh,...
        'BackgroundColor', SC.WINDOW_BG,...
        'String',ud.DisplayName,...
        'Value',ud.popval,...
        'Interruptible','off',...
        'Tag', 'linearclass_popup',...
        'Callback',{@i_classchange, pUD});
    classLabel = xregGui.labelcontrol('Parent', figh, ...
        'String', 'Linear model subclass:', ...
        'ControlSize', 150, ...
        'LabelSize', 120, ...
        'LabelSizeMode', 'absolute', ...
        'Gap', 5, ...
        'Control', ud.popup);

    ud.optsFrame = mbcgui.container.layoutpanel(...
        'Parent', figh, ...
        'BorderType', 'etchedin', ...
        'Title','Model options');
    ud.termsFrame = mbcgui.container.layoutpanel(...
        'Parent', figh, ...
        'BorderType', 'etchedin', ...
        'Title','Model terms');
    
    ud.ntermsinfo = xreggridbaglayout(ud.termsFrame, ...
        'packstatus', 'off', ...
        'vscroll', 'on', ...
        'slidersize', 15, ...
        'dimension', [0 3], ...
        'colsizes', [-1 30 2]);
    ud.termsedt = uicontrol('Parent',ud.termsFrame,...
        'Style','pushbutton',...
        'String','Edit Terms...',...
        'Callback',{@i_termeditor, pUD},...
        'Interruptible','off');
    
    if ud.ShowStepwise
        ud.StepOptions = {'None','Minimize PRESS','Forward selection', ...
            'Backward selection','Prune'};
        ud.StepFuncs = {'leastsq', @minpress, @forwardselect, ...
            @backwardselect, @prune};
        ud.FitOptions = uicontrol('Style','popupmenu',...
            'Parent',ud.termsFrame,...
            'BackgroundColor',SC.WINDOW_BG,...
            'String',ud.StepOptions,...
            'Callback',{@i_setStepwise, pUD},...
            'Interruptible','off',...
            'Tag', 'stepwise_popup');  
        stepLabel = xregGui.labelcontrol('Parent', ud.termsFrame, ...
            'String', 'Stepwise:', ...
            'ControlSize', 1, ...
            'ControlSizeMode', 'relative', ...
            'LabelSize', 50, ...
            'LabelSizeMode', 'absolute', ...
            'Gap', 5, ...           
            'Control', ud.FitOptions);
        ud.FitOptsButton = uicontrol('Style','pushbutton',...
            'Parent',ud.termsFrame,...
            'String','Options...',...
            'Callback',{@i_setFitOpts, pUD});
        div = xregGui.dividerline('Parent', ud.termsFrame);
        ud.StepLayout = xreggridbaglayout(ud.termsFrame, ...
            'dimension', [3 2], ...
            'rowsizes', [2 20 25], ...
            'gapy', 5, ...
            'colsizes', [-1 75], ...
            'mergeblock', {[1 1], [1 2]}, ...
            'mergeblock', {[2 2], [1 2]}, ...
            'elements', {div, stepLabel, [], [], [], ud.FitOptsButton});
        StepwiseHeight = 57;
        StepwiseGap = 5;
    else
        ud.StepOptions = {};
        ud.stepFuncs = {};
        ud.FitOptions = [];
        ud.FitOptsButton = [];
        ud.StepLayout = [];
        StepwiseHeight = 0;
        StepwiseGap = 0;
    end
    
    % Create model specific layout
    innerlyt = gui_globalmodpane(m,'layout',ud.optsFrame,p, ...
        'callback', {@i_modelupdate, pUD});
    ud.layoutsdone = false(1,length(ud.Group));
    ud.layoutsdone(ud.popval) = true;
    ud.layers = xregcardlayout(ud.optsFrame, ...
        'border', [10 10 10 5], ...
        'numcards',length(ud.Group), ...
        'currentcard', ud.popval);
    attach(ud.layers, innerlyt, ud.popval);

    termsGrid = xreggridbaglayout(ud.termsFrame, ...
        'dimension', [5 2], ...
        'rowsizes', [-1 5 25 StepwiseGap StepwiseHeight], ...
        'colsizes', [-1 75], ...
        'border', [10 10 10 5], ...
        'mergeblock', {[1 1], [1 2]}, ...
        'mergeblock', {[5 5], [1 2]}, ...
        'elements', {ud.ntermsinfo, [], [], [], ud.StepLayout, [], [], ud.termsedt});
    
    set(ud.optsFrame, 'LayoutComponent', {ud.layers});
    set(ud.termsFrame, 'LayoutComponent', {termsGrid});

    lyt = xreggridbaglayout(figh, ...
        'dimension', [2 2], ...
        'rowsizes', [20 -1], ...
        'colsizes', [-1 210], ...
        'gapx', 10, ...
        'gapy', 10, ...
        'mergeblock', {[1 1], [1 2]}, ...
        'elements', {classLabel, ud.optsFrame, [], ud.termsFrame}, ...
        'userdata', pUD);
else
    lyt = figh;
    pUD = get(lyt, 'UserData');
    ud = pUD.info;
    
    % Update with new pointer
    ud.pointer = p;
    val = find(strcmp(class(p.info),ud.Group));
    if val~=ud.popval
        % Need to alter viewed sub-pane
        if ~ud.layoutsdone(val)
            % create
            attach(ud.layers, gui_globalmodpane(p.info,'layout',ud.optsFrame, ...
                ud.pointer,'callback',{@i_modelupdate, pUD}), ...
                val);
            ud.layoutsdone(val) = true;
            set(ud.layers,'packstatus','on');
        else
            % re-show
            sublyt = getcard(ud.layers,val);
            gui_globalmodpane(p.info, 'layout', sublyt{1}, ud.pointer);
        end
        set(ud.layers,'currentcard',val);
        set(ud.popup,'Value',val);
        ud.popval = val;
    else
        % re-show
        sublyt = getcard(ud.layers,val);
        gui_globalmodpane(p.info, 'layout', sublyt{1}, ud.pointer);
    end
end
pUD.info = ud;
i_termsinfo(ud);



function  i_termeditor(~,~,pUD)
% Pop open a term editing window
ud = pUD.info;
PR = xregGui.PointerRepository;
figh = ud.figure;
ptrID = PR.stackSetPointer(figh,'watch');

dlg = mbcgui.container.Dialog('Name','Term Editor',...
    'Size',[220 350],...
    'Buttons','CLOSE',...
    'Resize','off');
h = dlg.Figure;

pnl = mbcgui.container.layoutpanel('Parent', h, ...
    'BorderType', 'beveledin');
ud.termsel = term_selector(pnl, ...
    'frame.visible','off',...
    'frame.vborder',[2 0], ...
    'frame.hborder',[0 0]);
updatecommand(ud.termsel,@i_termschange,{pUD,'%MODEL'});
set(pnl, 'LayoutComponent', {ud.termsel});
dlg.Content = pnl;
pUD.info = ud;

model(ud.termsel,ud.pointer.info);
dlg.showDialog();
PR.stackRemovePointer(figh,ptrID);

function i_termschange(pUD,m)
% return function for term editing window
ud = pUD.info;
ud.pointer.info = m;
i_termsinfo(ud);
i_firecb(ud.callback,ud.pointer);


function  i_modelupdate(~, ~, pUD)
% update term info due to changes in options pane
ud = pUD.info;
PR = xregGui.PointerRepository;
figh = ud.figure;
ptrID = PR.stackSetPointer(figh,'watch');
i_termsinfo(ud);
if ~isempty(ud.callback)
    i_firecb(ud.callback,ud.pointer);
end
PR.stackRemovePointer(figh,ptrID);


function i_classchange(~, ~, pUD)
% need to create new model, copy parent model class over it
ud = pUD.info;
figh = ud.figure;
PR = xregGui.PointerRepository;
ptrID = PR.stackSetPointer(figh,'watch');

val = get(ud.popup,'Value');
oldm = ud.pointer.info;
newm = xregCreateModel(ud.fCreate{val},oldm);
ud.pointer.info = newm;

% update term_selector
i_termsinfo(ud);

% update model dependent_pane
if ~ud.layoutsdone(val)
    % create
    attach(ud.layers,gui_globalmodpane(newm,'layout',ud.optsFrame,ud.pointer, ...
        'callback', {@i_modelupdate, pUD}),val);
    ud.layoutsdone(val) = true;
    set(ud.layers,'packstatus','on');
else
    % re-show
    lyt = getcard(ud.layers,val);
    gui_globalmodpane(newm,'layout',lyt{1},ud.pointer);
end
% flick cards
set(ud.layers,'currentcard',val);
ud.popval = val;
pUD.info = ud;
if ~isempty(ud.callback)
    i_firecb(ud.callback,ud.pointer);
end
PR.stackRemovePointer(figh,ptrID);


function val = i_stepwise(ud)
m = ud.pointer.info;
om = getFitOpt(m);
if ischar(om) && strcmp(om,'leastsq') || strcmp(getname(om),'Least Squares');
    % No stepwise
    val = 1;
else
    nm = getname(om);
    AllOpts = get(ud.FitOptions,'String');
    val =  find( strncmp( nm,AllOpts,3 ) ) ;
end


function i_setStepwise(~, ~, pUD)
ud = pUD.info;
m = ud.pointer.info;
opt = get(ud.FitOptions,'Value');
if i_stepwise(ud)~=opt
    if opt==1
        om = lsqom(m);
        set(ud.FitOptsButton,'Enable','off');
    else
        om = feval(ud.StepFuncs{opt}, m);
        set(ud.FitOptsButton,'Enable','on');
    end
    m = setFitOpt(m,om);
    ud.pointer.info = m;
    i_firecb(ud.callback,ud.pointer);
end


function i_setFitOpts(~, ~, pUD)
ud = pUD.info;
m = ud.pointer.info;
om = getFitOpt(m);
[om,ok] = gui_setup(om,'figure');
if ok
    m = setFitOpt(m,om);
    ud.pointer.info = m;
    i_firecb(ud.callback, ud.pointer);
end


% Update the information in the Terms frame
function i_termsinfo(ud)
if ud.ShowStepwise
    stepval = i_stepwise(ud);
    set(ud.FitOptions, 'Value', stepval);
    if stepval==1
        set(ud.FitOptsButton, 'Enable', 'off');
    else
        set(ud.FitOptsButton, 'Enable', 'on');
    end
end

% update the info on the number of terms
[~,trmsorder,strs] = termorder(ud.pointer.info);
trms = cumsum(terms2(ud.pointer.info));

el = get(ud.ntermsinfo,'elements');
el = [el{:}];
nr = length(trmsorder)+1;
nreq = (nr)*2;
if length(el)<nreq
    % make more controls
    for n = (length(el)+1):nreq
        el(n) = uicontrol('Parent',ud.termsFrame, ...
            'Enable', 'inactive', ...
            'Style','text');
    end
elseif length(el)>nreq
    % delete some controls
    delete(el((nreq+1):end));
    el = el(1:nreq);
end

set(el(1:nr-1),{'String'},strs(:), ...
    'HorizontalAlignment','left', ...
    'FontWeight','normal');
set(el(nr),'String','Total number of terms:', ...
    'HorizontalAlignment','left',...
    'FontWeight','bold');
vals = [trms(trmsorder(1)); diff(trms(cumsum(trmsorder)))];
set(el(nr+1:end-1),{'String'},num2cell(vals(:),2), ...
    'HorizontalAlignment','right', ...
    'FontWeight','normal');
set(el(end),'String',trms(end), ...
    'HorizontalAlignment','right', ...
    'FontWeight','bold');

el = num2cell(el(:),2);

set(ud.ntermsinfo,'dimension',[nr+1 3],...
    'gap',5, ...
    'rowsizes',[repmat(15,1,nr-1) 5 15],...
    'elements',[el(1:nr-1); {[]}; el(nr:end-1); {[]}; el(end)]);


function i_firecb(cbstr,ptr)
% parse callback string and execute it
if ~isempty(cbstr)
    % parse for %MODEL% and %POINTER% 
    if ischar(cbstr)
        pcs=strfind(cbstr,'%');
        go=1;
        needobj=0;
        needval=0;
        while (go<=(length(pcs)-1))
            cmp=cbstr(pcs(go)+1:pcs(go+1)-1);
            if strcmp(cmp,'POINTER')
                needval=1;
                cbstr=[cbstr(1:pcs(go)-1) 'XX_POINTER_XX' cbstr(pcs(go+1)+1:end)];
                go=go+2;
                pcs=pcs+6;
            elseif strcmp(cmp,'MODEL')
                needobj=1;
                cbstr=[cbstr(1:pcs(go)-1) 'XX_MODEL_XX' cbstr(pcs(go+1)+1:end)];
                go=go+2;
                pcs=pcs+6;
            else
                go=go+1;
            end
        end

        if needobj
            assignin('base','XX_MODEL_XX',ptr.info);
        end
        if needval
            assignin('base','XX_POINTER_XX',ptr);
        end
        evalin('base',cbstr);
        
        % clear up base workspace
        evalin('base','clear(''XX_MODEL_XX'',''XX_POINTER_XX'');');
    else
        xregcallback(cbstr, [] , struct('ModelPointer', ptr));
    end
end