From ad68c69135ac41509edccaf8d9f5033f579d6d74 Mon Sep 17 00:00:00 2001 From: mkonicek Date: Wed, 23 Mar 2011 13:01:22 +0100 Subject: [PATCH] Object graph member icons. Object graph supports IEnumerable, and fixed a cast bug in IList. TODO release PermanentReferences for collections. --- .../Drawing/PositionedGraphNodeControl.xaml | 14 +++++----- .../PositionedGraphNodeControl.xaml.cs | 12 ++++++--- .../Graph/Layout/TreeModel/ContentNode.cs | 6 +++-- .../Layout/TreeModel/ContentPropertyNode.cs | 26 ++++++++++++++----- .../Graph/ObjectGraph/ObjectGraphBuilder.cs | 20 +++++++++----- .../Visualizers/Utils/DebuggerHelpers.cs | 2 +- .../Visualizers/Utils/ListHelper.cs | 2 +- 7 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml index 20bac82ca5..50b0fda06e 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml @@ -57,7 +57,7 @@ - + @@ -78,18 +78,16 @@ - - + - + - --> - + @@ -99,7 +97,7 @@ - + diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs index 881a90d09f..a850f02ba9 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml.cs @@ -26,6 +26,8 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing /// public partial class PositionedGraphNodeControl : UserControl { + public static readonly bool IsShowMemberIcon = true; + /// /// Occurs when is expanded. /// @@ -73,11 +75,15 @@ namespace Debugger.AddIn.Visualizers.Graph.Drawing public void CalculateWidthHeight() { + if (!IsShowMemberIcon) { + columnMemberIcon.Width = 0; + } + int nameColumnMaxLen = this.items.MaxOrDefault(contentNode => contentNode.Name.Length, 0); GridView gv = listView.View as GridView; - gv.Columns[1].Width = Math.Min(20 + nameColumnMaxLen * 6, 260); - gv.Columns[2].Width = 80; - listView.Width = gv.Columns[0].Width + gv.Columns[1].Width + gv.Columns[2].Width + 10; + columnName.Width = Math.Min(20 + nameColumnMaxLen * 6, 260); + columnText.Width = 80; + listView.Width = columnExpander.Width + columnMemberIcon.Width + columnName.Width + columnText.Width + 10; int maxItems = 10; listView.Height = 4 + Math.Min(this.items.Count, maxItems) * 20; diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs index 2f3917f3f4..517c94b663 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentNode.cs @@ -26,8 +26,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout this.parent = parent; } - // Icon next to the name - didn't add much value - //public ImageSource MemberIcon { get; set; } + /// + /// Icon next to the name - didn't add much value + /// + public ImageSource MemberIcon { get; set; } /// /// Path to this content node in the whole . diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs index 19e512eb79..53b4a1e2db 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/TreeModel/ContentPropertyNode.cs @@ -4,6 +4,7 @@ using System; using System.ComponentModel; using Debugger.AddIn.TreeModel; +using Debugger.AddIn.Visualizers.Graph.Drawing; using Debugger.MetaData; namespace Debugger.AddIn.Visualizers.Graph.Layout @@ -39,7 +40,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout this.Property.Evaluate(); this.Text = this.Property.Value; } - + public override bool ShowExpandPropertyButton { get @@ -59,17 +60,28 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout this.Name = sourcePropertyNode.Property.Name; // 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(). - this.Text = sourcePropertyNode.Property.Value; + this.Text = sourcePropertyNode.Property.Value; this.IsNested = false; this.IsExpanded = false; // always false, Property nodes are never expanded (they have IsPropertyExpanded) this.Property = new PositionedNodeProperty( sourcePropertyNode.Property, this.ContainingNode, expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression)); - - // Icon next to the name - didn't add much value - /*string imageName; - var image = ExpressionNode.GetImageForMember((IDebugMemberInfo)sourcePropertyNode.Property.PropInfo, out imageName); - this.MemberIcon = image.ImageSource;*/ + if (PositionedGraphNodeControl.IsShowMemberIcon) { + EvalMemberIcon(); + } + } + + 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; + } + } } } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs index 8afce87fd6..81181b0f89 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ObjectGraph/ObjectGraphBuilder.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Reflection; + +using Debugger.AddIn.TreeModel; using Debugger.AddIn.Visualizers.Common; using Debugger.AddIn.Visualizers.Utils; using Debugger.MetaData; @@ -146,15 +148,18 @@ namespace Debugger.AddIn.Visualizers.Graph thisNode.Content = new ThisNode(); ThisNode contentRoot = thisNode.Content; - DebugType iListType; - DebugType listItemType; - if (thisNode.PermanentReference.Type.ResolveIListImplementation(out iListType, out listItemType)) + DebugType collectionType; + DebugType itemType; + if (thisNode.PermanentReference.Type.ResolveIListImplementation(out collectionType, out itemType)) { // it is an IList - loadNodeCollectionContent(contentRoot, thisNode.Expression, iListType); - } - else - { + loadNodeCollectionContent(contentRoot, thisNode.Expression, collectionType); + } else if (thisNode.PermanentReference.Type.ResolveIEnumerableImplementation(out collectionType, out itemType)) { + // it is an IEnumerable + DebugType debugListType; + var debugListExpression = DebuggerHelpers.CreateDebugListExpression(thisNode.Expression, itemType, out debugListType); + loadNodeCollectionContent(contentRoot, debugListExpression, debugListType); + } else { // it is an object 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) { + thisObject = thisObject.CastToIList(); int listCount = getIListCount(thisObject, iListType); for (int i = 0; i < listCount; i++) diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs index d384e42113..cea98134eb 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/DebuggerHelpers.cs +++ b/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); // explicitely cast the variable to IEnumerable, where T is itemType Expression iEnumerableVariableExplicitCast = new CastExpression(iEnumerableType.GetTypeReference() , iEnumerableVariable, CastType.Cast); - return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.ToList()); + return new ObjectCreateExpression(listType.GetTypeReference(), iEnumerableVariableExplicitCast.SingleItemList()); } /// diff --git a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs index 87a5eac336..f285970d15 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Visualizers/Utils/ListHelper.cs @@ -25,7 +25,7 @@ namespace Debugger.AddIn.Visualizers.Utils return list; } - public static List ToList(this T singleItem) + public static List SingleItemList(this T singleItem) { var newList = new List(); newList.Add(singleItem);