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];
 }
Exemple #3
0
        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));
 }
Exemple #11
0
 public ArrayList FetchKids(TreeNodeBase nodebase)
 {
     Debug.Assert(nodebase.allkids != null);
     return(nodebase.allkids);
 }
Exemple #12
0
 /* 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);
 }