www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cageview/+optim/InputValuesTableView.m

    classdef InputValuesTableView < mbcgui.multiview.View
    %cageview.optim.InputValuesTableView class
    %   cageview.optim.InputValuesTableView extends mbcgui.multiview.View.
    %
    %    cageview.optim.InputValuesTableView properties:
    %       Parent - Property is of type 'MATLAB array'
    %       Position - Property is of type 'rect'
    %       Enable - Property is of type 'on/off'
    %       Visible - Property is of type 'on/off'
    %       Userdata - Property is of type 'MATLAB array'
    %       Tag - Property is of type 'string'
    %       Display - Property is of type 'MATLAB array' (read only)
    %       MessageService - Property is of type 'handle'
    %       Options - Property is of type 'handle vector'
    %       Actions - Property is of type 'handle vector'
    %       UIContextMenu - Property is of type 'MATLAB array'
    %
    %    cageview.optim.InputValuesTableView methods:
    %       copy - Execute a copy to the clipboard
    %       deleteRows - Delete selected runs.
    %       duplicateRows - Duplicate selected runs.
    %       paste - Execute a paste from the clipboard
    
    %  Copyright 2005-2015 The MathWorks, Inc.
    
    properties (Access=protected, AbortSet)
        %FREEVARIABLEPOINTERS Property is of type 'MATLAB array'
        FreeVariablePointers = [];
        %FIXEDVARIABLEPOINTERS Property is of type 'MATLAB array'
        FixedVariablePointers = [];
        %HFREETABLE Property is of type 'handle'
        hFreeTable = [];
        %HFIXEDTABLE Property is of type 'handle'
        hFixedTable = [];
        %HVIEWCHOOSER Property is of type 'handle'
        hViewChooser = [];
        %HNUMRUNS Property is of type 'handle'
        hNumRuns = [];
        %CURRENTSELECTION Property is of type 'MATLAB array'
        CurrentSelection = struct( 'Table', '', 'Rows', [  ], 'Columns', [  ] );
    end
    
    methods  % constructor block
        function obj = InputValuesTableView(varargin)
        %INPUTVALUESTABLEVIEW Constructor for InputValuesTableView
        %  OBJ = INPUTVALUESTABLEVIEW(PROP, VALUE) constructs a class that is the
        %  base class for tables that edit initial value data for an optimization.
        
        % Call the inherited constructor
        obj@mbcgui.multiview.View(varargin{ : }); % converted super class constructor call
        
        % Create tables
        freePane = mbcgui.container.titlebarpanel(...
            'Parent', obj.Parent,...
            'BarTitle','Free Variables');
        
        P = com.mathworks.toolbox.mbc.gui.peer.OptimVectorTablePeer;
        obj.hFreeTable = mbcwidgets.Table2D(P, ...
            'Parent', freePane, ...
            'UIContextMenu',obj.UIContextMenu,...
            'Editable', true);
        obj.hFreeTable.Peer.setTableName( 'FreeValuesTable' );
        obj.hFreeTable.Peer.setBorder([]);
        obj.hFreeTable.Peer.setDisplayMode(1);
        obj.addListeners([ ...
            handle.listener(obj.hFreeTable.Peer, 'VectorChanged', {@i_editvalue, obj, 'free'}); ...
            handle.listener(obj.hFreeTable.Peer, 'MousePressed', {@i_passonbtndown, obj}); ...
            handle.listener(obj.hFreeTable, 'SelectionChanged', {@i_selchange, obj, 'free'}); ...
            ]);
        set(freePane, 'ContentHandle', obj.hFreeTable);
        
        fixedPane = mbcgui.container.titlebarpanel(...
            'Parent', obj.Parent,...
            'BarTitle','Fixed Variables');
        
        P = com.mathworks.toolbox.mbc.gui.peer.OptimVectorTablePeer;
        obj.hFixedTable = mbcwidgets.Table2D(P, ...
            'Parent', fixedPane, ...
            'UIContextMenu',obj.UIContextMenu,...
            'Editable', true);
        obj.hFixedTable.Peer.setTableName( 'FixedValuesTable' );
        obj.hFixedTable.Peer.setBorder([]);
        obj.hFixedTable.Peer.setDisplayMode(1);
        obj.addListeners([ ...
            handle.listener(obj.hFixedTable.Peer, 'VectorChanged', {@i_editvalue, obj, 'fixed'}); ...
            handle.listener(obj.hFixedTable.Peer, 'MousePressed', {@i_passonbtndown, obj}); ...
            handle.listener(obj.hFixedTable, 'SelectionChanged', {@i_selchange, obj, 'fixed'}); ...
            ]);
        set(fixedPane, 'ContentHandle', obj.hFixedTable);
        
        topPanel = mbcgui.container.layoutpanel(...
            'Parent', obj.Parent, ...
            'BorderType', 'etchedin');
        
        % Create number of runs control
        hEditor = mbcgui.widget.Spinner('Parent', topPanel, ...
            'Value', 1, ...
            'Min',1, ...
            'Rule', 'int', ...
            'Callback', {@i_setnumruns, obj});
        obj.hNumRuns = xregGui.labelcontrol('Parent', topPanel, ...
            'ControlSizeMode', 'absolute', ...
            'ControlSize', 60, ...
            'LabelSizeMode', 'absolute', ...
            'LabelSize', 90, ...
            'String', 'Number of runs:', ...
            'Control', hEditor);
        
        % Create view switching control
        SC = xregGui.SystemColorsDbl;
        hChooser = uicontrol('Parent', topPanel, ...
            'Style', 'popupmenu', ...
            'String', {'Compact', 'Expanded vertically', 'Expanded horizontally'}, ...
            'Value', 2, ...
            'BackgroundColor', SC.WINDOW_BG, ...
            'Callback', {@i_settablemode, [obj.hFreeTable obj.hFixedTable]});
        obj.hViewChooser = xregGui.labelcontrol('Parent', topPanel, ...
            'ControlSizeMode', 'relative', ...
            'ControlSize', 1, ...
            'LabelSizeMode', 'absolute', ...
            'LabelSize', 110, ...
            'String', 'Vector display format:', ...
            'Control', hChooser);
        
        grd = xreggridbaglayout(topPanel, ...
            'dimension', [1 2], ...
            'colsizes', [160 250], ...
            'rowsizes', 20, ...
            'border', [4 6 4 6], ...
            'elements', {obj.hNumRuns, obj.hViewChooser});
        set(topPanel, 'LayoutComponent', {grd});
        
        tblSplit = xregsplitlayout(obj.Parent, ...
            'orientation', 'lr', ...
            'dividerwidth', 4, ...
            'dividerstyle', 'flat', ...
            'left', freePane, ...
            'right', fixedPane);
        L = xreggridbaglayout(obj.Parent, ...
            'dimension', [3 1], ...
            'rowsizes', [36 2 -1], ...
            'elements', {topPanel, [], tblSplit});
        obj.ContentHandle = L;
        
        % Hook up to the message service if it exists
        if ~isempty(obj.MessageService)
            obj.pPostSetMessageService;
        end
        
        % Create copy/paste actions
        cpAG = mbcgui.actions.ActionGroup('', '&Clipboard');
        cpAG.MenuType = 'separate';
        A1 = mbcgui.actions.Action({@i_copy, obj}, '&Copy');
        A2 = mbcgui.actions.Action({@i_paste, obj}, '&Paste');
        cpAG.Actions = [A1 A2];
        
        % Create input editing actions
        editAG = mbcgui.actions.ActionGroup('', '&Inputs');
        editAG.MenuType = 'separate';
        A1 = mbcgui.actions.StatefulAction({@i_duplicate, obj}, '&Duplicate Runs');
        A2 = mbcgui.actions.StatefulAction({@i_delete, obj}, 'D&elete Runs');
        A3 = mbcgui.actions.StatefulAction({@i_fill, obj}, '&Fill All Runs');
        editAG.Actions = [A1 A2 A3];
        set(editAG.Actions, 'Enabled', false);
        
        ms = obj.MessageService;
        importAG = mbcgui.actions.ActionGroup('', '&Inputs');
        importAG.MenuType = 'separate'; 
        importAG.Actions = [ms.Actions.ImportDataset ms.Actions.ImportOutput];
        obj.Actions.Actions = [cpAG; editAG; importAG];
        
        uic = uicontextmenu(ancestor(obj.Parent,'figure'));
        createMenuItem(obj.Actions,uic);
        obj.UIContextMenu = uic;
        
        end  % InputValuesTableView
        
    end  % constructor block
    
    methods  % public methods
        %----------------------------------------
        function copy(obj)
        %COPY Execute a copy to the clipboard
        %   COPY(OBJ) copies the data from the current selection to the clipboard
        
        if obj.hasData
            if strcmp(obj.CurrentSelection.Table, 'free')
                hT = obj.hFreeTable;
            elseif strcmp(obj.CurrentSelection.Table, 'fixed')
                hT = obj.hFixedTable;
            else
                hT = [];
            end
            if ~isempty(hT)
                hT.Peer.copy;
            end
        end
        
        end  % copy
        
        %----------------------------------------
        function deleteRows(obj)
        %DELETEROWS Delete selected runs.
        %   DELETEROWS(OBJ) deletes the currently selected runs in the table.
        
        if obj.hasData ...
                && ~isempty(obj.CurrentSelection.Table) ...
                && ~isempty(obj.CurrentSelection.Rows)
            
            optim = obj.MessageService.getOptim;
            optim = removeRuns(optim, obj.CurrentSelection.Rows);
            obj.MessageService.setOptim(optim, 'inputvalue');
        end
        
        end  % deleteRows
        
        %----------------------------------------
        function duplicateRows(obj)
        %DUPLICATEROWS Duplicate selected runs.
        %   DUPLICATEROWS(OBJ) duplicates the currently selected runs in the table.
        
        if obj.hasData ...
                && ~isempty(obj.CurrentSelection.Table) ...
                && ~isempty(obj.CurrentSelection.Rows)
            
            optim = obj.MessageService.getOptim;
            optim = duplicateinitialvaluedata(optim, obj.CurrentSelection.Rows);
            obj.MessageService.setOptim(optim, 'inputvalue');
        end
        
        end  % duplicateRows
        
        %----------------------------------------
        function paste(obj)
        %PASTE Execute a paste from the clipboard
        %   PASTE(OBJ) pastes data from the clipboard to the current table
        %   selection.
        
        if obj.hasData
            if strcmp(obj.CurrentSelection.Table, 'free')
                hT = obj.hFreeTable;
            elseif strcmp(obj.CurrentSelection.Table, 'fixed')
                hT = obj.hFixedTable;
            else
                hT = [];
            end
            if ~isempty(hT)
                hT.Peer.paste;
            end
        end
        
        end  % paste
        
    end  % public methods
    
    methods (Access=protected)
        %----------------------------------------
        function pFillAllRuns(obj)
        %PFILLALLRUNS Fill entire columns from selection
        %   PFILLALLRUNS(OBJ) fills an entire column of variable values from the
        %   seleted row, for the selected columns.  If more than one row is
        %   selected, nothing is done.
        
        if obj.hasData ...
                && ~isempty(obj.CurrentSelection.Table) ...
                && length(obj.CurrentSelection.Rows)==1 ...
                && ~isempty(obj.CurrentSelection.Columns)
            
            if strcmp(obj.CurrentSelection.Table, 'free')
                pInp = obj.FreeVariablePointers;
            elseif strcmp(obj.CurrentSelection.Table, 'fixed')
                pInp = obj.FixedVariablePointers;
            else
                pInp = mbcpointer(1,0);
            end
            
            optim = obj.MessageService.getOptim;
            RunIdx = obj.CurrentSelection.Rows;
            ColIdx = obj.CurrentSelection.Columns;
            for n = 1:length(ColIdx)
                Data = getinitialvaluedata(optim, pInp(ColIdx(n)));
                optim = setinitialvaluedata(optim, ...
                    pInp(ColIdx(n)), 1:getNumRuns(optim), Data{1}(RunIdx,:));
            end
            obj.MessageService.setOptim(optim, 'inputvalue');
        end
        
        end  % pFillAllRuns
        
        %----------------------------------------
        function pFillTable(obj, TableToUpdate)
        %PFILLTABLE Refresh the table contents
        %  PFILLTABLE(OBJ) refreshes the data that is being displayed in the table.
        
        if nargin<2 || strcmp(TableToUpdate, 'all')
            TableToUpdate = {'fixed', 'free'};
        end
        
        if obj.hasData
            optim = obj.MessageService.getOptim;
            if ismember('free', TableToUpdate);
                obj.FreeVariablePointers = getfreevalues(optim);
                i_settabledata(optim, obj.hFreeTable, obj.FreeVariablePointers);
            end
            if ismember('fixed', TableToUpdate);
                obj.FixedVariablePointers = getfixedvalues(optim);
                i_settabledata(optim, obj.hFixedTable, obj.FixedVariablePointers);
            end
        else
            if ismember('free', TableToUpdate);
                obj.FreeVariablePointers = mbcpointer(1,0);
                obj.hFreeTable.Peer.clear;
            end
            if ismember('fixed', TableToUpdate);
                obj.FixedVariablePointers = mbcpointer(1,0);
                obj.hFixedTable.Peer.clear;
            end
        end
        
        if ismember(obj.CurrentSelection.Table, TableToUpdate)
            % Reset selection to empty if the current selection table has been
            % redrawn.
            obj.pSelectionChange('', [], []);
        end
        end  % pFillTable
        
        %----------------------------------------
        function [pFree, pFixed] = pGetDisplayedVariables(obj)
        %PGETDISPLAYEDVARIABLES Get list of currently displayed variable pointers.
        %   [PFREE, PFIXED] = PGETDISPLAYEDVARIABLES(OBJ) returns the list of
        %   currently displayed variable pointers.
        
        pFree = obj.FreeVariablePointers;
        pFixed = obj.FixedVariablePointers;
        
        end  % pGetDisplayedVariables
        
        %----------------------------------------
        function pPostSetMessageService(obj)
        %PPOSTSETMESSAGESERVICE Method that is called when the message service is set
        %  PPOSTSETMESSAGESERVICE(OBJ) is called in response to a new message
        %  service being set in the object.
        
        pPostSetMessageService@mbcgui.multiview.View(obj);
        
        obj.addMessageServiceListener( {'InputValueChanged', 'ConstraintChanged', 'ObjectiveChanged', 'DatasetChanged'}, ...
            {{@i_redraw, obj}, {@i_redrawfixed, obj}, {@i_redrawfixed, obj}, {@i_redrawfixed, obj}});
        
        % Redraw now
        obj.pFillTable;
        obj.pUpdateRuns;
        end  % pPostSetMessageService
        
        %----------------------------------------
        function pSelectionChange(obj, Table, Rows, Cols)
        %PSELECTIONCHANGE Update the selected region information.
        %   PSELECTIONCHANGE(OBJ, TABLE, ROWS, COLS) sets the selected region
        %   information as being the specified rows and columns in the specified
        %   table.  The other table's selection is cleared.
        
        SelInfo = struct('Table', Table, ...
            'Rows', Rows, ...
            'Columns', Cols);
        obj.CurrentSelection = SelInfo;
        if strcmp(Table, 'free')
            obj.hFixedTable.clearSelection;
        else
            obj.hFreeTable.clearSelection;
        end
        
        % Check whether actions should be enabled or disabled
        AG = obj.Actions.Actions.findobj('Label', '&Inputs');
        A = AG.Actions;
        
        if isempty(Rows)
            set(A([1 2]), 'Enabled', false);
        else
            set(A([1 2]), 'Enabled', true);
        end
        if isscalar(Rows)
            set(A(3), 'Enabled', true);
        else
            set(A(3), 'Enabled', false);
        end
        
        end  % pSelectionChange
        
        %----------------------------------------
        function pUpdateRuns(obj)
        %PUPDATERUNS Update the numebr of runs editor.
        %   PUPDATERUNS(OBJ) updates the number of runs that the object is
        %   reporting in the runs edit box.
        
        if obj.hasData
            optim = obj.MessageService.getOptim;
            obj.hNumRuns.Control.Value = getNumRuns(optim);
        else
            obj.hNumRuns.Control.Value = 0;
        end
        
        end  % pUpdateRuns
        
        %----------------------------------------
        function pUpdateTableData(obj, pInp, Rows, Cols, Data)
        %PUPDATETABLEDATA Update data source with new values.
        %   PUPDATETABLEDATA(OBJ, P_INP, ROWS, COLS, DATA) is called when the user
        %   edits the vectors in a table.  ROWS and COLS are vectors of indices.
        %   DATA is a cell array of vectors with size(DATA)==[length(ROWS)
        %   lengt(COLS)].  P_INP is the list of variables being displayed in the
        %   table.
        
        if obj.hasData
            optim = obj.MessageService.getOptim;
            for n = 1:length(Cols)
                setinitialvaluedata(optim, pInp(Cols(n)), Rows, cat(1, Data{:,n}));
            end
            
            obj.disableMessageServiceListeners;
            obj.MessageService.setOptim(optim, 'inputvalue');
            obj.enableMessageServiceListeners;
        end
        
        end  % pUpdateTableData
 
        function setUIContextMenu(obj)
        set([obj.hFreeTable, obj.hFixedTable],'UIContextMenu',obj.UIContextMenu);
        end
    end
    
end  % classdef

function i_passonbtndown(~, ~, obj)
obj.notify('ButtonDown');
end  % i_passonbtndown

function i_settablemode(src, ~, hTable)
hTable(1).Peer.setDisplayMode(get(src, 'Value')-1);
hTable(2).Peer.setDisplayMode(get(src, 'Value')-1);
end  % i_settablemode

function i_setnumruns(src, ~, obj)
if obj.hasData
    optim = obj.MessageService.getOptim;
    optim = setNumRuns(optim, get(src, 'Value'));
    obj.MessageService.setOptim(optim, 'InputValue');
end
end  % i_setnumruns

function i_editvalue(~, evt, obj, table)
% Convert data to a cell of vectors
CellData = cell(evt.JavaEvent.getObjectArray);
for n = 1:numel(CellData)
    CellData{n} = CellData{n}(:).';
end

[pFree, pFixed]= obj.pGetDisplayedVariables;
if strcmp(table, 'free')
    pInp = pFree;
else
    pInp = pFixed;
end

obj.pUpdateTableData(pInp, evt.JavaEvent.getRows+1, evt.JavaEvent.getColumns+1, CellData);
end  % i_editvalue

function i_selchange(src, evt, obj, table)
Sel = evt.data.SelectedDataRows;
VectorRows = unique(double(src.Peer.convertViewRowsToData(Sel-1)+1));
Sel = evt.data.SelectedDataColumns;
VectorCols = unique(double(src.Peer.convertViewColumnsToData(Sel-1)+1));
obj.pSelectionChange(table, VectorRows, VectorCols);
end  % i_selchange

% Action callbacks
function i_copy(~, ~, obj)
obj.copy;
end  % i_copy

function i_paste(~, ~, obj)
obj.paste;
end  % i_paste

function i_duplicate(~, ~, obj)
obj.duplicateRows;
end  % i_duplicate

function i_delete(~, ~, obj)
obj.deleteRows;
end  % i_delete

function i_fill(~, ~, obj)
obj.pFillAllRuns;
end  % i_fill

function i_settabledata(optim, hTable, pInp)
if isempty(pInp)
    Names = {};
    Data  = {};
else
    Names = pveceval(pInp, @getname);
    
    MatrixData = getinitialvaluedata(optim, pInp);
    
    % Convert cell of 2D data matrices into 2D cell of vector data for the
    % table
    Data = cell(getNumRuns(optim), length(pInp));
    for n = 1:length(pInp)
        Data(:,n) = num2cell(MatrixData{n},2);
    end
end
hTable.Peer.setData(Names, Data);
end  % i_settabledata

function i_redraw(~, ~, obj)
obj.pFillTable;
obj.pUpdateRuns;
end  % i_redraw


function i_redrawfixed(~, ~, obj)
% The pointer lists may contain items that have been created by an
% objective or constraint and thus data and names may have been changed
% in the edit, so we need to redraw.
obj.pFillTable('fixed');
end  % i_redrawfixed