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);