www.gusucode.com > mbcdesign 工具箱 matlab 源码程序 > mbcdesign/+xregdesgui/DesignEditorTree.m

    classdef DesignEditorTree < handle
    %DesignEditorTree maintains the design tree data, the UITree and the message
    %service package xregdesgui.package for use by the design editor
    
    %  Copyright 2011-2015 The MathWorks, Inc.
    
    properties(SetAccess=protected)
        %DESIGNTREE data
        DesignTree
        %UITREE graphical tree
        UITree = mbctreeadapter.NullTree;
        %PACKAGE xregdesgui.package message service for design editor
        Package
        %Actions design editor actions
        Actions
    end
    
    properties (Dependent)
        %CURRENTINDEX index to current design
        CurrentIndex
        %CHOSENINDEX index to chosen design
        ChosenIndex
        %CURRENTDESIGN current design (xregdesign)
        CurrentDesign
        %ROOT runtime pointer to root of design tree
        Root
        %CURRENT runtime pointer to current design
        Current
        %LIST list of runtime pointers to all design tree
        List
        %CHOSEN runtime pointer to chosen design
        Chosen
        %LOCKED lock the design tree
        Locked
    end
    
    properties(Access=private)
        Listeners
        DataChanged=false;
        QuietUpdate = false;
    end
    
    methods
        function D = DesignEditorTree(varargin)
        %DESIGNEDITORTREE design editor tree
        %  D = DesignEditorTree()
        %  D = DesignEditorTree(struc)
        
        D.DesignTree = mbctreeadapter.DesignTree;
        if nargin
            %load the design tree
            loadTree(D,varargin{:});
        end
        %create the message service
        D.Package = xregdesgui.DesignPackage();
        D.Actions = xregdesgui.Actions(D);
        % 1. listen to changes in current design pointer so I can suck them back into main pointer list
        % 2. listen to item changes in current so that the Constraints can be checked etc
        % 3. listen to changes in current design pointer to detect data corruption
        %    in tree callback
        D.Listeners=[ ...
            D.Package.addlistener('AnyChange',@(h,evt) iGetDesignChange(h,evt,D))...
            D.Package.addlistener('ItemChange',@(h,evt) iItemChange(h,evt,D)) ...
            D.Package.addlistener('AnyChange',@(h,evt) iTrackDesignChange(h,evt,D))];
        D.Listeners(3).Enabled = false;
        end
        
        function c=get.Current(D)
        c = D.DesignTree.Current;
        end
        
        function c=get.List(D)
        c = D.DesignTree.List;
        end
        function c=get.Chosen(D)
        c = D.DesignTree.Chosen;
        end
        
        function set.Locked(D,Locked)
        D.DesignTree.Locked = Locked;
        updateAll(D.UITree)
        end
        
        function Locked = get.Locked(D)
        Locked = D.DesignTree.Locked;
        end
        
        function r=get.Root(D)
        r= D.DesignTree.Root;
        end
        
        function ind=get.CurrentIndex(D)
        ind = D.DesignTree.CurrentIndex;
        end
        
        function set.CurrentIndex(D,ind)
        select(D,ind);
        end
        
        function ind=get.ChosenIndex(D)
        ind = D.DesignTree.ChosenIndex;
        end
        
        function set.ChosenIndex(D,ind)
        
        pOldChosen = D.DesignTree.Chosen;
        D.DesignTree.ChosenIndex = ind;
        
        D.DesignTree.ChosenIndex = ind;
        if ~isempty(ind)
            pdes = findDesign(D,ind);
            D.UITree.Chosen = pdes;
            update(D,pdes)
        end
        if ~isempty(pOldChosen)
            update(D,pOldChosen)
        end
        end
        
        function des = get.CurrentDesign(D)
        des = D.DesignTree.CurrentDesign;
        end
        
        function set.CurrentDesign(D,des)
        D.DesignTree.CurrentDesign = des;
        update(D,D.CurrentIndex);
        end
    end % set/get methods
    
    methods
        
        function createUITree(D,varargin)
        %CREATEUITREE create UI tree for designtree
        D.UITree = mbctreeadapter.UIDesignTree(varargin{:},'Chosen',D.DesignTree.Chosen);
        end
        
        function refresh(D,root,CurrentIndex)
        %REFRESH refresh the design tree data and UI tree
        %   refresh(D,root)
        if nargin<2
            root = D.DesignTree.Root;
        end
        if nargin<3
            CurrentIndex = 1;
        end
        refresh(D.DesignTree,root)
        refresh(D.UITree,root,Inf,root)
        D.ChosenIndex = D.DesignTree.ChosenIndex;
        D.CurrentIndex = CurrentIndex;
        
        end
        
        function select(D,pdes)
        %SELECT select a design
        %   select(D,pdes)
        %     pdes can be an index to the design list or a runtime pointer
        
        oldind= D.CurrentIndex;
        
        if nargin<2;
            pdes= D.CurrentDesign;
        end
        pdes=findDesign(D,pdes);
        select(D.DesignTree,pdes);
        select(D.UITree,pdes);
        
        if D.CurrentIndex==1
            % select the null view for the root
            des=[];
        else
            des = pdes.info;
        end
        if D.CurrentIndex==1 && oldind==0
            % initialize the design editor on openning
            D.Package.setdesign(des);
        else
            % change node
            D.Package.setdesign(des,'item');
        end
        
        end
        
        function pdes=add(D,des,parent)
        %ADD add a design to the design tree data and node
        %   pdes=add(D,des,parent)
        %       des is an xregdesign
        %       parent can be an index to the design list or an index. By
        %       default, parent is the current design
        
        if nargin<3
            parent=D.DesignTree.Current;
        else
            parent = findDesign(D,parent);
        end
        % add design to the design data
        pdes = add(D.DesignTree,des,parent);
        %add the design to the ui tree
        add(D.UITree,pdes);
        %update the design and select it
        update(D,parent);
        select(D,D.CurrentIndex)
        
        end
        
        function rename(D,pdes,NewName)
        %RENAME rename treenode
        %   rename(D,pdes,NewName)
        
        pdes = findDesign(D,pdes);
        if ~any(strcmp(NewName,D.DesignTree.AllNames))
            % update name only if it is unique
            pdes.info = name(pdes.info,NewName);
            D.Package.setdesign(pdes.info, 'name');
        end
        %update and locks and names
        update(D,pdes);
        end
        
        function update(D,pdes,des)
        %UPDATE update tree node
        %   update(D,pdes,des)
        %      pdes can be an index to the design list or a runtime pointer.
        %      A xregdesign object can be supplied to update the tree data
        
        pdes = findDesign(D,pdes);
        if nargin>2
            % only do update if design is not in message service
            doUpdate = ~D.QuietUpdate;
            pdes.info=des;
        else
            doUpdate = false;
        end
        
        update(D.DesignTree,pdes);
        update(D.UITree,pdes);
        if doUpdate && isequal(pdes,D.DesignTree.Current)
            %send message to design editor
            D.Package.setdesign(pdes.info,'design');
        end
        
        end
        
        function remove(D,pdes)
        %REMOVE remove design from the design tree data and uitree
        %   remove(D,pdes)
        
        pdes = findDesign(D,pdes);
        parent = getParent(D.DesignTree,pdes);
        remove(D.DesignTree,pdes);
        remove(D.UITree,pdes);
        update(D,parent)
        select(D,parent);
        end
        
        function lockNode(D,pdes)
        %LOCKNODE lock a node in the tree
        
        if nargin<2
            pdes = D.Current;
        else
            pdes = findDesign(D,pdes);
        end
        lockNode(D.DesignTree,pdes);
        %update any icons
        update(D,pdes);
        end
        
        function unlockNode(D,pdes)
        %UNLOCKNODE unlock specified design
        %  unlockNode(D) unlocks the current design
        %  unlockNode(D,pdes) unlocks the specified design
        
        if nargin<2
            pdes = D.Current;
        else
            pdes = findDesign(D,pdes);
        end
        unlockNode(D.DesignTree,pdes);
        
        update(D,pdes);
        end
        
        function OK = isLocked(D,pdes)
        OK = isLocked(D.DesignTree,pdes);
        end
        
        
        function loadTree(D,struc,Locked)
        %LOADTREE load tree from Design Tree structure as stored MBCMODEL
        %projects
        %   loadTree(D,s,Locked)
        %       s.designs: cell array of xregdesigns
        %       s.parents: index to parent nodes
        %       s.CurrentIndex currently selected index
        %       s.chosen:  index to chosen design
        
        if nargin<3
            Locked = false;
        end
        loadTree(D.DesignTree,struc,Locked);
        %redraw the tree
        if isfield(struc,'CurrentIndex')
            % selected node is saved in design tree structure
            Index = struc.CurrentIndex;
        else
            % select the root node
            Index = 1;
        end
        
        refresh(D,D.Root,Index);
        end
        
        function s = saveTree(D)
        %SAVETREE save tree into MBCMODEL structure
        %    s = saveTree(D)
        %       s.designs: cell array of xregdesigns
        %       s.parents: index to parent nodes
        %       s.chosen:  index to chosen design
        %       s.CurrentIndex currently selected index
        
        s = saveTree(D.DesignTree);
        s.CurrentIndex = D.CurrentIndex;
        end
        
        function clear(D)
        %CLEAR clear design tree data and UITree
        %   clear(D)
        clear(D.DesignTree);
        clear(D.UITree);
        end
        
        function enable(T)
        %   enable(T)
        %ENABLE enable uitree
        enable(T.UITree);
        end
        
        function disable(T)
        %DISABLE disable uitree
        %   disable(T)
        disable(T.UITree);
        end
        
        function updateAll(T)
        %UPDATEALL update all nodes in tree
        %   updateAll(T)
        
        updateAll(T)
        updateAll(T.UITree);
        % update current design
        if D.CurrentIndex~=1
            D.Package.setdesign(D.CurrentDesign,'lock');
        else
            D.Package.setdesign([],'lock');
        end
        
        end
        
        function setEditableNodes(T,p,State)
        %setEditableNodes set editable nodes in UITree
        %   setEditableNodes(T,p,State)
        setEditableNodes(T.UITree,p,State)
        end
        
        function expand(T,p)
        %expand expand tree from node
        %    expand(T,p)
        expand(T.UITree,p)
        end
        
        function ch = getChildren(T,p)
        %getChildren get children of node
        %    ch = getChildren(T,p)
        ch = getChildren(T.DesignTree,p);
        end
        
        function parent = getParent(T,p)
        %getParent get parent of node
        %   parent = getParent(T,p)
        parent = getParent(T.DesignTree,p);
        end
        
        function busy(obj,varargin)
        %busy make design editor busy
        busy(obj.Package,varargin{:})
        end
        
        function idle(obj)
        %idle make design editor idle
        idle(obj.Package)
        end
    end
    
    methods(Access=protected)
        function pdes=findDesign(D,pdes)
        %findDesign find design in tree
        %   pdes=findDesign(D,pdes)
        %   pdes can be an index or runtime pointer
        pdes = findDesign(D.DesignTree,pdes);
        end
    end
    
end




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                          %
%  Functions to maintain main data integrity and provide   %
%  access to data                                          %
%                                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function iGetDesignChange(~,~,D)
% get the design from the "current" package object and place it
% back into the list
des=D.Package.getdesign;
if ~isempty(des)
    D.QuietUpdate = true;
    D.CurrentDesign = des;
    D.QuietUpdate = false;
end
end

function iTrackDesignChange(~,~,D)
% Remember the fact that the design has been updated
D.DataChanged = true;
end

function iItemChange(~,~,D)
% this function is one of the first callbacks fired when the current item changes
dpackage=D.Package;
des=dpackage.getdesign;
if ~isempty(des)
    D.DataChanged = false;
    D.Listeners(3).Enabled = true;
    if getstyle(des)==1
        des=updatestores(des);
    end
    
    D.Listeners(3).Enabled = false;
    
    % We know that the above call may flush the event queue when this is an
    % tree callback.  To prevent data corruption, we have a listener on
    % the current design that is only active during activex callbacks.  If
    % this flag is set then the result from the updatestores is discarded.
    % This means the user will have to see the progress bars again, but
    % their data is not corrupted.
    if ~D.DataChanged
        % put design back into list and current
        dpackage.setdesign(des);  % a quiet update
        D.QuietUpdate = true;
        D.CurrentDesign = des;
        D.QuietUpdate = false;
    end
end
end