www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/mbcMatchDialog.m
function varargout = mbcMatchDialog(action, varargin) %mbcMatchDialog Allow the user to match one set of input factors to another % % [I, OK] = mbcMatchDialog(ACTION, A, B) % [I, OK] = mbcMatchDialog(ACTION, A, B, A_TITLE, B_TITLE) % % The output I is the indices into B that A matches to, i.e., A is matched to % B(I). The size of I is the same as the size of A. The output OK is required % because we are dealing with a GUI and this output records whether the user % clicked ''OK'' or ''Cancel''. The optional title arguments, A_TITLE and % B_TITLE allow for titles or labels to placed at the top of each of the lists % of input factors. % % See also CONBASE, CONINPUTFACTOR, XREGMODEL/GUI_SIGNALCHOOSER. % Copyright 2004-2015 The MathWorks, Inc. switch action case 'figure' % create modal dialog [varargout{1:2}] = dialog(varargin{:}); case 'layout' % create layout for matching inputs varargout{1} = createLayout(varargin{:}); case 'finalise' % finalise matching output [varargout{1:2}] = finalise(varargin{:}); case 'validate' % validate that there is a valid matching varargout{1} = validate(varargin{:}); case 'initialise' % initialise to use new input factors initialise(varargin{:}); end %------------------------------------------------------------------------------| function figureTitle = i_FigureTitle figureTitle = 'Match Constraint Inputs'; %------------------------------------------------------------------------------| function [matches, OK] = dialog(varargin) %dialog Creates GUI inside a dialog dlg = mbcgui.container.Dialog( ... 'Name', i_FigureTitle, ... 'Size',[600 300],... 'Resize','off' ); dlg.Content = createLayout(dlg.Figure,varargin{:}); dlg.ValidationFcn = @()validate(dlg.Content); closeAction = dlg.showDialog(); if strcmp(closeAction,'OK') % get updated sweepset from layout userdata matches = finalise(dlg.Content); OK = true; else matches = finalise(dlg.Content); OK = false; end delete(dlg); function layout = createLayout(Parent, cifA, cifB, titleA, titleB) %createLayout Create the layout if nargin < 3 error(message('mbc:coninputfactor:InvalidArguments8')); end if nargin < 4 titleA = 'New Factors'; end if nargin < 5 titleB = 'Existing Factors'; end if length( cifA ) > length( cifB ), error(message('mbc:coninputfactor:InvalidArguments9')); end layout = i_Layout( Parent, cifA, cifB, titleA, titleB ); function [matches,OK] = finalise(layout) %finalise Get final values from GUI ud = get(layout, 'UserData'); matches = ud.info.pMatches; OK = true; %------------------------------------------------------------------------------| function ok = validate(layout) %validate Check that state of the GUI is valid udp = get(layout, 'UserData'); matches = udp.info.pMatches; if any( matches == 0 ), xregerror( i_FigureTitle, 'All input factors must be matched' ); ok = false; else matches = matches(matches~=0); if numel( matches ) == numel( unique( matches ) ), ok = true; else xregerror( i_FigureTitle, 'Factors must be unique' ); ok = false; end end function initialise( layout, cifA, cifB ) udp = get(layout, 'UserData'); i_Initialise( udp, cifA, cifB ); %------------------------------------------------------------------------------| function lyt = i_Layout( parent, cifA, cifB, titleA, titleB ) %i_Layout create layout if isa( parent, 'xregcontainer' ), lyt = parent; else % Set up pointer to hold user data udp = xregGui.RunTimePointer; udp.LinkToObject( parent ); % A (left hand) list view listviewA = i_ListView( parent, {'Name', 'Matches'}, [100, 100] ); txtA = i_ListTitle( parent, titleA ); listviewA.SelectionChangedCallback = {@i_ListCallback, udp}; % B (right hand) list box listboxB = uicontrol( 'Parent', parent,... 'Style', 'listbox',... 'BackgroundColor', [1, 1, 1],... % white 'String', '',... % set this later 'Min', 0, 'Max', 0, ... % single selection 'Callback', {@i_ListBoxCallback, udp}, ... 'Tag', 'RightListBox'); txtB = i_ListTitle( parent, titleB ); % Selection buttons btnSelect = xregGui.iconuicontrol( 'Parent', parent, ... 'ImageFile', [xregrespath,'\leftarrow.bmp'], ... 'TransparentColor', [255, 255, 0], ... 'ToolTip', 'Match current factor to chosen factor', ... 'Callback', {@i_Select, udp, 'open'}, ... 'Tag', 'SelectButton'); lytSelect = xreggridlayout( parent, ... 'CorrectAlg', 'on', ... 'Dimension', [3, 1],... 'Elements', {[], btnSelect, []},... 'RowSizes', [10, 80, -1]); % Frame that can hold extra information about the selected signals [lytAInfo, aInfo] = i_InfoLayout( parent, 'Factor information' ); [lytBInfo, bInfo] = i_InfoLayout( parent, 'Factor information' ); % Principal layout elements = { txtA, [], txtB; listviewA, lytSelect, listboxB; lytAInfo, [], lytBInfo }; lyt = xreggridlayout( parent,... 'Dimension', [3, 3],... 'Correctalg', 'on',... 'Border', [10, 10, 10, 0],... 'GapX', 10,... 'RowSizes', [18, -1, 75],... 'ColSizes', [-1, 80, -1], ... 'Elements', elements); % Setup user data structure and store at end of pointer ud = struct( ... 'figh', parent, ... 'pMatches', [], ... 'cifA', [], ... 'cifB', [], ... 'listviewA', listviewA, ... 'listboxB', listboxB, ... 'btnSelect',btnSelect,... 'aInfo', aInfo, ... 'bInfo', bInfo ); udp.info = ud; % Initialize the lists i_Initialise( udp, cifA, cifB ); set(lyt, 'UserData', udp); end %------------------------------------------------------------------------------| function txt = i_InfoText( parent, string ) %i_InfoText Creates a uicontrol containing text txt = uicontrol( ... 'Parent', parent, ... 'Style', 'text', ... 'String', string, ... 'HorizontalAlignment', 'left', ... 'Callback', '' ); %------------------------------------------------------------------------------| function [frame, ud] = i_InfoLayout( parent, title ) %i_InfoLayout create information panel frame = mbcgui.container.layoutpanel('Parent', parent, ... 'BorderType', 'etchedin', ... 'Title', title, ... 'LayoutBorder', [7 0 7 5]); lbSymbol = i_InfoText( frame, 'Symbol:' ); lbUnit = i_InfoText( frame, 'Units:' ); lbRange = i_InfoText( frame, 'Range:' ); ud.Symbol = i_InfoText( frame, '' ); ud.Unit = i_InfoText( frame, '' ); ud.Range = i_InfoText( frame, '' ); lyt = xreggridlayout( frame,... 'Dimension', [3, 2],... 'Correctalg', 'on',... 'GapX', 5, ... 'GapY', 0, ... 'ColSizes', [40, -1],... 'RowSizes', [15, 15, 15],... 'Elements', {lbSymbol, lbUnit, lbRange, ud.Symbol, ud.Unit, ud.Range} ); set(frame, 'LayoutComponent', {lyt}); %------------------------------------------------------------------------------| function h = i_ListTitle( parent, str ) %i_ListTitle create list title h = uicontrol( 'Parent', parent,... 'Style', 'text',... 'HorizontalAlignment', 'left',... 'FontWeight', 'bold',... 'String', str ); %------------------------------------------------------------------------------| function h = i_ListView( parent, colHeaders, colSizes ) % create list view h = mbcwidgets.List( 'Parent', parent,... 'Editable', false, ... 'SelectionMode', 'SingleRow', ... 'Tag', 'matchList'); h.Peer.setColumnData(colHeaders); h.Peer.setColumnWidths(colSizes); %------------------------------------------------------------------------------| function i_Initialise( udp, cifA, cifB ) % update the user data with cifA, cifB information ud = udp.info; ud.cifA = cifA; ud.cifB = cifB; ud.pMatches = p_Match( cifA, cifB ); udp.info = ud; matches = ud.pMatches; aNames = ud.cifA.Name; bNames = ud.cifB.Name; % Set the list of symbols that need to be matched to Data = [aNames(:) cell(length(aNames),1)]; for i = 1:numel( aNames ), if matches(i) Data{i,2} = bNames{matches(i)}; end end ud.listviewA.Peer.setData(Data); ud.listviewA.selectRows(1); % Set the list of possible symbols from the chosen model set( ud.listboxB, 'String', bNames ); % Set the initial value of the list box if matches(1), set( ud.listboxB, 'Value', matches(1) ); else set( ud.listboxB, 'Value', 1 ); end i_UpdateInfoDisplays( ud ) %------------------------------------------------------------------------------| function i_ListBoxCallback( src, evt, udp ) ud = udp.info; selectionType = get( ud.figh, 'SelectionType' ); i_Select( src, evt, udp, selectionType ); % Is the user double clicked, then select the next item on the list view if strcmpi( 'open', selectionType ), i_IncrementListView( ud ); end %------------------------------------------------------------------------------| function i_Select( ~, ~, udp, selectionType ) % selectionType is one of {normal} | extend | alt | open. % 'normal' is a regular mouse click % 'extended' is a shift left click or middle button click % 'alt' is a control left click or right button click % 'open' is a double click ud = udp.info; if strcmpi( 'normal', selectionType ), % Update the information display i_UpdateInfoDisplays( ud ) elseif ~isempty(ud.listviewA.getSelectedRows) % Match the chosen symbol to selected current symbol i_MatchSymbols( udp ); end %------------------------------------------------------------------------------| function i_UpdateInfoDisplays( ud ) aIndex = ud.listviewA.getSelectedRows; i_UpdateOneInfoDisplay( ud.aInfo, ud.cifA, aIndex ) bIndex = get( ud.listboxB, 'Value' ); i_UpdateOneInfoDisplay( ud.bInfo, ud.cifB, bIndex ) %------------------------------------------------------------------------------| function i_UpdateOneInfoDisplay( info, cif, index ) set( info.Symbol, 'String', cif.Symbol{index} ); set( info.Unit, 'String', cif.Unit{index} ); set( info.Range, 'String', sprintf( '[%.4g, %.4g]', cif.Min(index), cif.Max(index) ) ); %------------------------------------------------------------------------------| function i_MatchSymbols( udp ) ud = udp.info; % Get the selected item from the A (left hand) list tgtIndex = ud.listviewA.getSelectedRows; % Get the selected item from the B (left hand) list chosen = get( ud.listboxB, 'Value' ); % Updated A (left hand) listview chosenNames = get( ud.listboxB, 'String' ); ud.listviewA.Peer.setDataAt(chosenNames{chosen},tgtIndex-1,1) % Update the matches vector matches = ud.pMatches; matches(tgtIndex) = chosen; ud.pMatches = matches; udp.info = ud; i_UpdateInfoDisplays( ud ) %------------------------------------------------------------------------------| function i_IncrementListView( ud ) % Get the current matches vector matches = ud.pMatches; nFactors = numel( matches ); % Get the selected item from the list of current symbols currentIndex = ud.listviewA.getSelectedRows; % Make the next item in the list the current item newIndex = mod( currentIndex, nFactors ) + 1; ud.listviewA.selectRows(newIndex); % Select the matching factor in this list box if matches(newIndex), set( ud.listboxB, 'Value', matches(newIndex) ); else nB = size( ud.cifB, 2 ); unmatched = setdiff( 1:nB, matches ); if any( unmatched ), set( ud.listboxB, 'Value', min( unmatched ) ); else set( ud.listboxB, 'Value', 1 ); end end i_UpdateInfoDisplays( ud ) %------------------------------------------------------------------------------| function i_ListCallback( ~, ~, udp ) % Get the user data % If the selected symbol is matched, update the chosen list box % Call i_UpdateInfoDisplays % Get the user data ud = udp.info; % Get the selected item from the list of current symbols tgtIndex = ud.listviewA.getSelectedRows; if ~isempty(tgtIndex) % If the slected symbol is matched, update the chosen list box matches = ud.pMatches; if matches(tgtIndex), set( ud.listboxB, 'Value', matches(tgtIndex) ); end % Update the info displays i_UpdateInfoDisplays( ud ); set(ud.btnSelect,'Enable','on'); else set(ud.btnSelect,'Enable','off'); end