Skip to content
Browse files

Object graph - simplified layout code.

  • Loading branch information...
1 parent 4897789 commit 550e862c4de9969e647681f625f0eb60e6b0ec8b @mkonicek mkonicek committed
Showing with 344 additions and 492 deletions.
  1. +2 −6 src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. +26 −48 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs
  3. +3 −3 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentNode.cs
  4. +1 −1 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentPropertyNode.cs
  5. +11 −11 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphDiff.cs
  6. +13 −13 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphMatcher.cs
  7. +1 −1 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedEdge.cs
  8. +5 −5 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedGraph.cs
  9. +20 −33 ...Ins/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/{PositionedGraphNode.cs → PositionedNode.cs}
  10. +3 −3 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs
  11. +0 −21 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeEdge.cs
  12. +0 −75 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNode.cs
  13. +0 −27 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNodeLR.cs
  14. +0 −27 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNodeTB.cs
  15. +187 −0 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs
  16. +0 −137 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs
  17. +14 −13 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraph.cs
  18. +58 −68 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
View
8 src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
@@ -315,15 +315,11 @@
<Compile Include="Visualizers\Graph\Layout\GraphMatcher.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedEdge.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedGraph.cs" />
- <Compile Include="Visualizers\Graph\Layout\PositionedGraphNode.cs" />
+ <Compile Include="Visualizers\Graph\Layout\PositionedNode.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedNodeProperty.cs" />
<Compile Include="Visualizers\Graph\Layout\PositionedPropertyEventArgs.cs" />
<Compile Include="Visualizers\Graph\Layout\Tree\LayoutDirection.cs" />
- <Compile Include="Visualizers\Graph\Layout\Tree\TreeEdge.cs" />
- <Compile Include="Visualizers\Graph\Layout\Tree\TreeLayouter.cs" />
- <Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNode.cs" />
- <Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNodeLR.cs" />
- <Compile Include="Visualizers\Graph\Layout\Tree\TreeGraphNodeTB.cs" />
+ <Compile Include="Visualizers\Graph\Layout\Tree\TreeLayout.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraph.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraphBuilder.cs" />
<Compile Include="Visualizers\Graph\ObjectGraph\ObjectGraphNode.cs" />
View
74 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/GraphDrawer.cs
@@ -19,7 +19,8 @@
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
- /// Draws <see cref="PositionedGraph"></see> on Canvas.
+ /// Draws <see cref="PositionedGraph" /> on Canvas.
+ /// Keeps the last displayed graph and does a smooth transition into the new graph.
/// </summary>
public class GraphDrawer
{
@@ -41,11 +42,10 @@ public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, G
{
// account for that the visual controls could have been reused (we are not reusing controls now - NodeControlCache does nothing)
-// this.canvas.Width = newGraph.BoundingRect.Width;
-// this.canvas.Height = newGraph.BoundingRect.Height;
+ this.canvas.Width = newGraph.BoundingRect.Width;
+ this.canvas.Height = newGraph.BoundingRect.Height;
- if (oldGraph == null)
- {
+ if (oldGraph == null) {
Draw(newGraph);
return;
}
@@ -57,38 +57,31 @@ public void StartAnimation(PositionedGraph oldGraph, PositionedGraph newGraph, G
DoubleAnimation fadeOutAnim = new DoubleAnimation(1.0, 0.0, durationFade);
DoubleAnimation fadeInAnim = new DoubleAnimation(0.0, 1.0, durationFade);
- foreach (UIElement drawing in canvas.Children)
- {
+ foreach (UIElement drawing in canvas.Children) {
var arrow = drawing as Path;
- if (arrow != null)
- {
+ if (arrow != null) {
arrow.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim);
}
}
- foreach (PositionedEdge edge in newGraph.Edges)
- {
- addEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
+ foreach (PositionedEdge edge in newGraph.Edges) {
+ AddEdgeToCanvas(edge).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
}
- foreach (PositionedGraphNode removedNode in diff.RemovedNodes)
- {
+ foreach (PositionedNode removedNode in diff.RemovedNodes) {
removedNode.NodeVisualControl.BeginAnimation(UIElement.OpacityProperty, fadeOutAnim);
}
- foreach (PositionedGraphNode addedNode in diff.AddedNodes)
- {
- addNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
+ foreach (PositionedNode addedNode in diff.AddedNodes) {
+ AddNodeToCanvas(addedNode).BeginAnimation(UIElement.OpacityProperty, fadeInAnim);
}
bool first = true;
- foreach (PositionedGraphNode node in diff.ChangedNodes)
- {
+ foreach (PositionedNode node in diff.ChangedNodes) {
var newNode = diff.GetMatchingNewNode(node);
PointAnimation anim = new PointAnimation();
- if (first)
- {
+ if (first) {
anim.Completed += new EventHandler((o, e) => { Draw(newGraph); });
first = false;
}
@@ -111,29 +104,14 @@ public void Draw(PositionedGraph posGraph)
{
canvas.Children.Clear();
- /*try
- {
- // why do the controls disappear?
- var n1 = posGraph.Nodes.First().NodeVisualControl;
- var n2 = posGraph.Nodes.Skip(1).First().NodeVisualControl;
- var n3 = posGraph.Nodes.Skip(2).First().NodeVisualControl;
- if (n1 == n2 || n1 == n3 || n2 == n3)
- {
- ClearCanvas();
- }
- }
- catch{}*/
-
// draw nodes
- foreach (PositionedGraphNode node in posGraph.Nodes)
- {
- addNodeToCanvas(node);
+ foreach (PositionedNode node in posGraph.Nodes) {
+ AddNodeToCanvas(node);
}
// draw edges
- foreach (PositionedEdge edge in posGraph.Edges)
- {
- addEdgeToCanvas(edge);
+ foreach (PositionedEdge edge in posGraph.Edges) {
+ AddEdgeToCanvas(edge);
}
edgeTooltip.Visibility = Visibility.Hidden;
@@ -149,7 +127,7 @@ public void ClearCanvas()
canvas.Children.Clear();
}
- private PositionedGraphNodeControl addNodeToCanvas(PositionedGraphNode node)
+ PositionedGraphNodeControl AddNodeToCanvas(PositionedNode node)
{
canvas.Children.Add(node.NodeVisualControl);
Canvas.SetLeft(node.NodeVisualControl, node.Left);
@@ -157,13 +135,13 @@ private PositionedGraphNodeControl addNodeToCanvas(PositionedGraphNode node)
return node.NodeVisualControl;
}
- private Path addEdgeToCanvas(PositionedEdge edge)
+ Path AddEdgeToCanvas(PositionedEdge edge)
{
- PathFigure edgeSplineFigure = createEdgeSpline(edge);
+ PathFigure edgeSplineFigure = CreateEdgeSpline(edge);
PathGeometry geometryVisible = new PathGeometry();
geometryVisible.Figures.Add(edgeSplineFigure);
- geometryVisible.Figures.Add(createEdgeArrow(edge));
+ geometryVisible.Figures.Add(CreateEdgeArrow(edge));
Path pathVisible = new Path();
pathVisible.Stroke = Brushes.Black;
@@ -210,7 +188,7 @@ private Path addEdgeToCanvas(PositionedEdge edge)
return pathVisible;
}
- private PathFigure createEdgeSpline(PositionedEdge edge)
+ PathFigure CreateEdgeSpline(PositionedEdge edge)
{
PathFigure figure = new PathFigure();
figure.IsClosed = false;
@@ -225,7 +203,7 @@ private PathFigure createEdgeSpline(PositionedEdge edge)
return figure;
}
- private PathFigure createEdgeArrow(PositionedEdge edge)
+ PathFigure CreateEdgeArrow(PositionedEdge edge)
{
Point splineEndPoint = edge.SplinePoints[edge.SplinePoints.Count - 1];
Point splineEndHandlePoint = edge.SplinePoints[edge.SplinePoints.Count - 2];
@@ -240,14 +218,14 @@ private PathFigure createEdgeArrow(PositionedEdge edge)
arrowFigure.IsFilled = true;
arrowFigure.StartPoint = splineEndPoint; // arrow tip
- Vector tangent2 = rotate90(tangent);
+ Vector tangent2 = Rotate90(tangent);
arrowFigure.Segments.Add(new LineSegment(basePoint + tangent2 * 0.15, true));
arrowFigure.Segments.Add(new LineSegment(basePoint - tangent2 * 0.15, true));
return arrowFigure;
}
- private static Vector rotate90(Vector v)
+ static Vector Rotate90(Vector v)
{
// (x, y) -> (y, -x)
double t = v.X;
View
6 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentNode.cs
@@ -15,7 +15,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public class ContentNode : Utils.ITreeNode<ContentNode>
{
- public ContentNode(PositionedGraphNode containingNode, ContentNode parent)
+ public ContentNode(PositionedNode containingNode, ContentNode parent)
{
if (containingNode == null)
throw new ArgumentNullException("containingNode");
@@ -74,11 +74,11 @@ public string Path
private List<ContentNode> children = new List<ContentNode>();
public List<ContentNode> Children { get { return this.children; } }
- PositionedGraphNode containingNode;
+ PositionedNode containingNode;
/// <summary>
/// PositionedGraphNode that contains this PropertyNodeViewModel.
/// </summary>
- public PositionedGraphNode ContainingNode
+ public PositionedNode ContainingNode
{
get { return this.containingNode; }
}
View
2 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentPropertyNode.cs
@@ -13,7 +13,7 @@ public class ContentPropertyNode : ContentNode, IEvaluate
{
PositionedNodeProperty positionedProperty;
- public ContentPropertyNode(PositionedGraphNode containingNode, ContentNode parent)
+ public ContentPropertyNode(PositionedNode containingNode, ContentNode parent)
: base(containingNode, parent)
{
}
View
22 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphDiff.cs
@@ -13,15 +13,15 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public class GraphDiff
{
- private List<PositionedGraphNode> addedNodes = new List<PositionedGraphNode>();
- private List<PositionedGraphNode> deletedNodes = new List<PositionedGraphNode>();
- private List<PositionedGraphNode> changedNodes = new List<PositionedGraphNode>();
- private Dictionary<PositionedGraphNode, PositionedGraphNode> matching = new Dictionary<PositionedGraphNode, PositionedGraphNode>();
+ private List<PositionedNode> addedNodes = new List<PositionedNode>();
+ private List<PositionedNode> deletedNodes = new List<PositionedNode>();
+ private List<PositionedNode> changedNodes = new List<PositionedNode>();
+ private Dictionary<PositionedNode, PositionedNode> matching = new Dictionary<PositionedNode, PositionedNode>();
/// <summary>
/// Nodes in the new graph that were added.
/// </summary>
- public IList<PositionedGraphNode> AddedNodes
+ public IList<PositionedNode> AddedNodes
{
get { return addedNodes.AsReadOnly(); }
}
@@ -29,7 +29,7 @@ public IList<PositionedGraphNode> AddedNodes
/// <summary>
/// Nodes in the old graph that were removed.
/// </summary>
- public IList<PositionedGraphNode> RemovedNodes
+ public IList<PositionedNode> RemovedNodes
{
get { return deletedNodes.AsReadOnly(); }
}
@@ -38,27 +38,27 @@ public IList<PositionedGraphNode> RemovedNodes
/// Nodes in the old graph that were chaged.
/// These have matching new nodes, which can be obtained by <see cref="GetMatchingNewNode"/>.
/// </summary>
- public IList<PositionedGraphNode> ChangedNodes
+ public IList<PositionedNode> ChangedNodes
{
get { return changedNodes.AsReadOnly(); }
}
- public PositionedGraphNode GetMatchingNewNode(PositionedGraphNode oldNode)
+ public PositionedNode GetMatchingNewNode(PositionedNode oldNode)
{
return matching.GetValue(oldNode);
}
- internal void SetAdded(PositionedGraphNode addedNode)
+ internal void SetAdded(PositionedNode addedNode)
{
addedNodes.Add(addedNode);
}
- internal void SetRemoved(PositionedGraphNode removeddNode)
+ internal void SetRemoved(PositionedNode removeddNode)
{
deletedNodes.Add(removeddNode);
}
- internal void SetMatching(PositionedGraphNode matchFrom, PositionedGraphNode matchTo)
+ internal void SetMatching(PositionedNode matchFrom, PositionedNode matchTo)
{
matching[matchFrom] = matchTo;
changedNodes.Add(matchFrom);
View
26 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/GraphMatcher.cs
@@ -27,7 +27,7 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
else
{
GraphDiff addAllDiff = new GraphDiff();
- foreach (PositionedGraphNode newNode in newGraph.Nodes)
+ foreach (PositionedNode newNode in newGraph.Nodes)
addAllDiff.SetAdded(newNode);
return addAllDiff;
}
@@ -35,7 +35,7 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
else if (newGraph == null)
{
GraphDiff removeAllDiff = new GraphDiff();
- foreach (PositionedGraphNode oldNode in oldGraph.Nodes)
+ foreach (PositionedNode oldNode in oldGraph.Nodes)
removeAllDiff.SetRemoved(oldNode);
return removeAllDiff;
}
@@ -43,12 +43,12 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
// none of the graphs is null
GraphDiff diff = new GraphDiff();
- Dictionary<int, PositionedGraphNode> newNodeForHashCode = buildHashToNodeMap(newGraph);
- Dictionary<PositionedGraphNode, bool> newNodeMatched = new Dictionary<PositionedGraphNode, bool>();
+ Dictionary<int, PositionedNode> newNodeForHashCode = buildHashToNodeMap(newGraph);
+ Dictionary<PositionedNode, bool> newNodeMatched = new Dictionary<PositionedNode, bool>();
- foreach (PositionedGraphNode oldNode in oldGraph.Nodes)
+ foreach (PositionedNode oldNode in oldGraph.Nodes)
{
- PositionedGraphNode matchingNode = matchNode(oldNode, newNodeForHashCode);
+ PositionedNode matchingNode = matchNode(oldNode, newNodeForHashCode);
if (matchingNode != null)
{
diff.SetMatching(oldNode, matchingNode);
@@ -59,7 +59,7 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
diff.SetRemoved(oldNode);
}
}
- foreach (PositionedGraphNode newNode in newGraph.Nodes)
+ foreach (PositionedNode newNode in newGraph.Nodes)
{
if (!newNodeMatched.ContainsKey(newNode))
{
@@ -70,19 +70,19 @@ public GraphDiff MatchGraphs(PositionedGraph oldGraph, PositionedGraph newGraph)
return diff;
}
- private Dictionary<int, PositionedGraphNode> buildHashToNodeMap(PositionedGraph graph)
+ private Dictionary<int, PositionedNode> buildHashToNodeMap(PositionedGraph graph)
{
- var hashToNodeMap = new Dictionary<int, PositionedGraphNode>();
- foreach (PositionedGraphNode node in graph.Nodes)
+ var hashToNodeMap = new Dictionary<int, PositionedNode>();
+ foreach (PositionedNode node in graph.Nodes)
{
hashToNodeMap[node.ObjectNode.HashCode] = node;
}
return hashToNodeMap;
}
- private PositionedGraphNode matchNode(PositionedGraphNode oldNode, Dictionary<int, PositionedGraphNode> newNodeMap)
+ private PositionedNode matchNode(PositionedNode oldNode, Dictionary<int, PositionedNode> newNodeMap)
{
- PositionedGraphNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode);
+ PositionedNode newNodeFound = newNodeMap.GetValue(oldNode.ObjectNode.HashCode);
if ((newNodeFound != null) && isSameAddress(oldNode, newNodeFound))
{
return newNodeFound;
@@ -93,7 +93,7 @@ private PositionedGraphNode matchNode(PositionedGraphNode oldNode, Dictionary<in
}
}
- private bool isSameAddress(PositionedGraphNode node1, PositionedGraphNode node2)
+ private bool isSameAddress(PositionedNode node1, PositionedNode node2)
{
return node1.ObjectNode.PermanentReference.GetObjectAddress() == node2.ObjectNode.PermanentReference.GetObjectAddress();
}
View
2 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedEdge.cs
@@ -11,7 +11,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// <summary>
/// Edge with position information.
/// </summary>
- public class PositionedEdge : NamedEdge<PositionedNodeProperty, PositionedGraphNode>, SplineRouting.IEdge
+ public class PositionedEdge : NamedEdge<PositionedNodeProperty, PositionedNode>, SplineRouting.IEdge
{
private IList<Point> splinePoints = new List<Point>();
/// <summary>
View
10 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedGraph.cs
@@ -13,9 +13,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public class PositionedGraph
{
- private List<PositionedGraphNode> nodes = new List<PositionedGraphNode>();
+ private List<PositionedNode> nodes = new List<PositionedNode>();
- public PositionedGraphNode Root { get; set; }
+ public PositionedNode Root { get; set; }
public System.Windows.Rect BoundingRect
{
@@ -33,12 +33,12 @@ public System.Windows.Rect BoundingRect
/// <summary>
/// All nodes in the graph.
/// </summary>
- public IEnumerable<PositionedGraphNode> Nodes
+ public IEnumerable<PositionedNode> Nodes
{
get { return nodes; }
}
- internal void AddNode(PositionedGraphNode node)
+ internal void AddNode(PositionedNode node)
{
this.nodes.Add(node);
}
@@ -50,7 +50,7 @@ public IEnumerable<PositionedEdge> Edges
{
get
{
- foreach (PositionedGraphNode node in this.Nodes)
+ foreach (PositionedNode node in this.Nodes)
{
foreach (PositionedEdge edge in node.Edges)
{
View
53 ...izers/Graph/Layout/PositionedGraphNode.cs → ...isualizers/Graph/Layout/PositionedNode.cs
@@ -13,18 +13,16 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// <summary>
/// ObjectNode with added position information.
/// </summary>
- public class PositionedGraphNode : SplineRouting.IRect
+ public class PositionedNode : SplineRouting.IRect
{
- public static readonly double MaxHeight = 300;
-
/// <summary>
/// Creates new PositionedNode.
/// </summary>
/// <param name="objectNode">Underlying ObjectNode.</param>
- public PositionedGraphNode(ObjectGraphNode objectNode)
+ public PositionedNode(ObjectGraphNode objectNode)
{
this.objectNode = objectNode;
- initVisualControl();
+ InitVisualControl();
}
public event EventHandler<PositionedPropertyEventArgs> PropertyExpanded;
@@ -44,56 +42,45 @@ public ObjectGraphNode ObjectNode
/// <summary>
/// Tree-of-properties content of this node.
/// </summary>
- public ContentNode Content
- {
- get; set;
- }
+ public ContentNode Content { get; set; }
+
+ /// <summary>
+ /// The size of the subtree of this node in the layout.
+ /// </summary>
+ public double SubtreeSize { get; set; }
- private PositionedGraphNodeControl nodeVisualControl;
/// <summary>
/// Visual control to be shown for this node.
/// </summary>
- public PositionedGraphNodeControl NodeVisualControl
- {
- get
- {
- return this.nodeVisualControl;
- }
- }
+ public PositionedGraphNodeControl NodeVisualControl { get; private set; }
public void InitContentFromObjectNode(Expanded expanded)
{
this.Content = new ContentNode(this, null);
this.Content.InitOverride(this.ObjectNode.Content, expanded);
- this.nodeVisualControl.Root = this.Content;
+ this.NodeVisualControl.Root = this.Content;
}
- private void initVisualControl()
+ private void InitVisualControl()
{
- this.nodeVisualControl = NodeControlCache.Instance.GetNodeControl();
- this.nodeVisualControl.MaxHeight = MaxHeight;
-
+ this.NodeVisualControl = NodeControlCache.Instance.GetNodeControl();
// propagate events from nodeVisualControl
- this.nodeVisualControl.PropertyExpanded += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_PropertyExpanded);
- this.nodeVisualControl.PropertyCollapsed += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_PropertyCollapsed);
- this.nodeVisualControl.ContentNodeExpanded += new EventHandler<ContentNodeEventArgs>(NodeVisualControl_ContentNodeExpanded);
- this.nodeVisualControl.ContentNodeCollapsed += new EventHandler<ContentNodeEventArgs>(NodeVisualControl_ContentNodeCollapsed);
+ this.NodeVisualControl.PropertyExpanded += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_PropertyExpanded);
+ this.NodeVisualControl.PropertyCollapsed += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_PropertyCollapsed);
+ this.NodeVisualControl.ContentNodeExpanded += new EventHandler<ContentNodeEventArgs>(NodeVisualControl_ContentNodeExpanded);
+ this.NodeVisualControl.ContentNodeCollapsed += new EventHandler<ContentNodeEventArgs>(NodeVisualControl_ContentNodeCollapsed);
}
public IEnumerable<PositionedNodeProperty> Properties
{
- get
- {
- return this.Content.FlattenProperties();
- }
+ get { return this.Content.FlattenProperties(); }
}
public virtual IEnumerable<PositionedEdge> Edges
{
get
{
- foreach (PositionedNodeProperty property in this.Properties)
- {
+ foreach (PositionedNodeProperty property in this.Properties) {
if (property.Edge != null)
yield return property.Edge;
}
@@ -102,7 +89,7 @@ public virtual IEnumerable<PositionedEdge> Edges
public void Measure()
{
- this.nodeVisualControl.Measure(new Size(800, 800));
+ this.NodeVisualControl.Measure(new Size(800, 800));
}
public double Left { get; set; }
View
6 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedNodeProperty.cs
@@ -16,7 +16,7 @@ public class PositionedNodeProperty : IEvaluate
/// Creates new PositionedNodeProperty.
/// </summary>
/// <param name="objectProperty">Underlying <see cref="ObjectProperty"/></param>
- public PositionedNodeProperty(ObjectGraphProperty objectProperty, PositionedGraphNode containingNode, bool isPropertyExpanded)
+ public PositionedNodeProperty(ObjectGraphProperty objectProperty, PositionedNode containingNode, bool isPropertyExpanded)
{
if (containingNode == null)
throw new ArgumentNullException("containingNode");
@@ -48,11 +48,11 @@ public ObjectGraphProperty ObjectGraphProperty
get { return this.objectGraphProperty; }
}
- private PositionedGraphNode containingNode;
+ private PositionedNode containingNode;
/// <summary>
/// <see cref="PositionedNode"/> which contains this Property.
/// </summary>
- public PositionedGraphNode ContainingNode
+ public PositionedNode ContainingNode
{
get { return this.containingNode; }
}
View
21 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeEdge.cs
@@ -1,21 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
-
-using System;
-
-namespace Debugger.AddIn.Visualizers.Graph.Layout
-{
- // TODO this class is almost not necessary, is used only for TreeLayouter purposes.
- // TreeLayouter could remember the additional information in a Dictionary PositionedEdge -> bool
-
- /// <summary>
- /// Edge in the tree-layouted <see cref="PositionedGraph"/>.
- /// </summary>
- public class TreeGraphEdge : PositionedEdge
- {
- /// <summary>
- /// Is this an edges making up the main tree?
- /// </summary>
- public bool IsTreeEdge { get; set; }
- }
-}
View
75 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNode.cs
@@ -1,75 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
-
-using System;
-using System.Collections.Generic;
-using Debugger.AddIn.Visualizers.Graph.Drawing;
-
-namespace Debugger.AddIn.Visualizers.Graph.Layout
-{
- /// <summary>
- /// Node in tree-layouted <see cref="PositionedGraph"/>.
- /// This is the abstract ancestor of TreeNodeLR and TreeNodeTB.
- /// There are 2 dimensions - "main" and "lateral".
- /// Main dimension is the dimension in which the graph depth grows (vertical when TB, horizontal when LR).
- /// Lateral dimension is the other dimension. Siblings are placed next to each other in Lateral dimension.
- /// </summary>
- public abstract class TreeGraphNode : PositionedGraphNode
- {
- public static TreeGraphNode Create(LayoutDirection direction, ObjectGraphNode objectNode)
- {
- switch (direction) {
- case LayoutDirection.TopBottom: return new TreeNodeTB(objectNode);
- case LayoutDirection.LeftRight: return new TreeNodeLR(objectNode);
- default: throw new DebuggerVisualizerException("Unsupported layout direction: " + direction.ToString());
- }
- }
-
- public double HorizontalMargin { get; set; }
- public double VerticalMargin { get; set; }
-
- protected TreeGraphNode(ObjectGraphNode objectNode) : base(objectNode)
- {
- }
-
- /// <summary>
- /// Width or height of the subtree.
- /// </summary>
- public double SubtreeSize { get; set; }
-
- public abstract double MainCoord { get; set; }
- public abstract double LateralCoord { get; set; }
-
- public abstract double MainSize { get; }
- public abstract double LateralSize { get; }
-
- public double MainSizeWithMargin { get { return MainSize + MainMargin; } }
- public double LateralSizeWithMargin { get { return LateralSize + LateralMargin; } }
-
- public abstract double MainMargin { get; }
- public abstract double LateralMargin { get; }
-
- public IEnumerable<PositionedEdge> ChildEdges
- {
- get
- {
- foreach (TreeGraphEdge childEdge in Edges)
- {
- if (childEdge.IsTreeEdge)
- {
- yield return childEdge;
- }
- }
- }
- }
-
- public IEnumerable<TreeGraphNode> Childs
- {
- get
- {
- foreach (PositionedEdge outEdge in this.ChildEdges)
- yield return (TreeGraphNode)outEdge.Target;
- }
- }
- }
-}
View
27 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNodeLR.cs
@@ -1,27 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
-
-using System;
-using Debugger.AddIn.Visualizers.Graph.Drawing;
-
-namespace Debugger.AddIn.Visualizers.Graph.Layout
-{
- /// <summary>
- /// TreeNode used in LR layout mode.
- /// </summary>
- public class TreeNodeLR: TreeGraphNode
- {
- public TreeNodeLR(ObjectGraphNode objectNode) : base(objectNode)
- {
- }
-
- public override double MainSize { get { return this.Width; } }
- public override double LateralSize { get { return this.Height ; } }
-
- public override double MainCoord { get { return this.Left; } set { this.Left = value; } }
- public override double LateralCoord { get { return this.Top; } set { this.Top = value; } }
-
- public override double MainMargin { get { return this.HorizontalMargin; } }
- public override double LateralMargin { get { return this.VerticalMargin; } }
- }
-}
View
27 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeGraphNodeTB.cs
@@ -1,27 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
-
-using System;
-using Debugger.AddIn.Visualizers.Graph.Drawing;
-
-namespace Debugger.AddIn.Visualizers.Graph.Layout
-{
- /// <summary>
- /// TreeNode used in TB layout mode.
- /// </summary>
- public class TreeNodeTB : TreeGraphNode
- {
- public TreeNodeTB(ObjectGraphNode objectNode) : base(objectNode)
- {
- }
-
- public override double MainSize { get { return this.Height; } }
- public override double LateralSize { get { return this.Width; } }
-
- public override double MainCoord { get { return this.Top; } set { this.Top = value; } }
- public override double LateralCoord { get { return this.Left; } set { this.Left = value; } }
-
- public override double MainMargin { get { return this.VerticalMargin; } }
- public override double LateralMargin { get { return this.HorizontalMargin; } }
- }
-}
View
187 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayout.cs
@@ -0,0 +1,187 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
+
+using System;
+using System.Collections.Generic;
+using System.Windows;
+using Debugger.AddIn.Visualizers.Graph.Drawing;
+using System.Linq;
+
+namespace Debugger.AddIn.Visualizers.Graph.Layout
+{
+ /// <summary>
+ /// Calculates layout of <see cref="ObjectGraph" />, producing <see cref="PositionedGraph" />.
+ /// </summary>
+ public class TreeLayout
+ {
+ private static readonly double NodeMarginH = 30;
+ private static readonly double NodeMarginV = 30;
+
+ GraphEdgeRouter edgeRouter = new GraphEdgeRouter();
+ /// <summary>
+ /// The produced layout is either a horizontal or vertical tree.
+ /// </summary>
+ public LayoutDirection LayoutDirection { get; private set; }
+
+ public TreeLayout(LayoutDirection layoutDirection)
+ {
+ this.LayoutDirection = layoutDirection;
+ }
+
+ /// <summary>
+ /// Calculates layout for given <see cref="ObjectGraph" />.
+ /// </summary>
+ /// <param name="objectGraph"></param>
+ /// <returns></returns>
+ public PositionedGraph CalculateLayout(ObjectGraph objectGraph, Expanded expanded)
+ {
+ var positionedGraph = BuildPositionedGraph(objectGraph, expanded);
+ CalculateLayout(positionedGraph);
+ this.edgeRouter.RouteEdges(positionedGraph);
+
+ return positionedGraph;
+ }
+
+ // Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode
+ PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, Expanded expanded)
+ {
+ var positionedNodeFor = new Dictionary<ObjectGraphNode, PositionedNode>();
+ var positionedGraph = new PositionedGraph();
+
+ // create empty PositionedNodes
+ foreach (ObjectGraphNode objectNode in objectGraph.ReachableNodes) {
+ var posNode = new PositionedNode(objectNode);
+ posNode.InitContentFromObjectNode(expanded);
+ positionedGraph.AddNode(posNode);
+ positionedNodeFor[objectNode] = posNode;
+ }
+
+ // create edges
+ foreach (PositionedNode posNode in positionedGraph.Nodes)
+ {
+ foreach (PositionedNodeProperty property in posNode.Properties) {
+ if (property.ObjectGraphProperty.TargetNode != null) {
+ ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode;
+ PositionedNode edgeTarget = positionedNodeFor[targetObjectNode];
+ property.Edge = new PositionedEdge {
+ Name = property.Name, Source = property, Target = edgeTarget
+ };
+ }
+ }
+ }
+ positionedGraph.Root = positionedNodeFor[objectGraph.Root];
+ return positionedGraph;
+ }
+
+ void CalculateLayout(PositionedGraph positionedGraph)
+ {
+ HashSet<PositionedNode> seenNodes = new HashSet<PositionedNode>();
+ HashSet<PositionedEdge> treeEdges = new HashSet<PositionedEdge>();
+ // first layout pass
+ CalculateSubtreeSizes(positionedGraph.Root, seenNodes, treeEdges);
+ // second layout pass
+ CalculateNodePosRecursive(positionedGraph.Root, treeEdges, 0, 0);
+ }
+
+ // determines which edges are tree edges, and calculates subtree size for each node
+ private void CalculateSubtreeSizes(PositionedNode root, HashSet<PositionedNode> seenNodes, HashSet<PositionedEdge> treeEdges)
+ {
+ seenNodes.Add(root);
+ double subtreeSize = 0;
+ foreach (var property in root.Properties) {
+ var edge = property.Edge;
+ if (edge != null) {
+ var targetNode = edge.Target;
+ if (!seenNodes.Contains(targetNode)) {
+ // when we come to a node for the first time, we declare the incoming edge a tree edge
+ treeEdges.Add(edge);
+ CalculateSubtreeSizes(targetNode, seenNodes, treeEdges);
+ subtreeSize += targetNode.SubtreeSize;
+ }
+ }
+ }
+ root.Measure();
+ root.SubtreeSize = Math.Max(GetLateralSizeWithMargin(root), subtreeSize);
+ }
+
+
+ /// <summary>
+ /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom layout.
+ /// </summary>
+ /// <param name="node"></param>
+ /// <param name="lateralStart"></param>
+ /// <param name="mainStart"></param>
+ void CalculateNodePosRecursive(PositionedNode node, HashSet<PositionedEdge> treeEdges, double lateralBase, double mainBase)
+ {
+ double childsSubtreeSize = TreeChildNodes(node, treeEdges).Sum(child => child.SubtreeSize);
+ double center = TreeEdges(node, treeEdges).Count() == 0 ? 0 : 0.5 * (childsSubtreeSize - (GetLateralSizeWithMargin(node)));
+ if (center < 0) {
+ // if root is larger than subtree, it would be shifted below lateralStart
+ // -> make whole layout start at lateralStart
+ lateralBase -= center;
+ }
+
+ SetLateral(node, GetLateral(node) + lateralBase + center);
+ SetMain(node, mainBase);
+
+ double childLateral = lateralBase;
+ double childsMainFixed = GetMain(node) + GetMainSizeWithMargin(node);
+ foreach (var child in TreeChildNodes(node, treeEdges)) {
+ CalculateNodePosRecursive(child, treeEdges, childLateral, childsMainFixed);
+ childLateral += child.SubtreeSize;
+ }
+ }
+
+ IEnumerable<PositionedEdge> TreeEdges(PositionedNode node, HashSet<PositionedEdge> treeEdges)
+ {
+ return node.Edges.Where(e => treeEdges.Contains(e));
+ }
+
+ IEnumerable<PositionedNode> TreeChildNodes(PositionedNode node, HashSet<PositionedEdge> treeEdges)
+ {
+ return TreeEdges(node, treeEdges).Select(e => e.Target);
+ }
+
+ #region Horizontal / vertical layout helpers
+
+ double GetMainSizeWithMargin(PositionedNode node)
+ {
+ return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Width + NodeMarginH : node.Height + NodeMarginV;
+ }
+
+ double GetLateralSizeWithMargin(PositionedNode node)
+ {
+ return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Height + NodeMarginV : node.Width + NodeMarginH;
+ }
+
+ double GetMain(PositionedNode node)
+ {
+ return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Left : node.Top;
+ }
+
+ double GetLateral(PositionedNode node)
+ {
+ return (this.LayoutDirection == LayoutDirection.LeftRight) ? node.Top : node.Left;
+ }
+
+ void SetMain(PositionedNode node, double value)
+ {
+ if (this.LayoutDirection == LayoutDirection.LeftRight) {
+ node.Left = value;
+ } else {
+ node.Top = value;
+ }
+ }
+
+ void SetLateral(PositionedNode node, double value)
+ {
+ if (this.LayoutDirection == LayoutDirection.LeftRight) {
+ node.Top = value;
+ } else {
+ node.Left = value;
+ }
+ }
+
+ #endregion
+ }
+}
View
137 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/Tree/TreeLayouter.cs
@@ -1,137 +0,0 @@
-// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
-// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
-
-using System;
-using System.Collections.Generic;
-using System.Windows;
-using Debugger.AddIn.Visualizers.Graph.Drawing;
-using System.Linq;
-
-namespace Debugger.AddIn.Visualizers.Graph.Layout
-{
- /// <summary>
- /// Calculates layout of <see cref="ObjectGraph" />, producing <see cref="PositionedGraph" />.
- /// </summary>
- public class TreeLayouter
- {
- private static readonly double horizNodeMargin = 30;
- private static readonly double vertNodeMargin = 30;
-
- GraphEdgeRouter edgeRouter = new GraphEdgeRouter();
-
- public TreeLayouter()
- {
- }
-
- /// <summary>
- /// Calculates layout for given <see cref="ObjectGraph" />.
- /// </summary>
- /// <param name="objectGraph"></param>
- /// <returns></returns>
- public PositionedGraph CalculateLayout(ObjectGraph objectGraph, LayoutDirection direction, Expanded expanded)
- {
- var positionedGraph = BuildPositionedGraph(objectGraph, direction, expanded);
- CalculateLayout(positionedGraph);
- this.edgeRouter.RouteEdges(positionedGraph);
-
- return positionedGraph;
- }
-
- PositionedGraph BuildPositionedGraph(ObjectGraph objectGraph, LayoutDirection direction, Expanded expanded)// Expanded is passed so that the correct ContentNodes are expanded in the PositionedNode
- {
- var treeNodeFor = new Dictionary<ObjectGraphNode, PositionedGraphNode>();
- var resultGraph = new PositionedGraph();
-
- // create empty PositionedNodes
- foreach (ObjectGraphNode objectGraphNode in objectGraph.ReachableNodes) {
- TreeGraphNode posNode = TreeGraphNode.Create(direction, objectGraphNode);
- posNode.InitContentFromObjectNode(expanded);
- posNode.HorizontalMargin = horizNodeMargin;
- posNode.VerticalMargin = vertNodeMargin;
- resultGraph.AddNode(posNode);
- treeNodeFor[objectGraphNode] = posNode;
- }
-
- // create edges
- foreach (PositionedGraphNode posNode in resultGraph.Nodes)
- {
- foreach (PositionedNodeProperty property in posNode.Properties) {
- if (property.ObjectGraphProperty.TargetNode != null) {
- ObjectGraphNode targetObjectNode = property.ObjectGraphProperty.TargetNode;
- PositionedGraphNode edgeTarget = treeNodeFor[targetObjectNode];
- property.Edge = new TreeGraphEdge
- { IsTreeEdge = false, Name = property.Name, Source = property, Target = edgeTarget };
- }
- }
- }
- resultGraph.Root = treeNodeFor[objectGraph.Root];
- return resultGraph;
- }
-
- void CalculateLayout(PositionedGraph resultGraph)
- {
- HashSet<PositionedGraphNode> seenNodes = new HashSet<PositionedGraphNode>();
- // first layout pass
- CalculateSubtreeSizes((TreeGraphNode)resultGraph.Root, seenNodes);
- // second layout pass
- CalculateNodePosRecursive((TreeGraphNode)resultGraph.Root, 0, 0);
- }
-
- // determines which edges are tree edges, and calculates subtree size for each node
- private void CalculateSubtreeSizes(TreeGraphNode root, HashSet<PositionedGraphNode> seenNodes)
- {
- seenNodes.Add(root);
- double subtreeSize = 0;
-
- foreach (PositionedNodeProperty property in root.Properties) {
- var edge = property.Edge as TreeGraphEdge; // we know that these egdes are TreeEdges
- if (edge != null) {
- var neigborNode = (TreeGraphNode)edge.Target;
- if (seenNodes.Contains(neigborNode)) {
- edge.IsTreeEdge = false;
- } else {
- edge.IsTreeEdge = true;
- CalculateSubtreeSizes(neigborNode, seenNodes);
- subtreeSize += neigborNode.SubtreeSize;
- }
- }
- }
- root.Measure();
- root.SubtreeSize = Math.Max(root.LateralSizeWithMargin, subtreeSize);
- }
-
-
- /// <summary>
- /// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom fashion.
- /// </summary>
- /// <param name="node"></param>
- /// <param name="lateralStart"></param>
- /// <param name="mainStart"></param>
- private void CalculateNodePosRecursive(TreeGraphNode node, double lateralStart, double mainStart)
- {
- double childsSubtreeSize = node.Childs.Sum(child => child.SubtreeSize);
- // center this node
- double center = node.ChildEdges.Count() == 0 ? 0 : 0.5 * (childsSubtreeSize - (node.LateralSizeWithMargin));
- if (center < 0) {
- // if root is larger than subtree, it would be shifted below lateralStart
- // -> make whole layout start at lateralStart
- lateralStart -= center;
- }
-
- // design alternatives
- // node.MainPos += center; // used this
- // Adapt(node).PosLateral += center; // TreeNodeAdapterLR + TreeNodeAdapterTB
- // SetMainPos(node, GetMainPos(node) + 10) // TreeNodeAdapterLR + TreeNodeAdapterTB, no creation
-
- node.LateralCoord += lateralStart + center;
- node.MainCoord = mainStart;
-
- double childLateral = lateralStart;
- double childsMainFixed = node.MainCoord + node.MainSizeWithMargin;
- foreach (TreeGraphNode child in node.Childs) {
- CalculateNodePosRecursive(child, childLateral, childsMainFixed);
- childLateral += child.SubtreeSize;
- }
- }
- }
-}
View
27 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraph.cs
@@ -8,8 +8,11 @@
namespace Debugger.AddIn.Visualizers.Graph
{
/// <summary>
- /// Object graph built by <see cref="ObjectGraphBuilder"/>. The graph is never empty.
+ /// Object graph built by <see cref="ObjectGraphBuilder"/>.
/// </summary>
+ /// <remarks>
+ /// The graph is never empty.
+ /// </remarks>
public class ObjectGraph
{
/// <summary>
@@ -23,16 +26,16 @@ public class ObjectGraph
/// <param name="node">node to be added</param>
internal void AddNode(ObjectGraphNode node)
{
- _nodes.Add(node);
+ nodes.Add(node);
}
- private List<ObjectGraphNode> _nodes = new List<ObjectGraphNode>();
+ private List<ObjectGraphNode> nodes = new List<ObjectGraphNode>();
/// <summary>
/// All nodes in the graph. Should always contain at least one node.
/// </summary>
public IEnumerable<ObjectGraphNode> Nodes
{
- get { return _nodes; }
+ get { return nodes; }
}
// HACK to support expanding/collapsing, because expanding is done by modifying ObjectGraph and rebuiling PosGraph
@@ -40,22 +43,20 @@ public IEnumerable<ObjectGraphNode> ReachableNodes
{
get
{
- var seenNodes = new HashSet<ObjectGraphNode>();
- determineReachableNodes(this.Root, seenNodes);
- foreach (var node in seenNodes)
- {
+ var reachableNodes = new HashSet<ObjectGraphNode>();
+ FindReachableNodesRecursive(this.Root, reachableNodes);
+ foreach (var node in reachableNodes) {
yield return node;
}
}
}
- private void determineReachableNodes(ObjectGraphNode root, HashSet<ObjectGraphNode> seenNodes)
+
+ void FindReachableNodesRecursive(ObjectGraphNode root, HashSet<ObjectGraphNode> seenNodes)
{
seenNodes.Add(root);
-
- foreach(var prop in root.Properties)
- {
+ foreach(var prop in root.Properties) {
if (prop.TargetNode != null && !seenNodes.Contains(prop.TargetNode))
- determineReachableNodes(prop.TargetNode, seenNodes);
+ FindReachableNodesRecursive(prop.TargetNode, seenNodes);
}
}
}
View
126 src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraphControl.xaml.cs
@@ -14,9 +14,11 @@
using System.Windows.Media;
using Debugger.AddIn.Visualizers.Graph.Layout;
+using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Services;
-using ICSharpCode.NRefactory.Ast;
+
+using Log = ICSharpCode.Core.LoggingService;
namespace Debugger.AddIn.Visualizers.Graph
{
@@ -33,7 +35,6 @@ public partial class ObjectGraphControl : UserControl
private PositionedGraph oldPosGraph;
private PositionedGraph currentPosGraph;
private GraphDrawer graphDrawer;
- private Layout.TreeLayouter layouter;
/// <summary> Long-lived map telling which graph nodes and content nodes the user expanded. </summary>
private Expanded expanded = new Expanded();
@@ -50,7 +51,6 @@ public ObjectGraphControl()
this.layoutViewModel.PropertyChanged += new PropertyChangedEventHandler(layoutViewModel_PropertyChanged);
this.cmbLayoutDirection.DataContext = this.layoutViewModel;
- this.layouter = new TreeLayouter();
this.graphDrawer = new GraphDrawer(this.canvas);
}
@@ -61,7 +61,40 @@ public void Clear()
public void Refresh()
{
- refreshGraph();
+ clearErrorMessage();
+ if (string.IsNullOrEmpty(txtExpression.Text))
+ {
+ this.graphDrawer.ClearCanvas();
+ return;
+ }
+ if (debuggerService.IsProcessRunning) // "Process not paused" exception still occurs
+ {
+ ErrorMessage("Cannot inspect when the process is running.");
+ return;
+ }
+ bool isSuccess = true;
+ try
+ {
+ this.objectGraph = RebuildGraph(txtExpression.Text);
+ }
+ catch(DebuggerVisualizerException ex)
+ {
+ isSuccess = false;
+ ErrorMessage(ex.Message);
+ }
+ catch(Debugger.GetValueException ex)
+ {
+ isSuccess = false;
+ ErrorMessage("Expression cannot be evaluated - " + ex.Message);
+ }
+ if (isSuccess)
+ {
+ LayoutGraph(this.objectGraph);
+ }
+ else
+ {
+ this.graphDrawer.ClearCanvas();
+ }
}
private ICSharpCode.NRefactory.Ast.Expression shownExpression;
@@ -97,80 +130,38 @@ private void Inspect_Button_Click(object sender, RoutedEventArgs e)
this.Refresh();
}
- void refreshGraph()
- {
- clearErrorMessage();
- if (string.IsNullOrEmpty(txtExpression.Text))
- {
- this.graphDrawer.ClearCanvas();
- return;
- }
- if (debuggerService.IsProcessRunning) // "Process not paused" exception still occurs
- {
- showErrorMessage("Cannot inspect when the process is running.");
- return;
- }
- bool graphBuiltOk = true;
- try
- {
- this.objectGraph = rebuildGraph(txtExpression.Text);
- }
- catch(DebuggerVisualizerException ex)
- {
- graphBuiltOk = false;
- showErrorMessage(ex.Message);
- }
- catch(Debugger.GetValueException ex)
- {
- graphBuiltOk = false;
- showErrorMessage("Expression cannot be evaluated - " + ex.Message);
- }
- if (graphBuiltOk)
- {
- layoutGraph(this.objectGraph);
- }
- else
- {
- this.graphDrawer.ClearCanvas();
- }
- }
-
- ObjectGraph rebuildGraph(string expression)
+ ObjectGraph RebuildGraph(string expression)
{
this.objectGraphBuilder = new ObjectGraphBuilder(debuggerService);
- ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Building graph for expression: " + txtExpression.Text);
+ Log.Debug("Debugger visualizer: Building graph for expression: " + txtExpression.Text);
return this.objectGraphBuilder.BuildGraphForExpression(expression, this.expanded.Expressions);
}
- void layoutGraph(ObjectGraph graph)
+ void LayoutGraph(ObjectGraph graph)
{
- if (this.oldPosGraph != null)
- {
- foreach (var oldNode in this.oldPosGraph.Nodes)
- {
+ if (this.oldPosGraph != null) {
+ foreach (var oldNode in this.oldPosGraph.Nodes) {
// controls from old graph would be garbage collected, reuse them
NodeControlCache.Instance.ReturnForReuse(oldNode.NodeVisualControl);
}
}
this.oldPosGraph = this.currentPosGraph;
- ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Calculating graph layout");
- this.currentPosGraph = this.layouter.CalculateLayout(graph, layoutViewModel.SelectedEnumValue, this.expanded);
- ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Graph layout done");
- registerExpandCollapseEvents(this.currentPosGraph);
+ Log.Debug("Debugger visualizer: Calculating graph layout");
+ var layoutDirection = layoutViewModel.SelectedEnumValue;
+ this.currentPosGraph = new TreeLayout(layoutDirection).CalculateLayout(graph, this.expanded);
+ Log.Debug("Debugger visualizer: Graph layout done");
+ RegisterExpandCollapseEvents(this.currentPosGraph);
var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph);
- ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: starting graph animation");
+ Log.Debug("Debugger visualizer: starting graph animation");
this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff);
- //this.graphDrawer.Draw(this.currentPosGraph); // buggy layout with NodeControlCache
}
void layoutViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
- if (e.PropertyName == "SelectedEnumValue") // TODO special event for enum value change
- {
- if (this.objectGraph != null)
- {
- layoutGraph(this.objectGraph);
+ if (e.PropertyName == "SelectedEnumValue") {
+ if (this.objectGraph != null) {
+ LayoutGraph(this.objectGraph);
}
}
}
@@ -180,17 +171,16 @@ void clearErrorMessage()
this.pnlError.Visibility = Visibility.Collapsed;
}
- void showErrorMessage(string message)
+ void ErrorMessage(string message)
{
this.txtError.Text = message;
this.pnlError.Visibility = Visibility.Visible;
//MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}
- void registerExpandCollapseEvents(PositionedGraph posGraph)
+ void RegisterExpandCollapseEvents(PositionedGraph posGraph)
{
- foreach (var node in posGraph.Nodes)
- {
+ foreach (var node in posGraph.Nodes) {
node.PropertyExpanded += new EventHandler<PositionedPropertyEventArgs>(node_PropertyExpanded);
node.PropertyCollapsed += new EventHandler<PositionedPropertyEventArgs>(node_PropertyCollapsed);
node.ContentNodeExpanded += new EventHandler<ContentNodeEventArgs>(node_ContentNodeExpanded);
@@ -201,13 +191,13 @@ void registerExpandCollapseEvents(PositionedGraph posGraph)
void node_ContentNodeExpanded(object sender, ContentNodeEventArgs e)
{
expanded.ContentNodes.SetExpanded(e.Node);
- layoutGraph(this.objectGraph);
+ LayoutGraph(this.objectGraph);
}
void node_ContentNodeCollapsed(object sender, ContentNodeEventArgs e)
{
expanded.ContentNodes.SetCollapsed(e.Node);
- layoutGraph(this.objectGraph);
+ LayoutGraph(this.objectGraph);
}
void node_PropertyExpanded(object sender, PositionedPropertyEventArgs e)
@@ -218,7 +208,7 @@ void node_PropertyExpanded(object sender, PositionedPropertyEventArgs e)
// add edge (+ possibly nodes) to underlying object graph (no need to fully rebuild)
// TODO can add more nodes if they are expanded - now this adds always one node
e.Property.ObjectGraphProperty.TargetNode = this.objectGraphBuilder.ObtainNodeForExpression(e.Property.Expression);
- layoutGraph(this.objectGraph);
+ LayoutGraph(this.objectGraph);
}
void node_PropertyCollapsed(object sender, PositionedPropertyEventArgs e)
@@ -228,7 +218,7 @@ void node_PropertyCollapsed(object sender, PositionedPropertyEventArgs e)
// just remove edge from underlying object graph (no need to fully rebuild)
e.Property.ObjectGraphProperty.TargetNode = null;
- layoutGraph(this.objectGraph);
+ LayoutGraph(this.objectGraph);
}
}
}

0 comments on commit 550e862

Please sign in to comment.
Something went wrong with that request. Please try again.