Browse Source

Object graph member icons. Object graph supports IEnumerable, and fixed a cast bug in IList. TODO release PermanentReferences for collections.

pull/15/head
mkonicek 15 years ago
parent
commit
ad68c69135
  1. 14
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml
  2. 12
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs
  3. 6
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs
  4. 26
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs
  5. 20
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs
  6. 2
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs
  7. 2
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs

14
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml

@ -57,7 +57,7 @@
<!-- Databound item is ContentNode --> <!-- Databound item is ContentNode -->
<GridView.Columns> <GridView.Columns>
<!-- Expand button (either property or nested) --> <!-- Expand button (either property or nested) -->
<GridViewColumn Header="Plus" Width="20"> <GridViewColumn Header="Plus" Width="20" x:Name="columnExpander">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Margin="0 2 0 0"> <StackPanel Margin="0 2 0 0">
@ -78,18 +78,16 @@
</DataTemplate> </DataTemplate>
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
<!-- Icon - didn't add much value --> <!-- Icon -->
<!-- <GridViewColumn Header="Icon" Width="10" x:Name="columnMemberIcon" >
<GridViewColumn Header="Icon" Width="10">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<Image Width="10" Height="10" Source="{Binding MemberIcon}"></Image> <Image Width="10" Height="10" Source="{Binding MemberIcon}" Margin="-6 0"></Image>
</DataTemplate> </DataTemplate>
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
-->
<!-- Name --> <!-- Name -->
<GridViewColumn Header="Name" Width="60"> <GridViewColumn Header="Name" Width="60" x:Name="columnName">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@ -99,7 +97,7 @@
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
<!-- Text --> <!-- Text -->
<GridViewColumn Header="Value" Width="60" CellTemplate="{StaticResource valueColumnTemplate}"> <GridViewColumn Header="Value" Width="60" CellTemplate="{StaticResource valueColumnTemplate}" x:Name="columnText">
</GridViewColumn> </GridViewColumn>
</GridView.Columns> </GridView.Columns>
</GridView> </GridView>

12
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs

@ -26,6 +26,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
/// </summary> /// </summary>
public partial class PositionedGraphNodeControl : UserControl public partial class PositionedGraphNodeControl : UserControl
{ {
public static readonly bool IsShowMemberIcon = true;
/// <summary> /// <summary>
/// Occurs when <see cref="PositionedNodeProperty"/> is expanded. /// Occurs when <see cref="PositionedNodeProperty"/> is expanded.
/// </summary> /// </summary>
@ -73,11 +75,15 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing
public void CalculateWidthHeight() public void CalculateWidthHeight()
{ {
if (!IsShowMemberIcon) {
columnMemberIcon.Width = 0;
}
int nameColumnMaxLen = this.items.MaxOrDefault(contentNode => contentNode.Name.Length, 0); int nameColumnMaxLen = this.items.MaxOrDefault(contentNode => contentNode.Name.Length, 0);
GridView gv = listView.View as GridView; GridView gv = listView.View as GridView;
gv.Columns[1].Width = Math.Min(20 + nameColumnMaxLen * 6, 260); columnName.Width = Math.Min(20 + nameColumnMaxLen * 6, 260);
gv.Columns[2].Width = 80; columnText.Width = 80;
listView.Width = gv.Columns[0].Width + gv.Columns[1].Width + gv.Columns[2].Width + 10; listView.Width = columnExpander.Width + columnMemberIcon.Width + columnName.Width + columnText.Width + 10;
int maxItems = 10; int maxItems = 10;
listView.Height = 4 + Math.Min(this.items.Count, maxItems) * 20; listView.Height = 4 + Math.Min(this.items.Count, maxItems) * 20;

6
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs

@ -26,8 +26,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.parent = parent; this.parent = parent;
} }
// Icon next to the name - didn't add much value /// <summary>
//public ImageSource MemberIcon { get; set; } /// Icon next to the name - didn't add much value
/// </summary>
public ImageSource MemberIcon { get; set; }
/// <summary> /// <summary>
/// Path to this content node in the whole <see cref="PositionedGraph"></see>. /// Path to this content node in the whole <see cref="PositionedGraph"></see>.

26
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs

@ -4,6 +4,7 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using Debugger.AddIn.TreeModel; using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Graph.Drawing;
using Debugger.MetaData; using Debugger.MetaData;
namespace Debugger.AddIn.Visualizers.Graph.Layout namespace Debugger.AddIn.Visualizers.Graph.Layout
@ -39,7 +40,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.Property.Evaluate(); this.Property.Evaluate();
this.Text = this.Property.Value; this.Text = this.Property.Value;
} }
public override bool ShowExpandPropertyButton public override bool ShowExpandPropertyButton
{ {
get get
@ -59,17 +60,28 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
this.Name = sourcePropertyNode.Property.Name; this.Name = sourcePropertyNode.Property.Name;
// Important to set Text here, as we might be just building new view over existing (evaluated) model. // Important to set Text here, as we might be just building new view over existing (evaluated) model.
// If the model is not evaluated yet, this will be string.Empty and filled in Evaluate(). // If the model is not evaluated yet, this will be string.Empty and filled in Evaluate().
this.Text = sourcePropertyNode.Property.Value; this.Text = sourcePropertyNode.Property.Value;
this.IsNested = false; this.IsNested = false;
this.IsExpanded = false; // always false, Property nodes are never expanded (they have IsPropertyExpanded) this.IsExpanded = false; // always false, Property nodes are never expanded (they have IsPropertyExpanded)
this.Property = new PositionedNodeProperty( this.Property = new PositionedNodeProperty(
sourcePropertyNode.Property, this.ContainingNode, sourcePropertyNode.Property, this.ContainingNode,
expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression)); expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression));
if (PositionedGraphNodeControl.IsShowMemberIcon) {
// Icon next to the name - didn't add much value EvalMemberIcon();
/*string imageName; }
var image = ExpressionNode.GetImageForMember((IDebugMemberInfo)sourcePropertyNode.Property.PropInfo, out imageName); }
this.MemberIcon = image.ImageSource;*/
void EvalMemberIcon()
{
// should never be null, just to be sure
if ((this.Property != null) && (this.Property.ObjectGraphProperty != null)) {
var memberInfo = (IDebugMemberInfo)this.Property.ObjectGraphProperty.MemberInfo;
if (memberInfo != null) {
string imageName;
var image = ExpressionNode.GetImageForMember(memberInfo, out imageName);
this.MemberIcon = image.ImageSource;
}
}
} }
} }
} }

20
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs

@ -4,6 +4,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using Debugger.AddIn.TreeModel;
using Debugger.AddIn.Visualizers.Common; using Debugger.AddIn.Visualizers.Common;
using Debugger.AddIn.Visualizers.Utils; using Debugger.AddIn.Visualizers.Utils;
using Debugger.MetaData; using Debugger.MetaData;
@ -146,15 +148,18 @@ namespace Debugger.AddIn.Visualizers.Graph
thisNode.Content = new ThisNode(); thisNode.Content = new ThisNode();
ThisNode contentRoot = thisNode.Content; ThisNode contentRoot = thisNode.Content;
DebugType iListType; DebugType collectionType;
DebugType listItemType; DebugType itemType;
if (thisNode.PermanentReference.Type.ResolveIListImplementation(out iListType, out listItemType)) if (thisNode.PermanentReference.Type.ResolveIListImplementation(out collectionType, out itemType))
{ {
// it is an IList // it is an IList
loadNodeCollectionContent(contentRoot, thisNode.Expression, iListType); loadNodeCollectionContent(contentRoot, thisNode.Expression, collectionType);
} } else if (thisNode.PermanentReference.Type.ResolveIEnumerableImplementation(out collectionType, out itemType)) {
else // it is an IEnumerable
{ DebugType debugListType;
var debugListExpression = DebuggerHelpers.CreateDebugListExpression(thisNode.Expression, itemType, out debugListType);
loadNodeCollectionContent(contentRoot, debugListExpression, debugListType);
} else {
// it is an object // it is an object
loadNodeObjectContent(contentRoot, thisNode.Expression, thisNode.PermanentReference.Type); loadNodeObjectContent(contentRoot, thisNode.Expression, thisNode.PermanentReference.Type);
} }
@ -162,6 +167,7 @@ namespace Debugger.AddIn.Visualizers.Graph
private void loadNodeCollectionContent(AbstractNode node, Expression thisObject, DebugType iListType) private void loadNodeCollectionContent(AbstractNode node, Expression thisObject, DebugType iListType)
{ {
thisObject = thisObject.CastToIList();
int listCount = getIListCount(thisObject, iListType); int listCount = getIListCount(thisObject, iListType);
for (int i = 0; i < listCount; i++) for (int i = 0; i < listCount; i++)

2
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs

@ -30,7 +30,7 @@ namespace Debugger.AddIn.Visualizers.Utils
var iEnumerableType = DebugType.CreateFromType(itemType.AppDomain, typeof(IEnumerable<>), itemType); var iEnumerableType = DebugType.CreateFromType(itemType.AppDomain, typeof(IEnumerable<>), itemType);
// explicitely cast the variable to IEnumerable<T>, where T is itemType // explicitely cast the variable to IEnumerable<T>, where T is itemType
Expression iEnumerableVariableExplicitCast = new CastExpression(iEnumerableType.GetTypeReference() , iEnumerableVariable, CastType.Cast); Expression iEnumerableVariableExplicitCast = new CastExpression(iEnumerableType.GetTypeReference() , iEnumerableVariable, CastType.Cast);
return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.ToList()); return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.SingleItemList());
} }
/// <summary> /// <summary>

2
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs

@ -25,7 +25,7 @@ namespace Debugger.AddIn.Visualizers.Utils
return list; return list;
} }
public static List<T> ToList<T>(this T singleItem) public static List<T> SingleItemList<T>(this T singleItem)
{ {
var newList = new List<T>(); var newList = new List<T>();
newList.Add(singleItem); newList.Add(singleItem);

Loading…
Cancel
Save