www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/+cgoptimgui/ExpressionSelector.m

    classdef ExpressionSelector < mbcgui.widget.BasicContainer
    %cgoptimgui.ExpressionSelector class
    %   cgoptimgui.ExpressionSelector extends mbcgui.widget.BasicContainer.
    %
    %    cgoptimgui.ExpressionSelector 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)
    %       Expression - Property is of type 'MATLAB array'
    %       ExpressionEvalMode - Property is of type 'int32'
    %       Filters - Property is of type 'MATLAB array'
    %       pPROJ - Property is of type 'MATLAB array'
    %
    %    cgoptimgui.ExpressionSelector methods:
    %       createExpressionFilter - Create an expression filter
    %       generateModelFilter - Create a filter to return models
    %       generateTableFilter - Create a filter to return tables
    %       generateVariableFilter - Create a filter to return variables
    
    %   Copyright 2006-2015 The MathWorks, Inc.
    
    properties (AbortSet, SetObservable)
        %EXPRESSION Property is of type 'MATLAB array'
        Expression = mbcpointer( 1 );
        %EXPRESSIONEVALMODE Property is of type 'int32'
        ExpressionEvalMode = 0;
        %FILTERS Property is of type 'MATLAB array'
        Filters = [  ];
        %PPROJ Property is of type 'MATLAB array'
        pPROJ = mbcpointer( 1 );
    end
    
    properties (Access=protected, AbortSet, SetObservable)
        %ITEMFILTER Property is of type 'MATLAB array'
        ItemFilter = '';
        %ITEMLIST Property is of type 'handle'
        ItemList = '';
        %ITEMEVALFUNC Property is of type 'MATLAB array'
        ItemEvalFunc = '';
        %ITEMFUNCLABEL Property is of type 'handle'
        ItemFuncLabel = '';
    end
    
    events
        ExpressionChanged
        ExpressionEvalModeChanged
    end  % events
    
    methods  % constructor block
        function obj = ExpressionSelector(varargin)
        %EXPRESSIONSELECTOR Constructor for cgoptimgui.ExpressionSelector objects
        %   OBJ = EXPRESSIONSELECTOR(PROP, VAL, ...) creates a new
        %   ExpressionSelector object. This object is used to allow the user to
        %   select an expression from an optionally filtered list and set the
        %   evaluation mode for the filter.
        %
        %   See also CGOPTIMGUI.BOUNDSELECTOR
        
        % Call parent class constructor
        obj@mbcgui.widget.BasicContainer(varargin{ : }); % converted super class constructor call
        
        % Set up the filters field if required
        if isempty(obj.Filters)
            varFilt = generateVariableFilter(obj);
            modFilt = generateModelFilter(obj);
            tabFilt = generateTableFilter(obj);
            varFilt = createExpressionFilter(obj, varFilt);
            modFilt = createExpressionFilter(obj, modFilt);
            tabFilt = createExpressionFilter(obj, tabFilt);
            fNames = {'DescName', 'TypeName', 'Fcn'};
            cVals = {'Show variables', 'Variable', varFilt; ...
                'Show models', 'Model', modFilt; ...
                'Show tables', 'Table', tabFilt};
            obj.Filters = cell2struct(cVals, fNames, 2);
        end
        
        % Construct the object
        SC = xregGui.SystemColorsDbl;
        ItemFilterStr = cell(size(obj.Filters));
        [ItemFilterStr{:}] = deal(obj.Filters(:).DescName);
        obj.ItemFilter = uicontrol('Parent', obj.Parent,...
            'Style','popupmenu',...
            'String', ItemFilterStr,...
            'BackgroundColor',SC.WINDOW_BG, ...
            'Callback', @n_fillItemList);
        obj.ItemList = cgtools.exprList('parent', obj.Parent, ...
            'ItemColumnWidth', .6);
        obj.ItemEvalFunc = uicontrol('Parent', obj.Parent, ...
            'Style', 'popupmenu', ...
            'String', {'Evaluation output', 'PEV value'}, ...
            'BackgroundColor', SC.WINDOW_BG, ...
            'Callback', @n_editItemEvalFunc);
        obj.ItemFuncLabel = xregGui.labelcontrol('Parent', obj.Parent, ...
            'String', 'Evaluate quantity:', ...
            'LabelSize', 90, ...
            'LabelSizeMode', 'absolute', ...
            'ControlSize', 1, ...
            'ControlSizeMode', 'relative', ...
            'Control', obj.ItemEvalFunc);
        
        L = xreggridbaglayout(obj.Parent, ...
            'dimension', [5 1], ...
            'rowsizes', [20 3 -1 5 20], ...
            'colsizes', -1, ...
            'elements', {...
            obj.ItemFilter, [], obj.ItemList, [], obj.ItemFuncLabel,...
            });
        
        % Create layout and assign to parent
        obj.ContentHandle = L;
        
        % Update the GUI
        obj.pUpdate;
        
        % Create listeners
        obj.addPropertyListeners( ...
            { ...
            'Expression', ...
            'ExpressionEvalMode', ...
            'pPROJ', ...
            'Filters', ...
            }, ...
            { ...
            @n_expressionChanged, ...
            @n_expressionEvalModeChanged, ...
            @n_projectChanged, ...
            @n_filtersChanged, ...
            } ...
            );
        obj.addListeners( ...
            handle.listener(obj.ItemList, 'SelectionChanged', @n_ItemListSelection) ...
            );
        
        
            function n_fillItemList(~, ~)
            
            obj.pFillItemList;
            
            end
        
            function n_ItemListSelection(src, ~)
            
            % Disable the listeners
            obj.disableListeners;
            
            % Set the new expression and reset the possible evaluation options
            obj.Expression = src.SelectedItems;
            obj.pSetItemEvalOptions;
            
            % Enable the listeners
            obj.enableListeners;
            
            % Send the expression changed event
            notify(obj, 'ExpressionChanged');
            
            end
        
            function n_editItemEvalFunc(src, ~)
            
            % Disable the listeners
            obj.disableListeners;
            
            % Set the item evaluation function
            EvalMode = get(src, 'Value');
            EvalMode(EvalMode == 1) = 0;
            obj.ExpressionEvalMode = EvalMode;
            
            % Enable the listeners
            obj.enableListeners;
            
            % Send the expression evaluation mode changed event
            notify(obj, 'ExpressionEvalModeChanged');
            
            end
        
            function n_expressionChanged(~, ~)
            
            % Perform update tasks following expression change
            obj.pUpdateAfterExpressionChg;
            
            end
        
            function n_expressionEvalModeChanged(~, ~)
            
            % Perform update tasks following expression eval mode change
            obj.pUpdateAterEvalModeChg;
            
            end
        
            function n_projectChanged(~, ~)
            
            % Perform update tasks following project change
            obj.pUpdateAfterProjectChg;
            
            end
        
            function n_filtersChanged(~, ~)
            
            % Perform update tasks following filter change
            obj.pUpdateAfterFiltersChg;
            
            end
        
        end
        
    end  % constructor block
    
    methods
        function set.Expression(obj,value)
        obj.Expression = i_setExpression(obj,value);
        end
        
        function set.ExpressionEvalMode(obj,value)
        obj.ExpressionEvalMode = i_setExpressionEvalMode(obj,value);
        end
        
        function set.Filters(obj,value)
        obj.Filters = i_setFilters(obj,value);
        end
        
        function set.pPROJ(obj,value)
        obj.pPROJ = i_setProject(obj,value);
        end
        
    end   % set and get functions
    
    methods  % public methods
        %----------------------------------------
        function exprFilt = createExpressionFilter(obj, initFilt, varargin)
        %CREATEEXPRESSIONFILTER Create an expression filter
        %   EXPRFILT = CREATEEXPRESSIONFILTER(OBJ, INITFILT) creates a filter that
        %   produces a sublist of expressions from a CAGE project. INITFILT must
        %   conform to the API : PITEMS = INITFILTER(pPROJ), where pPROJ is a
        %   pointer to a CAGE project.
        %
        %   EXPRFILT = CREATEEXPRESSIONFILTER(OBJ, INITFILT, SUBSFILT1, SUBSFILT2,
        %   ...) allows subsequent filters to be specified. The subsequent filters
        %   must conform to the API: PITEMS = SUBSFILT(PITEMS, pPROJ). When
        %   EXPRFILT is evaluated, PITEMS is generated from INITFILT, and then each
        %   SUBSFILT is applied to PITEMS to generate the final expression list.
        
        
        if nargin < 2
            error(message('mbc:ExpressionSelector:InvalidArgument2'));
        end
        
        exprFilt = @() inner(initFilt, varargin{:});
        
            function pOut = inner(initFilt, varargin)
            
            pOut = initFilt(obj.pPROJ);
            for i = 2:nargin
                pOut = varargin{i-1}(pOut, obj.pPROJ);
            end
            
            end
        
        end
        %----------------------------------------
        function fnFilt = generateModelFilter(obj) %#ok<MANU>
        %GENERATEMODELFILTER Create a filter to return models
        %   FNFILT = GENERATEMODELFILTER(OBJ) returns a function handle to a
        %   function which will return all the models in a CAGE project
        
        fnFilt = @(pPROJ) inner(pPROJ);
        
            function out = inner(pPROJ)
            if isnull(pPROJ)
                out = mbcpointer(0);
            else
                out = getmodels(pPROJ.info);
            end
            end
        
        end
        
        %----------------------------------------
        function fnFilt = generateTableFilter(obj) %#ok<MANU>
        %GENERATETABLEFILTER Create a filter to return tables
        %   FNFILT = GENERATETABLEFILTER(OBJ) returns a function handle to a
        %   function which will return all the tables in a CAGE project
        
        fnFilt = @(pPROJ) inner(pPROJ);
        
            function out = inner(pPROJ)
            if isnull(pPROJ)
                out = mbcpointer(0);
            else
                out = gettables(pPROJ.info);
            end
            end
        
        end
        %----------------------------------------
        function fnFilt = generateVariableFilter(obj) %#ok<MANU>
        %GENERATEVARIABLEFILTER Create a filter to return variables
        %
        %   FNFILT = GENERATEVARIABLEFILTER(OBJ) returns a function handle to a
        %   function which will return all the variables in a CAGE project
        
        
        fnFilt = @(pPROJ) inner(pPROJ);
        
            function pExpr = inner(pPROJ)
            if isnull(pPROJ)
                pExpr = mbcpointer(0);
            else
                pExpr = pPROJ.getvars('all');
            end
            
            end
        end
        
    end  % public methods
    
    methods (Access=protected)
        %----------------------------------------
        function pFillItemList(obj)
        %PFILLITEMLIST Populate the CAGE item list
        %   OUT = PFILLITEMLIST(OBJ) populates the CAGE item list with the
        %   appropriate CAGE items (variables, tables or models)
        
        val = get(obj.ItemFilter, 'Value');
        obj.ItemList.Items = obj.Filters(val).Fcn();
        obj.ItemList.ItemHeaderText = obj.Filters(val).TypeName;
        
        end  % pFillItemList
        
        %----------------------------------------
        function idx = pFindExpression(obj)
        %PFINDEXPRESSION Find the filter category for the supplied expression
        %   IDX = PFINDEXPRESSION(OBJ) finds which filter category OBJ.PEXPRESSION
        %   belongs to. If there is more than one category, the first is returned.
        
        idx = 0;
        for i = 1:length(obj.Filters)
            idxPtr = findptrs(obj.Expression, obj.Filters(i).Fcn());
            if idxPtr
                idx = i;
                break
            end
        end
        end  % pFindExpression
        
        %----------------------------------------
        function pSetItemEvalOptions(obj)
        %PSETITEMEVALOPTIONS Set the expression item evaluation options
        %   PSETITEMEVALOPTIONS(OBJ) sets the evaluation options for the selected
        %   expression in OBJ.
        
        % Find the possible ways of evaluating the item in the list
        cando = true(1, 2);
        opts = {'Evaluation value', 'PEV value'};
        if ~isnull(obj.Expression)
            cando(2) = obj.Expression.pevcheck;
        end
        
        % Set the possible evaluation methods
        set(obj.ItemEvalFunc, 'String', opts(cando));
        
        % If new expression does not support PEV, then set ExpressionEvalMode back
        % to 1 (evaluate)
        if obj.ExpressionEvalMode > length(opts(cando))
            set(obj.ItemEvalFunc, 'Value', 1);
            obj.ExpressionEvalMode = 0;
            notify(obj, 'ExpressionEvalModeChanged');
        end
        
        end  % pSetItemEvalOptions
        
        %----------------------------------------
        function pUpdate(obj)
        %PUPDATE Update the GUI
        %   PUPDATE(OBJ) updates the graphical components from the settings in OBJ.
        
        % Perform a complete update
        obj.pUpdateAfterExpressionChg;
        obj.pUpdateAterEvalModeChg;
        
        end  % pUpdate
        
        %----------------------------------------
        function pUpdateAfterExpressionChg(obj)
        %PUPDATEAFTEREXPRESSIONCHG Update the GUI after an expression change
        %   PUPDATEAFTEREXPRESSIONCHG(OBJ) updates the expression related graphical
        %   components from the settings in OBJ.
        
        % Set the evaluation options for the selected expression
        obj.pSetItemEvalOptions;
        
        % Set the item filter to have the correct value
        filterValue = pFindExpression(obj);
        obj.pUpdateItemFilter(filterValue);
        
        % Fill the CAGE item list
        obj.pFillItemList;
        
        % Set the correct expression in the list
        obj.ItemList.SelectedItem = obj.Expression;
        
        end  % pUpdateAfterExpressionChg
        
        %----------------------------------------
        function pUpdateAfterFiltersChg(obj)
        %PUPDATEAFTERFILTERSCHG Update after the filters have changed
        %   PUPDATEAFTERFILTERSCHG(OBJ) updates the object after the filters have
        %   been changed
        
        % Set the string in the expression group selector
        ItemFilterStr = cell(size(obj.Filters));
        [ItemFilterStr{:}] = deal(obj.Filters(:).DescName);
        set(obj.ItemFilter, 'String', ItemFilterStr);
        
        % Try and find current expression in new expression groups and set
        % the group
        idx = pFindExpression(obj);
        obj.pUpdateItemFilter(idx);
        
        % If the expression cannot be found, then set the expression to NULL
        if ~idx
            obj.Expression = mbcpointer(1);
            obj.ExpressionEvalMode = 0;
            notify(obj, 'ExpressionChanged');
            notify(obj, 'ExpressionEvalModeChanged');
        end
        
        % Refill the CAGE item list
        obj.pFillItemList;
        
        end  % pUpdateAfterFiltersChg
        
        %----------------------------------------
        function pUpdateAfterProjectChg(obj)
        %PUPDATEAFTERPROJECTCHG Update object after h.pPROJ change
        %   PUPDATEAFTEREVALMODECHG(OBJ) updates object after h.pPROJ has been
        %   changed
        
        % Reset the expression and the evaluation mode
        obj.Expression = mbcpointer(1);
        obj.ExpressionEvalMode = 0;
        
        % Send both events
        notify(obj, 'ExpressionChanged');
        notify(obj, 'ExpressionEvalModeChanged');
        end  % pUpdateAfterProjectChg
        
        %----------------------------------------
        function pUpdateAterEvalModeChg(obj)
        %PUPDATEATEREVALMODECHG Update itemevalfunc GUI control
        %   PUPDATEATEREVALMODECHG(OBJ) updates OBJ.ITEMEVALFUNC.
        
        % If Eval Mode has been set to 2, but PEV isn't supported then set
        % the mode back to 0.
        if obj.ExpressionEvalMode == 2 && ...
                (isnull(obj.Expression) || ~obj.Expression.pevcheck)
            obj.ExpressionEvalMode = 0;
        end
        
        % Set the correct evaluate quantity
        ItemEval = obj.ExpressionEvalMode;
        ItemEval(ItemEval==0) = 1;
        set(obj.ItemEvalFunc, 'Value', ItemEval);
        
        end  % pUpdateAterEvalModeChg
        
        %----------------------------------------
        function pUpdateItemFilter(obj, filterValue)
        %PUPDATEITEMFILTER Update the Item Filter popup
        %   PUPDATEITEMFILTER(OBJ) updates the Item Filter popup control
        
        % Set the item filter to have the correct value
        filterValue(~filterValue) = 1;
        set(obj.ItemFilter, 'Value', filterValue);
        
        end  % pUpdateItemFilter
        
    end
    
end  % classdef

function val = i_setExpression(~, val)

if ~isa(val, 'xregpointer') || length(val)~=1 || ...
        (isvalid(val) && ~isa(val.info, 'cgexpr'))
    error(message('mbc:ExpressionSelector:InvalidArgument3'));
end
end  % i_setExpression

function val = i_setExpressionEvalMode(~, val)

if ~ismember(val, [0 2])
    % We are currently not supporting boundary constraint evaluation in
    % ExpressionSelector. We will need to support this if this widget is
    % used in the model constraint GUI.
    error(message('mbc:ExpressionSelector:InvalidArgument4'));
end
end  % i_setExpressionEvalMode

function val = i_setFilters(~, val)

if ~isstruct(val) || ...
        ~all(ismember(fieldnames(val), {'DescName', 'TypeName', 'Fcn'}))
    error(message('mbc:ExpressionSelector:InvalidArgument5'));
end
end  % i_setFilters

function val = i_setProject(~, val)

if ~isa(val, 'xregpointer') || ...
        ~( (isvalid(val) && isproject(val.info)) || ~isvalid(val))
    error(message('mbc:BoundSelector:InvalidArgument3'));
end
end  % i_setProject