www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+xregbdrygui/Actions.m

    classdef Actions < handle
    %Actions Boundary Editor Actions
    
    % Copyright 2005-2016 The MathWorks, Inc. and Ford Global Technologies, Inc.
    
    properties (SetAccess=private)
        MessageService
        %MakeBoundary make a new boundary model
        MakeBoundary
        %CopyConstraint copy current boundary
        CopyConstraint
        %DeleteConstraint delete boundary
        DeleteConstraint
        %ExportToSimulink export boundary to Simulink
        ExportToSimulink
        %SetupConstraint setup boundary model
        SetupConstraint
        %AddBest add boundary to best
        AddBest
        %RemoveBest remove boundary from best 
        RemoveBest
        %ShowBoundaryPoints show boundary points on plots
        ShowBoundaryPoints
        %ShowValidationPoints show validation data on plots
        ShowValidationPoints
        %FileActionGroup file actions
        FileActionGroup
        %EditActionGroup edit boundary actions
        EditActionGroup
        %BestActionGroup best boundary actions
        BestActionGroup
        %AllViewGroup other global view actions
        AllViewGroup
        %Listeners listener store
        Listeners
        %Owner owner figure
        Owner
    end
    
    methods
        function obj = Actions(MessageService,Owner)
        %Actions constructor 
        %    obj = Actions(MessageService,Owner)
        
        if nargin>1
            obj.Owner = Owner;
        end
        
        obj.MessageService = MessageService;
        % Make Boundary, aka, the big just do everything button
        obj.MakeBoundary = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.makeBoundary, ...
            '&New Boundary...', ...
            'New boundary model', ...
            xregrespath( 'bdryNew.bmp' ) );
        obj.CopyConstraint = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.copyConstraint, ...
            'D&uplicate Boundary', ...
            'Duplicate boundary model', ...
            xregrespath( 'bdryDuplicate.bmp' ) );
        
        % Delete constraiint actions
        obj.DeleteConstraint = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.deleteConstraint, ...
            '&Delete Boundary', ...
            'Delete boundary model', ...
            xregrespath( 'delete.bmp' ) );
        
        obj.FileActionGroup = mbcgui.actions.ActionGroup;
        obj.FileActionGroup.Actions = [
            obj.MakeBoundary
            ];
        obj.FileActionGroup.MenuType =  'separate';
        
        % Export constraint to Simulink
        obj.ExportToSimulink = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.exportToSimulink, ...
            '&Export to Simulink...', ...
            'Export boundary model to Simulink' );
        
        % Constraint set-up and fit mbcgui.actions.StatefulActions
        obj.SetupConstraint = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.setupConstraint, ...
            '&Set Up Boundary...', ...
            'Set up boundary model', ...
            xregrespath( 'bdrySetup.bmp' ) );
        
        obj.EditActionGroup = mbcgui.actions.ActionGroup;
        obj.EditActionGroup.Actions = [
            obj.SetupConstraint
            obj.CopyConstraint
            obj.DeleteConstraint
            ];
        obj.EditActionGroup.MenuType =  'separate';
        
        % Best constraint mbcgui.actions.StatefulActions
        obj.AddBest = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.addToBestConstraint, ...
            'A&dd to Best', ...
            'Add boundary model to best', ...
            xregrespath( 'bdryAddBest.bmp' ) );
        obj.RemoveBest = mbcgui.actions.StatefulAction( ...
            @( s, e ) obj.removeFromBestConstraint, ...
            '&Remove from Best', ...
            'Remove boundary model from best', ...
            xregrespath( 'bdryRemoveBest.bmp' ) );
        
        obj.BestActionGroup = mbcgui.actions.ActionGroup;
        obj.BestActionGroup.Actions = [
            obj.AddBest
            obj.RemoveBest
            ];
        obj.BestActionGroup.MenuType = 'separate';
        
        % Actions that apply to all views
        obj.ShowBoundaryPoints = mbcgui.actions.ToggleAction( ...
            @( s, e ) obj.showBoundaryPoints, ...
            '&Show Boundary Points', ...
            'Show boundary points', ...
            xregrespath( 'bdryPoints.bmp' ) );
        
        obj.ShowValidationPoints = mbcgui.actions.ToggleAction( ...
            @( s, e ) obj.showValidationPoints, ...
            'Show &Validation Points', ...
            'Show validation points', ...
            xregrespath( 'validationPoints.bmp' ) );
        
        obj.AllViewGroup = mbcgui.actions.ActionGroup;
        obj.AllViewGroup.Actions = [
            obj.ShowBoundaryPoints, ...
            obj.ShowValidationPoints%, ...
            % h.SomeViewAction
            ];
        obj.AllViewGroup.MenuType =  'separate';
        
        % At startup we disable all actions and wait for some even to enable them
        set( obj.MakeBoundary,            'Enabled', false );
        set( obj.FileActionGroup.Actions, 'Enabled', false );
        set( obj.EditActionGroup.Actions, 'Enabled', false );
        set( obj.BestActionGroup.Actions, 'Enabled', false );
        
        
        % Add Listeners to control the "Enable" property of the Actions
        obj.pAddListener( event.listener( obj.MessageService, 'RootChange', ...
            @( s, e ) obj.pPostSetRoot ) );
        obj.pAddListener( event.listener( obj.MessageService, 'NodeChange', ...
            @( s, e ) obj.pPostSetNode ) );
        obj.pAddListener( event.listener( obj.MessageService, 'BestChange', ...
            @( s, e ) obj.pPostSetBest ) );
        obj.pAddListener( event.listener( obj.MessageService, 'ConstraintChange', ...
            @( s, e ) obj.pPostSetConstraint ) );
        end
        
        function createFileMenu(obj,menuFile)
        %createFileMenu create file menus from actions 
        
        % File Menu items
        obj.FileActionGroup.createMenuItem(  menuFile );
        obj.ExportToSimulink.createMenuItem( menuFile );
        end
        
        function  createEditMenu(obj,menuEdit)
        %createEditMenu create edit menu from actions 

        obj.EditActionGroup.createMenuItem( menuEdit );
        obj.BestActionGroup.createMenuItem( menuEdit );

        end
    end
    
    methods (Access=private)
        %----------------------------------------
        function deleteConstraint(obj)
        %DELETECONSTRAINT Delete a constaint from the boundary dev tree
        %  DELETECONSTRAINT(OBJ)
        
        bms = obj.MessageService;
        pr = bms.Root;
        cn = bms.CurrentNode;
        
        if isequal( cn, pr ),
            xregerror( 'Delete Boundary Model', 'Cannot delete root node.' );
        else
            p = cn.Parent;
            p.removebest( cn );
            p = cn.delete;
            bms.setCurrentNode( p );
        end
        
        end  % deleteConstraint
        
        %----------------------------------------
        function exportToSimulink(obj)
        %EXPORTTOSIMULINK Export the current constraint to Simulink
        %   EXPORTTOSIMULINK(OBJ)
        
        bms = obj.MessageService;
        
        name = sprintf( '%s_Boundary', mbcMakeValidName( bms.CurrentNode.fullname));
        
        con = bms.getConstraint;
        con = setName( con, name );
        
        modelDir = mbcGetPath( 'mbcmodel', 'model' );
        currentDir  = cd( modelDir );
        extn = get_param(0,'ModelFileFormat');
        [filename, pathname] = uiputfile( ...
            {sprintf('*.%s',extn), sprintf('Simulink Model (*.%s)',extn)
            '*.*','All Files (*.*)'}, ...
            'Save As', name );
        cd( currentDir );
        
        if isequal( filename, 0 ) || isequal( pathname, 0 ),
            % User pressed cancel ==> nothing to do
        else
            mv2sl( con, fullfile( pathname, filename ) );
        end
        
        end  % exportToSimulink
        
        %----------------------------------------
        function makeBoundary(obj)
        %MAKEBOUNDARY Set-up and fit constraint
        %  MAKEBOUNDARY(OBJ)
        %
        %  See also SETUPCONSTRAINT, FITCONSTRAINT.
        
        
        BMS = obj.MessageService;
        CURRENT_NODE = BMS.CurrentNode;
        pr = BMS.Root;
        
        busy(BMS,'Creating new boundary model...');
        
        % Get the user to choose "response", "local" or global" node
        if pr.getnumstages == 2,
            % When we have two stage data we need to get the user to choose which
            % level they want to build constraints at.
            [level, ok] = i_ChooseLevel;
        else
            % Assume pr.getnumstages == 1
            ok = true;
            level = 1;
        end
        
        if ok
            bdev = CURRENT_NODE.makeBdryNode(level);
        end
        
        
        % Set up the constraint type and active factors
        if ok,
            [bdev, ok] = guiSetupConstraint( bdev,'Parent', obj.Owner );
            if ok,
                BMS.setCurrentNode( bdev );
            else
                i_CleanUpTreeNodes;
            end
        end
        
        idle(BMS)
        
        % Set the various constraint fit options and build the constriant
        %  -- This should be done by "@xregbdrygui\@Editor\fitConstraint" but we
        %     want to detect when the user clicks the 'Cancel' button.
        if ok
            bdev = fitConstraint(bdev, 'All');
            BMS.sendEvent( 'ConstraintChange' );
        end
        
        %--------------------------------------------------------------------------
            function i_CleanUpTreeNodes
            delete( bdev );
            BMS.setCurrentNode( CURRENT_NODE );
            end % of nested function i_CleanUpTreeNodes
        
        %--------------------------------------------------------------------------
            function [level, ok] = i_ChooseLevel
            
            LevelOrder = [1 2 0];
            if CURRENT_NODE==pr
                rbgroup = [];
                hDialog = mbcgui.dialog.StandardDialog( obj, ...
                    'PageInfoFunction', @i_LevelChooserInfo, ...
                    'DisplaySinglePageAsTab', false, ...
                    'Title', 'Choose Level',...
                    'Parent',obj.Owner);
                ok = hDialog.show;
                if ok,
                    level = LevelOrder(rbgroup.Selected) ;
                else
                    level = 0;
                end
                delete( hDialog );
            else
                level = LevelOrder(CURRENT_NODE.getstages==LevelOrder);
                ok = true;
            end
            
            %--------------------------------------------------------------------------
                function hInfo = i_LevelChooserInfo(~, hPageGroup)
                hInfo = mbcgui.dialog.PageInfo( ...
                    'PageGroup', hPageGroup, ...
                    'Name', 'Base Editor', ...
                    'PreferredWidth', 580, ...
                    'PreferredHeight', 320, ...
                    'HelpHandler', 'mv_helptool', ...
                    'HelpCode', '', ...
                    'CreateCallback', @i_CreateLevelChooserLayout);
                end % of nested function i_generateEditorPages
            
            %--------------------------------------------------------------------------
                function i_CreateLevelChooserLayout(hInfo, ~)
                figh = hInfo.Parent;
                
                rbgroup = xregGui.rbgroup( 'Parent', figh, ...
                    'nx', 1, 'ny', 3, ...
                    'String', {'Local'; 'Global';'Response'});
                % Note that CURRENT_NODE.getstages will be
                %   1 --> Local
                %   2 --> Global
                %   0 --> Response
                
                rbgroup.Selected = 3;
                
                txtHelp = uicontrol( ...
                    'Parent', figh,...
                    'Style', 'text',...
                    'HorizontalAlignment','left',...
                    'String', 'Select level to make boundary model for');
                layout = xreggridbaglayout( figh,...
                    'dimension', [3, 3],...
                    'rowsizes', [25, 60, -1],...
                    'colsizes', [50, 120, -1],...
                    'border', [30, 30, 30, 30],...
                    'MergeBlock', {[1, 1], [1, 3]}, ...
                    'elements', {
                    txtHelp, [], []
                    [], rbgroup, []
                    [], [], []} );
                
                hInfo.setUI( layout );
                end % of nested function i_CreateLevelChooserLayout
            
            end % of nested function i_ChooseLevel
        
        end % of main function makeBoundary
        
        %----------------------------------------
        function addToBestConstraint(obj)
        %ADDTOBESTCONSTRAINT
        %  ADDTOBESTCONSTRAINT(OBJ) Adds the current node to the list of best
        %  constraints for the parent of the current node
        
        bms = obj.MessageService;
        pr = bms.Root;
        cn = bms.CurrentNode;
        if isequal( cn, pr ),
            xregerror( 'Add Best Boundary Model', 'Cannot add root to list of best boundary models.' );
        else
            pn = cn.Parent;
            pn.addbest( cn );
            
            bms.sendEvent( 'BestChange' );
        end
        
        end  % addToBestConstraint
        
        %----------------------------------------
        function copyConstraint(obj)
        %COPYCONSTRAINT
        %  COPYCONSTRAINT(OBJ) Copy the current constraint node to make a new node.
        
        bms = obj.MessageService;
        cn = bms.CurrentNode;
        if cn.isa( 'xregbdryroot' ),
            xregerror( 'Copy Boundary Model', 'Cannot copy root node.' );
        else
            new = cn.duplicate;
            new = name( new, name(new) );
            
            bms.setCurrentNode( new );
            
        end
        
        end  % copyConstraint
        
        %----------------------------------------
        function removeFromBestConstraint(obj)
        %REMOVEFROMBESTCONSTRAINT
        %  REMOVEFROMBESTCONSTRAINT(OBJ) Remove the current node from the list of
        %  best constraints.
        
        bms = obj.MessageService;
        pr = bms.Root;
        cn = bms.CurrentNode;
        if isequal( cn, pr ),
            xregerror( 'Remove Best Boundary Model', ...
                'Cannot remove root node from the list of best boundary models.' );
        else
            pn = cn.Parent;
            pn.removebest( cn );
            
            bms.sendEvent( 'BestChange' );
        end
        
        end  % removeFromBestConstraint
        
        
        %----------------------------------------
        function ok = setupConstraint(obj)
        %SETUPCONSTRAINT Allow the user to set-up the constraint type and active factors
        %  SETUPCONSTRAINT(OBJ)
        
        bms = obj.MessageService;
        
        cn = bms.CurrentNode;
        if isa( cn, 'xregpointer' ) && cn.isa( 'xregbdrydev' ),
            busy(bms,'Editing model...');
            [new, ok] = guiSetupConstraint( cn.info, 'Parent', obj.Owner );
            idle(bms)
            
            if ok
                cn.info = new;
                % fit boundary model with default fit options
                [cn.info,~] = fitConstraint(cn.info, 'All');
                bms.sendEvent( 'NameChange' );
                bms.sendEvent( 'ConstraintChange' );
            end
            
        else
            xregerror( 'Boundary Model Settings', 'Cannot edit settings at root node' );
        end
        
        end  % setupConstraint
        
        %----------------------------------------
        function showBoundaryPoints(obj)
        %SHOWBOUNDARYPOINTS Respond to user turning boundary point highlighting on or off
        %   SHOWBOUNDARYPOINTS(OBJ)
        
        bms = obj.MessageService;
        
        if obj.ShowBoundaryPoints.Selected,
            bms.BoundaryPointHighlight = 'on';
        else
            bms.BoundaryPointHighlight = 'off';
        end
        
        bms.sendEvent( 'BoundaryPointsHighlight' );
        
        end  % showBoundaryPoints
        
        %----------------------------------------
        function showValidationPoints(obj)
        %SHOWVALIDATIONPOINTS Respond to user turning boundary point highlighting on or off
        %   SHOWVALIDATIONPOINTS(OBJ)
        
        bms = obj.MessageService;
        
        if obj.ShowValidationPoints.Selected
            bms.ValidationPointHighlight = 'on';
        else
            bms.ValidationPointHighlight = 'off';
        end
        
        bms.sendEvent( 'ValidationPointsToggled' );
        end  % showValidationPoints
        
        %----------------------------------------
        function pPostSetBest(obj)
        %PPOSTSETBEST Respond to a change in the best constraint
        %  PPOSTSETBEST(OBJ)
        %  If the best constraint changes at the current node then the current node
        %  can only be
        %  -- added if it is not
        %  -- removed if it is
        %  already a best constraint
        
        cn = obj.MessageService.CurrentNode;
        if isa( cn, 'xregpointer' ) && cn.isa( 'xregbdrynode' ),
            % Best constraint
            obj.AddBest.Enabled    = cn.canAddBest;
            obj.RemoveBest.Enabled = cn.canRemoveBest;
        end
        
        end  % pPostSetBest
        
        %----------------------------------------
        function pPostSetConstraint(obj)
        %PPOSTSETCONSTRAINT Respond to a change in the constraint at the current node
        %  PPOSTSETCONSTRAINT(OBJ)
        %  A change in the constraint affects the boundary editor in the following
        %  ways:
        %  -- Fitting of a constraint may or may not be possible. Also, if fitting
        %     is possible, only some combinations may be possible.
        %  -- If there is no constraint at the current node then it cannot be set
        %     as a best constraint
        
        bms = obj.MessageService;
        cn = bms.CurrentNode;
        if isa( cn, 'xregpointer' ) && cn.isa( 'xregbdrynode' ),
            % Export to Simulink
            obj.ExportToSimulink.Enabled = cn.canExportToSimulink;
            
            % Best constraint
            obj.AddBest.Enabled    = cn.canAddBest;
            obj.RemoveBest.Enabled = cn.canRemoveBest;
        end
        
        end  % pPostSetConstraint
        
        %----------------------------------------
        function pPostSetNode(obj)
        %PPOSTSETNODE Respond to a change in the current node
        %  PPOSTSETNODE(OBJ)
        %  A change in the current node has the following affects on the boundary
        %  editor:
        %  -- If the current node is not an XREGBDRYDEV then a constraint cannot be
        %     set-up (type and active factors)
        %  -- The ability to make new constraints, duplicate constraints and delete
        %     constraints is affected
        %  -- If the current node is some unknown type then all actions will be
        %     disabled.
        %  -- If the current node is a boundary dev (leaf node) then we enable the
        %     "show boundary points" action. Otherwise, we disable the action.
        
        BMS = obj.MessageService;
        cn = BMS.CurrentNode;
        if isa( cn, 'xregpointer' ) && cn.isa( 'xregbdrynode' ),
            % New, duplicate, delete
            obj.MakeBoundary.Enabled    = cn.canNewConstraint;
            obj.CopyConstraint.Enabled   = cn.canCopyConstraint;
            obj.DeleteConstraint.Enabled = cn.canDeleteConstraint;
            % Constraint fitting
            obj.SetupConstraint.Enabled  = cn.canSetupConstraint;
            % Boundary Point Highlighting
            obj.ShowBoundaryPoints.Enabled = cn.isa( 'xregbdrydev' );
            % Validation Point Highlighting
            validationPointsEnabled = cn.supportsValidationData() && ~isempty(cn.getvalidationdata('stage', 'response'));
            obj.ShowValidationPoints.Enabled = validationPointsEnabled;
        else
            % Disable all the actions
            set( obj.FileActionGroup.Actions, 'Enabled', false );
            set( obj.EditActionGroup.Actions,  'Enabled', false );
            set( obj.BestActionGroup.Actions, 'Enabled', false );
        end
        
        end  % pPostSetNode
        
        %----------------------------------------
        function pPostSetRoot(obj)
        %PPOSTSETROOT Respond to a change in the current node
        %  PPOSTSETROOT(OBJ)
        %  A change in the root node has the following affects on the boundary
        %  editor:
        %  -- If the root node is a pointer to xregbdryroot then we enable the "Make
        %     Bdry Model" action
        
        pr = obj.MessageService.Root;
        set( obj.MakeBoundary, 'Enabled', ...
            isa( pr, 'xregpointer' ) && pr.isa( 'xregbdryroot' ) );
        
        end  % pPostSetRoot
        
        function pAddListener(obj, varargin)
        %PADDLISTENER Add a listener to the list held by the boundary editor
        %  PADDLISTENER(OBJ, LISTENER) adds the given LISTENER to the list of
        %  listeners held by the Editor (OBJ).
        %
        %  if you want PADDLISTENER( OBJ, handle.listener( <arguments> ) ), then use
        %  PADDLISTENER( OBJ, <arguments> ).
        
        if nargin == 2,
            obj.Listeners = [obj.Listeners; varargin{1}];
        else
            obj.Listeners = [obj.Listeners; varargin{:} ];
        end
        end
    end
    
end