public DiffCallTreeForm(TreeNodeBase root, AllocationDiff allocDiff) { this.Root = root; this._allocDiff = allocDiff; InitForm(); }
public Color GetColor(object obj, TreeNodeBase root, bool positive) { //###TreeNode node = (TreeNode)root; DiffDataNode node = (DiffDataNode)root; int idx = (int)node.nodetype + (positive ? 0 : 3); return new Color[] { Color.Black, Color.Green, Color.BlueViolet, Color.White, Color.Yellow, Color.Beige }[idx]; }
public DiffCallTreeForm([NotNull] TreeNodeBase root, [NotNull] AllocationDiff allocDiff) { this.Root = root; this._allocDiff = allocDiff; Controls.Clear(); controlCollection?.Controls.Clear(); InitializeComponent(); defaultFont = new Font(new FontFamily("Tahoma"), 8); var treeView = new DiffTreeListView(this); treeView.Dock = DockStyle.Fill; treeView.Font = defaultFont; var sort = new SortingBehaviour(sortingOrder: -1, counterId: -1); var highlight = new SortingBehaviour(sortingOrder: -1, counterId: 2); /* add columns */ treeView.AddColumn(new ColumnInformation(-1, "Function name", ColumnInformation.ColumnTypes.Tree), 250); foreach (int counter in DiffStatistics.DefaultCounters) { AddColumn(treeView, counter); } treeView.ColumnClick += new EventHandler(SortOn); treeView.ViewState = new ViewState(sort, highlight); treeView.Root = Root; treeView.Size = new System.Drawing.Size(332, 108); treeView.Visible = true; controlCollection.Controls.Add(treeView); SetcallTreeView(); this.Visible = true; }
private void treeListBox_MouseDown(object s, MouseEventArgs e) { int index = treeListBox.IndexFromPoint(e.X, e.Y); if (index == ListBox.NoMatches) { return; } TreeNodeBase node = (TreeNodeBase)Items[index]; if (e.Button == MouseButtons.Left) { int offset = node.depth * (treeListBox.ItemHeight - 1) - leftEdge; if (offset <= e.X && e.X < offset + (treeListBox.ItemHeight - 1)) { ToggleBranch(index); } } else { // Customize the context menu ContextMenu contextMenu = this.ContextMenu; ColumnInformation ci = ((DiffColumn)columns[0]).ColumnInformation; string fnName = treeOwner.GetInfo(TokenObject, node, ci).ToString(); ContextSelection = index; EventHandler eventHandler = new EventHandler(this.ContextMenu_Selection); contextMenu.MenuItems.Clear(); contextMenu.MenuItems.Add(new MenuItem("Save to...", eventHandler)); //contextMenu.MenuItems.Add( new MenuItem( "Save forward ...", eventHandler)); //contextMenu.MenuItems.Add( new MenuItem( "Save backward ...", eventHandler)); } }
/* returns data about the item for a given counter. * object's ToString() is used to display that data */ private object GetInfo(object obj, TreeNodeBase node, int counterId) { long number = 0; DiffDataNode root = (DiffDataNode)node; if(counterId < 0) { return root.name; } else { number = root.data.GetCounterValue(counterId); } /* use empty string to denote `0` */ if(number == 0) { return ""; } return number; }
/* returns font used to display the item (part of the ITreeOwner interface) */ public Font GetFont(object obj, TreeNodeBase in_node) { DiffDataNode node = (DiffDataNode)in_node; FontStyle fs = FontStyle.Regular; if(node.data.firstTimeBroughtIn) { fs |= FontStyle.Italic; } if(node.highlighted) { fs |= FontStyle.Bold; } return (fs == FontStyle.Regular ? defaultFont : new Font(defaultFont, fs)); }
public ArrayList FetchKids(object tokenObject, TreeNodeBase nodebase) { return nodebase.allkids; }
/* Get the id of the selected allocation or call node */ public int GetNodeId( TreeNodeBase node ) { TreeNode n = (TreeNode)node; int id = -1; if(n.nodetype == TreeNode.NodeType.AssemblyLoad) { return id; } /* other special cases */ if(n.stackid <= 0) { return id; } int[] stacktrace = IndexToStacktrace(n.stackid); switch(n.nodetype) { case TreeNode.NodeType.Allocation: id = stacktrace[0]; break; case TreeNode.NodeType.Call: id = stacktrace[stacktrace.Length - 1]; break; } return id; }
/* read kids of a node from the backing store */ public ArrayList FetchKids(object tokenObject, TreeNodeBase nodebase) { TreeNode node = (TreeNode)nodebase; ArrayList kids = new ArrayList(); for(long offset = node.kidOffset; offset != -1; offset = node.prevOffset) { reader.Position = offset; node = new TreeNode(reader); node.HasKids = (node.kidOffset != -1); kids.Add(node); } return kids; }
/* returns data about the item for a given counter. * object's ToString() is used to display that data */ public object GetInfo(object obj, TreeNodeBase node, ColumnInformation info) { return(GetInfo(obj, node, info == null ? -1 : (int)info.Token)); }
public ArrayList FetchKids(TreeNodeBase nodebase) { Debug.Assert(nodebase.allkids != null); return(nodebase.allkids); }
/* returns data about the item for a given counter. * object's ToString() is used to display that data */ public object GetInfo(TreeNodeBase node, ColumnInformation info) { return(GetInfo(node, info == null ? -1 : info.Token)); }
private void Resort(int depth, TreeNodeBase root) { root.depth = depth; treeListBox.Items.Add(root); if(root.allkids != null && root.IsExpanded) { ArrayList nodes = treeOwner.ProcessNodes(TokenObject, root.allkids); for(int i = 0; i < nodes.Count; i++) { Resort(1 + depth, (TreeNodeBase)nodes[i]); } } }
void ToggleBranch(int index) { TreeNodeBase node = (TreeNodeBase)Items[index]; if (!node.HasKids) { /*node.allkids = treeOwner.FetchKids(TokenObject, node); * if(node.allkids.Count ==0) * { * return; * }*/ return; } int count = Items.Count; if (node.IsExpanded) { index++; int upTo = index; TreeNodeBase kid = null; // eh, hopefully item access is cheap ListBox.ObjectCollection items = treeListBox.Items; while (upTo < count && (kid = (TreeNodeBase)items[upTo]).depth > node.depth) { kid.IsExpanded = false; upTo++; } int i, nodesInList = items.Count; int toRemove = upTo - index; int costOfRemoveAt = toRemove * (1 + nodesInList - upTo); int costOfRebuilding = 2 * nodesInList + 3 * (nodesInList - (upTo - index)); if (costOfRemoveAt < costOfRebuilding) { for (i = upTo; i-- > index;) { items.RemoveAt(i); } } else { object[] allNodes = new object[nodesInList - toRemove]; for (i = 0; i < index; i++) { allNodes[i] = items[i]; } for (i = upTo; i < nodesInList; i++) { allNodes[i - toRemove] = items[i]; } ReplaceContents(allNodes); } node.IsExpanded = false; } else { AddAfter(index, node); node.IsExpanded = true; } }
private void treeListBox_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { /* 0 stands for SB_HORZ */ int leftEdge = GetScrollPos(treeListBox.Handle, 0); if (leftEdge != this.leftEdge) { this.leftEdge = leftEdge; RedoColumnLayout(); } int position = 0; Graphics g = e.Graphics; ListBox treeView = treeListBox; if (e.Index < 0 || e.Index >= treeView.Items.Count) { return; } StringFormat sf = new StringFormat(StringFormatFlags.NoWrap); sf.Trimming = StringTrimming.EllipsisCharacter; TreeNodeBase node = (TreeNodeBase)Items[e.Index]; int crossover = (treeListBox.ItemHeight - 1) * (1 + node.depth); g.FillRectangle(new SolidBrush(Color.White), position, e.Bounds.Top, crossover, e.Bounds.Height); Rectangle itemRect = new Rectangle(crossover, e.Bounds.Top, e.Bounds.Right - crossover, e.Bounds.Height); g.FillRectangle(new SolidBrush(e.BackColor), itemRect); if (e.State == DrawItemState.Focus) { ControlPaint.DrawFocusRectangle(g, itemRect, e.ForeColor, e.BackColor); } Pen grayPen = new Pen(Color.LightGray); g.DrawLine(grayPen, 0, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom - 1); Font fontToUse = treeOwner.GetFont(TokenObject, node); Color color = treeOwner.GetColor(TokenObject, node, (e.State & DrawItemState.Selected) != DrawItemState.Selected); Brush brush = new SolidBrush(color); Region oldClip = g.Clip; foreach (DiffColumn c in columns) { ColumnInformation current = c.ColumnInformation; Rectangle rect = new Rectangle(position, e.Bounds.Top, c.Width, e.Bounds.Height); g.Clip = new Region(rect); string res = treeOwner.GetInfo(TokenObject, node, current).ToString(); if (current.ColumnType == ColumnInformation.ColumnTypes.Tree) { rect.Offset((1 + node.depth) * (treeListBox.ItemHeight - 1), 0); rect.Width -= (1 + node.depth) * (treeListBox.ItemHeight - 1); if (node.HasKids) { Pen p = new Pen(Color.Gray); int y0 = e.Bounds.Top; int x0 = position + node.depth * (treeListBox.ItemHeight - 1); g.DrawRectangle(p, x0 + 3, y0 + 3, (treeListBox.ItemHeight - 9), (treeListBox.ItemHeight - 9)); g.DrawLine(p, x0 + 5, y0 + (treeListBox.ItemHeight - 3) / 2, x0 + (treeListBox.ItemHeight - 8), y0 + (treeListBox.ItemHeight - 3) / 2); if (!node.IsExpanded) { g.DrawLine(p, x0 + (treeListBox.ItemHeight - 3) / 2, y0 + 5, x0 + (treeListBox.ItemHeight - 3) / 2, y0 + (treeListBox.ItemHeight - 8)); } } } if (res != null) { int characters, lines; SizeF layoutArea = new SizeF(rect.Width, rect.Height); SizeF stringSize = g.MeasureString(res, fontToUse, layoutArea, sf, out characters, out lines); g.DrawString(res.Substring(0, characters) + (characters < res.Length ? "..." : ""), fontToUse, brush, rect.Location, sf); g.DrawLine(grayPen, rect.Right - 1, e.Bounds.Top, rect.Right - 1, e.Bounds.Bottom - 1); } position += c.Width; } g.Clip = oldClip; }
private void treeListBox_MouseDown(object s, MouseEventArgs e) { int index = treeListBox.IndexFromPoint(e.X, e.Y); if (index == ListBox.NoMatches) { return; } TreeNodeBase node = (TreeNodeBase)Items[index]; if (e.Button == MouseButtons.Left) { int offset = node.depth * (treeListBox.ItemHeight - 1) - leftEdge; if (offset <= e.X && e.X < offset + (treeListBox.ItemHeight - 1)) { ToggleBranch(index); } } else { // Customize the context menu ContextMenu contextMenu = this.ContextMenu; ColumnInformation ci = ((Column)columns[0]).ColumnInformation; string fnName = treeOwner.GetInfo(TokenObject, node, ci).ToString(); String strFn; CallTreeForm.FnViewFilter[] filterFns; ContextSelection = index; EventHandler eventHandler = new EventHandler(this.ContextMenu_Selection); contextMenu.MenuItems.Clear(); contextMenu.MenuItems.Add(new MenuItem("Find...", eventHandler)); contextMenu.MenuItems.Add(new MenuItem("Find " + fnName + " forward", eventHandler)); contextMenu.MenuItems.Add(new MenuItem("Find " + fnName + " backward", eventHandler)); filterFns = treeOwner.GetIncludeFilters(); for (int i = 0; i < 2; i++) { if (filterFns[i].functionId > 0) { if (filterFns[i].nodetype == TreeNode.NodeType.Call) { strFn = treeOwner.MakeNameForFunction(filterFns[i].functionId); } else { strFn = treeOwner.MakeNameForAllocation(filterFns[i].functionId, 0); } } else { strFn = "none"; } contextMenu.MenuItems.Add(new MenuItem("Set Include filter " + (i + 1).ToString() + " (" + strFn + ")", eventHandler)); } filterFns = treeOwner.GetExcludeFilters(); for (int i = 0; i < 2; i++) { if (filterFns[i].functionId > 0) { if (filterFns[i].nodetype == TreeNode.NodeType.Call) { strFn = treeOwner.MakeNameForFunction(filterFns[i].functionId); } else { strFn = treeOwner.MakeNameForAllocation(filterFns[i].functionId, 0); } } else { strFn = "none"; } contextMenu.MenuItems.Add(new MenuItem("Set Exclude filter " + (i + 1).ToString() + " (" + strFn + ")", eventHandler)); } contextMenu.MenuItems.Add(new MenuItem("Clear Filters", eventHandler)); contextMenu.MenuItems.Add(new MenuItem("Regenerate Tree", eventHandler)); } }
/* returns data about the item for a given counter. * object's ToString() is used to display that data */ public object GetInfo(object obj, TreeNodeBase node, ColumnInformation info) { return GetInfo(obj, node, info == null ? -1 : (int)info.Token); }
private int AddAfter(int index, TreeNodeBase root) { if(root.allkids == null) { root.allkids = treeOwner.FetchKids(TokenObject, root); } ArrayList nodes = treeOwner.ProcessNodes(TokenObject, root.allkids); int numNodes = nodes.Count, nodesInList = treeListBox.Items.Count; int costOfRebuilding = 3 * (numNodes + nodesInList); int costOfInsertions = (1 + nodesInList - index) * numNodes; int i, newDepth = 1 + root.depth; if(costOfInsertions < costOfRebuilding) { foreach(TreeNodeBase curr in nodes) { curr.depth = newDepth; treeListBox.Items.Insert(++index, curr); } } else { ++index; ListBox.ObjectCollection items = treeListBox.Items; object[] allNodes = new object[numNodes + nodesInList]; for(i = 0; i < index; i++) { allNodes[i] = items[i]; } for(; i < index + numNodes; i++) { allNodes[i] = nodes[i - index]; ((TreeNodeBase)allNodes[i]).depth = newDepth; } for(; i < numNodes + nodesInList; i++) { allNodes[i] = items[i - numNodes]; } ReplaceContents(allNodes); } return index; }
public ArrayList FetchKids(object tokenObject, TreeNodeBase nodebase) { return(nodebase.allkids); }