30 changed files with 2009 additions and 48 deletions
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class AssemblyNode : INode |
||||
{ |
||||
public AssemblyNode(IAssembly assembly) |
||||
{ |
||||
this.AssemblyInfo = assembly; |
||||
namespaces = new List<INode>(); |
||||
} |
||||
|
||||
public IAssembly AssemblyInfo { get; private set; } |
||||
|
||||
public string Name { |
||||
get { return AssemblyInfo.AssemblyName; } |
||||
} |
||||
|
||||
internal List<INode> namespaces; |
||||
|
||||
public IList<INode> Children { |
||||
get { return namespaces; } |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public void CalculateMetricsAndFreeze(IEnumerable<AssemblyNode> assemblies) |
||||
{ |
||||
|
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class EventNode : INode |
||||
{ |
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class FieldNode : INode |
||||
{ |
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public interface IValue |
||||
{ |
||||
string Text { get; } |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class MethodNode : INode |
||||
{ |
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class NamespaceNode : INode |
||||
{ |
||||
public NamespaceNode(string name) |
||||
{ |
||||
this.Name = name; |
||||
} |
||||
|
||||
public string Name { get; private set; } |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
return Enumerable.Empty<INode>().ToList(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class PropertyNode : INode |
||||
{ |
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
// 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.Text; |
||||
|
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// Description of Relationship.
|
||||
/// </summary>
|
||||
public class Relationship : IValue |
||||
{ |
||||
public ISet<RelationshipType> Relationships { get; private set; } |
||||
|
||||
public int OccurrenceCount { get; private set; } |
||||
|
||||
public string Text { get { return OccurrenceCount.ToString(); } } |
||||
|
||||
public INode To { get; set; } |
||||
public INode From { get; set; } |
||||
|
||||
public Relationship() |
||||
{ |
||||
Relationships = new HashSet<RelationshipType>(); |
||||
} |
||||
|
||||
public void AddRelationship(RelationshipType type) |
||||
{ |
||||
if (type == RelationshipType.UseThis || type == RelationshipType.UsedBy) |
||||
OccurrenceCount++; |
||||
|
||||
Relationships.Add(type); |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
var builder = new StringBuilder(); |
||||
|
||||
foreach (var relationship in Relationships) |
||||
builder.Append(relationship + " "); |
||||
|
||||
builder.Append(OccurrenceCount); |
||||
return builder.ToString(); |
||||
} |
||||
} |
||||
|
||||
public enum RelationshipType |
||||
{ |
||||
OneWayTo, |
||||
UseThis, |
||||
UsedBy, |
||||
Same, |
||||
Contains, |
||||
None |
||||
} |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
// 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 ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Engine.Dom |
||||
{ |
||||
public class TypeNode : INode |
||||
{ |
||||
public ITypeDefinition TypeDefinition { get; private set; } |
||||
|
||||
public string Name { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IList<INode> Children { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> Uses { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<INode> UsedBy { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public Relationship GetRelationship(INode value) |
||||
{ |
||||
Relationship r = new Relationship(); |
||||
if (value == this) |
||||
r.AddRelationship(RelationshipType.Same); |
||||
return r; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
// 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.Text; |
||||
|
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
public class DependencyMatrix : VisibleMatrix<INode, Relationship> |
||||
{ |
||||
protected override Relationship GetCellValue(int rowIndex, int columnIndex) |
||||
{ |
||||
var toRelationship = HeaderRows[rowIndex].Value.GetRelationship(HeaderColumns[columnIndex].Value); |
||||
var fromRelationship = HeaderColumns[columnIndex].Value.GetRelationship(HeaderRows[rowIndex].Value); |
||||
|
||||
toRelationship.From = HeaderRows[rowIndex].Value; |
||||
toRelationship.To = HeaderColumns[columnIndex].Value; |
||||
|
||||
// add other way
|
||||
foreach (var relationship in fromRelationship.Relationships) { |
||||
if (relationship == RelationshipType.UseThis) |
||||
toRelationship.AddRelationship(RelationshipType.UsedBy); |
||||
} |
||||
|
||||
return toRelationship; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// 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.Linq.Expressions; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls.Primitives; |
||||
|
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
public class DependencyMatrixControl : MatrixControl<VisibleMatrix<INode, Relationship>, INode, Relationship> |
||||
{ |
||||
|
||||
} |
||||
} |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
// 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.Text; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
public abstract class Matrix<TItem, TValue> |
||||
{ |
||||
protected List<Cell<TItem>> headerRows; |
||||
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<TItem, TItem, TValue> cache; |
||||
|
||||
protected Matrix() |
||||
{ |
||||
headerRows = new List<Cell<TItem>>(); |
||||
headerColumns = new List<Cell<TItem>>(); |
||||
cache = new DoubleKeyDictionary<TItem, TItem, 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(TItem rowIndex, TItem columnIndex) |
||||
{ |
||||
return cache[rowIndex, columnIndex]; |
||||
} |
||||
|
||||
private void SaveToCache(TItem rowIndex, TItem columnIndex, TValue result) |
||||
{ |
||||
cache.Add(rowIndex, columnIndex, result); |
||||
} |
||||
|
||||
public TValue this[int rowIndex, int columnIndex] |
||||
{ |
||||
get |
||||
{ |
||||
if (rowIndex > HeaderRows.Count || rowIndex < 0 || |
||||
columnIndex > HeaderColumns.Count || columnIndex < 0) |
||||
return default(TValue); |
||||
|
||||
var from = HeaderRows[rowIndex].Value; |
||||
var to = HeaderColumns[columnIndex].Value; |
||||
|
||||
var cacheResult = GetFromCache(from, to); |
||||
if (cacheResult != null) |
||||
return cacheResult; |
||||
|
||||
var result = GetCellValue(rowIndex, columnIndex); |
||||
SaveToCache(from, to, result); |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
public abstract void SetVisibleItems(HeaderType type, ICollection<TItem> visibleItems); |
||||
protected abstract TValue GetCellValue(int rowIndex, int columnIndex); |
||||
} |
||||
|
||||
public class Cell<TItem> |
||||
{ |
||||
public TItem Value { get; set; } |
||||
public bool Visible { get; set; } |
||||
|
||||
public Cell(TItem value) |
||||
{ |
||||
Value = value; |
||||
} |
||||
} |
||||
|
||||
public enum HeaderType |
||||
{ |
||||
Columns, |
||||
Rows |
||||
} |
||||
} |
@ -0,0 +1,522 @@
@@ -0,0 +1,522 @@
|
||||
// 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.Drawing.Drawing2D; |
||||
using System.Linq; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using System.Windows.Interop; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Imaging; |
||||
|
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
using PointF = System.Drawing.PointF; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
public class MatrixControl<TMatrix, TItem, TValue> : FrameworkElement, IScrollInfo |
||||
where TValue : IValue |
||||
where TMatrix : Matrix<TItem, TValue> |
||||
{ |
||||
public event EventHandler<HoveredCellEventArgs<TValue>> HoveredCellChanged; |
||||
|
||||
private Dictionary<string, ImageSource> imgs = new Dictionary<string, ImageSource>(); |
||||
private Coords currentCell = new Coords(0, 0); |
||||
private string font; |
||||
|
||||
private bool canHorizontalScroll = true; |
||||
private bool canVerticalScroll = true; |
||||
private Size extent = new Size(0, 0); |
||||
private Size viewport = new Size(0, 0); |
||||
private Point offset; |
||||
|
||||
// will be loaded from Matrix
|
||||
private int matrixWidth = 0; |
||||
private int matrixHeight = 0; |
||||
|
||||
private int fontSize = 0; |
||||
private int penSize = 0; |
||||
|
||||
|
||||
protected int PageSizeWidth { get; set; } |
||||
protected int PageSizeHeight { get; set; } |
||||
|
||||
public TMatrix Matrix { get; set; } |
||||
|
||||
public int CellHeight { get; set; } |
||||
|
||||
public int CellWidth { get; set; } |
||||
|
||||
public HoveredCell<TValue> HoveredCell { get; set; } |
||||
|
||||
public bool RenderZeroes { get; set; } |
||||
|
||||
public IColorizer<TValue> Colorizer { get; set; } |
||||
|
||||
public MatrixControl() |
||||
{ |
||||
CellHeight = CellWidth = 18; |
||||
matrixWidth = 0; |
||||
matrixHeight = 0; |
||||
fontSize = CellHeight / 3; |
||||
penSize = 1; |
||||
font = "Verdana"; |
||||
|
||||
HoveredCell = new HoveredCell<TValue>(); |
||||
} |
||||
|
||||
public void SetVisibleItems(HeaderType type, ICollection<TItem> visibleItems) |
||||
{ |
||||
Matrix.SetVisibleItems(type, visibleItems); |
||||
|
||||
matrixHeight = Matrix.HeaderRows.Count; |
||||
matrixWidth = Matrix.HeaderColumns.Count; |
||||
|
||||
bool changedCoords = false; |
||||
if (currentCell.X > matrixHeight) { |
||||
currentCell = new Coords(matrixHeight - 1, currentCell.Y); |
||||
changedCoords = true; |
||||
} |
||||
|
||||
if (currentCell.Y > matrixWidth) { |
||||
currentCell = new Coords(currentCell.X, matrixWidth - 1); |
||||
changedCoords = true; |
||||
} |
||||
|
||||
if (changedCoords) { |
||||
SetHoveredCell(); |
||||
} |
||||
|
||||
if (matrixHeight >= 0 && matrixWidth >= 0) |
||||
InvalidateVisual(); |
||||
} |
||||
|
||||
public void HighlightLine(HeaderType type, INode node) |
||||
{ |
||||
var items = type == HeaderType.Columns ? Matrix.HeaderColumns : Matrix.HeaderRows; |
||||
for (int i = 0; i < items.Count; i++) { |
||||
if (items[i].Value.Equals(node)) { |
||||
if (currentCell.X == i && type == HeaderType.Rows) |
||||
return; |
||||
if (currentCell.Y == i && type == HeaderType.Columns) |
||||
return; |
||||
|
||||
currentCell = type == HeaderType.Columns ? |
||||
new Coords(i, currentCell.Y) : |
||||
new Coords(currentCell.X, i); |
||||
|
||||
SetHoveredCell(); |
||||
InvalidateVisual(); |
||||
|
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) |
||||
{ |
||||
base.OnMouseMove(e); |
||||
|
||||
var point = e.GetPosition(this); |
||||
if (point.X < matrixWidth * CellWidth |
||||
&& point.Y < matrixHeight * CellHeight) |
||||
currentCell = new Coords( |
||||
(int)((point.X + offset.X) / CellWidth), |
||||
(int)((point.Y + offset.Y) / CellHeight)); |
||||
// else // if we are out of matrix just use last cell
|
||||
// currentCell = new Coords(-1, -1);
|
||||
|
||||
if (currentCell.X != HoveredCell.RowIndex || |
||||
currentCell.Y != HoveredCell.ColumnIndex) |
||||
{ |
||||
InvalidateVisual(); |
||||
SetHoveredCell(); |
||||
} |
||||
} |
||||
|
||||
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e) |
||||
{ |
||||
base.OnMouseDown(e); |
||||
Relationship relationship = HoveredCell.Value as Relationship; |
||||
Console.WriteLine("To: " + relationship.To.Name); |
||||
Console.WriteLine("From:" + relationship.From.Name); |
||||
} |
||||
|
||||
protected void SetHoveredCell() |
||||
{ |
||||
HoveredCell.RowIndex = currentCell.Y; |
||||
HoveredCell.ColumnIndex = currentCell.X; |
||||
HoveredCell.Value = Matrix[HoveredCell.RowIndex, HoveredCell.ColumnIndex]; |
||||
if (HoveredCellChanged != null) |
||||
HoveredCellChanged(this, new HoveredCellEventArgs<TValue>(HoveredCell)); |
||||
} |
||||
|
||||
protected override void OnRender(DrawingContext drawingContext) |
||||
{ |
||||
base.OnRender(drawingContext); |
||||
|
||||
// how much space we got for cells
|
||||
var maxWidth = ((int) viewport.Width / CellWidth) + 1; |
||||
var maxHeight = ((int) viewport.Height / CellHeight) + 1; |
||||
|
||||
// how many cells we will draw
|
||||
// sometimes happens when half of cell is hidden in scroll so text isnt drawn
|
||||
// so lets drawn one more cell
|
||||
var cellsHorizontally = maxWidth >= matrixWidth ? matrixWidth : maxWidth + 1; |
||||
var cellsVertically = maxHeight >= matrixHeight ? matrixHeight : maxHeight + 1; |
||||
|
||||
PageSizeWidth = cellsHorizontally; |
||||
PageSizeHeight = cellsVertically; |
||||
|
||||
// number of cell which arent visible
|
||||
var scaledOffsetX = (int)offset.X / CellWidth; |
||||
var scaledOffsetY = (int)offset.Y / CellHeight; |
||||
|
||||
// sets how much of cell on border should be drawn
|
||||
var offsetDiffX = offset.X - scaledOffsetX * CellWidth; |
||||
var offsetDiffY = offset.Y - scaledOffsetY * CellHeight; |
||||
|
||||
// background
|
||||
var background = new Rect(0, 0, cellsHorizontally * CellWidth, cellsVertically * CellHeight); |
||||
var backgroundColor = new SolidColorBrush(Colors.Yellow); |
||||
backgroundColor.Freeze(); |
||||
drawingContext.DrawRectangle(backgroundColor, null, background); |
||||
|
||||
var currentXLine = (currentCell.X - scaledOffsetX) * CellWidth - offsetDiffX; |
||||
var currentYLine = (currentCell.Y - scaledOffsetY) * CellHeight - offsetDiffY; |
||||
|
||||
// hovering
|
||||
if (currentCell.X >= 0 || currentCell.Y >= 0) { |
||||
|
||||
// hover y line
|
||||
var rect = new Rect(0, |
||||
currentYLine, |
||||
CellWidth * cellsHorizontally, |
||||
CellHeight); |
||||
|
||||
var brush = new SolidColorBrush(Colors.GreenYellow); |
||||
brush.Freeze(); |
||||
drawingContext.DrawRectangle(brush, null, rect); |
||||
|
||||
// hover x line
|
||||
rect = new Rect(currentXLine, |
||||
0, |
||||
CellWidth, |
||||
CellHeight * cellsVertically); |
||||
|
||||
brush = new SolidColorBrush(Colors.GreenYellow); |
||||
brush.Freeze(); |
||||
drawingContext.DrawRectangle(brush, null, rect); |
||||
|
||||
// hover cell
|
||||
rect = new Rect( |
||||
(currentCell.X - scaledOffsetX) * CellWidth - offsetDiffX, |
||||
(currentCell.Y - scaledOffsetY) * CellHeight - offsetDiffY, |
||||
CellWidth, |
||||
CellHeight); |
||||
|
||||
brush = new SolidColorBrush(Colors.Red); |
||||
brush.Freeze(); |
||||
drawingContext.DrawRectangle(brush, null, rect); |
||||
} |
||||
|
||||
// text
|
||||
for (int i = 0; i < cellsHorizontally; i++) { |
||||
for (int j = 0; j < cellsVertically; j++) { // dont draw text in unavailables places
|
||||
int rowIndex = j + scaledOffsetY; |
||||
int columnIndex = i + scaledOffsetX; |
||||
|
||||
// adjust scales
|
||||
rowIndex = rowIndex >= Matrix.HeaderRows.Count ? rowIndex - 1 : rowIndex; |
||||
columnIndex = columnIndex >= Matrix.HeaderColumns.Count ? columnIndex - 1 : columnIndex; |
||||
|
||||
var value = Matrix[rowIndex, columnIndex]; |
||||
|
||||
if (Colorizer != null) { |
||||
var rect = new Rect( |
||||
i * CellWidth - offsetDiffX, |
||||
j * CellHeight - offsetDiffY, |
||||
CellWidth, |
||||
CellHeight); |
||||
|
||||
SolidColorBrush brush = null; |
||||
if ((i * CellWidth - offsetDiffX) == currentXLine || |
||||
((j * CellHeight - offsetDiffY) == currentYLine)) { |
||||
var color = Colors.GreenYellow; |
||||
if (currentCell.X == i && currentCell.Y == j) { |
||||
color = color.MixedWith(Colors.Red); |
||||
} |
||||
brush = Colorizer.GetColorBrushMixedWith(color, value); |
||||
|
||||
|
||||
} |
||||
else |
||||
brush = Colorizer.GetColorBrush(value); |
||||
|
||||
drawingContext.DrawRectangle(brush, null, rect); |
||||
} |
||||
|
||||
if (!RenderZeroes && value != null && value.Text != "0") // rendering zeroes would be distracting
|
||||
drawingContext.DrawImage( |
||||
CreateText(value.Text), |
||||
new Rect(i * CellWidth - offsetDiffX, j * CellHeight - offsetDiffY, CellWidth, CellHeight)); |
||||
} |
||||
} |
||||
|
||||
// grid
|
||||
var pen = new Pen(Brushes.Black, penSize); |
||||
pen.Freeze(); |
||||
|
||||
// grid x
|
||||
for (int i = 0; i <= cellsHorizontally; i++) |
||||
drawingContext.DrawLine(pen, |
||||
new Point(i * CellWidth - offsetDiffX, 0), |
||||
new Point(i * CellWidth - offsetDiffX, |
||||
cellsVertically * CellWidth)); |
||||
// grid y
|
||||
for (int i = 0; i <= cellsVertically; i++) |
||||
drawingContext.DrawLine(pen, |
||||
new Point(0, i * CellHeight - offsetDiffY), |
||||
new Point(cellsHorizontally * CellHeight, |
||||
i * CellHeight - offsetDiffY)); |
||||
} |
||||
|
||||
public ImageSource CreateText(string text) |
||||
{ |
||||
if (imgs.ContainsKey(text)) |
||||
return imgs[text]; |
||||
|
||||
var bmp = new System.Drawing.Bitmap(CellWidth, CellHeight); |
||||
var g = System.Drawing.Graphics.FromImage(bmp); |
||||
g.SmoothingMode = SmoothingMode.AntiAlias; |
||||
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; |
||||
|
||||
var fontOjb = new System.Drawing.Font(font, fontSize); |
||||
|
||||
var size = g.MeasureString(text, fontOjb); |
||||
|
||||
var spanWidth = (CellWidth - size.Width) / 2; |
||||
var spanHeight = (CellHeight - size.Height) / 2; |
||||
|
||||
g.DrawString(text, fontOjb, System.Drawing.Brushes.Black, new PointF(spanWidth, spanHeight)); |
||||
g.Dispose(); |
||||
|
||||
var bitmap = bmp.GetHbitmap(); |
||||
var img = Imaging.CreateBitmapSourceFromHBitmap(bitmap, |
||||
IntPtr.Zero, |
||||
Int32Rect.Empty, |
||||
BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height)); |
||||
img.Freeze(); |
||||
imgs.Add(text, img); |
||||
|
||||
Utils.DeleteObject(bitmap); |
||||
|
||||
return img; |
||||
} |
||||
|
||||
public bool CanVerticallyScroll |
||||
{ |
||||
get { return canVerticalScroll; } |
||||
set { canVerticalScroll = value; } |
||||
} |
||||
|
||||
public bool CanHorizontallyScroll |
||||
{ |
||||
get { return canHorizontalScroll; } |
||||
set { canHorizontalScroll = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Width of entire component
|
||||
/// </summary>
|
||||
public double ExtentWidth |
||||
{ |
||||
get { return extent.Width; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Height of entire component
|
||||
/// </summary>
|
||||
public double ExtentHeight |
||||
{ |
||||
get { return extent.Height; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Width of available area
|
||||
/// </summary>
|
||||
public double ViewportWidth |
||||
{ |
||||
|
||||
get { return viewport.Width; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Height of available area
|
||||
/// </summary>
|
||||
public double ViewportHeight |
||||
{ |
||||
get { return viewport.Height; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Where is scrollbar located on X
|
||||
/// </summary>
|
||||
public double HorizontalOffset |
||||
{ |
||||
get { return offset.X; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Where is scrollbar located on Y
|
||||
/// </summary>
|
||||
public double VerticalOffset |
||||
{ |
||||
get { return offset.Y; } |
||||
} |
||||
|
||||
public ScrollViewer ScrollOwner { get; set; } |
||||
|
||||
public void LineUp() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset - CellHeight); |
||||
} |
||||
|
||||
public void LineDown() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset + CellHeight); |
||||
} |
||||
|
||||
public void LineLeft() |
||||
{ |
||||
SetHorizontalOffset(HorizontalOffset - CellWidth); |
||||
} |
||||
|
||||
public void LineRight() |
||||
{ |
||||
SetHorizontalOffset(HorizontalOffset + CellWidth); |
||||
} |
||||
|
||||
public void PageUp() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset - CellHeight * PageSizeHeight); |
||||
} |
||||
|
||||
public void PageDown() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset + CellHeight * PageSizeHeight); |
||||
} |
||||
|
||||
public void PageLeft() |
||||
{ |
||||
SetHorizontalOffset(HorizontalOffset - CellWidth * PageSizeWidth); |
||||
} |
||||
|
||||
public void PageRight() |
||||
{ |
||||
SetHorizontalOffset(HorizontalOffset + CellWidth * PageSizeWidth); |
||||
} |
||||
|
||||
public void MouseWheelUp() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset - CellHeight); |
||||
} |
||||
|
||||
public void MouseWheelDown() |
||||
{ |
||||
SetVerticalOffset(VerticalOffset + CellHeight); |
||||
} |
||||
|
||||
public void MouseWheelLeft() |
||||
{ |
||||
SetVerticalOffset(HorizontalOffset - CellWidth); |
||||
} |
||||
|
||||
public void MouseWheelRight() |
||||
{ |
||||
SetVerticalOffset(HorizontalOffset + CellWidth); |
||||
} |
||||
|
||||
public void SetHorizontalOffset(double offset) |
||||
{ |
||||
if (offset == this.offset.X) return; |
||||
this.offset.X = Math.Round(offset / CellWidth) * CellWidth; |
||||
InvalidateVisual(); |
||||
} |
||||
|
||||
public void SetVerticalOffset(double offset) |
||||
{ |
||||
if (offset == this.offset.Y) return; |
||||
this.offset.Y = Math.Round(offset / CellHeight) * CellHeight; |
||||
InvalidateVisual(); |
||||
} |
||||
|
||||
public Rect MakeVisible(Visual visual, Rect rectangle) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
protected override Size MeasureOverride(Size availableSize) |
||||
{ |
||||
VerifyScrollData(availableSize, new Size(matrixWidth * CellWidth, matrixHeight * CellHeight)); |
||||
return viewport; |
||||
} |
||||
|
||||
protected override Size ArrangeOverride(Size finalSize) |
||||
{ |
||||
VerifyScrollData(finalSize, new Size(matrixWidth * CellWidth, matrixHeight * CellHeight)); |
||||
return finalSize; |
||||
} |
||||
|
||||
protected void VerifyScrollData(Size viewport, Size extent) |
||||
{ |
||||
if (double.IsInfinity(viewport.Width)) |
||||
viewport.Width = extent.Width; |
||||
|
||||
if (double.IsInfinity(viewport.Height)) |
||||
viewport.Height = extent.Height; |
||||
|
||||
// if viewport changes so recalculates offsets
|
||||
offset.X = Math.Max(0, Math.Min(offset.X, ExtentWidth - ViewportWidth)); |
||||
offset.Y = Math.Max(0, Math.Min(offset.Y, ExtentHeight - ViewportHeight)); |
||||
|
||||
this.extent = extent; |
||||
this.viewport = viewport; |
||||
|
||||
if (ScrollOwner != null) |
||||
ScrollOwner.InvalidateScrollInfo(); |
||||
} |
||||
|
||||
private struct Coords |
||||
{ |
||||
public int Y { get; private set; } |
||||
public int X { get; private set; } |
||||
|
||||
public Coords(int x, int y) : this() |
||||
{ |
||||
X = x; |
||||
Y = y; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class HoveredCell<TValue> |
||||
{ |
||||
public int RowIndex { get; set; } |
||||
public int ColumnIndex { get; set; } |
||||
public TValue Value { get; set; } |
||||
} |
||||
|
||||
public class HoveredCellEventArgs<TValue> : EventArgs |
||||
{ |
||||
public HoveredCell<TValue> HoveredCell { get; set; } |
||||
|
||||
public HoveredCellEventArgs(HoveredCell<TValue> cell) |
||||
{ |
||||
HoveredCell = cell; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
// 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; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// Description of VisibleMatrix.
|
||||
/// </summary>
|
||||
public abstract class VisibleMatrix<TItem, TValue> : Matrix<TItem, TValue> |
||||
{ |
||||
protected List<Cell<TItem>> visibleHeaderRows; |
||||
protected List<Cell<TItem>> visibleHeaderColumns; |
||||
|
||||
public override List<Cell<TItem>> HeaderRows |
||||
{ |
||||
get { |
||||
return visibleHeaderRows; |
||||
} |
||||
} |
||||
|
||||
public override List<Cell<TItem>> HeaderColumns |
||||
{ |
||||
get { |
||||
return visibleHeaderColumns; |
||||
} |
||||
} |
||||
|
||||
public override void SetVisibleItems(HeaderType type, ICollection<TItem> visibleItems) |
||||
{ |
||||
var items = type == HeaderType.Columns ? headerColumns : headerRows; |
||||
|
||||
foreach (var item in items) |
||||
{ |
||||
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(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
<UserControl x:Class="ICSharpCode.CodeQuality.Gui.DependencyMatrixView" |
||||
xmlns:gui="clr-namespace:ICSharpCode.CodeQuality.Gui" |
||||
xmlns:tv="http://icsharpcode.net/sharpdevelop/treeview" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<Grid> |
||||
<Grid.RowDefinitions> |
||||
<RowDefinition Height="1*" /> |
||||
<RowDefinition Height="Auto" /> |
||||
<RowDefinition Height="2*" /> |
||||
</Grid.RowDefinitions> |
||||
<Grid.ColumnDefinitions> |
||||
<ColumnDefinition Width="1*" /> |
||||
<ColumnDefinition Width="Auto" /> |
||||
<ColumnDefinition Width="2*" /> |
||||
</Grid.ColumnDefinitions> |
||||
<!-- Top TreeView --> |
||||
<tv:SharpTreeView Name="topTree" Grid.Column="2" ScrollViewer.ScrollChanged="ViewScrollChanged" ScrollViewer.VerticalScrollBarVisibility="Hidden"> |
||||
<tv:SharpTreeView.LayoutTransform> |
||||
<RotateTransform Angle="-90" /> |
||||
</tv:SharpTreeView.LayoutTransform> |
||||
</tv:SharpTreeView> |
||||
<GridSplitter Grid.Column="1" |
||||
Grid.RowSpan="3" |
||||
HorizontalAlignment="Center" |
||||
VerticalAlignment="Stretch" |
||||
ShowsPreview="True" |
||||
Width="1" /> |
||||
<GridSplitter Grid.Row="1" |
||||
Grid.ColumnSpan="3" |
||||
VerticalAlignment="Center" |
||||
HorizontalAlignment="Stretch" |
||||
ShowsPreview="True" |
||||
Height="1" /> |
||||
<!-- Left TreeView --> |
||||
<tv:SharpTreeView Name="leftTree" Grid.Row="2" ScrollViewer.ScrollChanged="ViewScrollChanged" ScrollViewer.VerticalScrollBarVisibility="Hidden"> |
||||
</tv:SharpTreeView> |
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Grid.Row="2" Grid.Column="2"> |
||||
<gui:DependencyMatrixControl x:Name="matrix" ScrollViewer.ScrollChanged="ViewScrollChanged" /> |
||||
</ScrollViewer> |
||||
</Grid> |
||||
</UserControl> |
@ -0,0 +1,118 @@
@@ -0,0 +1,118 @@
|
||||
// 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.Collections.Specialized; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Windows.Threading; |
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
using ICSharpCode.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for DependencyMatrixView.xaml
|
||||
/// </summary>
|
||||
public partial class DependencyMatrixView : UserControl |
||||
{ |
||||
public DependencyMatrixView() |
||||
{ |
||||
InitializeComponent(); |
||||
|
||||
topTree.Root = new ICSharpCode.TreeView.SharpTreeNode(); |
||||
leftTree.Root = new ICSharpCode.TreeView.SharpTreeNode(); |
||||
matrix.Colorizer = new DependencyColorizer(); |
||||
} |
||||
|
||||
public void Update(IEnumerable<INode> nodes) |
||||
{ |
||||
Extensions.FillTree(topTree, nodes); |
||||
Extensions.FillTree(leftTree, nodes); |
||||
|
||||
var leftCol = leftTree.Items.SourceCollection as INotifyCollectionChanged; |
||||
leftCol.CollectionChanged += BuildLeftINodeList; |
||||
|
||||
var topCol = topTree.Items.SourceCollection as INotifyCollectionChanged; |
||||
topCol.CollectionChanged += BuildTopINodeList; |
||||
|
||||
var matrix = new DependencyMatrix(); |
||||
AddChildrenToMatrix(matrix, nodes); |
||||
this.matrix.Matrix = matrix; |
||||
} |
||||
|
||||
void AddChildrenToMatrix(DependencyMatrix matrix, IEnumerable<INode> nodes) |
||||
{ |
||||
foreach (var node in nodes) { |
||||
matrix.AddColumn(node); |
||||
matrix.AddRow(node); |
||||
AddChildrenToMatrix(matrix, node.Children); |
||||
} |
||||
} |
||||
|
||||
void ViewScrollChanged(object sender, ScrollChangedEventArgs e) |
||||
{ |
||||
ScrollViewer scrollViewer = e.OriginalSource as ScrollViewer; |
||||
ScrollViewer topTree = this.topTree.GetScrollViewer(); |
||||
ScrollViewer leftTree = this.leftTree.GetScrollViewer(); |
||||
if (scrollViewer.Content == matrix) { |
||||
scrollViewer.SynchronizeScroll(topTree, ScrollSyncOption.HorizontalToVertical); |
||||
scrollViewer.SynchronizeScroll(leftTree, ScrollSyncOption.Vertical); |
||||
} |
||||
} |
||||
|
||||
#region Update MatrixControl
|
||||
|
||||
bool rebuildLeftNodeListRequested; |
||||
|
||||
void BuildLeftINodeList(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (rebuildLeftNodeListRequested) |
||||
return; |
||||
rebuildLeftNodeListRequested = true; |
||||
Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new Action(SetVisibleItemsForRows)); |
||||
} |
||||
|
||||
void SetVisibleItemsForRows() |
||||
{ |
||||
List<INode> leftNodes = new List<INode>(); |
||||
foreach (MatrixTreeNode node in leftTree.Items.OfType<MatrixTreeNode>()) { |
||||
var n = node.Node; |
||||
leftNodes.Add(n); |
||||
} |
||||
rebuildLeftNodeListRequested = false; |
||||
matrix.SetVisibleItems(HeaderType.Rows, leftNodes); |
||||
} |
||||
|
||||
|
||||
bool rebuildTopNodeListRequested; |
||||
|
||||
void BuildTopINodeList(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (rebuildTopNodeListRequested) |
||||
return; |
||||
rebuildTopNodeListRequested = true; |
||||
Dispatcher.BeginInvoke(DispatcherPriority.DataBind, new Action(SetVisibleItemsForColumns)); |
||||
} |
||||
|
||||
void SetVisibleItemsForColumns() |
||||
{ |
||||
List<INode> topNodes = new List<INode>(); |
||||
foreach (MatrixTreeNode node in topTree.Items.OfType<MatrixTreeNode>()) { |
||||
var n = node.Node; |
||||
topNodes.Add(n); |
||||
} |
||||
rebuildTopNodeListRequested = false; |
||||
matrix.SetVisibleItems(HeaderType.Columns, topNodes); |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
@ -1,13 +1,14 @@
@@ -1,13 +1,14 @@
|
||||
<UserControl x:Class="ICSharpCode.CodeQuality.Gui.MainView" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:gui="clr-namespace:ICSharpCode.CodeQuality.Gui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<DockPanel> |
||||
<ToolBar DockPanel.Dock="Top"> |
||||
<Button>Add Assembly</Button> |
||||
<Button Click="AddAssemblyClick">Add Assembly</Button> |
||||
</ToolBar> |
||||
<TabControl> |
||||
<TabItem Header="Dependency Matrix"> |
||||
|
||||
<gui:DependencyMatrixView x:Name="matrix" /> |
||||
</TabItem> |
||||
</TabControl> |
||||
</DockPanel> |
||||
|
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// 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 ICSharpCode.CodeQuality.Engine.Dom; |
||||
using ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
/// <summary>
|
||||
/// Description of MatrixTreeNode.
|
||||
/// </summary>
|
||||
public class MatrixTreeNode : SharpTreeNode |
||||
{ |
||||
INode node; |
||||
|
||||
public INode Node { |
||||
get { return node; } |
||||
} |
||||
|
||||
public MatrixTreeNode(INode node) |
||||
{ |
||||
this.node = node; |
||||
} |
||||
|
||||
public override object Icon { |
||||
get { return NodeIconService.GetIcon(node); } |
||||
} |
||||
|
||||
public override object Text { |
||||
get { return node.Name; } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,195 @@
@@ -0,0 +1,195 @@
|
||||
// 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.Text; |
||||
using System.Windows.Media.Imaging; |
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
using ICSharpCode.Core.Presentation; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.CodeQuality.Gui |
||||
{ |
||||
public static class NodeIconService |
||||
{ |
||||
static readonly BitmapSource NamespaceNode = GetImage("Icons.16x16.NameSpace"); |
||||
static readonly BitmapSource Assembly = GetImage("Icons.16x16.Assembly"); |
||||
|
||||
static readonly BitmapSource Class = GetImage("Icons.16x16.Class"); |
||||
static readonly BitmapSource InternalClass = GetImage("Icons.16x16.InternalClass"); |
||||
static readonly BitmapSource ProtectedClass = GetImage("Icons.16x16.ProtectedClass"); |
||||
static readonly BitmapSource PrivateClass = GetImage("Icons.16x16.PrivateClass"); |
||||
|
||||
static readonly BitmapSource Struct = GetImage("Icons.16x16.Struct"); |
||||
static readonly BitmapSource InternalStruct = GetImage("Icons.16x16.InternalStruct"); |
||||
static readonly BitmapSource ProtectedStruct = GetImage("Icons.16x16.ProtectedStruct"); |
||||
static readonly BitmapSource PrivateStruct = GetImage("Icons.16x16.PrivateStruct"); |
||||
|
||||
static readonly BitmapSource Interface = GetImage("Icons.16x16.Interface"); |
||||
static readonly BitmapSource InternalInterface = GetImage("Icons.16x16.InternalInterface"); |
||||
static readonly BitmapSource ProtectedInterface = GetImage("Icons.16x16.ProtectedInterface"); |
||||
static readonly BitmapSource PrivateInterface = GetImage("Icons.16x16.PrivateInterface"); |
||||
|
||||
static readonly BitmapSource Enum = GetImage("Icons.16x16.Enum"); |
||||
static readonly BitmapSource InternalEnum = GetImage("Icons.16x16.InternalEnum"); |
||||
static readonly BitmapSource ProtectedEnum = GetImage("Icons.16x16.ProtectedEnum"); |
||||
static readonly BitmapSource PrivateEnum = GetImage("Icons.16x16.PrivateEnum"); |
||||
|
||||
static readonly BitmapSource Delegate = GetImage("Icons.16x16.Delegate"); |
||||
static readonly BitmapSource InternalDelegate = GetImage("Icons.16x16.InternalDelegate"); |
||||
static readonly BitmapSource ProtectedDelegate = GetImage("Icons.16x16.ProtectedDelegate"); |
||||
static readonly BitmapSource PrivateDelegate = GetImage("Icons.16x16.PrivateDelegate"); |
||||
|
||||
static readonly BitmapSource MethodNode = GetImage("Icons.16x16.Method"); |
||||
static readonly BitmapSource ProtectedMethod = GetImage("Icons.16x16.ProtectedMethod"); |
||||
static readonly BitmapSource PrivateMethod = GetImage("Icons.16x16.PrivateMethod"); |
||||
|
||||
static readonly BitmapSource Property = GetImage("Icons.16x16.Property"); |
||||
static readonly BitmapSource ProtectedProperty = GetImage("Icons.16x16.ProtectedProperty"); |
||||
static readonly BitmapSource PrivateProperty = GetImage("Icons.16x16.PrivateProperty"); |
||||
|
||||
static readonly BitmapSource Field = GetImage("Icons.16x16.Field"); |
||||
static readonly BitmapSource ProtectedField = GetImage("Icons.16x16.ProtectedField"); |
||||
static readonly BitmapSource PrivateField = GetImage("Icons.16x16.PrivateField"); |
||||
|
||||
static readonly BitmapSource Event = GetImage("Icons.16x16.Event"); |
||||
static readonly BitmapSource ProtectedEvent = GetImage("Icons.16x16.ProtectedEvent"); |
||||
static readonly BitmapSource PrivateEvent = GetImage("Icons.16x16.PrivateEvent"); |
||||
|
||||
static readonly BitmapSource ConstantField = GetImage("Icons.16x16.Literal"); |
||||
|
||||
static BitmapSource GetImage(string name) |
||||
{ |
||||
try { |
||||
return PresentationResourceService.GetBitmapSource(name); |
||||
} catch (Exception) { |
||||
return null; // image isn't needed necessarily
|
||||
} |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(FieldNode field) |
||||
{ |
||||
// if (field.Field.IsPrivate)
|
||||
// return PrivateField;
|
||||
// if (field.Field.IsProtected)
|
||||
// return ProtectedField;
|
||||
// if (field.Field.IsConst)
|
||||
// return ConstantField;
|
||||
|
||||
return Field; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(INode node) |
||||
{ |
||||
if (node is AssemblyNode) |
||||
return GetIcon((AssemblyNode)node); |
||||
if (node is NamespaceNode) |
||||
return GetIcon((NamespaceNode)node); |
||||
if (node is TypeNode) |
||||
return GetIcon((TypeNode)node); |
||||
if (node is MethodNode) |
||||
return GetIcon((MethodNode)node); |
||||
if (node is FieldNode) |
||||
return GetIcon((FieldNode)node); |
||||
if (node is PropertyNode) |
||||
return GetIcon((PropertyNode)node); |
||||
if (node is EventNode) |
||||
return GetIcon((EventNode)node); |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(EventNode node) |
||||
{ |
||||
// if (node.Event.IsPrivate)
|
||||
// return PrivateEventField;
|
||||
// if (node.Event.IsProtected)
|
||||
// return ProtectedEventField;
|
||||
|
||||
return Event; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(MethodNode method) |
||||
{ |
||||
// if (method.Method.IsPrivate)
|
||||
// return PrivateMethod;
|
||||
// if (method.Method.IsProtected)
|
||||
// return ProtectedMethod;
|
||||
|
||||
// if (method.IsGetter || method.IsSetter)
|
||||
// {
|
||||
// if (method.IsPublic)
|
||||
// return PropertyMethod;
|
||||
// if (method.IsPrivate)
|
||||
// return PrivatePropertyMethod;
|
||||
// if (method.IsProtected)
|
||||
// return ProtectedPropertyMethod;
|
||||
// }
|
||||
|
||||
return MethodNode; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(PropertyNode property) |
||||
{ |
||||
return Property; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(AssemblyNode module) |
||||
{ |
||||
return Assembly; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(NamespaceNode ns) |
||||
{ |
||||
return NamespaceNode; |
||||
} |
||||
|
||||
public static BitmapSource GetIcon(TypeNode type) |
||||
{ |
||||
switch (type.TypeDefinition.Kind) { |
||||
case TypeKind.Enum: |
||||
if (type.TypeDefinition.IsPublic) |
||||
return Enum; |
||||
if (type.TypeDefinition.IsProtected) |
||||
return ProtectedEnum; |
||||
if (type.TypeDefinition.IsInternal) |
||||
return InternalEnum; |
||||
return PrivateEnum; |
||||
case TypeKind.Struct: |
||||
if (type.TypeDefinition.IsPublic) |
||||
return Struct; |
||||
if (type.TypeDefinition.IsProtected) |
||||
return ProtectedStruct; |
||||
if (type.TypeDefinition.IsInternal) |
||||
return InternalStruct; |
||||
return PrivateStruct; |
||||
case TypeKind.Interface: |
||||
if (type.TypeDefinition.IsPublic) |
||||
return Interface; |
||||
if (type.TypeDefinition.IsProtected) |
||||
return ProtectedInterface; |
||||
if (type.TypeDefinition.IsInternal) |
||||
return InternalInterface; |
||||
return PrivateInterface; |
||||
case TypeKind.Delegate: |
||||
if (type.TypeDefinition.IsPublic) |
||||
return Delegate; |
||||
if (type.TypeDefinition.IsProtected) |
||||
return ProtectedDelegate; |
||||
if (type.TypeDefinition.IsInternal) |
||||
return InternalDelegate; |
||||
return PrivateDelegate; |
||||
default: |
||||
if (type.TypeDefinition.IsPublic) |
||||
return Class; |
||||
if (type.TypeDefinition.IsProtected) |
||||
return ProtectedClass; |
||||
if (type.TypeDefinition.IsInternal) |
||||
return InternalClass; |
||||
return PrivateClass; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
// 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.Media; |
||||
|
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
|
||||
namespace ICSharpCode.CodeQuality |
||||
{ |
||||
/// <summary>
|
||||
/// Description of DependencyColorizer.
|
||||
/// </summary>
|
||||
public class DependencyColorizer : IColorizer<Relationship> |
||||
{ |
||||
private Dictionary<Color, SolidColorBrush> cache; |
||||
|
||||
public DependencyColorizer() |
||||
{ |
||||
cache = new Dictionary<Color, SolidColorBrush>(); |
||||
} |
||||
|
||||
public SolidColorBrush GetColorBrush(Relationship relationship) |
||||
{ |
||||
var color = GetColor(relationship); |
||||
if (cache.ContainsKey(color)) |
||||
return cache[color]; |
||||
|
||||
var brush = new SolidColorBrush(color); |
||||
brush.Freeze(); |
||||
|
||||
cache[color] = brush; |
||||
|
||||
return brush; |
||||
} |
||||
|
||||
public Color GetColor(Relationship relationship) |
||||
{ |
||||
if (relationship == null) |
||||
return Colors.Transparent; |
||||
|
||||
if (relationship.Relationships.Any(r => r == RelationshipType.UseThis)) |
||||
return Colors.LightBlue; |
||||
if (relationship.Relationships.Any(r => r == RelationshipType.UsedBy)) |
||||
return Colors.Violet; |
||||
if (relationship.Relationships.Any(r => r == RelationshipType.Same)) |
||||
return Colors.Gray; |
||||
|
||||
return Colors.Transparent; |
||||
} |
||||
|
||||
public SolidColorBrush GetColorBrushMixedWith(Color color, Relationship relationship) |
||||
{ |
||||
var mixedColor = GetColor(relationship); |
||||
mixedColor = mixedColor.MixedWith(color); |
||||
|
||||
if (cache.ContainsKey(mixedColor)) |
||||
return cache[mixedColor]; |
||||
|
||||
var brush = new SolidColorBrush(mixedColor); |
||||
brush.Freeze(); |
||||
|
||||
cache[mixedColor] = brush; |
||||
|
||||
return brush; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
// 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; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace ICSharpCode.CodeQuality |
||||
{ |
||||
public class DoubleKeyDictionary<K, T, V> : |
||||
IEnumerable<DoubleKeyPairValue<K, T, V>>, |
||||
IEquatable<DoubleKeyDictionary<K, T, V>> |
||||
{ |
||||
private Dictionary<T, V> innerDictionary; |
||||
|
||||
public DoubleKeyDictionary() |
||||
{ |
||||
OuterDictionary = new Dictionary<K, Dictionary<T, V>>(); |
||||
} |
||||
|
||||
private Dictionary<K, Dictionary<T, V>> OuterDictionary { get; set; } |
||||
|
||||
public void Add(K key1, T key2, V value) |
||||
{ |
||||
if (OuterDictionary.ContainsKey(key1)) { |
||||
if (innerDictionary.ContainsKey(key2)) { |
||||
OuterDictionary[key1][key2] = value; |
||||
} |
||||
else { |
||||
innerDictionary = OuterDictionary[key1]; |
||||
innerDictionary.Add(key2, value); |
||||
OuterDictionary[key1] = innerDictionary; |
||||
} |
||||
} |
||||
else { |
||||
innerDictionary = new Dictionary<T, V>(); |
||||
innerDictionary[key2] = value; |
||||
OuterDictionary.Add(key1, innerDictionary); |
||||
} |
||||
} |
||||
|
||||
public V this[K index1, T index2] |
||||
{ |
||||
get |
||||
{ |
||||
Dictionary<T, V> value1; |
||||
OuterDictionary.TryGetValue(index1, out value1); |
||||
if (value1 == null) |
||||
return default(V); |
||||
|
||||
V value2; |
||||
value1.TryGetValue(index2, out value2); |
||||
if (value2 == null) |
||||
return default(V); |
||||
|
||||
return value2; |
||||
} |
||||
|
||||
set |
||||
{ |
||||
Add(index1, index2, value); |
||||
} |
||||
} |
||||
|
||||
#region IEnumerable<DoubleKeyPairValue<K,T,V>> Members
|
||||
|
||||
public IEnumerator<DoubleKeyPairValue<K, T, V>> GetEnumerator() |
||||
{ |
||||
foreach (KeyValuePair<K, Dictionary<T, V>> outer in OuterDictionary) |
||||
foreach (KeyValuePair<T, V> inner in outer.Value) |
||||
yield return new DoubleKeyPairValue<K, T, V>(outer.Key, inner.Key, inner.Value); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||
{ |
||||
return GetEnumerator(); |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable<DoubleKeyDictionary<K,T,V>> Members
|
||||
|
||||
public bool Equals(DoubleKeyDictionary<K, T, V> other) |
||||
{ |
||||
if (OuterDictionary.Keys.Count != other.OuterDictionary.Keys.Count) |
||||
return false; |
||||
|
||||
bool isEqual = true; |
||||
|
||||
foreach (KeyValuePair<K, Dictionary<T, V>> innerItems in OuterDictionary) { |
||||
if (!other.OuterDictionary.ContainsKey(innerItems.Key)) |
||||
isEqual = false; |
||||
|
||||
if (!isEqual) |
||||
break; |
||||
|
||||
// here we can be sure that the key is in both lists,
|
||||
// but we need to check the contents of the inner dictionary
|
||||
Dictionary<T, V> otherInnerDictionary = other.OuterDictionary[innerItems.Key]; |
||||
foreach (KeyValuePair<T, V> innerValue in innerItems.Value) { |
||||
if (!otherInnerDictionary.ContainsValue(innerValue.Value)) |
||||
isEqual = false; |
||||
if (!otherInnerDictionary.ContainsKey(innerValue.Key)) |
||||
isEqual = false; |
||||
} |
||||
|
||||
if (!isEqual) |
||||
break; |
||||
} |
||||
|
||||
return isEqual; |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
|
||||
public class DoubleKeyPairValue<K, T, V> |
||||
{ |
||||
public K Key1 { get; set; } |
||||
public T Key2 { get; set; } |
||||
public V Value { get; set; } |
||||
|
||||
public DoubleKeyPairValue(K key1, T key2, V value) { |
||||
Key1 = key1; |
||||
Key2 = key2; |
||||
Value = value; |
||||
} |
||||
|
||||
public override string ToString() |
||||
{ |
||||
return Key1.ToString() + " - " + Key2.ToString() + " - " + Value.ToString(); |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
// 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.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Media; |
||||
|
||||
using ICSharpCode.CodeQuality.Engine.Dom; |
||||
using ICSharpCode.CodeQuality.Gui; |
||||
using ICSharpCode.TreeView; |
||||
|
||||
namespace ICSharpCode.CodeQuality |
||||
{ |
||||
/// <summary>
|
||||
/// Description of Extensions.
|
||||
/// </summary>
|
||||
public static class Extensions |
||||
{ |
||||
public static void FillTree(SharpTreeView tree, IEnumerable<INode> rootNodes) |
||||
{ |
||||
tree.Root = new SharpTreeNode(); |
||||
CreateItems(rootNodes, tree.Root); |
||||
} |
||||
|
||||
static void CreateItems(IEnumerable<INode> nodes, SharpTreeNode parent) |
||||
{ |
||||
foreach (INode node in nodes) { |
||||
var item = new MatrixTreeNode(node); |
||||
parent.Children.Add(item); |
||||
CreateItems(node.Children, item); |
||||
} |
||||
} |
||||
|
||||
public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject |
||||
{ |
||||
// depth-first Search
|
||||
int count = VisualTreeHelper.GetChildrenCount(obj); |
||||
for (int i = 0; i < count; i++) { |
||||
DependencyObject child = VisualTreeHelper.GetChild(obj, i); |
||||
|
||||
if (child is T) |
||||
return (T)child; |
||||
else { |
||||
T childOfChild = FindVisualChild<T>(child); |
||||
|
||||
if (childOfChild != null) |
||||
return childOfChild; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public static TContainer GetParent<TContainer>(this DependencyObject obj) where TContainer : DependencyObject |
||||
{ |
||||
if (obj == null) |
||||
return null; |
||||
while (VisualTreeHelper.GetParent(obj) != null && !(obj is TContainer)) |
||||
obj = VisualTreeHelper.GetParent(obj); |
||||
return obj as TContainer; |
||||
} |
||||
|
||||
public static Color MixedWith(this Color c1, Color c2) |
||||
{ |
||||
var percent = .5f; |
||||
var amountFrom = 1.0f - percent; |
||||
|
||||
return Color.FromArgb( |
||||
(byte)(c1.A * amountFrom + c2.A * percent), |
||||
(byte)(c1.R * amountFrom + c2.R * percent), |
||||
(byte)(c1.G * amountFrom + c2.G * percent), |
||||
(byte)(c1.B * amountFrom + c2.B * percent)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
// 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; |
||||
using System.Collections.Generic; |
||||
using System.Windows.Media; |
||||
|
||||
namespace ICSharpCode.CodeQuality |
||||
{ |
||||
/// <summary>
|
||||
/// Description of IColorizer.
|
||||
/// </summary>
|
||||
public interface IColorizer<TValue> |
||||
{ |
||||
SolidColorBrush GetColorBrush(TValue value); |
||||
SolidColorBrush GetColorBrushMixedWith(Color color, TValue value); |
||||
Color GetColor(TValue value); |
||||
} |
||||
} |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
// 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.Runtime.InteropServices; |
||||
|
||||
namespace ICSharpCode.CodeQuality |
||||
{ |
||||
/// <summary>
|
||||
/// Description of Utils.
|
||||
/// </summary>
|
||||
public class Utils |
||||
{ |
||||
[DllImport("gdi32.dll")] |
||||
public static extern bool DeleteObject(IntPtr hObject); |
||||
} |
||||
} |
Loading…
Reference in new issue