Browse Source

Object graph - Expanded properties are in bold.

pull/15/head
mkonicek 15 years ago
parent
commit
4b521fa95f
  1. 1
      src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj
  2. 30
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/BoolToBoldConverter.cs
  3. 7
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/NodeControlResources.xaml
  4. 21
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/PositionedGraphNodeControl.xaml
  5. 8
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ExpandedPaths.cs
  6. 57
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentNode.cs
  7. 10
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentPropertyNode.cs
  8. 3
      src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedGraphNode.cs

1
src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj

@ -222,6 +222,7 @@
<Compile Include="Visualizers\Common\VirtualizingCollection.cs" /> <Compile Include="Visualizers\Common\VirtualizingCollection.cs" />
<Compile Include="Visualizers\Common\VirtualizingObservableCollection.cs" /> <Compile Include="Visualizers\Common\VirtualizingObservableCollection.cs" />
<Compile Include="Visualizers\Controls\DragScrollViewer.cs" /> <Compile Include="Visualizers\Controls\DragScrollViewer.cs" />
<Compile Include="Visualizers\Graph\Drawing\BoolToBoldConverter.cs" />
<Compile Include="Visualizers\Graph\Drawing\PositionedGraphNodeControl.xaml.cs"> <Compile Include="Visualizers\Graph\Drawing\PositionedGraphNodeControl.xaml.cs">
<DependentUpon>PositionedGraphNodeControl.xaml</DependentUpon> <DependentUpon>PositionedGraphNodeControl.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>

30
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/BoolToBoldConverter.cs

@ -0,0 +1,30 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Data;
namespace Debugger.AddIn.Visualizers
{
/// <summary>
/// Used for TextBlocks in PositionedGraphNodeControl, to make property name bold when the property is expanded.
/// </summary>
public class BoolToBoldConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is bool))
return FontWeights.Normal;
return (bool)value ? FontWeights.Bold : FontWeights.Normal;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

7
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Drawing/NodeControlResources.xaml

@ -2,13 +2,16 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Debugger.AddIn.Visualizers" xmlns:local="clr-namespace:Debugger.AddIn.Visualizers"
> >
<local:TooltipVisibilityConverter x:Key="toolVisConverter"></local:TooltipVisibilityConverter> <local:TooltipVisibilityConverter x:Key="TooltipVisibilityConverter"></local:TooltipVisibilityConverter>
<local:BoolToBoldConverter x:Key="BoolToBoldConverter"></local:BoolToBoldConverter>
<DataTemplate x:Key="valueColumnTemplate"> <DataTemplate x:Key="valueColumnTemplate">
<TextBlock Text="{Binding Text}" MaxWidth="200"> <TextBlock Text="{Binding Text}" MaxWidth="200">
<TextBlock.ToolTip> <TextBlock.ToolTip>
<ToolTip <ToolTip
DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}" DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}"
Visibility="{Binding Converter={StaticResource toolVisConverter}, ConverterParameter=2}"> Visibility="{Binding Converter={StaticResource TooltipVisibilityConverter}, ConverterParameter=2}">
<TextBlock Text="{Binding Text}"></TextBlock> <TextBlock Text="{Binding Text}"></TextBlock>
</ToolTip> </ToolTip>
</TextBlock.ToolTip> </TextBlock.ToolTip>

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

@ -14,7 +14,7 @@
<aero:SystemDropShadowChrome> <aero:SystemDropShadowChrome>
<Grid> <Grid>
<ListView Name="listView" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Auto"> <ListView Name="listView" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListView.Background> <ListView.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#ddeeff" Offset="0.0" /> <GradientStop Color="#ddeeff" Offset="0.0" />
@ -29,16 +29,15 @@
<Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderThickness" Value="1" />
<Setter Property="Focusable" Value="false" /> <Setter Property="Focusable" Value="false" />
<Style.Triggers> <Style.Triggers>
<!--
<Trigger Property="ItemsControl.AlternationIndex" Value="0"> <Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Background" Value="Transparent"></Setter>
</Trigger> </Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1"> <Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="Transparent"></Setter> <Setter Property="Background" Value="Transparent"></Setter>
</Trigger> </Trigger>
-->
<DataTrigger Binding="{Binding IsNested}" Value="True"> <DataTrigger Binding="{Binding IsNested}" Value="True">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="Foreground" Value="#666666"></Setter> <Setter Property="Foreground" Value="#666666"></Setter>
<Setter Property="FontStyle" Value="Italic"></Setter> <Setter Property="FontStyle" Value="Italic"></Setter>
</DataTrigger> </DataTrigger>
@ -57,8 +56,9 @@
<Setter Property="FrameworkElement.Height" Value="1"/> <Setter Property="FrameworkElement.Height" Value="1"/>
</Style> </Style>
</GridView.ColumnHeaderContainerStyle> </GridView.ColumnHeaderContainerStyle>
<!-- 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">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate> <DataTemplate>
@ -66,6 +66,7 @@
<ToggleButton x:Name="Expander" Margin="-6 0" IsChecked="{Binding IsExpanded}" Click="NestedExpandButton_Click" Padding="0"></ToggleButton> <ToggleButton x:Name="Expander" Margin="-6 0" IsChecked="{Binding IsExpanded}" Click="NestedExpandButton_Click" Padding="0"></ToggleButton>
<ToggleButton x:Name="PropertyExpander" Margin="-6 0" IsChecked="{Binding IsPropertyExpanded}" Click="PropertyExpandButton_Click" Padding="0"></ToggleButton> <ToggleButton x:Name="PropertyExpander" Margin="-6 0" IsChecked="{Binding IsPropertyExpanded}" Click="PropertyExpandButton_Click" Padding="0"></ToggleButton>
</StackPanel> </StackPanel>
<!-- Do this by converter, not Triggers! -->
<DataTemplate.Triggers> <DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasChildren}" Value="False"> <DataTrigger Binding="{Binding Path=HasChildren}" Value="False">
<Setter TargetName="Expander" <Setter TargetName="Expander"
@ -80,19 +81,17 @@
</DataTemplate> </DataTemplate>
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
<!-- Name --> <!-- Name -->
<GridViewColumn Header="Name" Width="Auto"> <GridViewColumn Header="Name" Width="Auto">
<GridViewColumn.CellTemplate> <GridViewColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<!--
<TextBlock Text="hello" MinWidth="100"></TextBlock>
-->
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock MouseDown="TextBlock_MouseDown" Text="{Binding Name}"></TextBlock></StackPanel> <TextBlock Text="{Binding Name}" FontWeight="{Binding IsPropertyExpanded, Converter={StaticResource BoolToBoldConverter}}"></TextBlock>
</StackPanel>
</DataTemplate> </DataTemplate>
</GridViewColumn.CellTemplate> </GridViewColumn.CellTemplate>
</GridViewColumn> </GridViewColumn>
<!-- Text --> <!-- Text -->
<GridViewColumn Header="Value " Width="Auto" CellTemplate="{StaticResource valueColumnTemplate}"> <GridViewColumn Header="Value " Width="Auto" CellTemplate="{StaticResource valueColumnTemplate}">
</GridViewColumn> </GridViewColumn>
</GridView.Columns> </GridView.Columns>

8
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/ExpandedPaths.cs

@ -11,7 +11,7 @@ namespace Debugger.AddIn.Visualizers.Graph
/// </summary> /// </summary>
public class ExpandedPaths public class ExpandedPaths
{ {
private Dictionary<string, bool> expandedNodes = new Dictionary<string, bool>(); private Dictionary<string, bool> expandedPaths = new Dictionary<string, bool>();
public ExpandedPaths() public ExpandedPaths()
{ {
@ -19,17 +19,17 @@ namespace Debugger.AddIn.Visualizers.Graph
public bool IsExpanded(string path) public bool IsExpanded(string path)
{ {
return expandedNodes.ContainsKey(path) && (expandedNodes[path] == true); return expandedPaths.ContainsKey(path) && (expandedPaths[path] == true);
} }
public void SetExpanded(string path) public void SetExpanded(string path)
{ {
expandedNodes[path] = true; expandedPaths[path] = true;
} }
public void SetCollapsed(string path) public void SetCollapsed(string path)
{ {
expandedNodes[path] = false; expandedPaths[path] = false;
} }
} }
} }

57
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentNode.cs

@ -88,13 +88,24 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
/// </summary> /// </summary>
public virtual bool ShowExpandPropertyButton public virtual bool ShowExpandPropertyButton
{ {
get get {
{ // this is ContentNode -> no property, don't show expand button
// this is NestedNodeViewModel -> no property, don't show expand button
return false; return false;
} }
} }
/// <summary>
/// Is this an expanded Property node?
/// </summary>
public virtual bool IsPropertyExpanded
{
get {
// this is ContentNode -> no property, don't show expand button
return false;
}
set { throw new InvalidOperationException("Cannot set IsPropertyExpanded on " + typeof(ContentNode).Name); }
}
/// <summary> /// <summary>
/// Returns flattened subtree. /// Returns flattened subtree.
/// </summary> /// </summary>
@ -136,48 +147,40 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
} }
#endregion #endregion
public virtual void InitFrom(AbstractNode source, Expanded expanded) public virtual void InitOverride(AbstractNode source, Expanded expanded)
{ {
this.Name = getContentNodeName(source); this.Name = GetContentNodeName(source);
this.Text = ""; // lazy evaluated later this.Text = ""; // lazy evaluated later
this.IsNested = true; this.IsNested = true;
this.path = this.Parent == null ? this.Name : this.Parent.Path + "." + this.Name; this.path = this.Parent == null ? this.Name : this.Parent.Path + "." + this.Name;
this.IsExpanded = (source is ThisNode) || expanded.ContentNodes.IsExpanded(this); this.IsExpanded = (source is ThisNode) || expanded.ContentNodes.IsExpanded(this);
foreach (AbstractNode child in source.Children) foreach (AbstractNode child in source.Children) {
{ ContentNode newChild = null;
if (child is PropertyNode) if (child is PropertyNode) {
{ newChild = new ContentPropertyNode(this.ContainingNode, this);
var newChild = new ContentPropertyNode(this.ContainingNode, this); } else {
newChild.InitFrom(child, expanded); newChild = new ContentNode(this.ContainingNode, this);
this.Children.Add(newChild);
}
else
{
var newChild = new ContentNode(this.ContainingNode, this);
newChild.InitFrom(child, expanded);
this.Children.Add(newChild);
} }
newChild.InitOverride(child, expanded);
this.Children.Add(newChild);
} }
} }
private string getContentNodeName(AbstractNode source) private string GetContentNodeName(AbstractNode source)
{ {
if (source is ThisNode) if (source is ThisNode) {
{
return "this"; return "this";
} }
if (source is NonPublicMembersNode) if (source is NonPublicMembersNode) {
{
return StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}"); return StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.NonPublicMembers}");
} }
var sourceBaseClassNode = source as BaseClassNode; var sourceBaseClassNode = source as BaseClassNode;
if (sourceBaseClassNode != null) if (sourceBaseClassNode != null) {
{ string baseClassString = StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}");
//return StringParser.Parse("${res:MainWindow.Windows.Debug.LocalVariables.BaseClass}") + " " + sourceBaseClassNode.TypeName; return string.Format("{0} ({1})", sourceBaseClassNode.TypeName, baseClassString);
return sourceBaseClassNode.TypeName;
} }
throw new ApplicationException("Unknown AbstractNode."); throw new ApplicationException("Unknown AbstractNode.");

10
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/ContentPropertyNode.cs

@ -31,7 +31,7 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
get { return this.positionedProperty.IsEvaluated; } get { return this.positionedProperty.IsEvaluated; }
} }
public bool IsPropertyExpanded public override bool IsPropertyExpanded
{ {
get { return this.positionedProperty.IsPropertyExpanded; } get { return this.positionedProperty.IsPropertyExpanded; }
set { this.positionedProperty.IsPropertyExpanded = value; } set { this.positionedProperty.IsPropertyExpanded = value; }
@ -52,19 +52,19 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
} }
} }
public override void InitFrom(AbstractNode source, Expanded expanded) public override void InitOverride(AbstractNode source, Expanded expanded)
{ {
if (!(source is PropertyNode)) if (!(source is PropertyNode))
throw new InvalidOperationException("PropertyNodeViewModel must initialize from PropertyNode"); throw new InvalidOperationException(string.Format("{0} must initialize from {1}", typeof(ContentPropertyNode).Name, typeof(PropertyNode).Name));
PropertyNode sourcePropertyNode = source as PropertyNode; PropertyNode sourcePropertyNode = source as PropertyNode;
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.
// Evaluated also in Evaluate() if needed. // 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 content nodes are never expanded this.IsExpanded = false; // always false, Property nodes are never expanded (they have IsPropertyExpanded)
this.positionedProperty = new PositionedNodeProperty( this.positionedProperty = new PositionedNodeProperty(
sourcePropertyNode.Property, this.ContainingNode, sourcePropertyNode.Property, this.ContainingNode,
expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression)); expanded.Expressions.IsExpanded(sourcePropertyNode.Property.Expression));

3
src/AddIns/Debugger/Debugger.AddIn/Visualizers/Graph/Layout/PositionedGraphNode.cs

@ -61,11 +61,10 @@ namespace Debugger.AddIn.Visualizers.Graph.Layout
} }
} }
// TODO for speedup of re-layout only, posNodeForObjectGraphNode will be a service, that will return existing posNodes or create empty new
public void InitContentFromObjectNode(Expanded expanded) public void InitContentFromObjectNode(Expanded expanded)
{ {
this.Content = new ContentNode(this, null); this.Content = new ContentNode(this, null);
this.Content.InitFrom(this.ObjectNode.Content, expanded); this.Content.InitOverride(this.ObjectNode.Content, expanded);
this.nodeVisualControl.Root = this.Content; this.nodeVisualControl.Root = this.Content;
} }

Loading…
Cancel
Save