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

    function hInfo = generateEditorPages(obj, hPageGroup) %#ok<INUSL>
%GENERATEEDITORPAGES Generate a set of dialog pages for constraint editing
%
%  HINFO = GENERATEEDITORPAGES(OBJ, HPAGEGROUP) returns an arrray of
%  DialogPageInfo objects that describe a set of panels for editing the
%  constraint.

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


hInfo = mbcgui.dialog.PageInfo( ...
    'PageGroup', hPageGroup, ...
    'Name', 'Table Editor', ...
    'PreferredWidth', 500, ...
    'PreferredHeight', 250, ...
    'HelpHandler', 'mv_helptool', ...
    'HelpCode', 'xreg_Con2DTable', ...
    'CreateCallback', @i_createlyt);



function i_createlyt(hInfo, ~)
%i_createlyt create layout of 2-D edit constraint

hParent = hInfo.Parent;
hGroup = hInfo.PageGroup;
obj = hInfo.getObject;

SC = xregGui.SystemColorsDbl;
ud.FactPop = [uicontrol('Parent',hParent,...
    'Style','popupmenu',...
    'String',{},...
    'BackgroundColor',SC.WINDOW_BG,...
    'Callback',{@i_factorchange, hInfo, 1}),...
    uicontrol('Parent',hParent,...
    'Style','popupmenu',...
    'String',{},...
    'BackgroundColor',SC.WINDOW_BG,...
    'Callback',{@i_factorchange, hInfo, 2}),...
    uicontrol('Parent',hParent,...
    'Style','popupmenu',...
    'String',{},...
    'BackgroundColor',SC.WINDOW_BG,...
    'Callback',{@i_factorchange, hInfo, 3})];

ud.xBreak = mbcgui.widget.Spinner('Parent',hParent,...
    'Min',2,...
    'Rule','int',...
    'ClickIncrement',1,...
    'Callback',{@i_tablesize, hInfo, 1}, ...
    'Tag', 'XBreakpoints');
ud.yBreak = mbcgui.widget.Spinner('Parent',hParent,...
    'Min',2,...
    'Rule','int',...
    'ClickIncrement',1,...
    'Callback',{@i_tablesize, hInfo, 2}, ...
    'Tag', 'YBreakpoints');

ud.XSpace = uicontrol('Parent',hParent,...
    'Style','pushbutton',...
    'String','Span Factor Range',...
    'Callback',{@i_spacebreaks, hInfo, 1});
ud.YSpace = uicontrol('Parent',hParent,...
    'Style','pushbutton',...
    'String','Span Factor Range',...
    'Callback',{@i_spacebreaks, hInfo, 2});

ud.Ineq = uicontrol('Parent',hParent,...
    'Style','popupmenu',...
    'String',{'>=','<='},...
    'BackgroundColor',SC.WINDOW_BG,...
    'Callback',{@i_ineqchange hInfo});

% create import from cage button
importEnabled = iCanImportFromCage();
ud.ImportTable = uicontrol('Parent', hParent,...
    'Style', 'pushbutton',...
    'String', 'Import Table...',...
    'Enable', importEnabled, ...
    'Callback', {@i_importTable, hInfo}, ...
    'Tag', 'importFromCageTable');

% create 2-D editable table
P = com.mathworks.toolbox.mbc.gui.peer.EditableHeaderTablePeer;
ud.Table = mbcwidgets.javacomponent(P, ...
    'parent', hParent, ...
    'Tag', 'Table');
ud.TableEditList = handle.listener(ud.Table.Peer, 'ValueChanged', {@i_tableedit, hInfo});

% create label controls
lblXFact = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'X factor:', ...
    'ControlSize', 60, ...
    'Control', ud.FactPop(1), ...
    'Border', [0 2 0 3]);
lblYFact = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'Y factor:', ...
    'ControlSize', 60, ...
    'Control', ud.FactPop(2), ...
    'Border', [0 2 0 3]);
lblZFact = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'Z factor:', ...
    'ControlSize', 60, ...
    'Control', ud.FactPop(3), ...
    'Border', [0 2 0 3]);
lblXSize = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'Number of breakpoints:', ...
    'ControlSize', 60, ...
    'Control', ud.xBreak, ...
    'Border', [0 2 0 3]);
lblYSize = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'Number of breakpoints:', ...
    'ControlSize', 60, ...
    'Control', ud.yBreak, ...
    'Border', [0 3 0 2]);
lblIneq = xregGui.labelcontrol('Parent', hParent, ...
    'String', 'Constraint inequality:', ...
    'ControlSize', 60, ...
    'Control', ud.Ineq, ...
    'Border', [0 2 0 3]);

hExtra = addOnButton(obj,hParent,hInfo);

dividerLine = xregGui.dividerline('parent', hParent, 'Orientation', 'vertical');

grid = xreggridbaglayout(hParent, ...
    'dimension', [4 6], ...
    'rowsizes', [25 25 25 -1], ...
    'colsizes', [120 190 110 3 -1 90], ...
    'gapx', 10, ...
    'gapy', 5, ...
    'mergeblock', {[4 4], [1 6]}, ... % for table
    'mergeblock', {[3 3], [5 6]}, ... % for import button
    'mergeblock', {[1 3], [4 4]}, ... % for divider line
    'elements', {lblXFact, lblYFact, lblZFact, ud.Table, ...
    lblXSize, lblYSize, lblIneq, [], ...
    ud.XSpace, ud.YSpace,[], [], ...
    dividerLine, [], [], [], ...
    [], [], [], [], ...
    ud.ImportTable, hExtra, [], []});

ud.ObjList = event.listener(hGroup, 'ObjectChanged', @(h,evt) i_update(hInfo));
hInfo.UserData = ud;
i_setvalues(hInfo);
hInfo.setUI(grid);


function enable = iCanImportFromCage()
%iCanImportFromCage returns enable state, enabled if there are tables that
%can be imported from CAGE
names = i_findSimpleTableNames('2d');
if isempty(names)
    enable = 'off';
else
    enable = 'on';
end

function i_update(hInfo)
i_setvalues(hInfo);


function i_setvalues(hInfo)
%i_setvalues set values in the GUI from the constraint
obj = hInfo.getObject;
ud = hInfo.UserData;

AvailFact = getInputFactors(obj);
Fact = getSymbols(AvailFact);
FactIndex = getActiveIndices(obj);
set(ud.FactPop, 'String', Fact, {'Value'}, num2cell(FactIndex)');

[xB, yB, zV] = getTable(obj);
[~, ineq] = getRelation( obj );
ActFact = getActiveFactors(obj);

ud.xBreak.Value = length(xB);
ud.yBreak.Value = length(yB);
if ineq
    set(ud.Ineq, 'Value', 2);
else
    set(ud.Ineq, 'Value', 1);
end

ud.Table.Peer.setData(zV, xB, yB);
ud.Table.Peer.setAxesLabels(getSymbols(ActFact(2)), getSymbols(ActFact(1)));



function i_factorchange(src, ~, hInfo, FactIndex)
%i_factorchange change selected factor
obj = hInfo.getObject;
ud = hInfo.UserData;

newval = get(src,'Value');
OldFact = getActiveIndices(obj);
if newval~=OldFact(FactIndex)
    NF = length(get(src,'String'));
    factind2 = find(OldFact==newval);
    if ~isempty(factind2)
        % change another popup to keep each factor only used once
        avail = setdiff((1:NF), OldFact(setdiff(1:3,FactIndex)));
        set(ud.FactPop(factind2),'Value',avail(1));
        FactIndex = [FactIndex factind2];
    end
    val = get(ud.FactPop,{'Value'});
    val = [val{:}];
    obj = setActiveIndices(obj, val);

    [xB, yB, zV] = getTable(obj);
    Fact = getActiveFactors(obj);
    R = getRange(Fact);
    for n = FactIndex
        switch n
            case 1
                xB = linspace(R(1, n), R(2, n), length(xB));
            case 2
                yB = linspace(R(1, n), R(2, n), length(yB));
            case 3
                [~, ineq] = getRelation( obj );
                if ineq==1
                    zV = repmat(R(2,n), size(zV));
                else
                    zV = repmat(R(1,n), size(zV));
                end
        end
    end
    ud.Table.Peer.setData(zV, xB, yB);
    ud.Table.Peer.setAxesLabels(getSymbols(Fact(2)), getSymbols(Fact(1)));
    
    obj = setTable(obj, xB, yB, zV);
    i_updateandignore(hInfo, obj);
end


function i_tablesize(src, ~, hInfo, DimIndex)
%i_tablesize update the size of the table
obj = hInfo.getObject;
ud = hInfo.UserData;
[xB, yB, zV] = getTable(obj);
Fact = getActiveFactors(obj);
R = getRange(Fact);
NewLen = get(src, 'Value');
if DimIndex==1
    % x
    OldLen = length(xB);
    if NewLen>OldLen
        xB = [xB, i_getnewvals(xB, R(:,1), NewLen-OldLen)];
        zV = [zV, repmat(zV(:, end), 1, NewLen-OldLen)];
    elseif NewLen<OldLen
        xB = xB(1:NewLen);
        zV = zV(:, 1:NewLen);
    end
    
else
    % y
    OldLen = length(yB);
    if NewLen>OldLen
        yB = [yB, i_getnewvals(yB, R(:,2), NewLen-OldLen)];
        zV = [zV; repmat(zV(end, :), NewLen-OldLen, 1)];
    elseif NewLen<OldLen
        yB = yB(1:NewLen);
        zV = zV(1:NewLen, :);
    end
    
end
ud.Table.Peer.setData(zV, xB, yB);

obj = setTable(obj, xB, yB, zV);
i_updateandignore(hInfo, obj);


function vals = i_getnewvals(Breaks, Range, N)
%i_getnewvals calculates values that new breakpoints should have
incr = Breaks(end)-Breaks(end-1);
vals = Breaks(end)+incr.*(1:N);
vals = min(vals, Range(2));


function i_spacebreaks(~, ~, hInfo, DimIndex)
%i_spacebreaks evenly space breakpoints across the range
obj = hInfo.getObject;
ud = hInfo.UserData;
[xB, yB, zV] = getTable(obj);
Fact = getActiveFactors(obj);
if DimIndex==1
    % x
    R = getRange(Fact(1));
    xB = linspace(R(1), R(2), ud.xBreak.Value);
    ud.Table.Peer.setColumnHeaderData(xB);
else
    % y
    R = getRange(Fact(2));
    yB = linspace(R(1), R(2), ud.yBreak.Value);
    ud.Table.Peer.setRowHeaderData(yB);
end
obj = setTable(obj, xB, yB, zV);
i_updateandignore(hInfo, obj);


function i_ineqchange(~, ~, hInfo)
%i_ineqchange callback fired when constraint inequality has changed 
obj = hInfo.getObject;
ud = hInfo.UserData;
ineq = get(ud.Ineq, 'Value');
obj = setRelation(obj, ineq-1);

% If all table values are at min or max, set them appropriately for this
% orientation of inequality
Fact = getActiveFactors(obj);
R = getRange(Fact(3));
[xB, yB, zV] = getTable(obj);
TableDataChange = false;
if ineq==1
    if all(zV(:)==R(2))
        zV(:) = R(1);
        TableDataChange = true;
    end
else
    if all(zV(:)==R(1))
        zV(:) = R(2);
        TableDataChange = true;
    end
end
if TableDataChange
    obj = setTable(obj, xB, yB, zV);
    ud.Table.Peer.setData(zV);
end
i_updateandignore(hInfo, obj);


function i_importTable(~,~,hInfo)
%i_importTable Import values from a cage 2-D table


obj = hInfo.getObject;
objFactors = getInputFactors(obj);

[inds, selectedTable, ok] = matchInputsToCageTable(objFactors, '2d');

if ok
    [~, ~, breakPoints, values] = i_getTableInfo('2d', selectedTable);

    % update selected factors
    obj = setActiveIndices(obj, inds);

    % update table values
    yB = breakPoints{1};
    xB = breakPoints{2};
    obj = setTable(obj, xB, yB, values');
    ud = hInfo.UserData;
    ud.Table.Peer.setData(values', xB, yB);

    hInfo.updateObject(obj);
end


function i_tableedit(~, evt, hInfo)
%i_tableedit callback fired when editing table values
obj = hInfo.getObject;
[xB, yB, zV] = getTable(obj);

R = evt.JavaEvent.getRows;
C = evt.JavaEvent.getColumns;
NewVal = evt.JavaEvent.getDoubleArray;
if isscalar(R)  && R==-1
    % Column header edit
    xB(C+1) = NewVal;
elseif isscalar(C) && C==-1
    % Row header edit
    yB(R+1) = NewVal;
else
    % Main table edit
    zV(R+1, C+1) = NewVal;
end

obj = setTable(obj, xB, yB, zV);
i_updateandignore(hInfo, obj);


function i_updateandignore(hInfo, obj)
%i_updateandignore Update the object and prevent the change event from firing here
ud = hInfo.UserData;
ud.ObjList.Enabled = false;
hInfo.updateObject(obj);
ud.ObjList.Enabled = true;



function [names, pointers, tableIndexMapping] = i_findSimpleTableNames(type)
%i_findSimpleTableNames Find tables of correct type that can be imported
names = {};
tableIndexMapping = [];
pointers = [];
tableProviders = mbcutils.GenericTableProvider.Instance.RegisteredTableProviders;
for i=1:length(tableProviders)
    [ithNames,ithPointers] = tableProviders{i}.getTableList(type);
    names = [names; ithNames];
    numNames = length(ithNames);
    tableIndexMapping = [tableIndexMapping; [i*ones(numNames,1), (1:numNames)']];
    pointers = [pointers, ithPointers];
end


function [tableName, inputNames, breakPoints, values] = i_getTableInfo(type, index)
%i_getTableInfo Get names and values from CAGE table
tableProvider = mbcutils.GenericTableProvider.Instance.getTableProvider(index(1));
tableIndex = index(2);
[tableName, inputNames] = getTableFactorNames(tableProvider, type, tableIndex);
[breakPoints, values] = getTableValues(tableProvider, type, tableIndex);