www.gusucode.com > appdesigner工具箱matlab源码程序 > appdesigner/+appdesigner/+internal/+controller/DesignTimeController.m

    classdef DesignTimeController < handle
    %DESIGNTIMECONTROLLER This is a class that handles
    % AppDesigner specific actions such as generating code, CodeName or grouping.
    
    % Copyright 2015-2016 The MathWorks, Inc.
    
    % Controller properties
    properties(SetAccess='private')
        
        % An array of listener objects to ensure that listeners don't go
        % out of scope.  This is deleted when object is deleted.
        DesignTimeListener
        
        % This is the component model that will be updated in response to
        % design time events.
        DesignTimeModel
    end
    
    % Code gen related properties
    properties (Access = 'private')
        
        % Component specific adapter instance.  This adapter will be of
        % class 'VisualComponentAdapter.
        ComponentAdapter
        
    end
    
    methods (Abstract, Access = protected)
        
        % This method will handle property sets from client
        % It should update the model appropriately based on the event data
        handleComponentPropertiesSet(obj, src, event);
        
    end
    
    methods
        
        function obj = DesignTimeController(model, proxyView)
            
            %
            % Inputs:
            %
            %   model             The model being controlled by this
            %                     controller
            %
            %
            %   proxyView         Used when  the ProxyView is already
            %                     created.  When passed in, instead of
            %                     creating a new ProxyView, this ProxyView
            %                     is used instead.
            %
            %                     Should be [ ] when a view does not
            %                     exist.
            %
            %   codeGenerator     Object that knows how to generate code
            %                     using the component and the adapter.
            narginchk(2,3)
            
            obj.DesignTimeModel = model;
            
            % Add dynamic design time property to the model
            obj.addDesignTimeProperty();
            
            % ProxyView will be empty when controller is created in the
            % context of getting the design time defaults.  This may happen
            % in the method getComponentDesignTimeDefaults in the adapters
            if ~isempty(proxyView)
                % Set ComponentAdapter of Model
                obj.ComponentAdapter = proxyView.Adapter;
                
                % Listen for propertiesSet events on the peerNode
                obj.DesignTimeListener = ...
                    addlistener(proxyView.PeerNode,'propertiesSet', ...
                    @obj.handleDesignTimePeerNodeEvent);
                
                % Update code gen, CodeName, and GroupId design time properties
                designTimeProperties = obj.DesignTimeModel.DesignTimeProperties;
                designTimeProperties.updateProperties(model, proxyView.Adapter, proxyView);
                designTimeProperties.updateCode(model, proxyView.Adapter, proxyView);

            end
        end
        
        function delete(obj)
            % Clean up listeners
            delete(obj.DesignTimeListener);
        end
    end
    
    
    methods(Access = 'private')
        function handleDesignTimePeerNodeEvent(obj, src, event)
            % Private handler for the propertiesSet event being fired from
            % the PeerNode
            %
            % src: the PeerNode with the property change
            %
            % event: EventData provided through the peerNode framework
            
            % Handle Property Change events
            % This is handled by the sub class controller
            
            % We are only handling property sets from the client. Events
            % from the client have a non-empty originator.
                        
            valuesStruct = appdesservices.internal.peermodel.convertJavaMapToStruct(event.getData());
            isClientEvent = appdesservices.internal.peermodel.isEventFromClient(event);
            
            filteredValuesStruct = obj.handleDesignTimeProperties(valuesStruct, isClientEvent);
            
            if ~isempty(filteredValuesStruct)
                
                if isClientEvent  
                    % Update the model if the properties set happened
                    % from the client
                    handleComponentPropertiesSet(obj, src, filteredValuesStruct);
                  
                end
                designTimeProperties = obj.DesignTimeModel.DesignTimeProperties;

                % CodeGen update
                designTimeProperties.updateCode(obj.DesignTimeModel, obj.ComponentAdapter, obj.ProxyView);
            end
        end
        
        function unhandledPropertyValuesStruct = handleDesignTimeProperties(obj, valuesStruct, isClientEvent)
            % HANDLEDESIGNTIMEPROPERTIES - Filter app designer specific
            % properties that do not need to be handled by the component
            % controllers.
            % It is assumed that valuesStruct has two fields, 'newValues'
            % and 'oldValues'
            
            % These are properties that are appdesigner specific, these do
            % not need to be processed by the component controllers. After
            % processing them, remove form valuesStruct
            designTimePropertiesToHandle = {'CodeName', 'GroupId'};
            
            % Initialize struct
            unhandledPropertyValuesStruct = valuesStruct;
            
            for index = 1: numel(designTimePropertiesToHandle)
                % Verify that property is in the newValues field, and
                % update to the model's dynamic property before trying to
                % remove
                propertyName = designTimePropertiesToHandle{index};
                if isfield(valuesStruct.newValues, designTimePropertiesToHandle{index})
                    if isClientEvent
                        % Update the properties if the properties set happened
                        % from the client
                        obj.DesignTimeModel.DesignTimeProperties.(propertyName) = valuesStruct.newValues.(propertyName);
                    end
                    
                    unhandledPropertyValuesStruct.newValues = rmfield(valuesStruct.newValues, propertyName);
                    unhandledPropertyValuesStruct.oldValues = rmfield(valuesStruct.oldValues, propertyName);
                end
            end
            
            
            if(isClientEvent)
              
                if(isfield(valuesStruct.newValues, 'ComponentCode'))
                    unhandledPropertyValuesStruct.newValues = rmfield(valuesStruct.newValues, 'ComponentCode');
                end
            end
            
            % If there are no longer any property updates after filtering,
            % return empty.
            if isempty(fields(unhandledPropertyValuesStruct.newValues))
                unhandledPropertyValuesStruct = [];
            end
            
        end
        
        function addDesignTimeProperty(obj)
            
            % Dynamic design time properties for the model
            % In the loading case, the property is already in the model
            if ~isprop(obj.DesignTimeModel, 'DesignTimeProperties')
                addprop(obj.DesignTimeModel, 'DesignTimeProperties');
                
                % Set inital data for the design time property
                obj.DesignTimeModel.DesignTimeProperties = ...
                    appdesigner.internal.model.DesignTimeProperties();
            end
        end
    end
    
end