Browse Source

Matrix control is now synchronized with trees.

pull/19/head
Tomas Linhart 15 years ago
parent
commit
706df5031d
  1. 3
      src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyMatrixControl.cs
  2. 32
      src/AddIns/Analysis/CodeQuality/Src/Controls/MatrixControl.cs
  3. 66
      src/AddIns/Analysis/CodeQuality/Src/Controls/TreeMatrixControl.xaml.cs
  4. 17
      src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs
  5. 41
      src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs
  6. 35
      src/AddIns/Analysis/CodeQuality/Src/Utility/VisibleMatrix.cs

3
src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyMatrixControl.cs

@ -8,10 +8,11 @@ using System.Linq.Expressions;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using ICSharpCode.CodeQualityAnalysis.Utility;
namespace ICSharpCode.CodeQualityAnalysis.Controls namespace ICSharpCode.CodeQualityAnalysis.Controls
{ {
public class DependencyMatrixControl : MatrixControl<INode, Relationship> public class DependencyMatrixControl : MatrixControl<VisibleMatrix<INode, Relationship>, INode, Relationship>
{ {
} }

32
src/AddIns/Analysis/CodeQuality/Src/Controls/MatrixControl.cs

@ -14,13 +14,14 @@ using System.Windows.Media.Imaging;
namespace ICSharpCode.CodeQualityAnalysis.Controls namespace ICSharpCode.CodeQualityAnalysis.Controls
{ {
public class MatrixControl<TItem, TValue> : FrameworkElement, IScrollInfo public class MatrixControl<TMatrix, TItem, TValue> : FrameworkElement, IScrollInfo
where TValue : IValue where TValue : IValue
where TMatrix : Matrix<TItem, TValue>
{ {
public event EventHandler<HoveredCellEventArgs<TValue>> HoveredCellChanged; public event EventHandler<HoveredCellEventArgs<TValue>> HoveredCellChanged;
private Dictionary<string, ImageSource> imgs = new Dictionary<string, ImageSource>(); private Dictionary<string, ImageSource> imgs = new Dictionary<string, ImageSource>();
private Coords currentCell = new Coords(-1, -1); private Coords currentCell = new Coords(0, 0);
private string font; private string font;
private bool canHorizontalScroll = true; private bool canHorizontalScroll = true;
@ -36,9 +37,9 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
private int fontSize = 0; private int fontSize = 0;
private int penSize = 0; private int penSize = 0;
private Matrix<TItem, TValue> matrix; private TMatrix matrix;
public Matrix<TItem, TValue> Matrix public TMatrix Matrix
{ {
get { return matrix; } get { return matrix; }
set set
@ -74,16 +75,13 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
public void SetVisibleItems(HeaderType tree, ICollection<TItem> visibleItems) public void SetVisibleItems(HeaderType tree, ICollection<TItem> visibleItems)
{ {
var items = tree == HeaderType.Columns ? matrix.HeaderColumns : matrix.HeaderRows; matrix.SetVisibleItems(tree, visibleItems);
foreach (var item in items) matrixHeight = matrix.HeaderRows.Count;
{ matrixWidth = matrix.HeaderColumns.Count;
var foundItem = visibleItems.Where(n => n.Equals(item.Value)).SingleOrDefault();
item.Visible = foundItem != null;
}
matrixHeight = matrix.HeaderRows.Count - 1; if (matrixHeight >= 0 && matrixWidth >= 0)
matrixWidth = matrix.HeaderColumns.Count - 1; InvalidateVisual();
} }
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
@ -184,8 +182,8 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
// text // text
for (int i = 0; i < cellsHorizontally; i++) { for (int i = 0; i < cellsHorizontally; i++) {
for (int j = 0; j < cellsVertically; j++) { // dont draw text in unavailables places for (int j = 0; j < cellsVertically; j++) { // dont draw text in unavailables places
int rowIndex = i + scaledOffsetX; int rowIndex = j + scaledOffsetX;
int columnIndex = j + scaledOffsetY; int columnIndex = i + scaledOffsetY;
var value = matrix[rowIndex, columnIndex]; var value = matrix[rowIndex, columnIndex];
if (Colorizer != null) { if (Colorizer != null) {
@ -464,10 +462,4 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
HoveredCell = cell; HoveredCell = cell;
} }
} }
public enum HeaderType
{
Columns,
Rows
}
} }

66
src/AddIns/Analysis/CodeQuality/Src/Controls/TreeMatrixControl.xaml.cs

@ -29,11 +29,11 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
private ScrollViewer leftScrollViewer; private ScrollViewer leftScrollViewer;
private ScrollViewer topScrollViewer; private ScrollViewer topScrollViewer;
public Matrix<INode, Relationship> Matrix public DependencyMatrix Matrix
{ {
get get
{ {
return matrixControl.Matrix; return (DependencyMatrix) matrixControl.Matrix;
} }
set set
@ -51,17 +51,16 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
} }
public void DrawTree(Module module) public void DrawTree(Module module)
{ {
Helper.FillTree(leftTree,module);
var leftCol = leftTree.Items.SourceCollection as INotifyCollectionChanged; var leftCol = leftTree.Items.SourceCollection as INotifyCollectionChanged;
leftCol.CollectionChanged += BuildLeftINodeList; leftCol.CollectionChanged += BuildLeftINodeList;
Helper.FillTree(leftTree, module);
Helper.FillTree(topTree,module);
var topCol = topTree.Items.SourceCollection as INotifyCollectionChanged; var topCol = topTree.Items.SourceCollection as INotifyCollectionChanged;
topCol.CollectionChanged += BuildTopINodeList; topCol.CollectionChanged += BuildTopINodeList;
Helper.FillTree(topTree, module);
} }
void Trees_Loaded (object sender, EventArgs e) void Trees_Loaded (object sender, EventArgs e)
{ {
leftTree.ApplyTemplate(); leftTree.ApplyTemplate();
@ -71,53 +70,54 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
topScrollViewer = Helper.FindVisualChild<ScrollViewer>(topTree); topScrollViewer = Helper.FindVisualChild<ScrollViewer>(topTree);
} }
bool rebuildLeftNodeListRequested; bool rebuildLeftNodeListRequested;
void BuildLeftINodeList (object sender,NotifyCollectionChangedEventArgs e) void BuildLeftINodeList(object sender,NotifyCollectionChangedEventArgs e)
{ {
if (rebuildLeftNodeListRequested) if (rebuildLeftNodeListRequested)
return; return;
rebuildLeftNodeListRequested = true; rebuildLeftNodeListRequested = true;
Dispatcher.BeginInvoke( Dispatcher.BeginInvoke(
DispatcherPriority.DataBind, DispatcherPriority.DataBind,
new Action( new Action(SetVisibleItemsForRows));
delegate { }
List <INode> leftNodes = new List<INode>();
foreach (DependecyTreeNode element in leftTree.Items) { void SetVisibleItemsForRows()
var n = element.INode; {
leftNodes.Add(n); List<INode> leftNodes = new List<INode>();
} foreach (DependecyTreeNode element in leftTree.Items) {
rebuildLeftNodeListRequested = false; var n = element.INode;
matrixControl.SetVisibleItems(HeaderType.Rows,leftNodes); leftNodes.Add(n);
} }
)); rebuildLeftNodeListRequested = false;
matrixControl.SetVisibleItems(HeaderType.Rows, leftNodes);
} }
bool rebuildTopNodeListRequested; bool rebuildTopNodeListRequested;
void BuildTopINodeList (object sender,NotifyCollectionChangedEventArgs e) void BuildTopINodeList(object sender,NotifyCollectionChangedEventArgs e)
{ {
if (rebuildTopNodeListRequested) if (rebuildTopNodeListRequested)
return; return;
rebuildTopNodeListRequested = true; rebuildTopNodeListRequested = true;
Dispatcher.BeginInvoke( Dispatcher.BeginInvoke(
DispatcherPriority.DataBind, DispatcherPriority.DataBind,
new Action( new Action(SetVisibleItemsForColumns));
delegate { }
List <INode> topNodes = new List<INode>();
foreach (DependecyTreeNode element in topTree.Items) { void SetVisibleItemsForColumns()
var n = element.INode; {
topNodes.Add(n); List<INode> topNodes = new List<INode>();
} foreach (DependecyTreeNode element in topTree.Items) {
rebuildTopNodeListRequested = false; var n = element.INode;
matrixControl.SetVisibleItems(HeaderType.Columns,topNodes); topNodes.Add(n);
} }
)); rebuildTopNodeListRequested = false;
matrixControl.SetVisibleItems(HeaderType.Columns, topNodes);
} }
void OnHoverChanged (object sender ,HoveredCellEventArgs <Relationship> e) void OnHoverChanged(object sender ,HoveredCellEventArgs <Relationship> e)
{ {
if (e.HoveredCell.RowIndex < leftTree.Items.Count) { if (e.HoveredCell.RowIndex < leftTree.Items.Count) {
var leftNode = leftTree.Items[e.HoveredCell.RowIndex] as DependecyTreeNode; var leftNode = leftTree.Items[e.HoveredCell.RowIndex] as DependecyTreeNode;
@ -130,8 +130,6 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
topTree.SelectedItem = topNode; topTree.SelectedItem = topNode;
topTree.FocusNode(topNode); topTree.FocusNode(topNode);
} }
} }

17
src/AddIns/Analysis/CodeQuality/Src/MainWindow.xaml.cs

@ -100,13 +100,22 @@ namespace ICSharpCode.CodeQualityAnalysis
var matrix = new DependencyMatrix(); var matrix = new DependencyMatrix();
foreach (var ns in metricsReader.MainModule.Namespaces) { foreach (var ns in metricsReader.MainModule.Namespaces) {
matrix.HeaderRows.Add(new Cell<INode>(ns)); matrix.AddRow(ns);
foreach (var type in ns.Types) { foreach (var type in ns.Types) {
matrix.HeaderRows.Add(new Cell<INode>(type)); matrix.AddRow(type);
foreach (var field in type.Fields)
matrix.AddRow(field);
foreach (var method in type.Methods)
matrix.AddRow(method);
} }
matrix.HeaderColumns.Add(new Cell<INode>(ns));
matrix.AddColumn(ns);
foreach (var type in ns.Types) { foreach (var type in ns.Types) {
matrix.HeaderColumns.Add(new Cell<INode>(type)); matrix.AddColumn(type);
foreach (var field in type.Fields)
matrix.AddColumn(field);
foreach (var method in type.Methods)
matrix.AddColumn(method);
} }
} }

41
src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs

@ -10,18 +10,42 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility
{ {
public abstract class Matrix<TItem, TValue> public abstract class Matrix<TItem, TValue>
{ {
public List<Cell<TItem>> HeaderRows { get; set; } protected List<Cell<TItem>> headerRows;
public List<Cell<TItem>> HeaderColumns { get; set; } protected List<Cell<TItem>> headerColumns;
public virtual List<Cell<TItem>> HeaderRows
{
get {
return headerRows;
}
}
public virtual List<Cell<TItem>> HeaderColumns
{
get {
return headerColumns;
}
}
private DoubleKeyDictionary<int, int, TValue> cache; private DoubleKeyDictionary<int, int, TValue> cache;
protected Matrix() protected Matrix()
{ {
HeaderRows = new List<Cell<TItem>>(); headerRows = new List<Cell<TItem>>();
HeaderColumns = new List<Cell<TItem>>(); headerColumns = new List<Cell<TItem>>();
cache = new DoubleKeyDictionary<int, int, TValue>(); cache = new DoubleKeyDictionary<int, int, TValue>();
} }
public void AddRow(TItem value)
{
headerRows.Add(new Cell<TItem>(value));
}
public void AddColumn(TItem value)
{
headerColumns.Add(new Cell<TItem>(value));
}
private TValue GetFromCache(int rowIndex, int columnIndex) private TValue GetFromCache(int rowIndex, int columnIndex)
{ {
return cache[rowIndex, columnIndex]; return cache[rowIndex, columnIndex];
@ -49,7 +73,8 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility
return result; return result;
} }
} }
public abstract void SetVisibleItems(HeaderType type, ICollection<TItem> visibleItems);
protected abstract TValue GetCellValue(int rowIndex, int columnIndex); protected abstract TValue GetCellValue(int rowIndex, int columnIndex);
} }
@ -63,4 +88,10 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility
Value = value; Value = value;
} }
} }
public enum HeaderType
{
Columns,
Rows
}
} }

35
src/AddIns/Analysis/CodeQuality/Src/Utility/VisibleMatrix.cs

@ -12,30 +12,35 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility
/// </summary> /// </summary>
public abstract class VisibleMatrix<TItem, TValue> : Matrix<TItem, TValue> public abstract class VisibleMatrix<TItem, TValue> : Matrix<TItem, TValue>
{ {
public new List<Cell<TItem>> HeaderRows protected List<Cell<TItem>> visibleHeaderRows;
protected List<Cell<TItem>> visibleHeaderColumns;
public override List<Cell<TItem>> HeaderRows
{ {
get get {
{ return visibleHeaderRows;
return base.HeaderRows.Where(c => c.Visible).ToList();
}
set
{
base.HeaderRows = value;
} }
} }
public new List<Cell<TItem>> HeaderColumns public override List<Cell<TItem>> HeaderColumns
{ {
get get {
{ return visibleHeaderColumns;
return base.HeaderColumns.Where(c => c.Visible).ToList();
} }
}
public override void SetVisibleItems(HeaderType type, ICollection<TItem> visibleItems)
{
var items = type == HeaderType.Columns ? headerColumns : headerRows;
set foreach (var item in items)
{ {
base.HeaderColumns = value; var foundItem = visibleItems.Where(n => n.Equals(item.Value)).SingleOrDefault();
item.Visible = foundItem != null;
} }
visibleHeaderRows = headerRows.Where(c => c.Visible).ToList();
visibleHeaderColumns = headerColumns.Where(c => c.Visible).ToList();
} }
} }
} }

Loading…
Cancel
Save