www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+xregdatagui/TssfInfoView.m
classdef TssfInfoView < xregdatagui.AbstractDataView %xregdatagui.TssfInfoView class % xregdatagui.TssfInfoView extends xregdatagui.AbstractDataView. % xregdatagui.TssfInfoView is part of xregdatagui.TssfClusterView % % xregdatagui.TssfInfoView 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' (read only) % UIContextMenu - Property is of type 'MATLAB array' % Listeners - Property is of type 'handle vector' (read only) % DataListview - Property is of type 'handle' (read only) % DesignListview - Property is of type 'handle' (read only) % Interactive - Property is of type 'bool' % COMListeners - Property is of type 'handle vector' (read only) % % xregdatagui.TssfInfoView methods: % gettitle - returns string describing this view % pPostSetDmsIsReadOnly - A short description of the function % pPostSetInteractive - A short description of the function % pUpdateDisplay - complete update of the view display % pUpdateListviews - A short description of the function % pdmsDataTypeChangedUpdate - event handler for the dmsDataTypeChanged event % ptssfActualDesignChangedUpdate - update of the view display for design changes % Copyright 2015 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (AbortSet, SetObservable) %INTERACTIVE Property is of type 'bool' Interactive = true; end properties (SetAccess=protected, AbortSet, SetObservable) %DATALISTVIEW Property is of type 'handle' (read only) DataListview = []; %DESIGNLISTVIEW Property is of type 'handle' (read only) DesignListview = []; %COMLISTENERS Property is of type 'handle vector' (read only) COMListeners = []; end methods % constructor block function obj = TssfInfoView(varargin) %TssfInfoView constructor % OUT = TssfInfoView(VARARGIN) % Do the setup stuff from inside the abstractDataView constructor obj@xregdatagui.AbstractDataView(varargin{ : }); % converted super class constructor call % Create the graphical objects and put in the Display field obj.pCreateDisplay; % Update the display obj.pUpdateDisplay % Set up property listeners on the interactive property addlistener(obj,obj.findprop('Interactive'),'PostSet',@obj.pPostSetInteractive); end % tssfclusterview end % constructor block methods % public methods %---------------------------------------- function pPostSetDmsIsReadOnly(obj, ~,~) %PPOSTSETDMSISREADONLY disable actions if IsReadOnly changes % PPOSTSETDMSISREADONLY(OBJ,SRC, EVENT) % Set the Append status of the storage view obj.Interactive = ~obj.MessageService.IsReadOnly; end % pPostSetDmsIsReadOnly %---------------------------------------- function pPostSetInteractive(obj, ~,~) %PPOSTSETINTERACTIVE A short description of the function % PPOSTSETINTERACTIVE(OBJ, SRC, EVT) if obj.MessageService.isaTSSF boolInteractive = obj.Interactive; if boolInteractive strInteractive = 'on'; else strInteractive = 'off'; end else boolInteractive = false; strInteractive = 'off'; end % Ensure that the listviews are set correctly obj.DataListview.Peer.setDisplayChecks(boolInteractive); obj.DesignListview.Peer.setDisplayChecks(boolInteractive); set(obj.COMListeners, 'Enable', strInteractive); obj.DesignListview.UIContextMenu = obj.UIContextMenu; obj.DataListview.UIContextMenu = obj.UIContextMenu; end % pPostSetInteractive %---------------------------------------- function pUpdateDisplay(obj) %PUPDATEDISPLAY complete update of the view display % % PUPDATEDISPLAY(OBJ) % if hasData(obj) % Simulate a data type changed update obj.pdmsDataTypeChangedUpdate; % Check the class of the current data object if obj.MessageService.isaTSSF obj.ptssfActualDesignChangedUpdate; obj.pUpdateListviews end end end % pUpdateDisplay %---------------------------------------- function pUpdateListviews(obj) %PUPDATELISTVIEWS A short description of the function % OUT = PUPDATELISTVIEWS(IN) % Make sure it's a valid cluster index if obj.MessageService.CurrentClusterIndex < 1 return end % Get the data object tssf = obj.MessageService.TestplanSweepsetFilter; % OK - Get the cluster information thisCluster = get(tssf, 'clusters', obj.MessageService.CurrentClusterIndex); [alldata, data, design, tolerance] = get(tssf, {'actualdata', 'meandata', 'actualdesign' 'tolerances'}); % Subsample the design, data and testnums design = design(thisCluster.design, :); data = data(thisCluster.data, :); % Get the testnumbers testnums = testnum(alldata); testnums = testnums(thisCluster.data); % Set the tolerances designTol = repmat(tolerance, size(design, 1), 1); dataTol = repmat(tolerance, size(data, 1), 1); % Add items to the data listview ListData = cell(length(thisCluster.data),2+size(data,2)); DataChecks = false(length(thisCluster.data),1); for i = 1:length(thisCluster.data) % Find which design elements are in tolerance of this point designIndicesInTolerance = i_inTolerance(data(i,:), design, designTol); ListData{i,1} = sprintf('%d', testnums(i)); str = sprintf('%d, ', thisCluster.design(designIndicesInTolerance)); ListData{i,2} = str(1:end-2); for j = 1:size(data, 2) ListData{i,2+j} = sprintf('%.4g', data(i, j)); end DataChecks(i) = ismember(thisCluster.data(i), thisCluster.selecteddata); end obj.DataListview.Peer.setData(ListData); if obj.Interactive obj.DataListview.Peer.setChecks(DataChecks); end ListDesign = cell(length(thisCluster.design),2+size(design,2)); DataChecks = false(length(thisCluster.design),1); % Add items to the design listview for i = 1:length(thisCluster.design) % Find which design elements are in tolerance of this point dataIndicesInTolerance = i_inTolerance(design(i,:), data, dataTol); ListDesign{i,1} = sprintf('%d', thisCluster.design(i)); dataStr = sprintf('%d, ', testnums(dataIndicesInTolerance)); ListDesign{i,2} = dataStr(1:end-2); for j = 1:size(data, 2) ListDesign{i,2+j} = sprintf('%.4g', design(i, j)); end DataChecks(i) = ismember(thisCluster.design(i), thisCluster.selecteddesign); end obj.DesignListview.Peer.setData(ListDesign); if obj.Interactive obj.DesignListview.Peer.setChecks(DataChecks); end % Check for a design only cluster and ensure that the design checkboxes are % turned off in that case. dms = obj.MessageService; obj.Interactive = ~strcmp(thisCluster.status, 'unmatcheddesign') & dms.isaTSSF & ~dms.IsReadOnly ; end % pUpdateListviews %---------------------------------------- function pdmsDataTypeChangedUpdate(obj, ~,~) %PDMSDATATYPECHANGEDUPDATE event handler for the dmsDataTypeChanged event % PDMSDATATYPECHANGEDUPDATE(OBJ, SRC, EVT) % Find the tssfFiltersChanged listener tssfListeners = obj.MessageService.findListeners(obj.Listeners, 'TestplanSweepsetFilter'); % If the dataObject isn't a sweepsetfilter then... if obj.MessageService.isaTSSF % Turn on the TestplanSweepsetFilter listener [tssfListeners.Enabled] = deal(true); % Check if the view is interactive or not obj.Interactive = ~obj.MessageService.IsReadOnly; else % Clear the views obj.DataListview.setColumnData({}); obj.DesignListview.setColumnData({}); obj.DesignListview.setData({}); % Turn off the TestplanSweepsetFilter listener [tssfListeners.Enabled] = deal(false); % Ensure the view is non-interactive obj.Interactive = false; end end % pdmsDataTypeChangedUpdate %---------------------------------------- function ptssfActualDesignChangedUpdate(obj, ~,~) %ptssfActualDesignChangedUpdate update of the view display for design changes % ptssfActualDesignChangedUpdate(OBJ) % Re-create the column headers for the new global variables names = globalsignalnames(obj.MessageService.TestplanSweepsetFilter); % Make the names for the Data and the Design listviews dataNames = [{'Test Number' 'Design Indices in Tolerance'} names']; designNames = [{'Design Index' 'Test Numbers in Tolerance'} names']; widths = [80 150 60*ones(1, length(names))]; obj.DataListview.setColumnData(dataNames); obj.DataListview.setColumnWidths(widths); obj.DesignListview.setColumnData(designNames); obj.DesignListview.setColumnWidths(widths); end % ptssfActualDesignChangedUpdate end % public methods methods (Hidden) % possibly private or hidden %---------------------------------------- function pCreateDisplay(obj) %PCREATEDISPLAY create main display % We need two side by side listviews to display info about the current cluster obj.DataListview = mbcwidgets.List( 'Parent', obj.Parent,... 'Editable', false, ... 'UIContextMenu', obj.UIContextMenu,... 'ValueChangedCallback',@obj.onDataListviewCheck,... 'SelectionMode', 'MultiRow'); obj.DataListview.setColumnData({'Test Number' 'Design Indices in Tolerance'}); obj.DataListview.setColumnWidths([80 150]); obj.DataListview.Peer.setDisplayChecks(obj.Interactive); obj.DesignListview = mbcwidgets.List( 'Parent', obj.Parent,... 'Editable', false, ... 'UIContextMenu', obj.UIContextMenu,... 'ValueChangedCallback',@obj.onDesignListviewCheck,... 'SelectionMode', 'MultiRow'); obj.DesignListview.setColumnData({'Design Index' 'Test Numbers in Tolerance'}); obj.DesignListview.setColumnWidths([80 150]); obj.DesignListview.Peer.setDisplayChecks(obj.Interactive); % Create a split layout for the two listviews split = xregsplitlayout(obj.Parent, ... 'packgroup', 'xregdatagui.tssfinfoview',... 'orientation', 'lr',... 'split', [0.5 0.5],... 'dividerstyle', 'flat',... 'dividerwidth', 4,... 'left', obj.DataListview,... 'right', obj.DesignListview,.... 'enable', obj.Enable); obj.ContentHandle = split; comListeners= [ handle.listener(obj.DataListview.Peer, 'MousePressed', @obj.onListBtnDown) handle.listener(obj.DesignListview.Peer, 'MousePressed', @obj.onListBtnDown)]; obj.COMListeners = [obj.COMListeners ; comListeners]; end % pCreateDisplay function onDataListviewCheck(obj,~, evt) %onDataListviewCheck callback to check data listview item ClusterIdx = obj.MessageService.CurrentClusterIndex; % Check the cluster index is valid if obj.Interactive && ClusterIdx > 0 % Get the data object tssf = obj.MessageService.TestplanSweepsetFilter; % Get the current cluster information thisCluster = get(tssf, 'clusters', ClusterIdx); % Has anything changed state = ismember(thisCluster.data, thisCluster.selecteddata); % update state state(evt.data.Rows) = ~state(evt.data.Rows); % Indicate this task might take a little time busy(obj.MessageService,'Updating Cluster Information...'); try % Update the selected data tssf = setClusterSelectedData(tssf, thisCluster.data(state), ClusterIdx); % And flush the event queue obj.MessageService.flushEventQueue(tssf); % And let everyone know that the tests have changed obj.pSendSelectedTestsChanged; end % Remove the message and the pointer idle(obj.MessageService); end end % onDataListviewCheck %------------------------------------------------------------------------ function onDesignListviewCheck(obj,~, evt) %onDesignListviewCheck callback to check data listview item ClusterIdx = obj.MessageService.CurrentClusterIndex; % Check the cluster index is valid if obj.Interactive && ClusterIdx > 0 % Get the data object tssf = obj.MessageService.TestplanSweepsetFilter; % Get the current cluster information thisCluster = get(tssf, 'clusters', ClusterIdx); % Has anything changed state = ismember(thisCluster.design, thisCluster.selecteddesign); % Has anything happened to the listview % update state state(evt.data.Rows) = ~state(evt.data.Rows); % Indicate this task might take a little time busy(obj.MessageService,'Updating Cluster Information...'); try % Update the selected design points tssf = setClusterSelectedDesign(tssf, thisCluster.design(state), ClusterIdx); % And flush the event queue obj.MessageService.flushEventQueue(tssf); end % Remove the message and the pointer idle(obj.MessageService); end end % onDesignListviewCheck function onListBtnDown(obj,~, ~) notify(obj, 'ButtonDown'); end % onListBtnDown %---------------------------------------- function pPostSetDataMessageService(obj, ~,~) %PPOSTSETDATAMESSAGESERVICE setup MessageService listeners % PPOSTSETDATAMESSAGESERVICE(OBJ, SRC, EVT) % Call the super pPostSetDataMessageService pPostSetDataMessageService@xregdatagui.AbstractDataView(obj) dms = obj.MessageService; dmsListeners = [... event.listener(dms, 'dmsDataTypeChanged', @obj.pdmsDataTypeChangedUpdate);... event.listener(dms, 'tssfActualDesignChanged', @obj.ptssfActualDesignChangedUpdate);... event.listener(dms, 'tssfClustersCreated', @obj.onUpdateCurrentCluster);... event.listener(dms, 'CurrentClusterChanged', @obj.onUpdateCurrentCluster);... ]; obj.Listeners = [obj.Listeners(:); dmsListeners(:)]; end % pPostSetDataMessageService %---------------------------------------- function pSendSelectedTestsChanged(obj) %PSENDSELECTEDTESTSCHANGED set global test selection % PSENDSELECTEDTESTSCHANGED(obj) dms = obj.MessageService; tssf = dms.TestplanSweepsetFilter; % Get the information about the clusters if ~dms.isOneStage % updte selected tests for two-stage data only thisCluster = get(dms.TestplanSweepsetFilter, 'clusters', dms.CurrentClusterIndex); dms.setSelectedTests(convertTestIndices(tssf, thisCluster.selecteddata)); end end % pSendSelectedTestsChanged function onUpdateCurrentCluster(obj, ~,~) % Update the listviews obj.pUpdateListviews; end % iUpdateCurrentCluster end % possibly private or hidden end % classdef function indices = i_inTolerance(value, data, tol) % Ensure that value is the same size as data value = repmat(value, size(data, 1), 1); % Form a distance metric distance = abs((value - data)./tol); % Where are all in tolerance indices = find(all((distance < 1), 2)); end % i_inTolerance