Browse Source

- lazy evaluation of node content

- better displaying of exceptions

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4377 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Martin Koníček 17 years ago
parent
commit
84114e17f8
  1. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Common/ObjectPropertyComparer.cs
  2. 3
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/GraphDrawer.cs
  3. 8
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/NodeControl.xaml.cs
  4. 23
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml
  5. 9
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs
  6. 7
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/NestedNodeViewModel.cs
  7. 53
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PositionedGraphNode.cs
  8. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PositionedNodeProperty.cs
  9. 9
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PropertyNodeViewModel.cs
  10. 6
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/LayoutDirection.cs
  11. 66
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/TreeLayouter.cs
  12. 36
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraph.cs
  13. 52
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  14. 11
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml
  15. 51
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml.cs

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Common/ObjectPropertyComparer.cs

@ -14,6 +14,12 @@ namespace Debugger.AddIn.Visualizers.Common @@ -14,6 +14,12 @@ namespace Debugger.AddIn.Visualizers.Common
/// </summary>
class ObjectPropertyComparer : IComparer<ObjectProperty>
{
private static readonly ObjectPropertyComparer instance = new ObjectPropertyComparer();
public static ObjectPropertyComparer Instance
{
get { return instance; }
}
public int Compare(ObjectProperty prop1, ObjectProperty prop2)
{
// order by IsAtomic, Name

3
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/GraphDrawer.cs

@ -89,7 +89,6 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -89,7 +89,6 @@ namespace Debugger.AddIn.Visualizers.Graph
anim.Completed += new EventHandler((o, e) => { Draw(newGraph); });
first = false;
}
//anim.From = new Point(Canvas.GetLeft(node.NodeVisualControl), Canvas.GetTop(node.NodeVisualControl));
anim.From = node.LeftTop;
anim.To = newNode.LeftTop;
@ -122,7 +121,7 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -122,7 +121,7 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
private NodeControl addNodeToCanvas(PositionedGraphNode node)
private PositionedGraphNodeControl addNodeToCanvas(PositionedGraphNode node)
{
canvas.Children.Add(node.NodeVisualControl);
Canvas.SetLeft(node.NodeVisualControl, node.Left);

8
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/NodeControl.xaml.cs

@ -72,7 +72,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -72,7 +72,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
{
Button btnExpandCollapse = new Button();
btnExpandCollapse.Tag = property;
btnExpandCollapse.Content = property.IsExpanded ? "-" : "+";
btnExpandCollapse.Content = property.IsPropertyExpanded ? "-" : "+";
btnExpandCollapse.Width = 20;
propertyGrid.Children.Add(btnExpandCollapse);
Grid.SetRow(btnExpandCollapse, nRow);
@ -110,9 +110,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -110,9 +110,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
Button buttonClicked = ((Button)sender);
var property = (PositionedNodeProperty)buttonClicked.Tag;
property.IsExpanded = !property.IsExpanded;
buttonClicked.Content = property.IsExpanded ? "-" : "+";
if (property.IsExpanded)
property.IsPropertyExpanded = !property.IsPropertyExpanded;
buttonClicked.Content = property.IsPropertyExpanded ? "-" : "+";
if (property.IsPropertyExpanded)
{
OnPropertyExpanded(property);
}

23
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml

@ -48,12 +48,12 @@ @@ -48,12 +48,12 @@
</GridView.ColumnHeaderContainerStyle>
<GridView.Columns>
<!-- Expand button (either property or nested) -->
<GridViewColumn Header="Plus" Width="Auto">
<GridViewColumn Header="Plus" Width="35">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ToggleButton x:Name="Expander" Width="20" IsChecked="{Binding IsExpanded}" Click="NestedExpandButton_Click" Padding="0" Margin="0 0 6 0">+</ToggleButton>
<ToggleButton x:Name="PropertyExpander" Click="PropertyExpandButton_Click" Padding="0" Margin="0 0 6 0">+p</ToggleButton>
<ToggleButton x:Name="Expander" Width="20" Margin="0" IsChecked="{Binding IsExpanded}" Click="NestedExpandButton_Click" Padding="0">+</ToggleButton>
<ToggleButton x:Name="PropertyExpander" Width="20" Margin="0" IsChecked="{Binding IsPropertyExpanded}" Click="PropertyExpandButton_Click" Padding="0">+</ToggleButton>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasChildren}" Value="False">
@ -65,24 +65,29 @@ @@ -65,24 +65,29 @@
Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- Name -->
<GridViewColumn Header="Name" Width="Auto">
<GridViewColumn Header="Name" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" MinWidth="100"></TextBlock>
</StackPanel>
<!--
<TextBlock Text="hello" MinWidth="100"></TextBlock>
-->
<TextBlock Text="{Binding Name}" MinWidth="80"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!-- Text -->
<GridViewColumn Header="Value" Width="Auto">
<GridViewColumn Header="Value" Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" MinWidth="100"></TextBlock>
<!--
<TextBlock Text="val" MinWidth="100"></TextBlock>
-->
<TextBlock Text="{Binding Text}" MinWidth="80"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

9
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs

@ -52,7 +52,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -52,7 +52,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
this.view = initializeView(this.root);
// data virtualization, PropertyNodeViewModel implements IEvaluate
this.listView.ItemsSource = new VirtualizingObservableCollection<NestedNodeViewModel>(this.view);
//listView.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(listView_ScrollChanged));
}
}
@ -75,9 +74,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -75,9 +74,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
}
PositionedNodeProperty property = clickedNode.Property;
property.IsExpanded = !property.IsExpanded;
clickedButton.Content = property.IsExpanded ? "-p" : "+p";
if (property.IsExpanded)
//property.IsPropertyExpanded = !property.IsPropertyExpanded; // done by databinding
clickedButton.Content = property.IsPropertyExpanded ? "-" : "+";
if (property.IsPropertyExpanded)
{
OnPropertyExpanded(property);
}
@ -115,8 +114,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing @@ -115,8 +114,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
}
}
var a = new ListViewItem();
// set to Auto again to resize columns
var colName = (this.listView.View as GridView).Columns[0];
var colValue = (this.listView.View as GridView).Columns[1];

7
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/NestedNodeViewModel.cs

@ -21,20 +21,19 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -21,20 +21,19 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.containingNode = containingNode;
}
/// <summary>
/// Name displayed in GUI.
/// </summary>
public string Name { get; protected set; }
public string Name { get; set; }
/// <summary>
/// Text displayed in GUI.
/// </summary>
public string Text { get; protected set; }
public string Text { get; set; }
/// <summary>
/// Is this expandable node?
/// </summary>
public bool IsNested { get; protected set; }
public bool IsNested { get; set; }
/// <summary>
/// Does this node have any children?
/// </summary>

53
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PositionedGraphNode.cs

@ -25,6 +25,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -25,6 +25,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.objectNode = objectNode;
}
public event EventHandler<PositionedPropertyEventArgs> PropertyExpanded;
public event EventHandler<PositionedPropertyEventArgs> PropertyCollapsed;
private ObjectGraphNode objectNode;
/// <summary>
/// Underlying ObjectNode.
@ -34,8 +37,25 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -34,8 +37,25 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
get { return objectNode; }
}
public event EventHandler<PositionedPropertyEventArgs> PropertyExpanded;
public event EventHandler<PositionedPropertyEventArgs> PropertyCollapsed;
/// <summary>
/// Tree-of-properties content of this node.
/// </summary>
public NestedNodeViewModel Content
{
get; set;
}
private PositionedGraphNodeControl nodeVisualControl;
/// <summary>
/// Visual control to be shown for this node.
/// </summary>
public PositionedGraphNodeControl NodeVisualControl
{
get
{
return this.nodeVisualControl;
}
}
// TODO posNodeForObjectGraphNode will be a service, that will return existing posNodes or create empty new
public void InitContentFromObjectNode()
@ -46,7 +66,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -46,7 +66,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
public void InitView()
{
this.nodeVisualControl = new NodeControl();
this.nodeVisualControl = new PositionedGraphNodeControl();
this.nodeVisualControl.MaxHeight = 200;
this.nodeVisualControl.PropertyExpanded += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_Expanded);
this.nodeVisualControl.PropertyCollapsed += new EventHandler<PositionedPropertyEventArgs>(NodeVisualControl_Collapsed);
@ -54,20 +75,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -54,20 +75,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
public void FillView()
{
//this.nodeVisualControl.Root = this.Content;
foreach (var property in this.Properties)
this.nodeVisualControl.Root = this.Content;
/*foreach (var property in this.Properties)
{
property.Evaluate();
this.nodeVisualControl.AddProperty(property);
}
}
/// <summary>
/// Tree-of-properties content of this node.
/// </summary>
public NestedNodeViewModel Content
{
get; set;
}*/
}
// TODO do proper tree iteration
@ -83,17 +96,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -83,17 +96,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
}
}
private NodeControl nodeVisualControl;
/// <summary>
/// Visual control to be shown for this node.
/// </summary>
public NodeControl NodeVisualControl
{
get
{
return this.nodeVisualControl;
}
}
public virtual IEnumerable<PositionedEdge> Edges
{

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PositionedNodeProperty.cs

@ -32,7 +32,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -32,7 +32,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// <summary>
/// Is this property expanded?
/// </summary>
public bool IsExpanded { get; set; }
public bool IsPropertyExpanded { get; set; }
/// <summary>
/// Edge outgoing from this property to another <see cref="PositionedNode"/>.

9
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/PropertyNodeViewModel.cs

@ -32,6 +32,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -32,6 +32,12 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
get { return this.positionedProperty.IsEvaluated; }
}
public bool IsPropertyExpanded
{
get { return this.positionedProperty.IsPropertyExpanded; }
set { this.positionedProperty.IsPropertyExpanded = value; }
}
public void Evaluate()
{
this.positionedProperty.Evaluate();
@ -46,10 +52,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -46,10 +52,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
PropertyNode sourcePropertyNode = source as PropertyNode;
this.Name = sourcePropertyNode.Property.Name;
this.Text = ""; // lazy evaluated
this.Text = sourcePropertyNode.Property.Value; // lazy evaluated
this.IsNested = false;
this.IsExpanded = false;
this.Name = sourcePropertyNode.Property.Name;
this.positionedProperty = new PositionedNodeProperty(sourcePropertyNode.Property, this.ContainingNode);
}
}

6
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/LayoutDirection.cs

@ -13,9 +13,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -13,9 +13,9 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary>
public enum LayoutDirection
{
[Display("Top to bottom")]
TopBottom,
[Display("Left to right")]
LeftRight
LeftRight,
[Display("Top to bottom")]
TopBottom
}
}

66
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/Layout/Tree/TreeLayouter.cs

@ -22,8 +22,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -22,8 +22,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
private LayoutDirection layoutDirection = LayoutDirection.TopBottom;
PositionedGraph resultGraph = null;
HashSet<PositionedGraphNode> seenNodes = new HashSet<PositionedGraphNode>();
Dictionary<ObjectGraphNode, PositionedGraphNode> treeNodeFor = new Dictionary<ObjectGraphNode, PositionedGraphNode>();
@ -46,11 +44,11 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -46,11 +44,11 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
//TreeGraphNode tree = buildTreeRecursive(objectGraph.Root, expandedNodes);
// convert ObjectGraph to PositionedGraph with TreeEdges
PositionedGraph tree = buildTreeGraph(objectGraph, expandedNodes);
// first pass
calculateSubtreeSizes((TreeGraphNode)tree.Root);
// second pass
calculateNodePosRecursive((TreeGraphNode)tree.Root, 0, 0);
var resultGraph = buildTreeGraph(objectGraph, expandedNodes);
// first layout pass
calculateSubtreeSizes((TreeGraphNode)resultGraph.Root);
// second layout pass
calculateNodePosRecursive((TreeGraphNode)resultGraph.Root, 0, 0);
var neatoRouter = new NeatoEdgeRouter();
resultGraph = neatoRouter.CalculateEdges(resultGraph);
@ -60,10 +58,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -60,10 +58,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
private PositionedGraph buildTreeGraph(ObjectGraph objectGraph, ExpandedNodes expandedNodes)
{
resultGraph = new PositionedGraph();
var resultGraph = new PositionedGraph();
// create empty PosNodes
foreach (ObjectGraphNode objectGraphNode in objectGraph.Nodes)
foreach (ObjectGraphNode objectGraphNode in objectGraph.ReachableNodes)
{
TreeGraphNode posNode = createNewTreeGraphNode(objectGraphNode);
resultGraph.AddNode(posNode);
@ -84,7 +82,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -84,7 +82,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
// create edges outgoing from this posNode
foreach (PositionedNodeProperty property in posNode.Properties)
{
property.IsExpanded = expandedNodes.IsExpanded(property.Expression.Code);
property.IsPropertyExpanded = expandedNodes.IsExpanded(property.Expression.Code);
if (property.ObjectGraphProperty.TargetNode != null)
{
@ -137,54 +135,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -137,54 +135,6 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
return newGraphNode;
}
/*private TreeGraphNode buildTreeRecursive(ObjectGraphNode objectGraphNode, ExpandedNodes expandedNodes)
{
seenNodes.Add(objectGraphNode, null);
TreeGraphNode newTreeNode = createNewTreeGraphNode();
resultGraph.AddNode(newTreeNode);
treeNodeFor[objectGraphNode] = newTreeNode;
double subtreeSize = 0;
foreach (AbstractNode absNode in objectGraphNode.Content.Children)
{
var newTreeNodeContent = new NestedNodeViewModel();
ObjectGraphProperty property = ((PropertyNode)absNode).Property;
if (property.TargetNode != null)
{
ObjectGraphNode neighbor = property.TargetNode;
TreeGraphNode targetTreeNode = null;
bool newEdgeIsTreeEdge = false;
if (seenNodes.ContainsKey(neighbor))
{
targetTreeNode = treeNodeFor[neighbor];
newEdgeIsTreeEdge = false;
}
else
{
targetTreeNode = buildTreeRecursive(neighbor, expandedNodes);
newEdgeIsTreeEdge = true;
subtreeSize += targetTreeNode.SubtreeSize;
}
var posNodeProperty = newTreeNode.AddProperty(property, expandedNodes.IsExpanded(property.Expression.Code));
posNodeProperty.Edge = new TreeGraphEdge { IsTreeEdge = newEdgeIsTreeEdge, Name = property.Name, Source = posNodeProperty, Target = targetTreeNode };
}
else
{
// property.Edge stays null
newTreeNode.AddProperty(property, expandedNodes.IsExpanded(property.Expression.Code));
}
}
newTreeNode.Measure();
newTreeNode.SubtreeSize = Math.Max(newTreeNode.LateralSizeWithMargin, subtreeSize);
return newTreeNode;
}*/
/// <summary>
/// Given SubtreeSize for each node, positions the nodes, in a left-to-right or top-to-bottom fashion.
/// </summary>

36
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraph.cs

@ -38,22 +38,28 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -38,22 +38,28 @@ namespace Debugger.AddIn.Visualizers.Graph
get { return _nodes; }
}
/*
/// <summary>
/// All edges in the graph.
/// </summary>
public IEnumerable<ObjectEdge> Edges
// HACK to support expanding/collapsing, because expanding is done by modifying ObjectGraph and rebuiling PosGraph
public IEnumerable<ObjectGraphNode> ReachableNodes
{
get
{
var seenNodes = new HashSet<ObjectGraphNode>();
determineReachableNodes(this.Root, seenNodes);
foreach (var node in seenNodes)
{
yield return node;
}
}
}
private void determineReachableNodes(ObjectGraphNode root, HashSet<ObjectGraphNode> seenNodes)
{
get
{
foreach (ObjectNode node in this.Nodes)
{
foreach (ObjectEdge edge in node.Edges)
{
yield return edge;
}
}
seenNodes.Add(root);
foreach(var prop in root.ComplexProperties)
{
if (prop.TargetNode != null && !seenNodes.Contains(prop.TargetNode))
determineReachableNodes(prop.TargetNode, seenNodes);
}
}*/
}
}
}

52
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -11,6 +11,7 @@ using Debugger; @@ -11,6 +11,7 @@ using Debugger;
using Debugger.MetaData;
using Debugger.Expressions;
using Debugger.AddIn.Visualizers.Utils;
using Debugger.AddIn.Visualizers.Common;
namespace Debugger.AddIn.Visualizers.Graph
{
@ -79,13 +80,18 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -79,13 +80,18 @@ namespace Debugger.AddIn.Visualizers.Graph
{
if (string.IsNullOrEmpty(expression))
{
throw new DebuggerVisualizerException("Expression cannot be empty.");
throw new DebuggerVisualizerException("Expression is empty.");
}
resultGraph = new ObjectGraph();
Value rootValue = debuggerService.GetValueFromName(expression);
if (rootValue == null)
{
throw new DebuggerVisualizerException("Please use the visualizer when debugging.");
}
// empty graph for null expression
if (!debuggerService.GetValueFromName(expression).IsNull)
if (!rootValue.IsNull)
{
//resultGraph.Root = buildGraphRecursive(debuggerService.GetValueFromName(expression).GetPermanentReference(), expandedNodes);
resultGraph.Root = createNewNode(debuggerService.GetValueFromName(expression).GetPermanentReference());
@ -135,8 +141,20 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -135,8 +141,20 @@ namespace Debugger.AddIn.Visualizers.Graph
NestedNode contentRoot = new NestedNode(NestedNodeType.ThisNode);
thisNode.Content = contentRoot;
var propertyList = getProperties(thisNode.PermanentReference);
propertyList.Sort(ObjectPropertyComparer.Instance);
foreach (var property in propertyList)
{
contentRoot.AddChild(new PropertyNode(property));
}
}
private List<ObjectGraphProperty> getProperties(Value value)
{
List<ObjectGraphProperty> propertyList = new List<ObjectGraphProperty>();
// take all properties for this value (type = value's real type)
foreach(Expression memberExpr in thisNode.PermanentReference.Expression.AppendObjectMembers(thisNode.PermanentReference.Type, this.memberBindingFlags))
foreach(Expression memberExpr in value.Expression.AppendObjectMembers(value.Type, this.memberBindingFlags))
{
checkIsOfSupportedType(memberExpr);
@ -145,15 +163,17 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -145,15 +163,17 @@ namespace Debugger.AddIn.Visualizers.Graph
{
// properties are now lazy-evaluated
// string memberValueAsString = memberExpr.Evaluate(debuggerService.DebuggedProcess).InvokeToString();
AddAtomicPropertyChild(contentRoot, memberName, memberExpr);
propertyList.Add(createAtomicProperty(memberName, memberExpr));
}
else
{
ObjectGraphNode targetNode = null;
bool memberIsNull = memberExpr.IsNull();
AddComplexPropertyChild(contentRoot, memberName, memberExpr, targetNode, memberIsNull);
propertyList.Add(createComplesProperty(memberName, memberExpr, targetNode, memberIsNull));
}
}
return propertyList;
}
/// <summary>
@ -238,24 +258,18 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -238,24 +258,18 @@ namespace Debugger.AddIn.Visualizers.Graph
}
}
/// <summary>
/// Adds primitive property.
/// </summary>
public void AddAtomicPropertyChild(NestedNode node, string name, Expression expression)
public ObjectGraphProperty createAtomicProperty(string name, Expression expression)
{
// add child with no value (will be lazy-evaluated later)
node.AddChild(new PropertyNode(new ObjectGraphProperty
{ Name = name, Value = "", Expression = expression, IsAtomic = true, TargetNode = null }));
// value is empty (will be lazy-evaluated later)
return new ObjectGraphProperty
{ Name = name, Value = "", Expression = expression, IsAtomic = true, TargetNode = null };
}
/// <summary>
/// Adds complex property.
/// </summary>
public void AddComplexPropertyChild(NestedNode node, string name, Expression expression, ObjectGraphNode targetNode, bool isNull)
public ObjectGraphProperty createComplesProperty(string name, Expression expression, ObjectGraphNode targetNode, bool isNull)
{
// add child with no value (will be lazy-evaluated later)
node.AddChild(new PropertyNode(new ObjectGraphProperty
{ Name = name, Value = "", Expression = expression, IsAtomic = false, TargetNode = targetNode, IsNull = isNull }));
// value is empty (will be lazy-evaluated later)
return new ObjectGraphProperty
{ Name = name, Value = "", Expression = expression, IsAtomic = false, TargetNode = targetNode, IsNull = isNull };
}
/// <summary>

11
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml

@ -22,17 +22,24 @@ @@ -22,17 +22,24 @@
</StackPanel.Resources>
<Border Margin="3" Padding="3">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center">Expression:</TextBlock>
<TextBox Name="txtExpression" VerticalAlignment="Center" Width="100"></TextBox>
<Button Click="Inspect_Button_Click">Inspect</Button>
<TextBlock Margin="12 0 6 0" VerticalAlignment="Center">Layout:</TextBlock>
<ComboBox Name="cmbLayoutDirection" Width="150" ItemsSource="{Binding Path=EnumValues}" SelectedValue="{Binding Path=SelectedEnumValue}" SelectedValuePath="EnumValue" DisplayMemberPath="DisplayValue"></ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Name="pnlError" Visibility="Collapsed" Margin="0 6 0 0">
<TextBlock Margin="0 0 4 0" Name="lblError" FontStyle="Italic">Error: </TextBlock>
<TextBlock Margin="0 0 0 0" Name="txtError" FontStyle="Italic"></TextBlock>
</StackPanel>
</StackPanel>
</Border>
<Border Margin="3" Padding="3">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center">Layout:</TextBlock>
<ComboBox Name="cmbLayoutDirection" Width="150" ItemsSource="{Binding Path=EnumValues}" SelectedValue="{Binding Path=SelectedEnumValue}" SelectedValuePath="EnumValue" DisplayMemberPath="DisplayValue"></ComboBox>
</StackPanel>
</Border>
</StackPanel>

51
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Graph/VisualizerWPFWindow.xaml.cs

@ -92,49 +92,62 @@ namespace Debugger.AddIn.Visualizers.Graph @@ -92,49 +92,62 @@ namespace Debugger.AddIn.Visualizers.Graph
void refreshGraph()
{
this.objectGraph = rebuildGraph();
layoutGraph(this.objectGraph);
//GraphDrawer drawer = new GraphDrawer(graph);
//drawer.Draw(canvas);
}
ObjectGraph rebuildGraph()
{
this.objectGraphBuilder = new ObjectGraphBuilder(debuggerService);
bool graphBuiltOk = true;
guiClearException();
try
{
ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Building graph for expression: " + txtExpression.Text);
return this.objectGraphBuilder.BuildGraphForExpression(txtExpression.Text, this.expandedNodes);
this.objectGraph = rebuildGraph();
}
catch(DebuggerVisualizerException ex)
{
graphBuiltOk = false;
guiHandleException(ex);
return null;
}
catch(Debugger.GetValueException ex)
{
graphBuiltOk = false;
guiHandleException(ex);
return null;
}
if (graphBuiltOk)
{
layoutGraph(this.objectGraph);
}
}
ObjectGraph rebuildGraph()
{
this.objectGraphBuilder = new ObjectGraphBuilder(debuggerService);
ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Building graph for expression: " + txtExpression.Text);
return this.objectGraphBuilder.BuildGraphForExpression(txtExpression.Text, this.expandedNodes);
}
void layoutGraph(ObjectGraph graph)
{
ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Calculating graph layout");
Layout.TreeLayouter layouter = new Layout.TreeLayouter();
this.oldPosGraph = this.currentPosGraph;
ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Calculating graph layout");
this.currentPosGraph = layouter.CalculateLayout(graph, layoutViewModel.SelectedEnumValue, this.expandedNodes);
ICSharpCode.Core.LoggingService.Debug("Debugger visualizer: Graph layout completed");
registerExpandCollapseEvents(this.currentPosGraph);
//var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph);
//this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff);
this.graphDrawer.Draw(this.currentPosGraph);
var graphDiff = new GraphMatcher().MatchGraphs(oldPosGraph, currentPosGraph);
this.graphDrawer.StartAnimation(oldPosGraph, currentPosGraph, graphDiff);
//this.graphDrawer.Draw(this.currentPosGraph);
}
void guiClearException()
{
this.pnlError.Visibility = Visibility.Collapsed;
}
void guiHandleException(System.Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
this.txtError.Text = ex.Message;
this.pnlError.Visibility = Visibility.Visible;
//MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
}
void registerExpandCollapseEvents(PositionedGraph posGraph)

Loading…
Cancel
Save