public void DrawTreeMap(IRenderer Renderer)
        {
            if (DoRevalue ||
                (ShowLayout != ShowNodes.All && XRay.CoverChange) ||
                (ShowLayout == ShowNodes.Instances && XRay.InstanceChange))
            {
                RecalcCover(InternalRoot);
                RecalcCover(ExternalRoot);

                XRay.CoverChange    = false;
                XRay.InstanceChange = false;

                DoRevalue = false;
                RevalueCount++;

                DoResize = true;
            }

            if (DoResize)
            {
                var drawArea = new RectangleF(ScreenOffset.X, ScreenOffset.Y, ScreenSize.Width, ScreenSize.Height);

                float offset      = 0;
                float centerWidth = drawArea.Width;

                PositionMap.Clear();
                CenterMap.Clear();

                if (ShowingOutside)
                {
                    offset       = drawArea.Width * 1.0f / 4.0f;
                    centerWidth -= offset;

                    InternalRoot.SetArea(new RectangleF(ScreenOffset.X, ScreenOffset.Y, offset - PanelBorderWidth, drawArea.Height));
                    PositionMap[InternalRoot.ID] = InternalRoot;
                    SizeNode(Renderer, InternalRoot, CurrentRoot, false);
                }
                if (ShowingExternal)
                {
                    float extWidth = drawArea.Width * 1.0f / 4.0f;
                    centerWidth -= extWidth;

                    ExternalRoot.SetArea(new RectangleF(ScreenOffset.X + offset + centerWidth + PanelBorderWidth, ScreenOffset.Y, extWidth - PanelBorderWidth, drawArea.Height));
                    PositionMap[ExternalRoot.ID] = ExternalRoot;
                    SizeNode(Renderer, ExternalRoot, null, false);
                }

                CurrentRoot.SetArea(new RectangleF(ScreenOffset.X + offset, ScreenOffset.Y, centerWidth, drawArea.Height));
                PositionMap[CurrentRoot.ID] = CurrentRoot;
                SizeNode(Renderer, CurrentRoot, null, true);

                DoResize = false;
                ResizeCount++;
            }
        }
Example #2
0
        public void DrawTheadline()
        {
            if (DoRevalue)
            {
                RecalcCover(InternalRoot);
                RecalcCover(ExternalRoot);

                DoRevalue = false;
                RevalueCount++;

                DoResize = true;
            }

            // set what nodes are allowed in the threadline based on the current root
            if (CurrentThreadlineZoom != CurrentRoot)
            {
                CenterMap.Clear();
                CenterMap.Add(CurrentRoot.ID);

                Utilities.RecurseTree <NodeModel>(
                    tree: CurrentRoot.Nodes,
                    evaluate: n => CenterMap.Add(n.ID),
                    recurse: n => n.Nodes);

                CurrentThreadlineZoom = CurrentRoot;
            }

            long currentTick = XRay.Watch.ElapsedTicks;

            if (!Paused)
            {
                CalcThreadline(currentTick);
            }

            LayoutThreadlines(currentTick);
        }
Example #3
0
        private bool AddToTimeline(ThreadFlow flow, StackItem item)
        {
            // do stuff with item
            Threadline timeline;

            if (!Threadlines.TryGetValue(flow.ThreadID, out timeline))
            {
                timeline = new Threadline(flow, ThreadOrder++);
                Threadlines[flow.ThreadID] = timeline;
            }

            timeline.IsAlive = flow.IsAlive; // update

            var node = NodeModels[item.NodeID];

            if (node.Show &&
                (CenterMap.Contains(node.ID) ||
                 (ShowOutside && !node.XNode.External) ||
                 (ShowExternal && node.XNode.External)))
            {
                timeline.Sequence.Add(item);

                if (item.Depth > timeline.Deepest)
                {
                    timeline.Deepest = item.Depth;
                }

                timeline.DepthSet.Add(item.Depth);

                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #4
0
        public void DrawCallGraph()
        {
            if (DoRevalue ||
                XRay.CallChange ||
                (ShowLayout != ShowNodes.All && XRay.CoverChange) ||
                (ShowLayout == ShowNodes.Instances && XRay.InstanceChange))
            {
                RecalcCover(InternalRoot);
                RecalcCover(ExternalRoot);

                PositionMap.Clear();
                CenterMap.Clear();

                var root = CurrentRoot;
                //causes method graph with ShowExternal on to show nothing
                //if (root == InternalRoot && ShowExternal)
                //    root = TopRoot;

                TopGraph = new GraphSet(this, root);

                // combine position and center maps for graph tree
                Utilities.RecurseTree(
                    TopGraph,
                    s =>
                {
                    foreach (var kvp in s.PositionMap)
                    {
                        PositionMap[kvp.Key] = kvp.Value;
                    }

                    foreach (var id in s.CenterMap)
                    {
                        CenterMap.Add(id);
                    }
                },
                    s => s.Subsets.Values
                    );

                XRay.CallChange     = false;
                XRay.CoverChange    = false;
                XRay.InstanceChange = false;

                DoRevalue = false;
                RevalueCount++;

                DoResize = true;
            }

            // graph created in relative coords so it doesnt need to be re-computed each resize, only on recalc

            if (DoResize)
            {
                Utilities.RecurseTree(
                    TopGraph,
                    s =>
                {
                    foreach (var graph in s.Graphs)
                    {
                        if (s.GraphContainer == null)
                        {
                            ScaleGraph(graph, new RectangleF(ScreenOffset, ScreenSize));
                        }

                        else if (s.GraphContainer.XNode.External)
                        {
                            // this is assuming the external node is a triangle
                            var area   = s.GraphContainer.AreaF;
                            var inside = new RectangleF(area.X + area.Width / 4f, area.Y + area.Height / 2f, area.Width / 2f, area.Height / 2f);
                            ScaleGraph(graph, inside);
                        }
                        else
                        {
                            ScaleGraph(graph, s.GraphContainer.AreaF);
                        }
                    }
                },
                    s => s.Subsets.Values
                    );

                DoResize = false;
                ResizeCount++;
            }
        }
Example #5
0
 public static void CenterMapOn(Mapsui.Geometries.Point position)
 {
     CenterMap?.Invoke(position);
 }
        private void SizeNode(IRenderer Renderer, NodeModel root, NodeModel exclude, bool center)
        {
            if (!root.Show)
            {
                return;
            }

            RectangleF insideArea = root.AreaF;

            if (ShowLabels)
            {
                // check if enough room in root box for label
                var labelSpace = root.AreaF;
                labelSpace.Width  -= LabelPadding * 2.0f;
                labelSpace.Height -= LabelPadding * 2.0f;

                var   labelSize = new RectangleF(root.AreaF.Location, Renderer.MeasureString(root.Name, TextFont));
                float minHeight = (root.Nodes.Count > 0) ? labelSize.Height * 2.0f : labelSize.Height;

                if (minHeight < labelSpace.Height && labelSize.Width / 3f < labelSpace.Width)
                {
                    labelSize.X += LabelPadding;
                    labelSize.Y += LabelPadding;

                    if (labelSpace.Width < labelSize.Width)
                    {
                        root.LabelClipped = true;
                        labelSize.Width   = labelSpace.Width;
                    }

                    insideArea.Y      += labelSize.Height;
                    insideArea.Height -= labelSize.Height;

                    root.RoomForLabel = true;
                    root.LabelRect    = labelSize;
                }
            }

            List <Sector> sectors = new TreeMap(root, exclude, insideArea.Size).Results;

            foreach (Sector sector in sectors)
            {
                var node = sector.OriginalValue;

                sector.Rect = RectangleExtensions.Contract(sector.Rect, NodeBorderWidth);

                if (sector.Rect.X < NodeBorderWidth)
                {
                    sector.Rect.X = NodeBorderWidth;
                }
                if (sector.Rect.Y < NodeBorderWidth)
                {
                    sector.Rect.Y = NodeBorderWidth;
                }
                if (sector.Rect.X > insideArea.Width - NodeBorderWidth)
                {
                    sector.Rect.X = insideArea.Width - NodeBorderWidth;
                }
                if (sector.Rect.Y > insideArea.Height - NodeBorderWidth)
                {
                    sector.Rect.Y = insideArea.Height - NodeBorderWidth;
                }

                sector.Rect.X += insideArea.X;
                sector.Rect.Y += insideArea.Y;

                node.SetArea(sector.Rect);
                PositionMap[node.ID] = node;

                node.RoomForLabel = false; // cant do above without graphic artifacts
                node.LabelClipped = false;

                if (center)
                {
                    CenterMap.Add(node.ID);
                }

                if (sector.Rect.Width > 1.0f && sector.Rect.Height > 1.0f)
                {
                    SizeNode(Renderer, node, exclude, center);
                }
            }
        }
        private void DrawNode(NodeModel node, RectangleF area, RectangleF labelArea, int depth, bool drawChildren, bool showHit)
        {
            if (!node.Show)
            {
                return;
            }

            var xNode = node.XNode;

            // set background of node base color
            Color background = XColors.EmptyColor;

            // if selcted
            if (node.Hovered && ViewLayout == LayoutType.TreeMap)
            {
                if (depth > XColors.OverColors.Length - 1)
                {
                    depth = XColors.OverColors.Length - 1;
                }

                background = XColors.OverColors[depth];
            }
            else if (ViewLayout != LayoutType.TreeMap && !CenterMap.Contains(node.ID))
            {
                background = XColors.OutsideColor;
            }

            // if no overlay, draw the border color as the entire node cause its very small
            bool noBorder = area.Width < 3.0f || area.Height < 3.0f;

            if (noBorder)
            {
                background = XColors.ObjColors[(int)node.ObjType];
            }


            Color overlay = XColors.EmptyColor;

            if (showHit)
            {
                // check if function is an entry point or holding
                if (XRay.FlowTracking && xNode.StillInside > 0)
                {
                    GLUtils.BlendColors((xNode.EntryPoint > 0) ? XColors.EntryColor : XColors.HoldingColor, ref overlay);
                }

                // not an else if, draw over holding or entry
                if (xNode.ExceptionHit > 0)
                {
                    GLUtils.BlendColors(XColors.ExceptionColors[xNode.ExceptionHit], ref overlay);
                }

                else if (xNode.FunctionHit > 0)
                {
                    if (node.ObjType == XObjType.Field)
                    {
                        if (xNode.LastFieldOp == FieldOp.Set)
                        {
                            GLUtils.BlendColors(XColors.FieldSetColors[xNode.FunctionHit], ref overlay);
                        }
                        else
                        {
                            GLUtils.BlendColors(XColors.FieldGetColors[xNode.FunctionHit], ref overlay);
                        }
                    }
                    else
                    {
                        GLUtils.BlendColors(XColors.HitColors[xNode.FunctionHit], ref overlay);
                    }
                }

                else if (xNode.ConstructedHit > 0)
                {
                    GLUtils.BlendColors(XColors.ConstructedColors[xNode.ConstructedHit], ref overlay);
                }

                else if (xNode.DisposeHit > 0)
                {
                    GLUtils.BlendColors(XColors.DisposedColors[xNode.DisposeHit], ref overlay);
                }
            }

            if (FocusedNodes.Count > 0 && node.ObjType == XObjType.Class)
            {
                bool dependent   = DependentClasses.Contains(node.ID);
                bool independent = IndependentClasses.Contains(node.ID);

                if (dependent && independent)
                {
                    GLUtils.BlendColors(XColors.InterdependentColor, ref overlay);
                }

                else if (dependent)
                {
                    GLUtils.BlendColors(XColors.DependentColor, ref overlay);
                }

                else if (independent)
                {
                    GLUtils.BlendColors(XColors.IndependentColor, ref overlay);
                }
            }

            if (node.SearchMatch && !SearchStrobe)
            {
                GLUtils.BlendColors(XColors.SearchMatchColor, ref overlay);
            }

            if (FilteredNodes.Contains(node.ID))
            {
                GLUtils.BlendColors(XColors.FilteredColor, ref overlay);
            }
            else if (IgnoredNodes.Contains(node.ID))
            {
                GLUtils.BlendColors(XColors.IgnoredColor, ref overlay);
            }

            // mix background with overlay
            if (overlay != XColors.EmptyColor)
            {
                GLUtils.BlendColors(overlay, ref background);
            }

            // use a circle for external/outside nodes in the call map
            bool outside = (ViewLayout == LayoutType.CallGraph && node.XNode.External);


            // if just a point, drawing a border messes up pixels
            if (noBorder && !DrawSubpixel)
            {
                Renderer.DrawNode(background, area, outside, node, depth);
            }
            else
            {
                Color pen = XColors.ObjColors[(int)node.ObjType];

                if (FilteredNodes.Contains(node.ID))
                {
                    pen = XColors.FilteredColor;
                }
                else if (IgnoredNodes.Contains(node.ID))
                {
                    pen = XColors.IgnoredColor;
                }

                int penWidth = 1;
                if (FocusedNodes.Contains(node))
                {
                    penWidth = 2;
                }

                Renderer.DrawNode(background, area, outside, node, depth);
                Renderer.DrawNodeOutline(pen, penWidth, area, outside, node, depth);
            }

            // draw label
            //buffer.FillRectangle(SearchMatchBrush, node.DebugRect);
            if (ShowLabels && node.RoomForLabel)
            {
                Renderer.DrawTextBackground(XColors.LabelBgColor, labelArea.X, labelArea.Y, labelArea.Width, labelArea.Height);
                Renderer.DrawNodeLabel(node.Name, TextFont, XColors.ObjColors[(int)node.ObjType], labelArea, node, depth);

                // draw code inside node
                if (ShowCode && node.AreaF.Width > 50 && node.AreaF.Height > 50)
                {
                    if (node.ObjType == XObjType.Method)
                    {
                        string code = node.XNode.GetMethodCode();

                        Renderer.DrawString(code, TextFont, XColors.CodeColor, node.AreaF.X + 5, node.AreaF.Y + labelArea.Height + 5, node.AreaF.Width - 10, node.AreaF.Height - 10 - labelArea.Height);
                    }
                    // draw field values inside node
                    else if (node.ObjType == XObjType.Field)
                    {
                        var summary = "";
                        foreach (var value in node.GetFieldValues())
                        {
                            summary += value + "\r\n";
                        }

                        Renderer.DrawString(summary, TextFont, XColors.CodeColor, node.AreaF.X + 5, node.AreaF.Y + labelArea.Height + 5, node.AreaF.Width - 10, node.AreaF.Height - 10 - labelArea.Height);
                    }
                }
            }
            if (MapMode == TreeMapMode.Dependencies && node.ObjType == XObjType.Class)
            {
                drawChildren = false;
            }

            if (drawChildren && ((area.Width > 1 && area.Height > 1) || DrawSubpixel))
            {
                foreach (var sub in node.Nodes)
                {
                    DrawNode(sub, depth + 1, drawChildren);
                }
            }


            // after drawing children, draw instance tracking on top of it all

            /*if (XRay.InstanceTracking && node.ObjType == XObjType.Class)
             * {
             * if (XRay.InstanceCount[node.ID] > 0)
             *  {
             *      string count = XRay.InstanceCount[node.ID].ToString();
             *      Rectangle x = new Rectangle(node.Area.Location, buffer.MeasureString(count, InstanceFont).ToSize());
             *
             *      if (node.Area.Contains(x))
             *      {
             *          buffer.FillRectangle(NothingBrush, x);
             *          buffer.DrawString(count, InstanceFont, InstanceBrush, node.Area.Location.X + 2, node.Area.Location.Y + 2);
             *      }
             *  }
             * }*/
        }