www.gusucode.com > mbcview 工具箱matlab源码程序 > mbcview/@cgtools/@exprview/update.m

    function update(obj)
%UPDATE Redraw the expression view
%
%  UPDATE(OBJ) redraws the expression graph.

%  Copyright 2000-2010 The MathWorks, Inc. and Ford Global Technologies, Inc.


expr = obj.RootExpression;

ax = obj.hAxes;

% Clear the axes
ax.clear;

% Clear the selection
obj.pUpdateSelection(xregpointer);

if ~isnull(expr)
    % for each input, get the pointer, level and parent
    [plist,level,parent] = layerinfo(expr.info,2,expr);
    plist = [expr plist];
    level = [1 level];
    parent = [xregpointer parent];

    nlevels = max(level);

    % find the number of unique items on each level
    for i = 1:nlevels
        levelind = (level==i); % indices in plist of the items in level i
        level_ptrs = plist(levelind);
        uniqlevel_ptrs = unique(level_ptrs);
        % number of items on each level
        nlevelitems(i) = length(uniqlevel_ptrs);
    end

    % what is the maximum number of items on any level
    maxlevelitems = max(nlevelitems);

    % Determine the total space for the connections
    % The additional 30 adds space at the left and the bottom
    axiswidth = 130*nlevels +30;
    axisheight = 80*maxlevelitems + 30;
    obj.CanvasSize = [axiswidth, axisheight];

    set(obj.hAxes,'XLim',[0 axiswidth],'YLim',[0 axisheight], ...
        'Xdataperpixel', 1/obj.ZoomFactor, 'Ydataperpixel', 1/obj.ZoomFactor);

    sortplist = [];
    parentind = [];
    line_coords = zeros(sum(nlevelitems), 2);
    coordIdx = 1;
    for i = 1:nlevels
        levelind = find(level==i); % indices in plist of the items in level i
        level_ptrs = plist(levelind);
        level_parents = parent(levelind);

        [uniqlevel_ptrs] = unique(level_ptrs);

        for j = 1:length(uniqlevel_ptrs)
            ind = find(uniqlevel_ptrs(j) == level_ptrs);
            parentsj = level_parents(ind);

            % find the parents in the above level list
            [junk, parind] = intersect(double(sortplist(sum(nlevelitems(1:i-2))+1:sum(nlevelitems(1:i-1)))),double(parentsj));
            % index of the parents in sortplist
            parentind = [parentind {sum(nlevelitems(1:i-2)) + parind}];
        end

        sortplist = [sortplist uniqlevel_ptrs];
        for j = 1:nlevelitems(i)
            % middle of the block
            line_coords(coordIdx, :) = [axiswidth+50-(i*130),axisheight+15-(j*80)];
            coordIdx = coordIdx + 1;
        end
    end

    %connect each item in the level to its parent
    i_DrawLines(sortplist,parentind,line_coords,obj);

    % Decide on fontsize to use according to zoom factor
    FontSz = get(mbcgui.hgclassesutil.toNative(obj.Parent), 'DefaultTextFontSize')*obj.ZoomFactor;
    sortobjlist = infoarray(sortplist);
    for k = 1:length(sortplist)
        % Call an object method to create the block
        rh = ax.construct(@(ax) block(sortobjlist{k}, ax));
        
        % Add a context menu to non-input expresssions
        if isddvariable(sortobjlist{k})
            ContextMenu = [];
            HitT = 'off';
        else
            ContextMenu = obj.BlockContextMenu;
            HitT = 'on';
        end
        set(rh, ...
            'Position',[line_coords(k,1)-50, line_coords(k,2)-15,100,30],...
            'HitTest', HitT, ...
            'UIContextMenu',ContextMenu,...
            'ButtonDownFcn', {@i_selectitem, obj, sortplist(k)});
        name = getname(sortobjlist{k});
        hT = text(ax,...
            'Position',[line_coords(k,1)-45, line_coords(k,2)],...
            'Interpreter','none',...
            'String',name,...
            'FontSize',FontSz');
        ext = get(hT, 'Extent');
        if ext(3)>100
            name_len = length(name);
            name = [name(1:floor(name_len*(90/ext(3)))-1) '...'];
            set(hT, 'String', name);
        end
    end
end


%---------------------------------------------
function i_DrawLines(ptr,parentind,line_coords, obj)

ax = obj.hAxes;

for i = 1:length(ptr)
    parent_coords = line_coords(parentind{i},:);
    if ~isempty(parent_coords)
        node_coords = line_coords(i,:);

        % draw the line connecting the nodes
        for j =1:size(parent_coords,1) % can have more than one parent
            line(ax, ...
                'XData',[node_coords(1),parent_coords(j,1)],...
                'YData',[node_coords(2),parent_coords(j,2)],...
                'Color','k',...
                'LineWidth',1);

            x(1)= node_coords(1);
            x(2)= parent_coords(j,1);
            y(1)= node_coords(2);
            y(2)= parent_coords(j,2);

            k= 9;    %scale factor for arrow  size
            k2 = 4;   %scale factor for arrow width
            delx = x(2)-x(1);
            dely = y(2)-y(1);

            len =(delx^2 +dely^2)^.5;

            %normalised gradient
            dx = delx/len;
            dy = dely/len;

            %find midpoint
            x(3) = 0.5*(x(1)+x(2));
            y(3) = 0.5*(y(1)+y(2));

            %step back a distance k from midpoint along line
            x(4) = x(3)-k*dx;
            y(4) = y(3)-k*dy;

            %step out to the sides
            x(5) = x(4) + k2*dy;
            y(5) = y(4) - k2*dx;

            x(6) = x(4) - k2*dy;
            y(6) = y(4) + k2*dx;

            % add the arrow
            arrx = [x(3) x(5) x(6) x(3)];
            arry = [y(3) y(5) y(6) y(3)];

            % create a polygonal patch (arrow)
            patch(ax, ...
                'XData',arrx, ...
                'YData', arry, ...
                'FaceColor','k', ...
                'EdgeColor','k');
        end
    end
end


% Callback that selects a clicked block
function i_selectitem(src, evt, obj, pItem)
obj.pUpdateSelection(pItem);